codai docs
Gateway

Loturi

Umpli un șablon sau o creație dintr-un fișier CSV ori dintr-o foaie de calcul — câte o creație pe rând, cu limbă și randare opționale pe rând, export de stare și o arhivă ZIP cu videoclipurile.

Un lot transformă un tabel în creații: fiecare rând dintr-un fișier CSV (sau dintr-o creație de tip foaie de calcul) umple variabilele unui șablon sau ale unei creații și devine o creație separată. Rândurile pot fi traduse în limba lor și randate în MP4. Loturile rulează în fundal; le urmărești prin interogări repetate.

Crearea unui lot este gratuită. Traducerile și randările făcute pentru rânduri se facturează exact ca aceleași apeluri făcute manual (vezi Facturare).

MetodăCaleRezultat
POST/v1/studio/batchesValidează (dry_run) sau creează un lot (201)
GET/v1/studio/batches?limit=&before={ batches, next_before }, cele mai noi primele
GET/v1/studio/batches/{id}?rows=&status=&offset=&limit=Lotul, opțional cu rândurile lui
POST/v1/studio/batches/{id}/cancelAnulează rândurile care nu au început încă
POST/v1/studio/batches/{id}/retryReîncearcă rândurile eșuate
GET/v1/studio/batches/{id}/export.csvDescarcă starea fiecărui rând ca CSV
POST/v1/studio/batches/{id}/zipConstruiește o arhivă ZIP cu randările terminate (202)

Surse și date

Sursa este exact una dintre { "template_id": "<id>" } (un șablon cu cel puțin o variabilă) sau { "creative_id": "<id>", "seq"?: <versiune> } (o creație cu cel puțin o variabilă neblocată; implicit capul). Altfel răspunsul este 400 no_vars.

Datele sunt exact una dintre:

  • csv — text CSV cu un rând de antet, de cel mult 2 MB. Analizatorul respectă RFC 4180: câmpuri între ghilimele, "" în interiorul ghilimelelor, rânduri noi în celulele între ghilimele, sfârșituri de rând CRLF / LF / CR; un BOM UTF-8 este eliminat. Separatorul este detectat din antet (,, ; sau tab — o foaie exportată cu setări regionale românești folosește de obicei ;) sau impus cu delimiter. Celulele din antet sunt curățate de spații, rândurile scurte sunt completate cu celule goale, iar rândurile goale de la final sunt eliminate.
  • sheet — { "creative_id": "<creație foaie>", "node_id"?: "<id grilă>" }: prima (sau cea indicată) grilă ori tabel dintr-o creație de tip foaie de calcul, document sau prezentare. Antetul este format din titlurile coloanelor când fiecare coloană are unul, altfel din primul rând; datele calendaristice devin date ISO, valorile booleene true / false, numerele text simplu, iar celulele cu formule rămân goale.

Limite. Cel mult 500 de rânduri de date și 50 de coloane. Erorile CSV răspund 400 cu codul: empty, ragged (un rând mai lung decât antetul, cu indicele lui), unterminated_quote, too_many_columns, too_many_rows.

Asocierea coloanelor

Fiecare coloană se asociază unei variabile, unei coloane rezervate sau niciunei ținte. Fără mapping, coloanele sunt potrivite automat: diacriticele sunt eliminate, literele trecute la litere mici și orice altă secvență de caractere devine _, apoi numele coloanei este comparat cu cheia și eticheta fiecărei variabile (Titlu principal se potrivește cu variabila titlu_principal).

Coloană rezervatăSe potrivește și cuSemnificație
titletitluTitlul creației rândului (implicit: titlul sursei)
localelimba, language, langLimba rândului (BCP-47, de exemplu en, de-DE) — vezi Limbi
formataspectFormatul implicit al creației rândului (un id de format al sursei)

mapping înlocuiește potrivirea automată pentru fiecare coloană: { "Headline EN": "headline", "Notes": null, "Lang": "locale" } (null ignoră coloana). O țintă care nu este nici variabilă, nici coloană rezervată răspunde 400 invalid_mapping.

Valorile celulelor. O celulă goală păstrează valoarea implicită a variabilei. Numerele acceptă 1.5, 1,5 și 1 234,5; valorile booleene true / false, yes / no, da / nu, 1 / 0 și x; culorile #rgb, #rrggbb și #rrggbbaa; textele au cel mult 5000 de caractere.

Celule de imagine. O variabilă de tip imagine primește una dintre:

  • un id de asset al uneia dintre imaginile tale gata;
  • un nume de asset — cea mai nouă dintre imaginile tale gata al cărei nume sau nume de fișier se potrivește (fără a ține cont de majuscule);
  • o adresă URL https — importată în biblioteca ta Studio când rulează rândul (doar adrese publice, fiecare redirecționare verificată din nou; PNG, JPEG, WebP sau GIF de cel mult 10 MB). Aceeași adresă este importată o singură dată pe lot.

Rulare de probă

Trimite "dry_run": true ca să verifici totul fără să salvezi nimic (gratuit):

curl https://ai.codai.ro/v1/studio/batches \
  -H "Authorization: Bearer $CODAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "source": { "template_id": "<id șablon>" }, "csv": "headline,photo,locale\nAutumn sale,https://example.com/a.jpg,en\nReduceri de toamnă,poza-1,ro\n", "dry_run": true }'
{
  "dry_run": true,
  "columns": [{ "name": "headline", "index": 0, "maps_to": "headline", "kind": "var" }],
  "unmapped_vars": [],
  "rows": 2,
  "valid": 2,
  "errors": [],
  "preview": [{ "row": 0, "title": "Promo 9:16", "locale": "en", "format": null, "vars": { "headline": "Autumn sale" } }],
  "estimate": { "renders": 0, "localized_rows": 2 }
}

