codai docs
Referință APIGateway

Sandbox-uri

Workspace-uri gVisor izolate în care agenții rulează Python, bash și LibreOffice și predau fișierele ca artefacte scanate și semnate.

Un sandbox este un container izolat cu un director /workspace persistent. Codul tău sau agentul tău rulează comenzi în el (Python 3, bash, LibreOffice, Node 24, bibliotecile uzuale pentru date și documente, fonturi cu acoperire completă pentru limba română), scrie rezultatele în /workspace/out și le primește înapoi ca artefacte: scanate, cu hash și descărcabile printr-un link semnat. Workspace-ul se păstrează între execuții până când sandbox-ul este distrus sau expiră.

Două backend-uri folosesc același API. v2 este implicit din 18 octombrie 2026: un pod de lungă durată cu snapshot-uri de memorie (pauză/reluare, fork, kernel Python persistent, URL-uri de previzualizare), vezi Sandbox-uri v2. v1 (Cloud Run, workspace restaurat la fiecare exec, plus POST /snapshot) rămâne disponibil cu backend: "v1". Dacă omiți backend și v2 nu este disponibil pentru cheia ta, gateway-ul trece pe v1; câmpul backend din fiecare obiect sandbox îți spune ce ai primit.

Fiecare execuție este contorizată; timpul de exec se plătește ulterior din portofel (vezi Facturare), de aceea răspunsurile au x-codai-cost-micro-usd: 0. Fiecare rută cere o cheie codai_ care atinge nivelul de unelte l3_sandbox.

Modelul de securitate

  • Izolare gVisor. Fiecare sandbox rulează sub gVisor, cu propria graniță de kernel: v2 ca pod dedicat pe GKE, v1 pe Cloud Run (gen2). Sistemul de fișiere al imaginii este doar-citire pentru codul tău și doar /workspace poate fi scris.
  • Fără rețea implicit. Cu egress: { mode: 'none' } (implicit) nu există nicio rută spre exterior: IP-urile publice, rețelele private și serverul de metadate sunt inaccesibile.
  • Egress printr-un proxy cu listă de domenii permise. { mode: 'allowlist', domains: [...] } (cel mult 20 de nume de gazde, fără adrese IP, fără sufixe interne) sau { mode: 'preset', preset: 'pypi' | 'npm' } permite HTTPS doar către acele gazde, prin proxy-ul de egress codai, care rezolvă singur DNS-ul și jurnalizează fiecare conexiune. Funcționează pe ambele backend-uri; proxy-ul deschide tuneluri simple și nu injectează niciodată credențiale.
  • Niciun secret înăuntru. În sandbox nu există nicio cheie codai, credențială cloud sau token; variabilele de mediu numite CODAI_* sau GOOGLE_* sunt respinse.
  • Auditat. Fiecare creare, execuție, transfer de fișier, artefact, snapshot și distrugere este scrisă într-un jurnal de audit append-only; fiecare execuție returnează o chitanță de reproductibilitate.
  • Datele rămân în europe-west1 (x-codai-data-region).

Limite

LibreOffice convertește toate formatele office în sandbox, de exemplu soffice --headless --convert-to pdf --outdir /workspace/out raport.docx (și .xlsx, .pptx, .odt, HTML, CSV). Fiecare comandă rulează sub un init mic care preia procesele ajutătoare din fundal, iar exit_code este codul real de ieșire al comenzii tale.

LimităValoare implicităEroare
Sandbox-uri pornite per cheie3429 sandbox_concurrency_limit
Sandbox-uri v2 pornite per utilizator5 (toate cheile la un loc)429 sandbox_concurrency_limit
Sandbox-uri v2 pe pauză per utilizator10429 sandbox_paused_limit (la pauză)
Capacitatea platformei v2comună503 sandbox_capacity (reîncearcă)
Execuții simultane per sandbox1409 sandbox_busy
Durata de viață (ttl_seconds)implicit 1 h, maximum 24 h400 invalid_ttl
Timeout per execuție (timeout_seconds)900 s400
Mărimea workspace-ului2 GBeveniment error workspace_too_large
Secunde de execuție per utilizator pe zi7 200429 sandbox_daily_limit
Încărcare fișier100 MB413
Listă de egress20 de domenii400
stdout / stderr per execuțiecâte 1 MB, apoi un eveniment truncated—

Artefacte

GET /v1/sandboxes/{id}/artifacts colectează fiecare fișier din /workspace/out. Fiecare artefact are:

  • mime, detectat din conținut (nu din numele fișierului);
  • sha256 al octeților;
  • scan: verdictul ClamAV, clean, infected sau error;
  • url: un link de descărcare semnat, valabil 1 h, prezent doar când scan este clean (expires_at spune când expiră).

POST /v1/sandboxes/run returnează artefactele direct în rezultat.

Chitanțe

Fiecare execuție încheiată (rezultatul blocant și evenimentul final exit din stream) include o receipt: digest-ul imaginii, șablonul, SHA-256 al intrărilor și al comenzii, fiecare fișier rezultat cu SHA-256 și mărime, plus generația workspace-ului înainte și după. Păstreaz-o lângă documentul produs ca dovadă a codului care l-a generat și a intrărilor folosite.

Streaming

Trimite Accept: text/event-stream la POST /v1/sandboxes/{id}/exec ca să primești cadre data: pe măsură ce comanda rulează: start, apoi oricâte fragmente stdout / stderr (și truncated când un stream atinge 1 MB), apoi exact un exit (sau error). Fără acest header apelul blochează și returnează un singur rezultat JSON.

Idempotency-Key pe exec și run returnează, timp de 24 h, răspunsul salvat al unei cereri anterioare cu aceeași cheie, în loc să ruleze comanda din nou.

Pornire rapidă: un PDF cu diacritice românești

Dintr-o singură cerere cu POST /v1/sandboxes/run: sandbox-ul este creat, scriptul rulează, /workspace/out este colectat și sandbox-ul este distrus.

