---
title: "Generate covers for a book (async)"
method: POST
path: "/api/v1/covers/generate"
tags: ["Covers"]
---

# Generate covers for a book (async)

`POST /api/v1/covers/generate`

## Request

- Base URL: `https://beyourcover.com`
- URL: `https://beyourcover.com/api/v1/covers/generate`
- Auth: HTTP bearer

Queues an asynchronous cover-generation job through the V2 engine and returns `202` immediately. Costs `count` credits (reserved up-front; unused credits for partially/fully failed generations are refunded). Every genre is supported; a book in a genre that uses subgenres but has none set gets one before its first render, as in the app: the detected subgenre at confidence 50 or higher, else the genre's default (stored on the book). `422 unsupported_genre` remains as a safety net for a genre/subgenre with no route. Note: unlike the other job-creating endpoints, the fresh `202` envelope from this endpoint does NOT include an `operation` field (the idempotent `200` replay does).

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `bookId` string, uuid, required: ID of a book previously created via POST /api/v1/books. Must belong to the API key owner.
  - `count` integer: Number of covers to generate (1-5). Each cover costs 1 credit.
  - `templateId` string: Optional. Pin a specific V2 template. Must be a valid V2 template id (see GET /api/v1/templates); unknown ids return `invalid_template_id`.
  - `prompt` string: Optional. With `prompt_mode: "note"` (default, up to 1500 characters) it is a refinement note merged into the template's prompt (internally `mainElements`). With `prompt_mode: "verbatim"` (up to 6000 characters) it is the whole cover prompt, rendered as written.
  - `prompt_mode` 'note' | 'verbatim': How `prompt` is used. `note`: merged into a template prompt. `verbatim`: rendered exactly as written with no template, like the app's Prompt mode; `prompt` is then required, and `templateId`, `variant_overrides`, `motif_id`, `colorPalette` and `mood` are refused with `prompt_mode_conflict`.
  - `variant_overrides` object: Optional style choices for the pinned `templateId`, as axis → option (e.g. `{"titleColor": "bone-white"}`). The axes and options are the template's `variants` from GET /api/v1/templates; an axis left out (or set to null) is picked by the engine. Requires `templateId` (`variant_overrides_requires_template`); an unknown axis or option returns `invalid_variant_axis` or `invalid_variant_value`.
  - `motif_id` string: Optional motif id from GET /api/v1/books/{bookId}/motifs: the story object or symbol the cover shows. Applies to templates that render a motif. Not this book's → `404 motif_not_found`; a pinned template that renders no motif → `400 motif_not_used`.
  - `colorPalette` 'monochrome' | 'pastel' | 'earth' | 'muted' | 'dark' | 'bold' | 'warm' | 'cool' | 'metallic' | 'duotone': Optional. Must be one of the predefined palettes (`custom` is not accepted via the API).
  - `mood` 'intense' | 'mysterious' | 'romantic' | 'intellectual' | 'uplifting' | 'epic' | 'melancholic': Optional. Must be one of the predefined mood values.
  - `external_ref` string: Optional caller-supplied reference, stored on the job and echoed in responses and webhooks.
  - `webhookUrl` string: Optional per-job webhook URL. Overrides the API key's default webhook URL for this job.

## Response `200`

Idempotent replay: a job with the same `Idempotency-Key` already exists for this API key. Includes `operation`.

- JobReplay: 200 envelope returned when an Idempotency-Key matches an existing job. Unlike the fresh 202, `status` reflects the job's current state and `operation` is always present.
  - `jobId` string, uuid, required
  - `status` 'queued' | 'processing' | 'completed' | 'failed', required: Current status of the previously created job.
  - `operation` 'generate' | 'variation' | 'edit_image' | 'upscale' | 'audiobook_cover' | 'remove_text' | 'generate_reference' | 'wrap' | 'wrap_extend_front', required
  - `credits_reserved` integer: What the ORIGINAL job reserved. Returned by the variations, edit-image, upscale, audiobook-cover, remove-text, wraps and extend-front endpoints when the job recorded it.
  - `included_format` boolean: true when the book's marketing kit paid for the ORIGINAL job instead of credits. Returned by the edit-image, upscale, audiobook-cover, remove-text, wraps and extend-front endpoints.
  - `external_ref` string, nullable, required: The external_ref stored on the ORIGINAL job.
  - `created_at` string, date-time, required
  - `poll_url` string, required

## Other responses

- `202`: Job accepted and queued. NOTE: this envelope has no `operation` field.
- `400`: Validation or moderation failure. `code` is one of: `missing_book_id`, `invalid_count`, `invalid_field_type`, `field_too_long`, `invalid_field_value`, `invalid_template_id`, `invalid_prompt_mode`, `own_prompt_empty`, `own_prompt_too_long`, `prompt_mode_conflict`, `invalid_variant_overrides`, `variant_overrides_requires_template`, `invalid_variant_axis`, `invalid_variant_value`, `invalid_motif_id`, `motif_not_used`, `content_policy_violation`.
- `401`: Missing/malformed API key, unknown or inactive key, or inactive subscription detected during credit checks. `code`: `unauthorized`.
- `402`: Not enough credits (monthly + overage) for the requested operation. `code`: `insufficient_credits`.
- `403`: The API key is valid but its owner has no active enterprise subscription. `code`: `forbidden`.
- `404`: Book not found or not owned by this API key's user (`book_not_found`), or `motif_id` is not one of the book's motifs (`motif_not_found`).
- `422`: The book's genre/subgenre has no cover route (a safety net: every current genre has one). `code`: `unsupported_genre`.
- `429`: The subscription's concurrent-job limit is reached (jobs with status `queued` or `processing` count). `code`: `concurrency_limit`.
- `500`: Server error. `code` is `job_creation_failed` or `internal_error`. Reserved credits are refunded.

---

[API](https://skmtc.dev/beyourcover/apis/beyourcover-partner-api.md) · [All operations](https://skmtc.dev/beyourcover/apis/beyourcover-partner-api/llms.txt) · [OpenAPI document](https://skmtc.dev/beyourcover/apis/beyourcover-partner-api/revisions/82ad2c7c8ede?raw)