errors enumeră cel mult 100 de probleme sub forma { "row", "column", "message" } (un număr invalid, o imagine necunoscută, o limbă greșită, un format pe care sursa nu îl are); preview arată primele trei rânduri valide, iar estimate numără randările și traducerile pe care lotul le-ar factura. Corectează asocierea și încearcă din nou până când rezultatul arată bine.

Crearea și urmărirea unui lot

Același corp fără dry_run creează lotul și răspunde 201 { "batch": { … } }. Rândurile invalide sunt salvate ca failed, cu eroarea lor, iar restul rulează; când toate rândurile sunt invalide, răspunsul este 400 invalid_rows, cu erorile.

CâmpSemnificație
source{ template_id } sau { creative_id, seq? } (obligatoriu)
csv / sheetDatele, exact una dintre ele (obligatoriu)
delimiter,, ; sau \t (implicit: detectat)
mappingColoană → cheie de variabilă, title, locale, format sau null
titleTitlul lotului, cel mult 200 de caractere
rendertrue randează fiecare rând în MP4 (doar surse video, altfel 400 unsupported_kind; implicit false)
qualitydraft (implicit) sau final
formatId-ul formatului randărilor (implicit: formatul implicit al rândului sau al sursei)
localize{ "tone"?, "glossary"? } folosite pentru rândurile cu limbă
dry_runtrue doar validează

Fiecare rând trece prin pending → created → (localized) → (rendering) → done sau se termină ca failed ori skipped. GET /v1/studio/batches/{id} avansează puțin lotul la fiecare interogare și răspunde { "batch": { "id", "title", "status", "source", "total", "done", "failed", "pending", "skipped", "options", "columns", "cost_micro_usd", "zip", "created_at", "updated_at", "finished_at" } }; cu rows=1 adaugă rows (offset, limit cel mult 100, filtru opțional status), fiecare de forma { "idx", "status", "creative_id", "render_id", "render_url", "locale", "title", "error", "cost_micro_usd" } (render_url este o legătură semnată după ce randarea este gata). columns are forma { "header", "columns", "unmapped_vars" }: antetul CSV, aceeași potrivire a coloanelor ca la simulare și variabilele pe care nu le completează nicio coloană. cost_micro_usd este un șir zecimal (micro-USD). status al lotului este queued, running, completed, failed sau cancelled. Un lot care nu îți aparține răspunde 404 Batch not found..

Anulare și reîncercare. POST …/cancel marchează rândurile care nu au început încă drept skipped, iar lotul drept cancelled (409 not_cancellable după ce s-a terminat). POST …/retry pune rândurile eșuate înapoi în coadă — fiecare rând este încercat de cel mult 3 ori (409 nothing_to_retry când niciun rând nu mai poate fi reîncercat). Ambele răspund cu lotul.

Limbi

Cu o coloană locale, creația fiecărui rând este mai întâi tradusă în acea limbă cu modelul (aceeași traducere ca la Localizare, cu localize.tone și localize.glossary ale lotului) și apoi devine o creație în acea limbă, gata de randat. Lasă celula goală ca să păstrezi limba sursă.

Export, ZIP și limite

GET …/export.csv descarcă coloanele originale plus creative_id, status, error și render_url pentru fiecare rând (text/csv; charset=utf-8, <titlu>-status.csv). Celulele care încep cu =, +, -, @, tab sau retur de car primesc un ' în față, ca o foaie de calcul să nu le execute niciodată ca formule. Gratuit.

POST …/zip construiește în fundal o arhivă ZIP cu fiecare randare terminată (<idx>-<titlu>.mp4, cel mult 500 de fișiere) și răspunde 202 cu lotul (zip.status: "building"); interoghează lotul până când zip.status este ready și descarcă zip.url (semnat pentru o oră) — sau failed, cu zip.error. Fără nicio randare terminată răspunsul este 409 no_renders. Gratuit.

LimităValoare
Rânduri de date500
Coloane50
Mărimea fișierului CSV2 MB
Imagine importată10 MB, PNG / JPEG / WebP / GIF
Încercări pe rând3
Fișiere în arhiva ZIP500

Facturare

  • Crearea, validarea, interogarea, anularea, reîncercarea, exportul și construirea arhivei ZIP sunt gratuite.
  • Fiecare rând cu limbă este tradus și facturat ca POST …/localize (rânduri de utilizare codai::localize).
  • Fiecare randare de rând se facturează ca orice randare de aceeași calitate, după ce a reușit.
  • cost_micro_usd însumează cât au costat până acum lotul și fiecare rând.

SDK-uri și unelte de agent

const check = await codai.batches.dryRun({ source: { template_id: tpl.id }, csv });
if (check.valid === check.rows) {
  const { batch } = await codai.batches.create({ source: { template_id: tpl.id }, csv, render: true });
  await codai.batches.wait(batch.id); // interoghează la 3 s, cel mult 10 min
  const statusCsv = await codai.batches.exportCsv(batch.id);
  await codai.batches.zip(batch.id);
}
check = client.batches.dry_run(source={"template_id": tpl["id"]}, csv=csv_text)
batch = client.batches.create(source={"template_id": tpl["id"]}, csv=csv_text, render=True)["batch"]
client.batches.wait(batch["id"])  # interoghează la 3 s, cel mult 10 min
status_csv = client.batches.export_csv(batch["id"])

Agenții de pe desktop, telefon și VS Code folosesc creative_batch (template_id sau creative_id, csv sau sheet_creative_id, mapping, render, quality, format, dry_run) și creative_batch_status (batch_id, rows).

Hub (intern)

Hub-ul apelează aceleași rute sub /internal/studio/batches…, cu un token de serviciu și un user_id; corpurile și erorile sunt identice.

Pe această pagină