curl https://ai.codai.ro/v1/sandboxes/run \
  -H "Authorization: Bearer $CODAI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: act-2026-10-16-001" \
  -d @- <<'JSON'
{
  "language": "python",
  "timeout_seconds": 120,
  "code": "import os\nfrom reportlab.lib.pagesizes import A4\nfrom reportlab.pdfbase import pdfmetrics\nfrom reportlab.pdfbase.ttfonts import TTFont\nfrom reportlab.pdfgen import canvas\n\npdfmetrics.registerFont(TTFont('DejaVu', '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf'))\nos.makedirs('/workspace/out', exist_ok=True)\nc = canvas.Canvas('/workspace/out/act.pdf', pagesize=A4)\nc.setFont('DejaVu', 14)\nc.drawString(72, 770, 'Act adițional nr. 1 la contractul de prestări servicii')\nc.drawString(72, 745, 'Părțile convin: ședința se mută în București, str. Ștefan cel Mare.')\nc.save()\nprint('ok')\n"
}
JSON

Răspunsul este un rezultat de execuție în care artifacts[0].url descarcă act.pdf timp de o oră. Fontul DejaVu Sans include tot setul ă â î ș ț, așa că ș și ț cu virgulă dedesubt se afișează corect.

SDK-uri

import { Codai } from 'codai-sdk';

const client = new Codai({ apiKey: process.env.CODAI_API_KEY! });
const sb = await client.sandboxes.create({ ttl_seconds: 1800 });
await client.sandboxes.files.put(sb.id, 'in/date.csv', 'client,suma\nSC Exemplu SRL,1200\n');
for await (const ev of client.sandboxes.execStream(sb.id, {
  shell: 'python3 -c "import pandas as pd; print(pd.read_csv(\'in/date.csv\'))"',
})) {
  if (ev.type === 'stdout') process.stdout.write(ev.data);
  if (ev.type === 'exit') console.log('exit', ev.exit_code, ev.receipt.command_sha256);
}
const { data } = await client.sandboxes.artifacts(sb.id);
await client.sandboxes.delete(sb.id);
from codai import Codai

client = Codai(api_key="...")
sb = client.sandboxes.create(ttl_seconds=1800)
client.sandboxes.files.put(sb["id"], "in/date.csv", "client,suma\nSC Exemplu SRL,1200\n")
for ev in client.sandboxes.exec_stream(sb["id"], language="python", code="print(open('in/date.csv').read())"):
    if ev["type"] == "stdout":
        print(ev["data"], end="")
result = client.sandboxes.run(shell="weasyprint in/page.html out/page.pdf",
                              inputs=[{"path": "page.html", "url": "https://example.com/page.html"}])
client.sandboxes.delete(sb["id"])

Unealta de chat codai_sandbox

Adaugă { "type": "codai_sandbox" } în tools la POST /v1/chat/completions (opțional cu egress și template), iar gateway-ul face restul pe server: îi dă modelului sandbox_bash, sandbox_python, sandbox_edit și sandbox_files, le rulează într-un sandbox per x-codai-session-id (durată de viață 1 h, prelungită la fiecare folosire) și, la final, adaugă artefactele la mesajul final ca codai_sandbox.artifacts, plus o listă markdown cu linkuri semnate. Cheia are nevoie în continuare de nivelul de unelte l3_sandbox.

curl https://ai.codai.ro/v1/chat/completions \
  -H "Authorization: Bearer $CODAI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "x-codai-session-id: acte-firma-42" \
  -d '{"model":"codai","tools":[{"type":"codai_sandbox"}],
       "messages":[{"role":"user","content":"Fă-mi un PDF cu o hotărâre AGA pentru SC Exemplu SRL."}]}'

Unealta integrată exec_python rulează acum pe același backend de sandbox; nu mai execută cod în procesul gateway-ului.

Skill-uri pentru documente (compatibile cu Claude Skills)

Agent Skills predefinite de la Anthropic (docx, xlsx, pdf, pptx) au nevoie de un container propriu Anthropic, care nu există pe cloud-urile din spatele codai, așa că codai le oferă pe propriul sandbox, pentru orice model. Două forme echivalente:

{ "tools": [{ "type": "codai_sandbox", "skills": ["docx", "pdf"] }] }
{ "container": { "skills": [{ "type": "anthropic", "skill_id": "xlsx", "version": "latest" }] } }

Ambele merg pe /v1/chat/completions și pe /v1/messages. Pornesc unealta codai_sandbox și adaugă un bloc fix de instrucțiuni pentru skill-urile cerute (python-docx, openpyxl, reportlab/pypdf, python-pptx, weasyprint), astfel încât modelul produce fișiere reale în /workspace/out, pe care le primești ca linkuri semnate. Skill-urile proprii (type: "custom") și reutilizarea containerului (container.id) răspund cu 400; folosește x-codai-session-id ca să păstrezi un sandbox pe conversație.

Unelte MCP

