Skip to content
Jobs & streaming
  1. Docs
  2. API
  3. Jobs & streaming

Jobs & streaming

A website, an app or a video shot takes real time to make. Every call that builds something lets you choose how to wait — and turns are durable, so a dropped connection never cancels the work.

#Three ways to wait

SendYou getUse it when
nothing (default)The finished result, in one response.Scripts and servers that can hold a request open.
stream: trueServer-sent events as the work happens, then result.You want to show progress to a person.
background: true202 at once, with an id to check on.Agents, batches, queues, serverless functions with short limits.

A waiting call stays open as long as the work does — the server allows up to 800 seconds. Give your HTTP client a timeout of at least 15 minutes, or use stream or background.

#Streaming

With stream: true the response is text/event-stream. Each event is event: <name> and one data: <json> line. A Studio turn sends turn, plan and status as the director works; the last event is always result — the same body a waiting call returns — or error (message and request_id). Then the stream closes.

Event stream
event: turn
data: {"id": "1e0f…", "status": "building", "studio": "image", …}

event: plan
data: {…}

event: status
data: {…}

event: result
data: {"id": "1e0f…", "object": "studio.turn", "status": "completed", …}
curl -N -X POST "https://app.attria.io/api/v1/studio/image/turns" \
  -H "Authorization: Bearer $ATTRIA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"message": "Two scroll-stopping images for a summer iced-latte promo, bright and minimal", "auto": true, "stream": true}'

Show or log the events before result as progress, but don't build logic on their contents — only result and error are the contract.

#Background and polling

With background: true a Studio turn answers 202 Accepted as soon as it's claimed, with its id. Poll GET /v1/turns/{id} every 5–10 seconds until status is no longer building.

curl -X POST "https://app.attria.io/api/v1/studio/image/turns" \
  -H "Authorization: Bearer $ATTRIA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "message": "Two scroll-stopping images for a summer iced-latte promo, bright and minimal",
    "auto": true,
    "background": true
  }'
// Poll a background turn every 5–10 s until it stops building.
async function waitForTurn(id: string) {
  for (let delay = 5000; ; delay = 10000) {
    const res = await fetch(`https://app.attria.io/api/v1/turns/${id}`, {
      headers: { Authorization: `Bearer ${process.env.ATTRIA_API_KEY}` },
    });
    const turn = await res.json();
    if (turn.status !== "building") return turn;
    await new Promise((resolve) => setTimeout(resolve, delay));
  }
}

Never start a second copy of a turn because the first seems slow — poll it. The work continues whether or not you're polling, and it's in the Studio the whole time.

#How each kind of work is checked on

WorkCheck on it with
Studio turnsGET /v1/turns/{id}
A new website's buildGET /v1/websites/{id} — build.status and build.stage
Agent runs (background)The same request again, with the same Idempotency-Key — 202 while it runs. Or GET /v1/runs/{id}.
Video content appsThe same request again, with the same Idempotency-Key — it reads the job and moves it forward.

Repeating a request with its key is safe by design: it replays or reads, never runs twice. See Idempotency.

#Slow endpoints

These can take minutes, and are marked slow in the reference: