# Asset-uri (/ro/docs/gateway/assets)

Conținutul media codai Studio stocat — listezi, obții un URL semnat proaspăt, descarci sau ștergi imaginile, muzica și video-urile generate.

Un **asset** este un fișier generat pe care gateway-ul îl păstrează pentru tine: fiecare imagine, clip muzical sau video produs cu `response_format: "url"` și **fiecare job video terminat** (MP4-ul e stocat mereu). Asset-urile aparțin utilizatorului care deține cheia API — id-ul asset-ului altui utilizator întoarce `404` — și se păstrează **90 de zile**.

În loc de octeți base64 primești un obiect asset cu un **URL semnat valabil o oră**. URL-ul nu cere cheia API, așa că îl poți da unui browser, unui element `<audio>`/`<video>` sau unui utilitar de descărcare. Când expiră, ceri unul nou.

Agenții răsfoiesc biblioteca prin uneltele serverului MCP `studio_assets_list` (`kind`, `before`, `limit`) și `studio_renders_list` (`before`, `limit`, `root_render_id`). Ambele sunt doar citire și nu întorc niciodată URL-uri semnate; generarea media costă bani și nu e disponibilă prin ele.

## Obiectul asset [#obiectul-asset]

```json
{
  "asset_id": "7d0f2c1e-4b8a-4c1e-9a51-0f3c2e8d9b10",
  "kind": "video",
  "status": "ready",
  "model": "veo-3.1-fast-generate-001",
  "url": "https://storage.googleapis.com/…&X-Goog-Signature=…",
  "mime_type": "video/mp4",
  "bytes": 1834221,
  "duration_seconds": 4,
  "width": null,
  "height": null,
  "created_at": "2026-10-10T08:00:00.000Z",
  "expires_at": "2026-10-10T09:00:00.000Z"
}
```

| Câmp | Semnificație |
| --- | --- |
| `asset_id` | UUID stabil. Îl folosești ca să obții un URL proaspăt sau ca să ștergi asset-ul. |
| `kind` | `music`, `video`, `image`, `speech`, `render`, `upload` sau `sfx`. |
| `status` | `pending`, `ready`, `failed` sau `deleted`. Doar asset-urile `ready` au `url`. |
| `model` | Modelul upstream care l-a produs. |
| `url` | URL semnat al octeților, valabil o oră; `null` dacă nu e `ready`. Nu-l păstra în cache după `expires_at`. |
| `mime_type`, `bytes` | Tipul de conținut și mărimea obiectului stocat. |
| `duration_seconds` | Durata audio sau video; `null` pentru imagini. |
| `width`, `height` | Pixeli, când sunt cunoscuți; altfel `null`. |
| `created_at` | Momentul creării. Asset-ul e șters după 90 de zile. |
| `expires_at` | Momentul în care `url` nu mai funcționează; `null` când nu există URL. |

## Endpoint-uri [#endpoint-uri]

| Metodă | Cale | Rezultat |
| --- | --- | --- |
| `GET` | `/v1/assets?kind=&before=&limit=` | `{ object: "list", data: [asset…], next_before }`, cele mai noi primele |
| `GET` | `/v1/assets/{id}` | Un asset cu un `url` semnat proaspăt |
| `GET` | `/v1/assets/{id}/content` | Redirecționare `302` către URL-ul semnat |
| `DELETE` | `/v1/assets/{id}` | `{ id, object: "asset", deleted: true }` |

### Listare [#listare]

`kind` filtrează după tip, `limit` e între 1 și 100 (implicit 30). Pentru paginare, trimite `next_before` din răspunsul anterior ca `before`, până când `next_before` devine `null`.

```bash
curl "https://ai.codai.ro/v1/assets?kind=video&limit=20" \
  -H "Authorization: Bearer $CODAI_API_KEY"
```

### Obținerea octeților [#obținerea-octeților]

`GET /v1/assets/{id}` întoarce asset-ul cu un URL semnat nou. `GET /v1/assets/{id}/content` face același lucru și redirecționează către el, util cu `curl -L`. Redirecționarea are `cache-control: private, no-store`. Un asset fără conținut încă (`pending`) întoarce `404` pe `/content`.

```bash
curl -L -o plane.mp4 "https://ai.codai.ro/v1/assets/$ASSET_ID/content" \
  -H "Authorization: Bearer $CODAI_API_KEY"
```

### Ștergere [#ștergere]

`DELETE /v1/assets/{id}` șterge fișierul stocat și marchează asset-ul `deleted`; URL-urile deja emise nu mai funcționează. Ștergerea nu rambursează generarea.

## Crearea asset-urilor [#crearea-asset-urilor]

Cere `response_format: "url"` pe oricare endpoint media (vezi [Embeddings, audio și realtime](./embeddings-audio.mdx#un-url-în-loc-de-octeți)):

- `POST /v1/images/generations` și `POST /v1/images/edits` — câmp în body;
- `POST /v1/audio/music` — câmp în body;
- `GET /v1/videos/{id}` — parametrul de query `?response_format=url`.

Valoarea implicită rămâne `b64_json`, deci clienții existenți nu văd nicio schimbare. Video-urile se taxează exact o dată, iar MP4-ul lor e stocat indiferent de formatul cu care interoghezi.

Fiecare [randare Studio](./renders.mdx) terminată e stocată tot ca asset și apare la `kind=render` (`GET /v1/assets?kind=render`).

Efectele sonore importate din [biblioteca gratuită de efecte sonore](./sfx.mdx) CC0 sunt asset-uri de tip `kind=sfx`.

## Erori [#erori]

| HTTP | `code` | Când |
| --- | --- | --- |
| 400 | `bad_request` | `kind`, `before` (trebuie să fie dată-oră ISO) sau `limit` invalid. |
| 404 | `not_found` | Id necunoscut, asset-ul altui utilizator sau `/content` pe un asset fără conținut. |
| 503 | `assets_unavailable` | Stocarea asset-urilor nu e configurată pe acest gateway. |

## SDK-uri [#sdk-uri]

```ts
import { Codai } from 'codai-sdk';
const client = new Codai({ apiKey: process.env.CODAI_API_KEY! });

const { assets } = await client.music.generate({ prompt: 'calm lo-fi piano', response_format: 'url' });
const url = await client.assets.contentUrl(assets[0]!.asset_id); // URL proaspăt, valabil o oră
for await (const a of client.assets.iterate({ kind: 'video' })) console.log(a.asset_id, a.bytes);
await client.assets.delete(assets[0]!.asset_id);
```

```python
from codai import Codai
client = Codai(api_key=os.environ["CODAI_API_KEY"])

r = client.music.generate({"prompt": "calm lo-fi piano", "response_format": "url"})
url = client.assets.content_url(r.assets[0]["asset_id"])
for a in client.assets.iterate(kind="video"):
    print(a["asset_id"], a["bytes"])
client.assets.delete(r.assets[0]["asset_id"])
```

Ambele SDK-uri au și `list(...)`, `retrieve(id)`, `content(id)` (descarcă octeții de la URL-ul semnat) și `contentPath(id)` / `content_path(id)` (URL-ul de redirecționare autentificat).
