# Creatives

> **TL;DR** — The creatives feed gives your marketing systems a data record for each ad creative your organisation has approved on Wandura: film, episodes and scenes used, format, duration, hook, formula and the end of your rights. Records never contain a signed media URL. Sync them incrementally with `updated_since` and a cursor. Each record's `final.file_url` is a public share link to the final video: no API key needed, so you can hand it straight to Meta's video upload.

## What the feed contains
Creatives of your organisation with status `approved` or `pushed` (already delivered). Drafts and other organisations' creatives never appear. `final.ready` says whether the final render exists; once it does, [download it](https://docs.wandura.ai/developers/concepts/creatives#downloading-the-final-file) from `final.file_url`.

## Endpoints
| Endpoint | Use |
|---|---|
| [`GET /api/delivery/v1/creatives`](https://docs.wandura.ai/developers/reference/creatives-list) | Sync all records, incrementally. |
| [`GET /api/delivery/v1/creatives/{id}`](https://docs.wandura.ai/developers/reference/creatives-get) | Fetch or re-check one record. |
| [`GET /api/delivery/v1/creatives/{id}/file`](https://docs.wandura.ai/developers/reference/creatives-file) | Download the final video with your API key, instead of the share link in `final.file_url`. |

All three need a key with `creatives:export` ([Authentication](https://docs.wandura.ai/developers/authentication#scopes)) and share one rate-limit counter.

## Response envelope
Successful responses are wrapped in an envelope:

```json
{
  "code": 0,
  "message": "ok",
  "data": { "items": [], "next_cursor": null },
  "server_time": 1790679032
}
```

Errors use the same envelope **without** `data` (`code` is then a four-digit error code), except `429` and `400` `unsupported_version`, which use the flat format. Timestamps in this feed, `server_time` included, are Unix epoch seconds. See [Errors](https://docs.wandura.ai/developers/concepts/errors#creatives-envelope).

## Syncing
Records come oldest update first (by `updated_at`, then ID), so updates made during a sync land after the pages you have read. Keep a checkpoint (the largest `updated_at` of your last complete run), pass it as `updated_since`, page with `cursor`, and overwrite records by `creative_id`: a record can arrive twice. The full procedure and code: [Creatives sync](https://docs.wandura.ai/developers/guides/creatives-sync).

### Creatives that leave the feed
There are no deletion events. A creative that is no longer approved stops appearing. To check one you stored, call `GET /creatives/{id}`: `404` with `code` `4040` means it is gone.

## The record
| Field | What it tells you |
|---|---|
| `creative_id` | Stable ID. Your primary key. |
| `creative_code` | Immutable human-readable code; treat it as opaque. |
| `created_by` | Who made the creative: `email`, and `name` (or `null` when no name is set). `null` when the creator is unknown, for example a creative made by the system. |
| `film`, `episodes`, `scenes` | What the creative is made of: film, episode numbers, each clip with its start, end, action and line. |
| `hook` | The action and line of the opening scene. |
| `placement`, `aspect` | `reels_9x16`, `feed_4x5` or `square_1x1`, and the aspect ratio. |
| `duration_ms` | Total length of the clips used. |
| `formula` | The formula it was built with, if any. |
| `rights.ends_at` | 00:00 UTC of the **last day** of your export rights, or `null`. That day is included: stop using the creative at `ends_at + 86400`. |
| `final.ready` | Whether the final render exists. |
| `final.file_url` | Public, durable download link (no API key needed), revocable in the portal; each open redirects to a fresh 15-minute download link. Safe to hand to Meta's video upload. `null` until `final.ready` is `true`, and `null` when an admin of your organisation revoked the link. The file is the clean final, with your company's brand mark if your org has one. |

Every field: [List creatives](https://docs.wandura.ai/developers/reference/creatives-list#the-creative-record). Each record carries `schema_version` (currently `1`); new fields are added without changing it, so ignore fields you do not recognise.

## Downloading the final file
When `final.ready` is `true`, `final.file_url` is the creative's [share link](https://docs.wandura.ai/partners/creatives#share-link), such as `https://www.wandura.ai/api/c/Q3vh0xAbCdEfGhIjKlMnOpQrStUvWx9f.mp4`. It needs no API key. Each open answers `302` with a fresh download link valid for 15 minutes, so tools that fetch a file by URL, such as Meta's video upload (`file_url`), can use it directly, however long your campaign setup takes:

```bash
curl -sL -o final.mp4 "$FILE_URL"
```

- Store `final.file_url`, never the download link it redirects to: the download link expires after 15 minutes, the share link does not.
- Anyone holding the share link can download the file. Treat it like a password: do not publish it.
- Every open re-checks that the creative is still approved and that your export rights for the film are active; otherwise it answers `410`. An admin of your organisation can revoke the link in the portal, and it then answers `410` at once.
- After a revoke, the record's `final.file_url` is `null`. Revoking does not change `updated_at`, so an incremental sync does not pick it up: when a stored link answers `410`, call [Get a creative](https://docs.wandura.ai/developers/reference/creatives-get) for the current link. Still `null`? Ask your admin, or create a new share link in the portal.
- Each link allows 120 opens per minute; beyond that it answers `429` with `Retry-After`.
- The file is an MP4, 1080 × 1920: the clean final, with your company's brand mark if your org has one.

### Downloading with your API key
[`GET /api/delivery/v1/creatives/{id}/file`](https://docs.wandura.ai/developers/reference/creatives-file) downloads the same file with your API key instead of a share link. It answers `302` with a download link valid for 15 minutes; most HTTP clients follow it for you:

```bash
curl -sL -o final.mp4 "https://www.wandura.ai/api/delivery/v1/creatives/$CREATIVE_ID/file" -H "Authorization: Bearer $WANDURA_API_KEY"
```

- `409` with `code` `4090` means the final is not ready yet. After your export rights end, it answers `403` with `code` `4032`.
- Every download is logged against your API key. If a key leaks, revoke it: it can download every final of your organisation until then.

## Related
- [Creatives sync](https://docs.wandura.ai/developers/guides/creatives-sync)
- [When rights end](https://docs.wandura.ai/developers/production/rights-end)
