BeYourCover Jobs API

The Jobs API from BeYourCover — 2 operation(s) for jobs.

Operations 2

GET /api/v1/jobs/{jobId} Poll a job's status and result #
GET /api/v1/jobs List jobs #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/beyourcover-com:beyourcover-com-jobs-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

beyourcover-com-jobs-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: BeYourCover Partner Jobs API
  version: 1.1.0
  description: 'Enterprise/partner REST API for AI-powered book cover generation: covers from book details or from reference images, variations, edits, replacing a person with a photo, text removal, upscales, audiobook covers, and full print wraps for Amazon KDP with a print-ready PDF. Every endpoint except `GET /api/v1/health` requires a partner API key (`Authorization: Bearer byc_sk_...`). Long-running operations (generation, reference-image generation, variations, edits, replacing a person, text removal, upscales, audiobook covers, print wraps and a wrap''s front-panel re-extension) return `202 Accepted` with a job envelope; poll `GET /api/v1/jobs/{jobId}` or receive a webhook. Re-typesetting a wrap (`POST /api/v1/wraps/{wrapId}/render`) runs no model, so it answers `200` directly. All error responses use a uniform envelope: `{ "error": { "code": string, "message": string } }`.'
servers:
- url: https://beyourcover.com
  description: Production. All paths below are relative to the site origin.
security:
- ApiKeyBearer: []
tags:
- name: Jobs
paths:
  /api/v1/jobs/{jobId}:
    get:
      tags:
      - Jobs
      operationId: getJob
      summary: Poll a job's status and result
      description: 'Returns the job envelope. For `completed` jobs, all `covers[].signedUrl` values in `result` are freshly re-signed on every poll (1-hour expiry) and internal storage paths are stripped. Jobs belonging to a different API key/subscription return `404 job_not_found` (not 403). A job with `source: "web"` ran in the web app: it returns its status and credits, and `result` is always null.'
      parameters:
      - name: jobId
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: Job id returned by a job-creating endpoint (also embedded in `poll_url`).
      responses:
        '200':
          description: Current job state.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Job'
        '400':
          description: '`code`: `missing_job_id` (defensive; the path parameter is normally always present).'
          x-error-codes:
          - missing_job_id
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: 'Job not found, or found but owned by a different API key/subscription. `code`: `job_not_found`.'
          x-error-codes:
          - job_not_found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          description: '`code`: `temporarily_unavailable` — the workspace''s plan could not be checked. Retry.'
          x-error-codes:
          - temporarily_unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
  /api/v1/jobs:
    get:
      tags:
      - Jobs
      operationId: listJobs
      summary: List jobs
      description: 'Lists the subscription''s jobs, newest first, with optional status/operation/source filters and keyset cursor pagination. The list also holds the jobs the web app records when a workspace member spends credits there (`source: "web"`, for example `edit_font`, `marketing_resource` or `wrap_cover_generate`): they draw on the same credit balance. Result payloads are omitted — poll `GET /api/v1/jobs/{jobId}` for signed cover URLs.'
      parameters:
      - name: status
        in: query
        required: false
        schema:
          type: string
          enum:
          - queued
          - processing
          - completed
          - failed
        description: Filter by job status.
      - name: operation
        in: query
        required: false
        schema:
          type: string
          enum:
          - generate
          - variation
          - edit_image
          - upscale
          - audiobook_cover
          - remove_text
          - generate_reference
          - replace_person
          - wrap
          - wrap_extend_front
          - import_cover
          - generate_single
          - edit_font
          - convert_style
          - layerize_text
          - remove_text_variants
          - audiobook_generate
          - marketing_resource
          - kit_regeneration
          - brand_kit_extract
          - series_next_book
          - wrap_cover_generate
          - wrap_cover_regenerate
          - audiobook_upscale
          - refine_cover
          - wrap_back_cover_generate
          - wrap_cover_export
        description: 'Filter by operation. Accepts every operation a listed job can carry: the API''s, the web app''s, and older web operations that nothing writes now (`audiobook_upscale`, `refine_cover`, `wrap_back_cover_generate`, `wrap_cover_export`).'
      - name: source
        in: query
        required: false
        schema:
          type: string
          enum:
          - api
          - web
        description: 'Filter by where the job ran: `api` (this API or the MCP server) or `web` (the web app).'
      - $ref: '#/components/parameters/PageLimit'
      - $ref: '#/components/parameters/PageCursor'
      responses:
        '200':
          description: One page of jobs.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobList'
        '400':
          description: '`code` is one of: `invalid_status_filter`, `invalid_operation_filter`, `invalid_source_filter`, `invalid_limit`, `invalid_cursor`.'
          x-error-codes:
          - invalid_status_filter
          - invalid_operation_filter
          - invalid_source_filter
          - invalid_limit
          - invalid_cursor
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          description: Server error. `code` is `fetch_failed` or `internal_error`.
          x-error-codes:
          - fetch_failed
          - internal_error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
