> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vidgen.id/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a generation job

> Send a prompt and references to create a video or image. Returns a job id for polling.

Creates one generation job. Credits are deducted at this endpoint, and the request is answered **before** the result is ready.

> [!NOTE]
>
> Need the list of models you can put in the `model` field? Get it from [`GET /api/v1/models`](https://docs.vidgen.id/en/api-reference/models). The valid `parameters` values also depend on the model.

### Authorizations

**Authorization** `string` *required*

API key formatted `Bearer vg_...`. You can also use the `x-api-key` header.

### Request body

**model** `string` *required*

Model id from the catalog, for example `seedance-2-5-flash`. Spellings with dots and hyphens are treated the same. A model that exists but is currently disabled is answered `409`.

**prompt** `string`

A description of what you want created. **Required** except for motion control models, which may leave it empty because the server fills in a neutral instruction. Maximum 2,500 characters for motion models.

The prompt passes through content filtering first; sensitive words, public figures, or indications of abuse are removed before the request is forwarded. Some models sold openly without filtering are recognizable by their id (`spicy`, `nsfw`) and are not filtered.

**parameters** `object` (default: \{})

Output settings. Only recognized keys are processed; other keys are ignored without an error.

**recognized properties**

**duration** `string`

Duration in seconds, e.g. `"5"` or `"30"`. A trailing `s` is accepted and stripped. Validated against `capabilities.durations`. **Ignored on motion control models.**

**resolution** `string`

Resolution, e.g. `"720p"`, `"1080p"`, `"1K"`, `"2K"`, `"4K"`. Validated against `capabilities.resolutions`.

**ratio** `string`

Aspect ratio: `"16:9"`, `"9:16"`, `"1:1"`, `"4:3"`, `"3:4"`, or `"auto"`. `aspect_ratio` is accepted as an alias.

**quality** `string`

For image models that have `capabilities.qualities` (`low`, `medium`, `high`, `max`). Ignored if the model does not support it.

**background** `string`

For image models that have `capabilities.backgrounds` (`auto`, `transparent`, `opaque`).

**output\_format** `string`

Output format; `format` is accepted as an alias. Only used if the model has `capabilities.outputFormats`.

**negative\_prompt** `string`

What you do not want. Only forwarded if `capabilities.supportsNegativePrompt`.

**seed** `string`

Random seed for reproducible results. Only forwarded if `capabilities.supportsSeed`.

**orientation** `string`

Motion control only: `"image"` (output ratio follows the character image) or `"video"` (output ratio follows the motion video). Other values are ignored.

**references** `array\<object\>`

Input material: character images, products, or motion videos. Each object can be an asset from [`POST /api/v1/upload`](https://docs.vidgen.id/en/api-reference/upload) **or** a public URL.

**reference object**

**id** `string`

Asset id from the upload endpoint. If present, this object is used as-is (also send `url`, `file_url`, and `filename` exactly as you received them).

**url** `string`

A public media URL (`http` or `https`) that the server will download with a 20 second timeout. Download failures are answered `400`.

**type** `string`

`"image"`, `"video"`, or `"audio"`. May be omitted — the server detects it from the file contents. Maximum counts per type depend on the model (defaults: 9 images / 1 video / 1 audio; image models allow 10 images and no video or audio).

**filename** `string`

File name in server storage. Follow the exact value from the upload response.

**idempotencyKey** `string`

Minimum 8 characters. The same key returns the existing job with `200` and `idempotent: true`, without a second credit deduction. Below 8 characters, your value is ignored and the server generates its own key. See [Idempotency](https://docs.vidgen.id/en/concepts/idempotency.md).

```bash cURL theme={null} theme={null}
curl -X POST https://vigen.id/api/v1/generate \
  -H "Authorization: Bearer vg_4b1a82f3c9d0e1f2a3b4c5d6e7f80912" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2-5-flash",
    "prompt": "secangkir kopi di meja kayu, cahaya pagi, kamera dolly perlahan ke kanan",
    "parameters": { "duration": "5", "ratio": "16:9", "resolution": "720p" },
    "idempotencyKey": "order-4711-a39f2c7b"
  }'
```

```js Node.js theme={null} theme={null}
const res = await fetch("https://vigen.id/api/v1/generate", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.VIGEN_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "seedance-2-5-flash",
    prompt: "secangkir kopi di meja kayu, cahaya pagi, kamera dolly perlahan ke kanan",
    parameters: { duration: "5", ratio: "16:9", resolution: "720p" },
    idempotencyKey: "order-4711-a39f2c7b",
  }),
});

console.log(res.status, await res.json());
```

```python Python theme={null} theme={null}
res = requests.post(
    "https://vigen.id/api/v1/generate",
    headers={"Authorization": f"Bearer {api_key}"},
    json={
        "model": "seedance-2-5-flash",
        "prompt": "secangkir kopi di meja kayu, cahaya pagi, kamera dolly perlahan ke kanan",
        "parameters": {"duration": "5", "ratio": "16:9", "resolution": "720p"},
        "idempotencyKey": "order-4711-a39f2c7b",
    },
)

print(res.status_code, res.json())
```

### Responses

**success** `boolean`

`true` on every successful response.

**job** `object` *required*

The job object.

**job properties**

**id** `string` *required*

The id to poll at `GET /api/v1/jobs/{id}`.

**status** `string` *required*

`"queued"` for a new job. Other values: `dispatching`, `processing`, `succeeded`, `failed`, `cancelled`.

**model** `string`

Model id that was used.

**category** `string`

`"Video"`, `"Image"`, or `"Audio"`.

**prompt** `string`

The prompt **after** content filtering. This is what was actually processed.

**creditsCharged** `number` *required*

Credits deducted. `0` when the Unlimited quota covered it.

**createdAt** `string (ISO 8601)`

When the job was created, UTC.

**result** `object | null`

Only populated on an idempotent replay of an already finished job; always `null` for a new job.

**queue** `object`

Queue information at the moment the request was made.

**contents of queue**

**position** `number`

Position in the queue. `0` means it is being processed or the position is not reported.

**status** `string`

Mirrors the job status, usually `"queued"`.

**idempotent** `boolean`

Only present when the same key was already used and the original job is being returned.

```json 202 — new job theme={null} theme={null}
{
  "success": true,
  "job": {
    "id": "9f2c1d34-a8b7-4e0f-9a1b-2c3d4e5f6a7b",
    "status": "queued",
    "model": "seedance-2-5-flash",
    "category": "Video",
    "prompt": "secangkir kopi di meja kayu, cahaya pagi, kamera dolly perlahan ke kanan",
    "creditsCharged": 3,
    "createdAt": "2026-11-04T09:12:44.000Z"
  },
  "queue": { "position": 2, "status": "queued" }
}
```

```json 200 — idempotent replay theme={null} theme={null}
{
  "success": true,
  "job": {
    "id": "9f2c1d34-a8b7-4e0f-9a1b-2c3d4e5f6a7b",
    "status": "succeeded",
    "model": "seedance-2-5-flash",
    "category": "Video",
    "prompt": "secangkir kopi di meja kayu, cahaya pagi, kamera dolly perlahan ke kanan",
    "result": { "url": "https://vigen.id/api/media-proxy?token=..." },
    "creditsCharged": 3,
    "createdAt": "2026-11-04T09:12:44.000Z"
  },
  "queue": { "position": 0 },
  "idempotent": true
}
```

```json 402 — not enough credits theme={null} theme={null}
{
  "error": "Kredit akun tidak mencukupi. Pembuatan ini membutuhkan 10 kredit",
  "requiredCredits": 10,
  "currentCredits": 4
}
```

```json 429 — all concurrent slots busy theme={null} theme={null}
{
  "error": "Maksimal 2 proses generate bersamaan. Tunggu salah satunya selesai sebelum memulai yang baru.",
  "maxConcurrent": 2,
  "activeJobs": 2
}
```

```json 400 — invalid parameter theme={null} theme={null}
{
  "error": "Parameter tidak valid: Durasi 60s tidak didukung Seedance 2.5 Flash. Pilihan: 20s.",
  "fields": ["Durasi 60s tidak didukung Seedance 2.5 Flash. Pilihan: 20s."]
}
```

## What you need to know

> [accordion] Why 202 and not 200?
>
> Generation is asynchronous. `202` means the request was accepted and the queue entry is set up; you fetch the result later through the job id. The only `200` on this endpoint is an idempotent replay.

> [accordion] When are credits deducted and when do they come back?
>
> They are deducted before the job is saved. If the job fails, the cancellation fails to save, or the queue is full, the credits are refunded automatically with a refund reason recorded in the account history. You do not need to build your own refund mechanism.

> [accordion] Can a request be safely repeated?
>
> Yes, as long as you use the same `idempotencyKey` with a length of at least 8 characters. Without it, every retry is a new job with a new charge.

> [accordion] Extra fields in the body are ignored?
>
> Yes. A body sending `watermark: false` or `n: 2` produces no error, but also no effect. Only `model`, `prompt`, `parameters`, `references`, and `idempotencyKey` are read.

> [accordion] Limits that make this request get rejected
>
> Two concurrent processes (Unlimited accounts only), 50 successful videos per day, the server queue being full, or the site being under maintenance. All of them use `429` or `503`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.