---
title: Generation result
description: GET /v1/requests/{request_id} — fetch the finished result with links to the image, video or audio; while the job is still running, the API returns 202.
icon: PackageCheck
---

Fetch the finished generation with links to its media. While the job is queued or running, the call returns `202` — try again later.

## Playground

<Callout type="info" title="Use a test key here">
Paste a `clipia_test_…` key into the form below: it charges no credits and calls no models, and the response has the same shape. The form keeps the key in this browser, so never enter a live `clipia_live_…` key here: it is a server-side secret. See [Sandbox](/en/docs/getting-started/sandbox).
</Callout>

<ApiPlayground path="/v1/requests/{request_id}" method="get" />

`GET /v1/requests/:id` returns the result with an `output` field and status `200` once the job reaches a terminal status (`COMPLETED`, `FAILED` or `CANCELED`). All links point to the `media.clipia.ai` CDN. No extra key permission is needed.

<Method name="GET" path="/v1/requests/:id" />

## Request

<TypeTable
  type={{
    id: { type: 'string', description: 'The request_id from the submit response.', required: true }
  }}
/>

<Tabs items={['cURL', 'TypeScript', 'Python']}>
<Tab value="cURL">

```bash
curl https://api.clipia.ai/v1/requests/764cabcf-b745-4b3e-ae38-1200304cf45b \
  -H "Authorization: Bearer $CLIPIA_KEY"
```

</Tab>
<Tab value="TypeScript">

```ts
const result = await clipia.queue.result('764cabcf-b745-4b3e-ae38-1200304cf45b');

// While the job is running, the API returns 202 and the SDK sets pending: true.
if (result.pending) {
  console.log('still running:', result.status);
} else {
  console.log(result.output?.images?.[0]?.url);
}
```

</Tab>
<Tab value="Python">

```python
result = client.result("764cabcf-b745-4b3e-ae38-1200304cf45b")

# While the job is running, the API returns 202 and the SDK sets pending = True.
if result.pending:
    print("still running:", result.status)
else:
    print(result.output["images"][0]["url"])
```

</Tab>
</Tabs>

## Image

```json
{
  "request_id": "764cabcf-b745-4b3e-ae38-1200304cf45b",
  "status": "COMPLETED",
  "model": "nano-banana-2",
  "output": {
    "images": [
      {
        "url": "https://media.clipia.ai/....webp",
        "original_url": "https://media.clipia.ai/....png"
      }
    ]
  },
  "cost": 12,
  "created_at": "2026-10-09T12:00:00Z",
  "completed_at": "2026-10-09T12:00:18Z"
}
```

`output.images` is an array. `url` is an optimized WebP copy for display; `original_url` is the full-quality source file. Only the first image in the array has `original_url`.

## Video

```json
{
  "request_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
  "status": "COMPLETED",
  "model": "seedance-2-fast-i2v",
  "output": {
    "video": {
      "url": "https://media.clipia.ai/....mp4",
      "original_url": "https://media.clipia.ai/....mp4",
      "thumbnail_url": "https://media.clipia.ai/....webp"
    }
  },
  "cost": 40,
  "created_at": "2026-10-09T12:00:00Z",
  "completed_at": "2026-10-09T12:00:42Z"
}
```

`output.video` is an object with `url`. The `original_url` and `thumbnail_url` (a preview frame) fields may be missing.

## Audio

```json
{
  "output": {
    "audio": { "url": "https://media.clipia.ai/....mp3", "format": "mp3" },
    "audios": [
      { "url": "https://media.clipia.ai/....mp3", "format": "mp3" },
      { "url": "https://media.clipia.ai/...-2.mp3", "format": "mp3" }
    ]
  }
}
```

`output.audio` is the first track and `output.audios` lists every variant: music models return several tracks per run, text-to-speech returns one. The first element of `audios` equals `audio`. `format` is the file format taken from the URL extension (`mp3`, `wav`) and may be absent.

<Callout type="info" title="No dimensions or duration">
The response has no `width`, `height` or `duration` fields — neither live nor in the [sandbox](/en/docs/getting-started/sandbox). If you need them, read them from the file itself.
</Callout>