components:
  responses:
    Forbidden:
      description: 'The API key is valid but its owner has no active enterprise subscription (`forbidden`); or the acting member''s role does not allow the call: a reviewer cannot spend credits or change books (`forbidden_role`), and only the member who created a book may edit it or its covers (`not_book_creator`).'
      x-error-codes:
      - forbidden
      - forbidden_role
      - not_book_creator
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    Unauthorized:
      description: 'Missing/malformed API key, unknown or inactive key, or inactive subscription detected during credit checks. `code`: `unauthorized`.'
      x-error-codes:
      - unauthorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    InternalError:
      description: 'Unexpected server error. `code`: `internal_error`.'
      x-error-codes:
      - internal_error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
  schemas:
    WrapDimensions:
      type: object
      description: Print geometry at 300 DPI. All inch values are the finished canvas including bleed.
      properties:
        spineWidth:
          type: number
          description: 'Spine width in inches: derived from pageCount and paperType on a KDP wrap, entered by hand on a Barnes & Noble design from the editor.'
        fullWidth:
          type: number
          description: Full wrap width in inches (back + spine + front + bleed).
        fullHeight:
          type: number
          description: Full wrap height in inches (trim height + bleed).
        pixelWidth:
          type: integer
          description: fullWidth x dpi, rounded.
        pixelHeight:
          type: integer
          description: fullHeight x dpi, rounded.
        dpi:
          type: integer
          description: Always 300.
        bleed:
          type: number
          description: Bleed in inches per edge (0 for hardcover printed case).
        safeTextMargin:
          type: number
          description: Minimum inches between text and the trim edge.
        minFontSize:
          type: number
          description: Smallest point size the layout engine will emit.
        canHaveSpineText:
          type: boolean
          description: False when the spine is too thin for lettering (under 79 pages on KDP); spine text is dropped with a warning.
        barcodeZone:
          type: object
          description: Rectangle in inches, relative to the BACK COVER origin, that the printer covers with the barcode. The layout engine keeps text out of it.
          properties:
            x:
              type: number
            y:
              type: number
            width:
              type: number
            height:
              type: number
        sections:
          type: object
          description: Panel boundaries in inches from the left edge of the full wrap.
          additionalProperties:
            type: number
        bindingType:
          type: string
          enum:
          - paperback
          - hardcover
          - dust-jacket
          description: '`dust-jacket` (with flaps) appears only on Barnes & Noble designs made in the browser editor.'
    JobSummary:
      type: object
      required:
      - jobId
      - status
      - operation
      - source
      - created_at
      - poll_url
      properties:
        jobId:
          type: string
          format: uuid
        status:
          type: string
          enum:
          - queued
          - processing
          - completed
          - failed
        operation:
          type: string
          enum:
          - generate
          - variation
          - edit_image
          - upscale
          - audiobook_cover
          - remove_text
          - generate_reference
          - replace_person
          - wrap
          - wrap_extend_front
          - import_cover
          - generate_single
          - edit_font
          - convert_style
          - layerize_text
          - remove_text_variants
          - audiobook_generate
          - marketing_resource
          - kit_regeneration
          - brand_kit_extract
          - series_next_book
          - wrap_cover_generate
          - wrap_cover_regenerate
          - audiobook_upscale
          - refine_cover
          - wrap_back_cover_generate
          - wrap_cover_export
        source:
          type: string
          enum:
          - api
          - web
          description: '`api`: started through this API or the MCP server. `web`: recorded by the web app when a workspace member spent credits there; its output stays in the app.'
        external_ref:
          type:
          - string
          - 'null'
        credits_used:
          type:
          - integer
          - 'null'
        bookId:
          type:
          - string
          - 'null'
          format: uuid
        error:
          type:
          - string
          - 'null'
          description: Failure message when status is `failed`.
        created_at:
          type: string
          format: date-time
        started_at:
          type:
          - string
          - 'null'
          format: date-time
        completed_at:
          type:
          - string
          - 'null'
          format: date-time
        poll_url:
          type: string
          description: Path of the job detail endpoint (result payloads with signed URLs live there, not in this list).
        actor_user_id:
          type:
          - string
          - 'null'
          format: uuid
          description: 'The workspace member the job acted as: the key owner, or the member signed in over MCP OAuth. Null on jobs created before 2026-10-20.'
    WrapJobResult:
      type: object
      description: Result payload for a `wrap` or `wrap_extend_front` job. Unlike cover operations this carries an `assets` map, not a `covers` array — a wrap is several renditions of ONE design. For `wrap_extend_front`, `designStyle` and `preset` are omitted (the wrap's stored layout is reused).
      required:
      - wrapId
      - assets
      properties:
        wrapId:
          type: string
          format: uuid
          description: Pass to GET /api/v1/wraps/{wrapId} and the render endpoint.
        bookId:
          type: string
          format: uuid
        coverId:
          type: string
          format: uuid
          description: Public id of the cover used as the front panel.
        designStyle:
          type: string
          enum:
          - solid
          - textured
          - continuation
          - complementary
        preset:
          type: string
          enum:
          - standard
          - blurb-only
          - minimal
        dims:
          $ref: '#/components/schemas/WrapDimensions'
        layout_report:
          $ref: '#/components/schemas/WrapLayoutReport'
        warnings:
          type: array
          items:
            $ref: '#/components/schemas/WrapWarning'
        assets:
          $ref: '#/components/schemas/WrapAssets'
    GenerateJobResult:
      type: object
      required:
      - bookId
      - covers
      properties:
        bookId:
          type: string
          format: uuid
        covers:
          type: array
          items:
            $ref: '#/components/schemas/GeneratedCover'
      description: Result payload for `generate` jobs. Only successfully generated covers are included; `credits_used` reflects the successful count.
    AssetJobResult:
      type: object
      required:
      - covers
      properties:
        covers:
          type: array
          items:
            $ref: '#/components/schemas/CoverAssetResult'
      description: Result payload for `upscale` and `audiobook_cover` jobs. The new asset is attached to the SAME cover (coverId is the source cover's public id).
    Job:
      type: object
      required:
      - jobId
      - status
      - operation
      - source
      - external_ref
      - credits_used
      - created_at
      - started_at
      - completed_at
      - result
      - error
      properties:
        jobId:
          type: string
          format: uuid
        status:
          type: string
          enum:
          - queued
          - processing
          - completed
          - failed
        operation:
          type: string
          enum:
          - generate
          - variation
          - edit_image
          - upscale
          - audiobook_cover
          - remove_text
          - generate_reference
          - replace_person
          - wrap
          - wrap_extend_front
          - import_cover
          - generate_single
          - edit_font
          - convert_style
          - layerize_text
          - remove_text_variants
          - audiobook_generate
          - marketing_resource
          - kit_regeneration
          - brand_kit_extract
          - series_next_book
          - wrap_cover_generate
          - wrap_cover_regenerate
          - audiobook_upscale
          - refine_cover
          - wrap_back_cover_generate
          - wrap_cover_export
        source:
          type: string
          enum:
          - api
          - web
          description: '`api`: started through this API or the MCP server. `web`: recorded by the web app when a workspace member spent credits there; its output stays in the app.'
        external_ref:
          type:
          - string
          - 'null'
        credits_used:
          type:
          - integer
          - 'null'
          description: Credits actually consumed (set on completion; partial failures reduce it and refund the difference).
        created_at:
          type: string
          format: date-time
        started_at:
          type:
          - string
          - 'null'
          format: date-time
        completed_at:
          type:
          - string
          - 'null'
          format: date-time
        result:
          oneOf:
          - $ref: '#/components/schemas/GenerateJobResult'
          - $ref: '#/components/schemas/CoverOperationJobResult'
          - $ref: '#/components/schemas/AssetJobResult'
          - $ref: '#/components/schemas/WrapJobResult'
          - type: 'null'
          description: 'Null until the job completes. Shape depends on `operation`: `generate`/`generate_reference` -> GenerateJobResult; `variation`/`edit_image` -> CoverOperationJobResult; `upscale`/`audiobook_cover`/`remove_text` -> AssetJobResult; `wrap`/`wrap_extend_front` -> WrapJobResult. On each poll of a completed job, signed URLs and their `expiresAt` are refreshed. Always null for a `web` job.'
        error:
          type:
          - string
          - 'null'
          description: Failure message when status is `failed` (raw error_message string, not an error envelope).
        actor_user_id:
          type:
          - string
          - 'null'
          format: uuid
          description: 'The workspace member the job acted as: the key owner, or the member signed in over MCP OAuth. Null on jobs created before 2026-10-20.'
    CoverOperationJobResult:
      type: object
      required:
      - sourceCoverId
      - covers
      properties:
        sourceCoverId:
          type: string
          format: uuid
          description: Public id of the cover the operation was applied to.
        covers:
          type: array
          items:
            $ref: '#/components/schemas/GeneratedCover'
        failed_models:
          type: array
          items:
            type: string
          description: '`replace_person` only: the models of the pair that made no version. The job still succeeds, and keeps its credit, when one model made a version.'
      description: Result payload for `variation`, `edit_image` and `replace_person` jobs. Each entry is a NEW child cover. A `replace_person` job returns up to two covers, one per model, and names each model in `model`.
    WrapLayoutReport:
      type: object
      description: What the compositor actually drew, after auto-fit and guardrails.
      properties:
        width:
          type: integer
        height:
          type: integer
        dpi:
          type: integer
        blocks:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              fontSize:
                type: number
                description: Point size after auto-fit, which may be smaller than requested.
              heightPx:
                type: integer
              overflowsPanel:
                type: boolean
        warnings:
          type: array
          items:
            $ref: '#/components/schemas/WrapWarning'
    CoverAssetResult:
      type: object
      required:
      - coverId
      - asset
      - signedUrl
      - expiresAt
      properties:
        coverId:
          type: string
          format: uuid
          description: Public id of the (source) cover the asset belongs to.
        asset:
          type: string
          enum:
          - full
          - audiobook_preview
          - audiobook_full
          - no_text
          - no_text_full
          description: 'Which asset was produced: `full` (upscale of preview), `audiobook_full` (upscale of audiobook_preview), `audiobook_preview` (audiobook_cover jobs), `no_text` (remove_text jobs), or `no_text_full` (upscale of no_text).'
        signedUrl:
          type: string
          format: uri
        expiresAt:
          type: string
          format: date-time
    WrapWarning:
      type: object
      description: A layout adjustment the engine made, or a limitation of the finished wrap. Warnings never fail a job — they tell you what a human at the editor would have seen and fixed.
      required:
      - code
      - message
      properties:
        code:
          type: string
          enum:
          - text_too_long_for_band
          - text_too_long_for_block
          - preset_not_applied
          - text_overflows_panel
          - clamped_to_safe_area
          - moved_clear_of_barcode
          - barcode_zone_unavoidable
          - font_size_raised_to_minimum
          - spine_too_thin_for_text
          - italic_not_available
          - bold_not_available
          - image_block_not_rendered
          - spine_image_not_allowed
          - front_outpaint_trimmed
          - front_outpaint_incomplete
          - low_text_contrast
          - back_converted_to_solid
        blockId:
          type: string
          description: The text or image block the warning applies to, when it is block-specific.
        message:
          type: string
    WrapAssets:
      type: object
      description: Renditions of one wrap design. Re-signed on every poll/read.
      properties:
        wrap_preview:
          allOf:
          - $ref: '#/components/schemas/WrapAsset'
          description: 1024px-wide JPEG for on-screen review.
        wrap_flat:
          allOf:
          - $ref: '#/components/schemas/WrapAsset'
          description: Full-resolution composited JPEG at 300 DPI.
        wrap_pdf:
          allOf:
          - $ref: '#/components/schemas/WrapAsset'
          description: 'Print-ready PDF sized to fullWidth x fullHeight inches — the file you upload to KDP. The link is signed with `Content-Disposition: attachment`, so a browser saves the file (named like `wrap_cover_paperback_6x9_300pp_white_3820919b_1760000000000.pdf`, as the editor''s PDF export names it) instead of opening it in a tab.'
        back_art:
          allOf:
          - $ref: '#/components/schemas/WrapAsset'
          description: The generated back-cover artwork alone, without text. Present on GET /api/v1/wraps/{wrapId}.
    GeneratedCover:
      type: object
      required:
      - coverId
      - signedUrl
      - expiresAt
      properties:
        coverId:
          type: string
          format: uuid
          description: Public id of the cover. Use with the /api/v1/covers/{coverId} endpoints.
        signedUrl:
          type: string
          format: uri
          description: Time-limited signed URL for the preview image (1 hour).
        expiresAt:
          type: string
          format: date-time
        coverStyle:
          type: string
          description: Template/style id used to render the cover (e.g. a V2 template id).
        prompt:
          type: string
          description: The generation prompt stored for this cover.
        model:
          type: string
          description: '`replace_person` only: the image model that made this version.'
    ErrorEnvelope:
      type: object
      required:
      - error
      properties:
        error:
          type: object
          required:
          - code
          - message
          properties:
            code:
              type: string
              description: Machine-readable error code (snake_case).
            message:
              type: string
              description: Human-readable explanation. For 500s this is always a generic message.
            details:
              type: object
              description: Optional machine-readable recovery information. 402 responses carry { balance, required, billing_url }; unknown-path 404s carry absolute URLs for the OpenAPI spec, documentation, API catalog, authentication guide and health probe.
      description: Uniform error envelope used by every non-2xx JSON response.
    JobList:
      type: object
      required:
      - jobs
      - next_cursor
      properties:
        jobs:
          type: array
          items:
            $ref: '#/components/schemas/JobSummary'
          description: Newest first. Result payloads are omitted — poll `GET /api/v1/jobs/{jobId}` for signed cover URLs.
        next_cursor:
          type:
          - string
          - 'null'
          description: Pass as `cursor` to fetch the next page. `null` when there are no more results.
    WrapAsset:
      type: object
      required:
      - signedUrl
      - expiresAt
      properties:
        signedUrl:
          type: string
          format: uri
        expiresAt:
          type: string
          format: date-time
  parameters:
    PageCursor:
      name: cursor
      in: query
      required: false
      schema:
        type: string
      description: Opaque cursor from a previous response's `next_cursor`. Omit for the first page.
    PageLimit:
      name: limit
      in: query
      required: false
      schema:
        type: integer
        minimum: 1
        maximum: 100
      description: Page size (default 20, max 100).
  securitySchemes:
    ApiKeyBearer:
      type: http
      scheme: bearer
      bearerFormat: byc_sk_{32 hex chars}
      description: 'Partner API key sent as `Authorization: Bearer byc_sk_...`. The key must match `^byc_sk_[0-9a-f]{32}$`. A malformed, unknown, or inactive key yields `401 unauthorized`; a valid key whose owner has no active enterprise subscription yields `403 forbidden`.'