---
title: "Start a video generation"
method: POST
path: "/v1/generate/video"
tags: ["generation"]
---

# Start a video generation

`POST /v1/generate/video`

## Request

- Base URL: `https://aicontentdrop.com`
- URL: `https://aicontentdrop.com/v1/generate/video`
- Auth: HTTP bearer

Submits a video generation and returns immediately with status `generating`. Poll GET /v1/videos/{id} (every ~5 seconds) until status is `completed` (video_url populated) or `failed`. Credits are deducted only on success. This endpoint shares its implementation with the website, so safety checks, model fallback, and credit accounting are identical; its error shape is `{"error": "<message>"}`. 

**Async contract:** returns 202 with a `Location` header pointing at the poll URL; poll every ~5 seconds until `status` is `completed` or `failed`. **Idempotency:** send `Idempotency-Key` so a retry cannot double-charge. **Sandbox:** send `X-Sandbox: true` to rehearse without spending credits.

## Query parameters

- `sandbox` 'true'

## Headers

- `Idempotency-Key` string
- `X-Sandbox` 'true'
- `X-Sandbox` 'true' | '1'
- `Idempotency-Key` string

## Request body

- object
  - `prompt` string, required: What to generate, in natural language
  - `aiModel` string: Model ID from /v1/models (e.g. kling_3_0). Omit to let the platform choose.
  - `duration` number: Clip length in seconds (model-dependent caps apply)
  - `aspectRatio` string: 16:9, 9:16, or 1:1
  - `style` string
  - `negativePrompt` string
  - `imageUrl` string, uri: Optional image-to-video conditioning; must be a public https:// URL
  - `imageRefs` object[]: Multi-image references for models that support them
    - `url` string, uri, required
    - `role` string: e.g. reference_image, first_frame, last_frame
  - `endFrameUrl` string, uri: Convenience for a last_frame reference
  - `quality` string
  - `resolution` string
  - `mode` string

## Response `202`

Accepted. Poll GET /v1/videos/{id} until status is completed or failed.

- GenerationAccepted: 202 from either generation endpoint. `video` carries the job for images too — one shape across both so a client needs one parser.
  - `sandbox` boolean: true when X-Sandbox: true was sent. Nothing was generated and no credits were spent.
  - `video` GenerationJob, required: A submitted generation. Submit-and-poll: this is the acknowledgement, not the result. Poll GET /v1/videos/{id} until status is completed or failed.
    - `id` string, required: Poll this id. A sandbox job is prefixed `sandbox_`.
    - `title` string, nullable
    - `status` 'generating' | 'completed' | 'failed' | 'timeout', required
    - `aiModel` string, nullable: Normalised model id the job was routed to.
    - `creditsUsed` number: 0 at submission. Billing is post-deduct: credits are charged only when the generation succeeds.
    - `videoUrl` string, uri, nullable
    - `imageUrl` string, uri, nullable
    - `note` string, nullable

## Other responses

- `400`: Invalid request (missing prompt, bad imageUrl, unknown model, …)
- `401`: Missing, malformed, revoked, or budget-exhausted API key
- `402`: Insufficient credits
- `409`: The Idempotency-Key was already used with a different request body
- `429`: Rate limited. Read Retry-After (header) or error.retry_after_seconds (body) — they carry the same number — and wait that long. Retrying sooner extends the window rather than shortening it.
- `500`: Unexpected failure on our side. Retry once; nothing was charged.

---

[API](https://skmtc.dev/aicontentdrop/apis/ai-content-drop-api.md) · [All operations](https://skmtc.dev/aicontentdrop/apis/ai-content-drop-api/llms.txt) · [OpenAPI document](https://skmtc.dev/aicontentdrop/apis/ai-content-drop-api/revisions/75a13a8043ae?raw)