## Response fields

<TypeTable
  type={{
    request_id: { type: 'string', description: 'Request identifier' },
    status: { type: 'string', description: 'COMPLETED, FAILED or CANCELED' },
    model: { type: 'string', description: 'Model slug' },
    output: { type: 'object', description: 'images: [{ url, original_url? }], video: { url, original_url?, thumbnail_url? } or audio: { url, format? } together with audios: [{ url, format? }]. Usually an empty object for FAILED and CANCELED' },
    cost: { type: 'integer', description: 'Credits actually charged; 0 for FAILED and CANCELED — the reserve is returned' },
    created_at: { type: 'string', description: 'When the request was created, ISO 8601' },
    completed_at: { type: 'string', description: 'When it finished, ISO 8601; may be absent' },
    error: { type: 'object', description: '{ code, message } — only when status = FAILED; code comes from the dictionary below' },
    warnings: { type: 'array', description: '[{ code, parameter, message }] — parameters the server dropped while running the request. Omitted when there is nothing to report' }
  }}
/>

## Warnings

If sound was requested but the audio track did not pass the model's safety check, the server retries the generation once without sound. The request finishes as `COMPLETED`, and the response additionally carries a `warnings` array:

```json
{
  "status": "COMPLETED",
  "output": { "video": { "url": "https://media.clipia.ai/....mp4" } },
  "warnings": [
    {
      "code": "audio_dropped",
      "parameter": "generate_audio",
      "message": "The audio track did not pass the model's safety check, so the video is generated without sound. The price of the request is unchanged."
    }
  ]
}
```

The cost of the request does not change. `warnings` is omitted when there is nothing to report, and for `FAILED` and `CANCELED`. The same array comes with the `202` response and with the [request status](/en/docs/api-reference/status) while the silent video is still being generated. This is the only reason so far; treat an unfamiliar `code` as "the parameter was not applied".

## Generation error codes [#failed-codes]

With `status: "FAILED"`, the `error` object carries a code from a closed dictionary — it tells the client whether a retry makes sense. `error.message` is in English: a ready-made phrase about the reason when the server recognizes it, otherwise neutral text for the code, usually `Generation failed. Please retry or contact support.`; it has no names of internal systems. Credits for a `FAILED` job are always refunded.

| `error.code` | Meaning | Retry |
|------|---------|-------|
| `generation_failed` | generic generation failure, the default | yes |
| `content_moderated` | the request was rejected by content moderation | pointless with the same input |
| `invalid_input` | the model did not accept the input: size, format, parameters | fix the request |
| `model_unavailable` | the model is temporarily unavailable | later |
| `timeout` | the generation did not finish in time | yes |
| `rate_limited` | the model is overloaded | after a pause |
| `insufficient_credits` | not enough credits at charge time | after topping up |
| `result_unavailable` | the result was produced but not stored or not reachable | yes |
| `empty_result` | the model returned an empty result | yes, or change the request |
| `canceled` | canceled by the user or the system | — |

The failure [webhook](/en/docs/api-reference/webhooks) uses the same dictionary. The list may grow: treat an unknown code as `generation_failed`.

## Response codes

| HTTP | When | Body |
|------|------|------|
| `200` | `COMPLETED` | result with `output` |
| `200` | `FAILED` | `error: { code, message }`, `code` from the dictionary above, `generation_failed` by default; `cost: 0` |
| `200` | `CANCELED` | terminal response, `output` is usually empty, `cost: 0` |
| `202` | `IN_QUEUE` / `IN_PROGRESS` | `{ request_id, status }` — try again later |
| `400` | malformed ID | `message: invalid_request_id` |
| `404` | no such request | `code: not_found`, `message: request_not_found` |

<Callout type="info" title="202 is expected">
`202` only appears while the job is unfinished. `FAILED` and `CANCELED` are final responses with status `200`. On `FAILED`, the reserved credits are refunded in full. `error.code` is usually `generation_failed` (codes are lowercase snake_case), and `error.message` is in English: a ready-made phrase about the reason when the server recognizes it, otherwise neutral text for the code; it has no internal details. Branch on `status` and `error.code`, not on the message text.
</Callout>
