Skip to content
Studio turns
  1. Docs
  2. API
  3. Studio turns

Studio turns

The Studio API doesn't take a template and fill it in. You send a Studio's director a message, the way you would in the app, and it answers — with the finished thing, or with a question first.

#A turn is a message

Each Studio has one endpoint: POST /v1/studio/{studio}/turns. Without artifact_id a turn starts something new; with one — or with the conversation_id a previous turn returned — it keeps shaping the same thing.

StudioDirectorWhat a turn does
websiteWebsite Directorbuild or change a website
documentDocuments directorwrite or change a deck, proposal or document
appApp Builderbuild or change a workspace app
imageImages directormake images on a board
videoVideo directoredit a video project

Documents covers decks, proposals, résumés, invoices, one-pagers and reports.

Request bodyapplication/json

  • messagestringrequired

    What you would type to this Studio's director, in plain words. Answers to its questions go here too.

    max length 3800
  • artifact_idstring · uuidoptional

    Work on an existing artifact of this Studio (from a previous answer's artifact.id or a list endpoint). Omit to start a new one.

  • conversation_idstring · uuidoptional

    Continue a conversation: the conversation_id of a previous answer. Needed to answer a website director's questions before the site exists; otherwise artifact_id already implies it.

  • autobooleanoptional

    "Decide for me": the director settles anything unclear itself and makes the artifact now instead of asking. Default false — the director may answer needs_input with questions or an outline, exactly as in the app.

    Default false
  • streambooleanoptional

    Answer as server-sent events: turn, plan, status, then result (the same body a waited-for call returns).

    Default false
  • backgroundbooleanoptional

    Answer 202 as soon as the turn is claimed and keep working; poll GET /v1/turns/{id}.

    Default false

#What comes back

A turn always resolves to one of four statuses. Handle all four and you've handled everything a Studio can do.

Your codePOST /v1/studio/{studio}/turnsmessage · artifact_id · auto · stream · background
Studio directorThe same director as the app — it plans, asks or builds.
  • completedThe artifact and its urlDone. Keep shaping it with another turn on artifact_id.
  • needs_inputQuestions, or an outline to approveReply on the same artifact_id or conversation_id — or send auto: true. loops back as a new turn
  • buildingThe turn id (and a job, for websites)Still working. Poll GET /v1/turns/{id} every 5–10 s.
  • failederror — what went wrongThe turn started, then failed. Refusals before it starts are HTTP errors.
Waitdefault

One request, one response with the finished turn. Simplest; the server holds it open for up to 800 s.

Streamstream: true

Server-sent turn, plan and status events as the director works, then one result.

Backgroundbackground: true

202 as soon as the turn is claimed. Poll GET /v1/turns/{id} every 5–10 s.

The same four statuses for every Studio: websites, documents, apps, images and video.

Every answer carries the artifact (id, type, name, url, public_url), the conversation_id, and the director's own words in message.

#Questions and outlines

Like in the app, a director sometimes checks before it builds — who a deck is for, what a site sells — or proposes an outline to approve. The turn comes back needs_input:

Response200
{
  "id": "1e0f…",
  "object": "studio.turn",
  "status": "needs_input",
  "studio": "document",
  "artifact": {
    "id": "a3c2…",
    "type": "document",
    "name": "Untitled",
    "url": "https://app.attria.io/studio/documents/a3c2…",
    "public_url": null
  },
  "conversation_id": "c81b…",
  "message": "One quick question before I write this.",
  "questions": [
    {
      "text": "Who is this deck for?",
      "options": [
        "Investors",
        "Customers",
        "My team",
        "Custom"
      ]
    }
  ],
  "created_at": "2026-09-27T18:02:11Z",
  "completed_at": "2026-09-27T18:02:19Z"
}

Reply in plain words with another turn on the same artifact_id (or conversation_id, for a website that doesn't exist yet). The options are suggestions, not a menu. To approve an outline, say so — “Build it” works.

curl -X POST "https://app.attria.io/api/v1/studio/document/turns" \
  -H "Authorization: Bearer $ATTRIA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "artifact_id": "a3c2d1e0-5b4a-4c3d-8e2f-1a0b9c8d7e6f",
    "message": "Investors. Build it."
  }'

#Decide for me

Send auto: true and the director settles anything unclear itself and makes the artifact now — no questions, no outline to confirm. Use it for scripts, batch jobs and agents with no person to answer.

curl -X POST "https://app.attria.io/api/v1/studio/website/turns" \
  -H "Authorization: Bearer $ATTRIA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "message": "Build a landing page for Harbor Dental, a family dentist in Portland. Goal: book a first cleaning.",
    "auto": true
  }'

Directors use only what you tell them and your workspace's brand. Put every fact, figure, name and date in message — auto fills gaps in judgement, not in facts.

#How long turns take

StudioTypical turn
document20–60 s; longer for long decks.
image20–60 s, with the finished images in the answer.
app45–120 s.
video10–40 s for edits. Filming a shot or a motion graphic is a content app.
websiteA few seconds to answer building; the site then builds in 2–5 minutes.

A new website answers quickly with status: "building" and keeps building after the call returns. Poll GET /v1/turns/{id} — or GET /v1/websites/{id}, whose build.stage says which step it's on — every 5–10 seconds. For everything else, choose how to wait in Jobs & streaming.

#Endpoints

Reading what you made