Serverul MCP codai (https://ai.codai.ro/mcp) expune sandbox_create, sandbox_list, sandbox_exec, sandbox_files (list / read / write / artifacts) și sandbox_kill, plus uneltele v2 sandbox_run_code, sandbox_pause, sandbox_resume, sandbox_fork și sandbox_preview (vezi Sandbox-uri v2). Ele apelează aceleași rute cu cheia ta, deci nivelul de unelte, limitele și contorizarea sunt aceleași ca la API-ul REST. Citirile cu sandbox_files întorc cel mult 256 KB direct în răspuns; fișierele mai mari le iei prin op: "artifacts" (link semnat + SHA-256).

Facturare

Din 17 octombrie 2026 (00:00 UTC) timpul de exec se plătește din portofel cu 0,10 € pe oră de exec, iar primele 10 ore de exec pe utilizator pe lună calendaristică (UTC) sunt gratuite; consumul de dinainte de această dată nu se facturează niciodată. Un sandbox pornit, dar nefolosit, nu costă nimic. Consumul se decontează pe intervale de 10 minute (wallet_ledger, sursa sandbox_charge). Dacă un interval nu poate fi plătit, crearea și exec-urile noi răspund 402 insufficient_balance (cu unpaid_micro_eur) până când o alimentare a portofelului îl achită.

Această secțiune descrie prețul backend-ului v1. Sandbox-urile v2 (implicite) se facturează altfel, vezi Facturare v2.

Sandbox-uri v2

Disponibile pentru orice cheie din 18 octombrie 2026 și backend-ul implicit când omiți backend. API-ul REST de mai sus este comun: un sandbox își alege backend-ul o singură dată, la creare, iar backend (v1 sau v2) apare în fiecare obiect sandbox. Dacă v2 nu este disponibil pentru cheia ta și nu l-ai cerut explicit, crearea trece pe v1; cu backend: "v2" explicit, cererea eșuează.

Un sandbox v2 este o mașină izolată de lungă durată, nu un workspace restaurat la fiecare exec: procesele continuă să ruleze între apeluri, iar întreaga stare (memorie, procese pornite, /workspace) poate fi salvată ca snapshot, pusă pe pauză, reluată și copiată prin fork. Pe v2:

  • Egress funcționează ca pe v1: none (implicit), un preset pypi / npm sau o listă de cel mult 20 de domenii, prin proxy-ul de egress codai (tuneluri simple, fără injectare de credențiale). Fork-urile moștenesc egress-ul părintelui.
  • Unelte: Python 3, bash, bibliotecile pentru documente și Node 24 cu npm în fiecare șablon.
  • inputs la exec și GET /artifacts (scanate ClamAV, SHA-256, URL-uri semnate) se comportă exact ca pe v1.
  • Doar pe v1: POST /v1/sandboxes/{id}/snapshot răspunde 409 not_supported_on_v2; folosește pauza/fork-ul.

Limite v2

LimităValoareEroare
Sandbox-uri pornite per cheie3429 sandbox_concurrency_limit
Sandbox-uri v2 pornite per utilizator5, pe toate cheile tale429 sandbox_concurrency_limit
Sandbox-uri v2 pe pauză per utilizator10429 sandbox_paused_limit la pauză
Copii per fork5400 invalid_count
Capacitatea platformeirezervă comună503 sandbox_capacity, reîncearcă

503 sandbox_capacity este temporar: reîncearcă cu pauze din ce în ce mai lungi sau creează cu backend: "v1".

Șabloane

templateCe conține
codai-baseImaginea implicită: Python 3, bash, Node 24 + npm și bibliotecile pentru documente.
brivio-actecodai-base plus LibreOffice, pregătit pentru documente de birou și pornit deja încălzit.
desktopUn desktop Linux accesibil prin noVNC pe portul 6080 (îl deschizi cu un URL de previzualizare).

Când un șablon are un snapshot încălzit, răspunsul la creare conține restored: true.

Kernel persistent: run_code

POST /v1/sandboxes/{id}/run_code cu { "code": "...", "timeout_seconds": 60 } rulează o celulă Python într-un singur kernel de lungă durată. Variabilele globale se păstrează între apeluri, peste pauză/reluare și în fork-uri. Răspunsul este { stdout, stderr, result, error, duration_ms, execution_count, kernel_restarted }: result este repr-ul ultimei expresii (cel mult 64 KB), iar error este { name, value, traceback } pentru o excepție neprinsă. O celulă care depășește timpul limită repornește kernelul (kernel_restarted: true, starea se pierde). POST /v1/sandboxes/{id}/kernel/reset îl repornește intenționat; fișierele rămân.

Pauză și reluare

POST /v1/sandboxes/{id}/pause face un snapshot al sandbox-ului și îl oprește; statusul devine paused. Poți păstra cel mult 10 sandbox-uri v2 pe pauză (429 sandbox_paused_limit); șterge-le pe cele vechi ca să faci loc. La reluare, sandbox-ul intră din nou în limitele de sandbox-uri pornite. POST /v1/sandboxes/{id}/resume îl readuce și răspunde cu sandbox-ul plus restored și ready_ms. restored: true înseamnă că memoria și procesele au revenit exact cum erau; restored: false înseamnă o pornire la rece din workspace-ul salvat (fișierele sunt intacte, starea kernelului se pierde). codai măsoară asta în interiorul sandbox-ului; nu presupune niciodată.

Fork

POST /v1/sandboxes/{id}/fork cu { "count": 1..5, "ttl_seconds"?: n } face un snapshot al unui sandbox pornit (care continuă să ruleze) și pornește count copii din acel snapshot. Fiecare copie este un sandbox complet, cu id, workspace și stare de kernel proprii, și se facturează ca oricare altul. Răspunsul este { object: "list", parent_id, data: [{ id, restored, ready_ms, error? }] }: pentru fiecare copie, restored: false înseamnă că a pornit la rece, iar error înseamnă că a eșuat și nu rulează. Un fork nu poate duce o cheie peste 6 sandbox-uri active și nici pe tine peste 5 sandbox-uri v2 pornite (429 sandbox_concurrency_limit).

URL-uri de previzualizare

POST /v1/sandboxes/{id}/preview cu { "port": 3000, "ttl_seconds": 900 } răspunde { port, url, expires_at }: un URL HTTPS semnat pe *.sbx.codai.ro care trimite la acel port din sandbox (un server de dezvoltare sau noVNC pe 6080 în desktop). Porturi 1024–65535, cu excepția lui 8080; valabilitate între 60 s și 1 h (implicit 15 min). URL-ul nu cere cheie: oricine îl are ajunge la port până la expirare, așa că trimite-l doar celor care trebuie să vadă aplicația.

const sb = await client.sandboxes.create({
  template: 'codai-base',
  egress: { mode: 'preset', preset: 'pypi' },
}); // v2 implicit
await client.sandboxes.runCode(sb.id, {
  code: 'import pandas as pd\ndf = pd.DataFrame({"a": [1, 2]})',
});
const r = await client.sandboxes.runCode(sb.id, { code: 'df["a"].sum()' }); // r.result === '3'
const { data } = await client.sandboxes.fork(sb.id, { count: 3 });
await client.sandboxes.pause(sb.id);
const back = await client.sandboxes.resume(sb.id); // back.restored, back.ready_ms
sb = client.sandboxes.create(backend="v2", template="desktop")
p = client.sandboxes.preview(sb["id"], 6080, ttl_seconds=600)
print(p["url"], p["expires_at"])

Facturare v2

  • Pornit: 0,10 € pe oră de ceas cât timp sandbox-ul există (ocupat sau nefolosit), cu 5 ore gratuite pe utilizator pe lună calendaristică (UTC) (separat de orele de exec v1 de mai sus).
  • Pe pauză: se stochează doar snapshot-ul, cu 0,05 € pe GB-lună, contorizat orar.
  • Sumele se decontează din portofel ca la v1 (402 insufficient_balance când un interval nu poate fi plătit).
POST
/v1/sandboxes

Autorizare

bearerAuth
headerAutorizareBearer <codai_…>

O cheie API codai (prefix codai_). Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de suprafețele media potrivite scope-ului lor (/v1/realtime, /v1/audio/*, /v1/embeddings).

Parametri header

x-request-id?string

Id de corelare ales de client; e returnat ca x-codai-trace-id și persistat pe rândul de usage.

Lungimelength <= 128

Corpul cererii

application/json
  1. body
backend?string

Backend-ul de execuție: v2 (implicit: pod de lungă durată cu snapshot-uri de memorie, pauză/reluare, fork, kernel persistent, URL-uri de previzualizare, egress prin proxy-ul codai, Node 24 + npm) sau v1 (Cloud Run, workspace restaurat la fiecare exec, POST /snapshot). Dacă lipsește și v2 nu este disponibil pentru cheie, sandbox-ul se creează pe v1; un v2 explicit eșuează.

Implicit"v2"
Valoare din"v1""v2"
template?string

Șablonul de imagine. v1: doar codai-base. v2: codai-base, brivio-acte (unelte de birou deja încălzite) sau desktop (desktop Linux prin noVNC pe portul 6080).

Implicit"codai-base"
Valoare din"codai-base""brivio-acte""desktop"
ttl_seconds?integer

Durata de viață; sandbox-ul expiră după aceea (glisantă pentru sesiunile de chat). Cel mult 86400 pe v1 și 604800 pe v2.

Interval60 <= value <= 604800
Implicit3600
egress?||

Rețeaua spre exterior, pe ambele backend-uri. none (implicit) nu are deloc rețea; allowlist permite HTTPS către cel mult 20 de domenii prin proxy-ul de egress codai (fără adrese IP, fără gazde interne); preset deschide o listă predefinită (pypi, npm). Proxy-ul deschide tuneluri simple și nu injectează niciodată credențiale; fork-urile v2 moștenesc politica părintelui.

metadata?

Etichetele tale, returnate neschimbate.

Corpul răspunsului

Sandbox-ul nou.

application/json
  1. response
id*string
Formatuuid
object*"sandbox"
Valoare din"sandbox"
status*string
Valoare din"running""paused""stopped""expired""destroyed"
backend*string

Backend-ul ales la creare.

Valoare din"v1""v2"
restored?boolean

Doar la crearea unui sandbox v2: adevărat când a pornit dintr-un snapshot de șablon încălzit.

template*string
egress*||

Rețeaua spre exterior, pe ambele backend-uri. none (implicit) nu are deloc rețea; allowlist permite HTTPS către cel mult 20 de domenii prin proxy-ul de egress codai (fără adrese IP, fără gazde interne); preset deschide o listă predefinită (pypi, npm). Proxy-ul deschide tuneluri simple și nu injectează niciodată credențiale; fork-urile v2 moștenesc politica părintelui.

created_at*string
Formatdate-time
expires_at*string
Formatdate-time
last_exec_at*|
Formatdate-time
metadata*
usage*
Exemplu de cerere
curl -X POST 'https://ai.codai.ro/v1/sandboxes' \  -H 'Content-Type: application/json' \  -d '{}'
Exemplu de răspuns
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "object": "sandbox",  "status": "running",  "backend": "v1",  "restored": true,  "template": "string",  "egress": {    "mode": "none"  },  "created_at": "2019-08-24T14:15:22Z",  "expires_at": "2019-08-24T14:15:22Z",  "last_exec_at": "2019-08-24T14:15:22Z",  "metadata": {    "property1": "string",    "property2": "string"  },  "usage": {    "exec_count": 0,    "exec_seconds": 0  }}
GET
/v1/sandboxes

Autorizare

bearerAuth
headerAutorizareBearer <codai_…>

O cheie API codai (prefix codai_). Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de suprafețele media potrivite scope-ului lor (/v1/realtime, /v1/audio/*, /v1/embeddings).

Parametri query

status?string

Doar sandbox-urile cu acest status.

Valoare din"running""paused""stopped""expired""destroyed"

Parametri header

x-request-id?string

Id de corelare ales de client; e returnat ca x-codai-trace-id și persistat pe rândul de usage.

Lungimelength <= 128

Corpul răspunsului

Sandbox-urile tale.

application/json
  1. response
object?"list"
Valoare din"list"
data*array<>
Exemplu de cerere
curl -X GET 'https://ai.codai.ro/v1/sandboxes'
Exemplu de răspuns
{  "object": "list",  "data": [    {      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",      "object": "sandbox",      "status": "running",      "backend": "v1",      "restored": true,      "template": "string",      "egress": {        "mode": "none"      },      "created_at": "2019-08-24T14:15:22Z",      "expires_at": "2019-08-24T14:15:22Z",      "last_exec_at": "2019-08-24T14:15:22Z",      "metadata": {        "property1": "string",        "property2": "string"      },      "usage": {        "exec_count": 0,        "exec_seconds": 0      }    }  ]}
GET
/v1/sandboxes/{id}

Autorizare

bearerAuth
headerAutorizareBearer <codai_…>

O cheie API codai (prefix codai_). Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de suprafețele media potrivite scope-ului lor (/v1/realtime, /v1/audio/*, /v1/embeddings).

Parametri de cale

id*string

Id-ul sandbox-ului (uuid).

Formatuuid

Parametri header

x-request-id?string

Id de corelare ales de client; e returnat ca x-codai-trace-id și persistat pe rândul de usage.

Lungimelength <= 128

Corpul răspunsului

Sandbox-ul.

application/json
  1. response
id*string
Formatuuid
object*"sandbox"
Valoare din"sandbox"
status*string
Valoare din"running""paused""stopped""expired""destroyed"
backend*string

Backend-ul ales la creare.

Valoare din"v1""v2"
restored?boolean

Doar la crearea unui sandbox v2: adevărat când a pornit dintr-un snapshot de șablon încălzit.

template*string
egress*||

Rețeaua spre exterior, pe ambele backend-uri. none (implicit) nu are deloc rețea; allowlist permite HTTPS către cel mult 20 de domenii prin proxy-ul de egress codai (fără adrese IP, fără gazde interne); preset deschide o listă predefinită (pypi, npm). Proxy-ul deschide tuneluri simple și nu injectează niciodată credențiale; fork-urile v2 moștenesc politica părintelui.

created_at*string
Formatdate-time
expires_at*string
Formatdate-time
last_exec_at*|
Formatdate-time
metadata*
usage*
Exemplu de cerere
curl -X GET 'https://ai.codai.ro/v1/sandboxes/497f6eca-6276-4993-bfeb-53cbbbba6f08'
Exemplu de răspuns
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "object": "sandbox",  "status": "running",  "backend": "v1",  "restored": true,  "template": "string",  "egress": {    "mode": "none"  },  "created_at": "2019-08-24T14:15:22Z",  "expires_at": "2019-08-24T14:15:22Z",  "last_exec_at": "2019-08-24T14:15:22Z",  "metadata": {    "property1": "string",    "property2": "string"  },  "usage": {    "exec_count": 0,    "exec_seconds": 0  }}
POST
/v1/sandboxes/{id}/exec

Autorizare

bearerAuth
headerAutorizareBearer <codai_…>

O cheie API codai (prefix codai_). Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de suprafețele media potrivite scope-ului lor (/v1/realtime, /v1/audio/*, /v1/embeddings).

Parametri de cale

id*string

Id-ul sandbox-ului (uuid).

Formatuuid

Parametri header

x-request-id?string

Id de corelare ales de client; e returnat ca x-codai-trace-id și persistat pe rândul de usage.

Lungimelength <= 128
Idempotency-Key?string

Timp de 24 h returnează răspunsul salvat al unei cereri anterioare cu aceeași cheie, în loc să o ruleze din nou.

Lungimelength <= 255

Corpul cererii

application/json
  1. body

Exact unul dintre cmd, shell sau language + code.

cmd?array<string>

Comanda ca argv (fără shell).

Elementeitems <= 256
shell?string

O linie de shell rulată cu /bin/bash -lc.

Lungimelength <= 65536
language?string

Rulează code cu acest interpretor.

Valoare din"python""bash"
code?string

Codul sursă pentru language.

Lungimelength <= 1048576
env?

Variabile de mediu (cel mult 64; numele care încep cu CODAI_ sau GOOGLE_ sunt respinse).

cwd?string

Directorul de lucru din /workspace.

Lungimelength <= 1024
timeout_seconds?integer

Limita de timp pentru acest exec.

Interval1 <= value <= 900
Implicit120
stdin?string

Intrarea standard.

Lungimelength <= 1048576
inputs?array<>

Fișiere scrise doar-citire în /workspace/in înainte de rularea comenzii.

Elementeitems <= 50

Corpul răspunsului

Rezultat JSON sau stream SSE când cererea a trimis Accept: text/event-stream.

  1. response
exit_code*|

Codul de ieșire propriu al comenzii; 128 + n când a fost încheiată de semnalul n. null doar când execuția a depășit timpul (timed_out: true) sau procesul nu a putut fi pornit.

stdout*string

Ieșirea standard (cel mult 1 MB).

stderr*string

Ieșirea de erori (cel mult 1 MB).

timed_out*boolean
duration_ms*integer
artifacts?array<>

Prezent pe /v1/sandboxes/run.

receipt*

Ce a rulat și ce a produs: digest-ul imaginii, hash-urile intrărilor și ale comenzii, fiecare fișier rezultat cu SHA-256 și generațiile workspace-ului înainte și după.

Exemplu de cerere
curl -X POST 'https://ai.codai.ro/v1/sandboxes/497f6eca-6276-4993-bfeb-53cbbbba6f08/exec' \  -H 'Content-Type: application/json' \  -d '{}'
Exemplu de răspuns
{  "exit_code": 0,  "stdout": "string",  "stderr": "string",  "timed_out": true,  "duration_ms": 0,  "artifacts": [    {      "id": "string",      "path": "string",      "bytes": 0,      "mime": "string",      "sha256": "string",      "scan": "clean",      "url": "string",      "expires_at": "2019-08-24T14:15:22Z"    }  ],  "receipt": {    "image_digest": "string",    "template": "string",    "input_sha256": "string",    "command_sha256": "string",    "outputs": [      {        "path": "string",        "sha256": "string",        "bytes": 0      }    ],    "generation_before": 0,    "generation_after": 0  }}
PUT
/v1/sandboxes/{id}/files/{path}

Autorizare

bearerAuth
headerAutorizareBearer <codai_…>

O cheie API codai (prefix codai_). Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de suprafețele media potrivite scope-ului lor (/v1/realtime, /v1/audio/*, /v1/embeddings).

Parametri de cale

id*string

Id-ul sandbox-ului (uuid).

Formatuuid
path*string

Calea fișierului relativă la /workspace (sunt permise slash-uri, fiecare segment codat URL).

Lungimelength <= 1024

Parametri header

x-request-id?string

Id de corelare ales de client; e returnat ca x-codai-trace-id și persistat pe rândul de usage.

Lungimelength <= 128

Corpul cererii

body*fileapplication/octet-stream
Formatbinary

Corpul răspunsului

Scris: mărime, SHA-256 și noua generație.

application/json
  1. response
path*string
bytes*integer
sha256*string
generation*integer
Exemplu de cerere
curl -X PUT 'https://ai.codai.ro/v1/sandboxes/497f6eca-6276-4993-bfeb-53cbbbba6f08/files/string' \  -H 'Content-Type: application/octet-stream' \  -d 'string'
Exemplu de răspuns
{  "path": "string",  "bytes": 0,  "sha256": "string",  "generation": 0}
GET
/v1/sandboxes/{id}/files/{path}

Autorizare

bearerAuth
headerAutorizareBearer <codai_…>

O cheie API codai (prefix codai_). Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de suprafețele media potrivite scope-ului lor (/v1/realtime, /v1/audio/*, /v1/embeddings).

Parametri de cale

id*string

Id-ul sandbox-ului (uuid).

Formatuuid
path*string

Calea fișierului relativă la /workspace (sunt permise slash-uri, fiecare segment codat URL).

Lungimelength <= 1024

Parametri header

x-request-id?string

Id de corelare ales de client; e returnat ca x-codai-trace-id și persistat pe rândul de usage.

Lungimelength <= 128

Corpul răspunsului

Conținutul fișierului.

response?fileapplication/octet-stream
Formatbinary
Exemplu de cerere
curl -X GET 'https://ai.codai.ro/v1/sandboxes/497f6eca-6276-4993-bfeb-53cbbbba6f08/files/string'
Exemplu de răspuns
"string"
GET
/v1/sandboxes/{id}/files

Autorizare

bearerAuth
headerAutorizareBearer <codai_…>

O cheie API codai (prefix codai_). Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de suprafețele media potrivite scope-ului lor (/v1/realtime, /v1/audio/*, /v1/embeddings).

Parametri de cale

id*string

Id-ul sandbox-ului (uuid).

Formatuuid

Parametri query

path?string

Directorul relativ la /workspace.

Lungimelength <= 1024

Parametri header

x-request-id?string

Id de corelare ales de client; e returnat ca x-codai-trace-id și persistat pe rândul de usage.

Lungimelength <= 128

Corpul răspunsului

Intrările din director.

application/json
  1. response
entries*array<>
Exemplu de cerere
curl -X GET 'https://ai.codai.ro/v1/sandboxes/497f6eca-6276-4993-bfeb-53cbbbba6f08/files'
Exemplu de răspuns
{  "entries": [    {      "path": "string",      "bytes": 0,      "type": "file",      "mtime": "2019-08-24T14:15:22Z"    }  ]}
GET
/v1/sandboxes/{id}/artifacts

Autorizare

bearerAuth
headerAutorizareBearer <codai_…>

O cheie API codai (prefix codai_). Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de suprafețele media potrivite scope-ului lor (/v1/realtime, /v1/audio/*, /v1/embeddings).

Parametri de cale

id*string

Id-ul sandbox-ului (uuid).

Formatuuid

Parametri header

x-request-id?string

Id de corelare ales de client; e returnat ca x-codai-trace-id și persistat pe rândul de usage.

Lungimelength <= 128

Corpul răspunsului

Artefactele.

application/json
  1. response
data*array<>
Exemplu de cerere
curl -X GET 'https://ai.codai.ro/v1/sandboxes/497f6eca-6276-4993-bfeb-53cbbbba6f08/artifacts'
Exemplu de răspuns
{  "data": [    {      "id": "string",      "path": "string",      "bytes": 0,      "mime": "string",      "sha256": "string",      "scan": "clean",      "url": "string",      "expires_at": "2019-08-24T14:15:22Z"    }  ]}
POST
/v1/sandboxes/{id}/snapshot

Autorizare

bearerAuth
headerAutorizareBearer <codai_…>

O cheie API codai (prefix codai_). Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de suprafețele media potrivite scope-ului lor (/v1/realtime, /v1/audio/*, /v1/embeddings).

Parametri de cale

id*string

Id-ul sandbox-ului (uuid).

Formatuuid

Parametri header

x-request-id?string

Id de corelare ales de client; e returnat ca x-codai-trace-id și persistat pe rândul de usage.

Lungimelength <= 128

Corpul cererii

application/json
  1. body
name?string

Nume opțional pentru snapshot.

Lungimelength <= 128

Corpul răspunsului

Snapshot-ul.

application/json
  1. response
object*string

Numele obiectului din stocare.

bytes*integer
sha256*string
Exemplu de cerere
curl -X POST 'https://ai.codai.ro/v1/sandboxes/497f6eca-6276-4993-bfeb-53cbbbba6f08/snapshot' \  -H 'Content-Type: application/json' \  -d '{}'
Exemplu de răspuns
{  "object": "string",  "bytes": 0,  "sha256": "string"}
DELETE
/v1/sandboxes/{id}

Autorizare

bearerAuth
headerAutorizareBearer <codai_…>

O cheie API codai (prefix codai_). Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de suprafețele media potrivite scope-ului lor (/v1/realtime, /v1/audio/*, /v1/embeddings).

Parametri de cale

id*string

Id-ul sandbox-ului (uuid).

Formatuuid

Parametri header

x-request-id?string

Id de corelare ales de client; e returnat ca x-codai-trace-id și persistat pe rândul de usage.

Lungimelength <= 128

Corpul răspunsului

Distrus.

Exemplu de cerere
curl -X DELETE 'https://ai.codai.ro/v1/sandboxes/497f6eca-6276-4993-bfeb-53cbbbba6f08'
Exemplu de răspuns
Gol
POST
/v1/sandboxes/run

Autorizare

bearerAuth
headerAutorizareBearer <codai_…>

O cheie API codai (prefix codai_). Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de suprafețele media potrivite scope-ului lor (/v1/realtime, /v1/audio/*, /v1/embeddings).

Parametri header

x-request-id?string

Id de corelare ales de client; e returnat ca x-codai-trace-id și persistat pe rândul de usage.

Lungimelength <= 128
Idempotency-Key?string

Timp de 24 h returnează răspunsul salvat al unei cereri anterioare cu aceeași cheie, în loc să o ruleze din nou.

Lungimelength <= 255

Corpul cererii

application/json
  1. body

Câmpurile din SandboxCreate plus cele din SandboxExecRequest.

template?"codai-base"

Șablonul de imagine.

Implicit"codai-base"
Valoare din"codai-base"
ttl_seconds?integer

Durata de viață; sandbox-ul expiră după aceea (glisantă pentru sesiunile de chat).

Interval60 <= value <= 86400
Implicit3600
egress?||

Rețeaua spre exterior, pe ambele backend-uri. none (implicit) nu are deloc rețea; allowlist permite HTTPS către cel mult 20 de domenii prin proxy-ul de egress codai (fără adrese IP, fără gazde interne); preset deschide o listă predefinită (pypi, npm). Proxy-ul deschide tuneluri simple și nu injectează niciodată credențiale; fork-urile v2 moștenesc politica părintelui.

metadata?

Etichetele tale, returnate neschimbate.

cmd?array<string>

Comanda ca argv (fără shell).

Elementeitems <= 256
shell?string

O linie de shell rulată cu /bin/bash -lc.

Lungimelength <= 65536
language?string

Rulează code cu acest interpretor.

Valoare din"python""bash"
code?string

Codul sursă pentru language.

Lungimelength <= 1048576
env?

Variabile de mediu (cel mult 64; numele care încep cu CODAI_ sau GOOGLE_ sunt respinse).

cwd?string

Directorul de lucru din /workspace.

Lungimelength <= 1024
timeout_seconds?integer

Limita de timp pentru acest exec.

Interval1 <= value <= 900
Implicit120
stdin?string

Intrarea standard.

Lungimelength <= 1048576
inputs?array<>

Fișiere scrise doar-citire în /workspace/in înainte de rularea comenzii.

Elementeitems <= 50

Corpul răspunsului

Codul de ieșire, output-ul, artefactele și chitanța.

application/json
  1. response
exit_code*|

Codul de ieșire propriu al comenzii; 128 + n când a fost încheiată de semnalul n. null doar când execuția a depășit timpul (timed_out: true) sau procesul nu a putut fi pornit.

stdout*string

Ieșirea standard (cel mult 1 MB).

stderr*string

Ieșirea de erori (cel mult 1 MB).

timed_out*boolean
duration_ms*integer
artifacts?array<>

Prezent pe /v1/sandboxes/run.

receipt*

Ce a rulat și ce a produs: digest-ul imaginii, hash-urile intrărilor și ale comenzii, fiecare fișier rezultat cu SHA-256 și generațiile workspace-ului înainte și după.

Exemplu de cerere
curl -X POST 'https://ai.codai.ro/v1/sandboxes/run' \  -H 'Content-Type: application/json' \  -d '{}'
Exemplu de răspuns
{  "exit_code": 0,  "stdout": "string",  "stderr": "string",  "timed_out": true,  "duration_ms": 0,  "artifacts": [    {      "id": "string",      "path": "string",      "bytes": 0,      "mime": "string",      "sha256": "string",      "scan": "clean",      "url": "string",      "expires_at": "2019-08-24T14:15:22Z"    }  ],  "receipt": {    "image_digest": "string",    "template": "string",    "input_sha256": "string",    "command_sha256": "string",    "outputs": [      {        "path": "string",        "sha256": "string",        "bytes": 0      }    ],    "generation_before": 0,    "generation_after": 0  }}
POST
/v1/sandboxes/{id}/run_code

Autorizare

bearerAuth
headerAutorizareBearer <codai_…>

O cheie API codai (prefix codai_). Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de suprafețele media potrivite scope-ului lor (/v1/realtime, /v1/audio/*, /v1/embeddings).

Parametri de cale

id*string

Id-ul sandbox-ului (uuid).

Formatuuid

Parametri header

x-request-id?string

Id de corelare ales de client; e returnat ca x-codai-trace-id și persistat pe rândul de usage.

Lungimelength <= 128

Corpul cererii

application/json
  1. body
code*string

Codul Python al celulei.

Lungime1 <= length <= 1000000
timeout_seconds?integer

Secunde până la repornirea kernelului (implicit 60, maxim 900).

Interval1 <= value <= 900
Implicit60

Corpul răspunsului

Rezultatul celulei.

application/json
  1. response
stdout*string

Textul scris la stdout în timpul celulei.

stderr*string

Textul scris la stderr în timpul celulei.

result*|

repr-ul ultimei expresii sau null.

error*|

Excepția neprinsă sau null.

duration_ms*integer

Milisecunde de ceas.

execution_count*integer

Contorul de execuții al kernelului.

kernel_restarted*boolean

Adevărat când kernelul a fost repornit (timp depășit sau eroare) și starea lui s-a pierdut.

Exemplu de cerere
curl -X POST 'https://ai.codai.ro/v1/sandboxes/497f6eca-6276-4993-bfeb-53cbbbba6f08/run_code' \  -H 'Content-Type: application/json' \  -d '{  "code": "string"}'
Exemplu de răspuns
{  "stdout": "string",  "stderr": "string",  "result": "string",  "error": {    "name": "string",    "value": "string",    "traceback": "string"  },  "duration_ms": 0,  "execution_count": 0,  "kernel_restarted": true}
POST
/v1/sandboxes/{id}/kernel/reset

Autorizare

bearerAuth
headerAutorizareBearer <codai_…>

O cheie API codai (prefix codai_). Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de suprafețele media potrivite scope-ului lor (/v1/realtime, /v1/audio/*, /v1/embeddings).

Parametri de cale

id*string

Id-ul sandbox-ului (uuid).

Formatuuid

Parametri header

x-request-id?string

Id de corelare ales de client; e returnat ca x-codai-trace-id și persistat pe rândul de usage.

Lungimelength <= 128

Corpul răspunsului

Kernelul a fost repornit.

application/json
  1. response
ok*true
Valoare dintrue
Exemplu de cerere
curl -X POST 'https://ai.codai.ro/v1/sandboxes/497f6eca-6276-4993-bfeb-53cbbbba6f08/kernel/reset'
Exemplu de răspuns
{  "ok": true}
POST
/v1/sandboxes/{id}/pause

Autorizare

bearerAuth
headerAutorizareBearer <codai_…>

O cheie API codai (prefix codai_). Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de suprafețele media potrivite scope-ului lor (/v1/realtime, /v1/audio/*, /v1/embeddings).

Parametri de cale

id*string

Id-ul sandbox-ului (uuid).

Formatuuid

Parametri header

x-request-id?string

Id de corelare ales de client; e returnat ca x-codai-trace-id și persistat pe rândul de usage.

Lungimelength <= 128

Corpul răspunsului

Sandbox-ul pus pe pauză.

application/json
  1. response
id*string
Formatuuid
object*"sandbox"
Valoare din"sandbox"
status*string
Valoare din"running""paused""stopped""expired""destroyed"
backend*string

Backend-ul ales la creare.

Valoare din"v1""v2"
restored?boolean

Doar la crearea unui sandbox v2: adevărat când a pornit dintr-un snapshot de șablon încălzit.

template*string
egress*||

Rețeaua spre exterior, pe ambele backend-uri. none (implicit) nu are deloc rețea; allowlist permite HTTPS către cel mult 20 de domenii prin proxy-ul de egress codai (fără adrese IP, fără gazde interne); preset deschide o listă predefinită (pypi, npm). Proxy-ul deschide tuneluri simple și nu injectează niciodată credențiale; fork-urile v2 moștenesc politica părintelui.

created_at*string
Formatdate-time
expires_at*string
Formatdate-time
last_exec_at*|
Formatdate-time
metadata*
usage*
Exemplu de cerere
curl -X POST 'https://ai.codai.ro/v1/sandboxes/497f6eca-6276-4993-bfeb-53cbbbba6f08/pause'
Exemplu de răspuns
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "object": "sandbox",  "status": "running",  "backend": "v1",  "restored": true,  "template": "string",  "egress": {    "mode": "none"  },  "created_at": "2019-08-24T14:15:22Z",  "expires_at": "2019-08-24T14:15:22Z",  "last_exec_at": "2019-08-24T14:15:22Z",  "metadata": {    "property1": "string",    "property2": "string"  },  "usage": {    "exec_count": 0,    "exec_seconds": 0  }}
POST
/v1/sandboxes/{id}/resume

Autorizare

bearerAuth
headerAutorizareBearer <codai_…>

O cheie API codai (prefix codai_). Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de suprafețele media potrivite scope-ului lor (/v1/realtime, /v1/audio/*, /v1/embeddings).

Parametri de cale

id*string

Id-ul sandbox-ului (uuid).

Formatuuid

Parametri header

x-request-id?string

Id de corelare ales de client; e returnat ca x-codai-trace-id și persistat pe rândul de usage.

Lungimelength <= 128

Corpul răspunsului

Sandbox-ul reluat.

application/json
  1. response
id*string
Formatuuid
object*"sandbox"
Valoare din"sandbox"
status*string
Valoare din"running""paused""stopped""expired""destroyed"
backend*string

Backend-ul ales la creare.

Valoare din"v1""v2"
restored*boolean

Adevărat când starea din memorie a fost restaurată, fals la o pornire la rece.

template*string
egress*||

Rețeaua spre exterior, pe ambele backend-uri. none (implicit) nu are deloc rețea; allowlist permite HTTPS către cel mult 20 de domenii prin proxy-ul de egress codai (fără adrese IP, fără gazde interne); preset deschide o listă predefinită (pypi, npm). Proxy-ul deschide tuneluri simple și nu injectează niciodată credențiale; fork-urile v2 moștenesc politica părintelui.

created_at*string
Formatdate-time
expires_at*string
Formatdate-time
last_exec_at*|
Formatdate-time
metadata*
usage*
ready_ms*integer

Milisecunde până când sandbox-ul a răspuns.

Exemplu de cerere
curl -X POST 'https://ai.codai.ro/v1/sandboxes/497f6eca-6276-4993-bfeb-53cbbbba6f08/resume'
Exemplu de răspuns
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "object": "sandbox",  "status": "running",  "backend": "v1",  "template": "string",  "egress": {    "mode": "none"  },  "created_at": "2019-08-24T14:15:22Z",  "expires_at": "2019-08-24T14:15:22Z",  "last_exec_at": "2019-08-24T14:15:22Z",  "metadata": {    "property1": "string",    "property2": "string"  },  "usage": {    "exec_count": 0,    "exec_seconds": 0  },  "restored": true,  "ready_ms": 0}
POST
/v1/sandboxes/{id}/fork

Autorizare

bearerAuth
headerAutorizareBearer <codai_…>

O cheie API codai (prefix codai_). Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de suprafețele media potrivite scope-ului lor (/v1/realtime, /v1/audio/*, /v1/embeddings).

Parametri de cale

id*string

Id-ul sandbox-ului (uuid).

Formatuuid

Parametri header

x-request-id?string

Id de corelare ales de client; e returnat ca x-codai-trace-id și persistat pe rândul de usage.

Lungimelength <= 128

Corpul cererii

application/json
  1. body
count*integer

Câți copii să pornească (1–5).

Interval1 <= value <= 5
ttl_seconds?integer

Durata de viață a fiecărui copil în secunde (implicit: cât a rămas din părinte).

Interval60 <= value <= 604800

Corpul răspunsului

Copiii.

application/json
  1. response
object*"list"
Valoare din"list"
parent_id*string
Formatuuid
data*array<>
Exemplu de cerere
curl -X POST 'https://ai.codai.ro/v1/sandboxes/497f6eca-6276-4993-bfeb-53cbbbba6f08/fork' \  -H 'Content-Type: application/json' \  -d '{  "count": 1}'
Exemplu de răspuns
{  "object": "list",  "parent_id": "1c6ca187-e61f-4301-8dcb-0e9749e89eef",  "data": [    {      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",      "restored": true,      "ready_ms": 0,      "error": {        "code": "string",        "message": "string"      }    }  ]}
POST
/v1/sandboxes/{id}/preview

Autorizare

bearerAuth
headerAutorizareBearer <codai_…>

O cheie API codai (prefix codai_). Tokenurile efemere de la POST /v1/tokens sunt acceptate doar de suprafețele media potrivite scope-ului lor (/v1/realtime, /v1/audio/*, /v1/embeddings).

Parametri de cale

id*string

Id-ul sandbox-ului (uuid).

Formatuuid

Parametri header

x-request-id?string

Id de corelare ales de client; e returnat ca x-codai-trace-id și persistat pe rândul de usage.

Lungimelength <= 128

Corpul cererii

application/json
  1. body
port*integer

Portul din sandbox (1024–65535, nu 8080).

Interval1024 <= value <= 65535
ttl_seconds?integer

Valabilitatea în secunde (60–3600, implicit 900).

Interval60 <= value <= 3600
Implicit900

Corpul răspunsului

URL-ul de previzualizare semnat.

application/json
  1. response
port*integer
url*string

URL HTTPS semnat; oricine îl are ajunge la port până la expirare.

Formaturi
expires_at*string
Formatdate-time
Exemplu de cerere
curl -X POST 'https://ai.codai.ro/v1/sandboxes/497f6eca-6276-4993-bfeb-53cbbbba6f08/preview' \  -H 'Content-Type: application/json' \  -d '{  "port": 1024}'
Exemplu de răspuns
{  "port": 0,  "url": "http://example.com",  "expires_at": "2019-08-24T14:15:22Z"}

Pe această pagină