# Request a Spark Idea

`POST /v1/images/{image_id}/spark/ideas`

Queues a Spark Idea for the image and returns immediately with
`status: processing` — a fresh request starts in flight, and an
idempotent reuse only ever matches an in-flight Idea. Use
[Retrieve a Spark Idea](/api/spark-ideas/getSparkIdea) to poll for
terminal states (`completed` / `failed`).

Idempotent on `image_id`: while an Idea is in flight for the image,
subsequent calls return the existing Idea with `200 OK` instead of
creating a new one. A fresh create returns `202 Accepted`. The
organization check runs before the idempotent lookup, so callers
from a different organization cannot reuse another org's in-flight
Idea — they get `404 IMAGE_NOT_FOUND` instead.

## Responses

### 200 — An Idea was already in flight for this image; the existing one is returned.

**application/json**

- **object**
  - `idea_id` (string, required) — Identifier of the Spark Idea. Pass it to [Retrieve a Spark Idea](/api/spark-ideas/getSparkIdea) to poll for the result.
  - `image_id` (string, required) — Root image the Idea was requested for.
  - `status` (enum: "processing" | "failed" | "completed", required) — Lifecycle status of a Spark request, shared by Spark Ideas and Spark
Images.

- `processing` — non-terminal; the request is queued or running.
- `completed` — terminal success; the response payload is populated.
- `failed` — terminal failure. Also reported for a request that stayed
  non-terminal past the 5-minute processing timeout, even when the
  underlying record still reads as in-flight, so a stuck request is
  always observable here.

  - `result_url` (string, required) — Relative path to poll for the Idea result.
  - `created_at` (string, required)

### 202 — New Idea accepted for processing.

**application/json**

- **object**
  - `idea_id` (string, required) — Identifier of the Spark Idea. Pass it to [Retrieve a Spark Idea](/api/spark-ideas/getSparkIdea) to poll for the result.
  - `image_id` (string, required) — Root image the Idea was requested for.
  - `status` (enum: "processing" | "failed" | "completed", required) — Lifecycle status of a Spark request, shared by Spark Ideas and Spark
Images.

- `processing` — non-terminal; the request is queued or running.
- `completed` — terminal success; the response payload is populated.
- `failed` — terminal failure. Also reported for a request that stayed
  non-terminal past the 5-minute processing timeout, even when the
  underlying record still reads as in-flight, so a stuck request is
  always observable here.

  - `result_url` (string, required) — Relative path to poll for the Idea result.
  - `created_at` (string, required)

### 400 — Validation error. Check `error_code` to distinguish:
  - GENERATED_IMAGE_NOT_ALLOWED — the image is itself Spark-generated; only root images may seed Spark
  - MISSING_PRODUCT_CATEGORY — the image has no `product_category_id` assigned


**application/json**

- **object** — Standardized error format for all `/v1/*` endpoints. `error_code` is a
stable SCREAMING_SNAKE_CASE identifier clients can switch on.

  - `detail` (string) — Human-readable error message
  - `status_code` (integer) — HTTP status code
  - `error_code` (string) — Stable machine-readable error code
  - `request_id` (any) — Request identifier for correlation
  - `extra` (any) — Endpoint-specific additional context. For example,
IMAGE_DOWNLOAD_FAILED populates extra.failed_urls with per-URL
failure reasons so clients can triage bulk submissions.

  - `timestamp` (string)

### 401 — Missing or invalid Bearer token

### 404 — Image not found for this id in the caller's organization
(`error_code: IMAGE_NOT_FOUND`). Returned both when the image
does not exist and when it belongs to a different organization.


**application/json**

- **object** — Standardized error format for all `/v1/*` endpoints. `error_code` is a
stable SCREAMING_SNAKE_CASE identifier clients can switch on.

  - `detail` (string) — Human-readable error message
  - `status_code` (integer) — HTTP status code
  - `error_code` (string) — Stable machine-readable error code
  - `request_id` (any) — Request identifier for correlation
  - `extra` (any) — Endpoint-specific additional context. For example,
IMAGE_DOWNLOAD_FAILED populates extra.failed_urls with per-URL
failure reasons so clients can triage bulk submissions.

  - `timestamp` (string)

### 500 — Failed to enqueue the Idea for processing
(`error_code: SQS_ENQUEUE_FAILED`). The Idea row is marked
`failed` before the error is raised.


**application/json**

- **object** — Standardized error format for all `/v1/*` endpoints. `error_code` is a
stable SCREAMING_SNAKE_CASE identifier clients can switch on.

  - `detail` (string) — Human-readable error message
  - `status_code` (integer) — HTTP status code
  - `error_code` (string) — Stable machine-readable error code
  - `request_id` (any) — Request identifier for correlation
  - `extra` (any) — Endpoint-specific additional context. For example,
IMAGE_DOWNLOAD_FAILED populates extra.failed_urls with per-URL
failure reasons so clients can triage bulk submissions.

  - `timestamp` (string)
