AI template builds
Give this prompt to your AI agent. The agent does the task for you.
Read https://thirds.ai/docs/api-reference/template-builds and help me choose the right thirds.ai endpoint and write a request. Check the fields and credentials in this reference.
Create an editable template with AI, send changes, read draft results, and publish the version you choose.
See all API resources or read API keys and requests.
Endpoints
createTemplateBuild
POST /v1/template-builds
Start a template build
Start one durable Build a template conversation from words, supported HTML, one source image, or your own working template source. The fixed successful price is 50 credits. A build from source makes no model call and costs 0 credits. A failed build releases the full reservation. Free monthly credits cannot pay for AI work: an account whose trial, pack, and subscription credits cannot cover the price answers 402 ai_needs_paid_credits and holds nothing. An AI message often takes a minute or two.
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
Idempotency-Key | header | Yes | {"type":"string","minLength":1,"maxLength":255,"pattern":"^[ -~]+$"} |
Request body: application/json, TemplateBuildCreate.
| Status | Meaning | Body |
|---|---|---|
| 200 | An earlier matching request was replayed. | application/json: TemplateBuild |
| 202 | The durable build was accepted. | application/json: TemplateBuild |
| 400 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 401 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 402 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 403 | The authenticated account is suspended. The code is account_suspended. | application/json: ErrorEnvelope |
| 404 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 405 | The method is not allowed on this route. | application/json: ErrorEnvelope |
| 409 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 413 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 431 | The request has more than 64 headers or more than 32 KiB of header names and values. | application/json: ErrorEnvelope |
| 503 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
getTemplateBuild
GET /v1/template-builds/{build_id}
Get a template build
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
build_id | path | Yes | TemplateBuildId |
| Status | Meaning | Body |
|---|---|---|
| 200 | The current draft and latest message facts. | application/json: TemplateBuild |
| 401 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 403 | The authenticated account is suspended. The code is account_suspended. | application/json: ErrorEnvelope |
| 404 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 405 | The method is not allowed on this route. | application/json: ErrorEnvelope |
| 431 | The request has more than 64 headers or more than 32 KiB of header names and values. | application/json: ErrorEnvelope |
| 500 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
listTemplateMessages
GET /v1/template-builds/{build_id}/messages
List template chat messages
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
build_id | path | Yes | TemplateBuildId |
| Status | Meaning | Body |
|---|---|---|
| 200 | The user-visible messages in chat order. One chat holds at most 100 messages. | application/json: {"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/TemplateMessage"}} — TemplateMessage |
| 401 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 403 | The authenticated account is suspended. The code is account_suspended. | application/json: ErrorEnvelope |
| 404 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 405 | The method is not allowed on this route. | application/json: ErrorEnvelope |
| 431 | The request has more than 64 headers or more than 32 KiB of header names and values. | application/json: ErrorEnvelope |
| 500 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
editTemplateBuild
POST /v1/template-builds/{build_id}/messages
Edit the working template
Run one later AI edit. A text or HTML edit costs 25 credits. A new source image costs 50 credits. A source message replaces the draft with your own working template, makes no model call, and costs 0 credits. A failed edit keeps the previous valid draft and releases the reservation. Free monthly credits cannot pay for AI work: an account whose trial, pack, and subscription credits cannot cover the price answers 402 ai_needs_paid_credits and holds nothing. An AI message often takes a minute or two.
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
build_id | path | Yes | TemplateBuildId |
Idempotency-Key | header | Yes | {"type":"string","minLength":1,"maxLength":255,"pattern":"^[ -~]+$"} |
Request body: application/json, TemplateMessageCreate.
| Status | Meaning | Body |
|---|---|---|
| 200 | An earlier matching edit was replayed. | application/json: TemplateBuild |
| 202 | The durable edit was accepted. | application/json: TemplateBuild |
| 400 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 401 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 402 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 403 | The authenticated account is suspended. The code is account_suspended. | application/json: ErrorEnvelope |
| 404 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 405 | The method is not allowed on this route. | application/json: ErrorEnvelope |
| 409 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 413 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 431 | The request has more than 64 headers or more than 32 KiB of header names and values. | application/json: ErrorEnvelope |
| 503 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
getTemplateBuildDraft
GET /v1/template-builds/{build_id}/draft
Get the working template
Read the current draft as editable source, sample data, schema, and output. The build has no draft until its first message succeeds.
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
build_id | path | Yes | TemplateBuildId |
| Status | Meaning | Body |
|---|---|---|
| 200 | The current working template. | application/json: TemplateBuildDraft |
| 401 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 403 | The authenticated account is suspended. The code is account_suspended. | application/json: ErrorEnvelope |
| 404 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 405 | The method is not allowed on this route. | application/json: ErrorEnvelope |
| 431 | The request has more than 64 headers or more than 32 KiB of header names and values. | application/json: ErrorEnvelope |
| 500 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
getTemplateMessageDraft
GET /v1/template-builds/{build_id}/messages/{message_id}/draft
Get a completed message draft
Read the retained final source, sample data, schema, and output from a succeeded message in an owned build. The response excludes the brand snapshot. Reading it changes no state and costs no credits. Pending, failed, and cancelled messages have no final draft.
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
build_id | path | Yes | TemplateBuildId |
message_id | path | Yes | TemplateMessageId |
| Status | Meaning | Body |
|---|---|---|
| 200 | The final draft. Cache-Control is private, no-store. | application/json: TemplateBuildDraft |
| 401 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 403 | The authenticated account is suspended. The code is account_suspended. | application/json: ErrorEnvelope |
| 404 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 405 | The method is not allowed on this route. | application/json: ErrorEnvelope |
| 431 | The request has more than 64 headers or more than 32 KiB of header names and values. | application/json: ErrorEnvelope |
| 500 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
cancelTemplateMessage
DELETE /v1/template-builds/{build_id}/messages/{message_id}
Cancel a pending template message
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
build_id | path | Yes | TemplateBuildId |
message_id | path | Yes | TemplateMessageId |
| Status | Meaning | Body |
|---|---|---|
| 200 | The message was cancelled and its reservation was released. | application/json: TemplateMessage |
| 401 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 403 | The authenticated account is suspended. The code is account_suspended. | application/json: ErrorEnvelope |
| 404 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 405 | The method is not allowed on this route. | application/json: ErrorEnvelope |
| 409 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 431 | The request has more than 64 headers or more than 32 KiB of header names and values. | application/json: ErrorEnvelope |
| 500 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
publishTemplateBuild
POST /v1/template-builds/{build_id}/publish
Publish the current working template
Explicitly publish the current valid draft as one normal immutable saved-template version. Repeating publication of the same draft returns the same version.
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
build_id | path | Yes | TemplateBuildId |
| Status | Meaning | Body |
|---|---|---|
| 200 | This draft was already published. | application/json: TemplatePublication |
| 201 | The immutable template version was published. | application/json: TemplatePublication |
| 400 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 401 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 403 | The authenticated account is suspended. The code is account_suspended. | application/json: ErrorEnvelope |
| 404 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 405 | The method is not allowed on this route. | application/json: ErrorEnvelope |
| 409 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
| 431 | The request has more than 64 headers or more than 32 KiB of header names and values. | application/json: ErrorEnvelope |
| 500 | The one error envelope every backend response uses. | application/json: ErrorEnvelope |
Schemas
TemplateBuildId
Schema rules: {"type":"string","pattern":"^build_[0-9a-f]{32}$"}.
TemplateMessageId
Schema rules: {"type":"string","pattern":"^msg_[0-9a-f]{32}$"}.
TemplateBuildInput
Schema rules: {"oneOf":[{"type":"object","properties":{"type":{"const":"prompt"},"prompt":{"type":"string","minLength":1,"maxLength":65536}},"required":["type","prompt"],"additionalProperties":false},{"type":"object","properties":{"type":{"const":"html"},"html":{"type":"string","minLength":1,"maxLength":65536}},"required":["type","html"],"additionalProperties":false},{"type":"object","description":"Rebuild a still PNG, JPEG, or WebP as an editable branded template. Inspired by the source, not a pixel copy. At most 10 MiB, 7680 by 4320, and 32 million pixels. An invalid file fails before the model.","properties":{"type":{"const":"image"},"base64":{"type":"string","minLength":1,"maxLength":13981016,"contentEncoding":"base64"}},"required":["type","base64"],"additionalProperties":false},{"type":"object","description":"Your own working template, sent as data. It must pass the saved-template checks and evaluate with sample_data. It becomes the draft without a model call and costs 0 credits.","properties":{"type":{"const":"source"},"source":{"type":"string","minLength":1,"maxLength":1048576},"sample_data":{"type":"object"},"schema":{"oneOf":[{"type":"object"},{"type":"boolean"}]}},"required":["type","source"],"additionalProperties":false}]}.
TemplateOutputIntent
Schema rules: {"oneOf":[{"type":"object","description":"Let the model choose PDF or image from the message. An image result from a source image uses the source dimensions.","properties":{"type":{"const":"auto"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"const":"pdf"}},"required":["type"],"additionalProperties":false},{"type":"object","description":"Request an image. Set both width and height to override the source dimensions. Without a source image, omitted dimensions use 1200 by 628.","properties":{"type":{"const":"image"},"format":{"type":"string","enum":["png","jpeg","webp"],"default":"png"},"width":{"type":"integer","minimum":320,"maximum":7680},"height":{"type":"integer","minimum":200,"maximum":4320}},"required":["type"],"additionalProperties":false}]}.
TemplateOutput
Schema rules: {"oneOf":[{"type":"object","properties":{"type":{"const":"pdf"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"const":"image"},"format":{"type":"string","enum":["png","jpeg","webp"]},"width":{"type":"integer","minimum":320,"maximum":7680},"height":{"type":"integer","minimum":200,"maximum":4320}},"required":["type","format","width","height"],"additionalProperties":false}]}.
TemplateBuildCreate
| Field | Required | Description and type |
|---|---|---|
brand_kit_id | Yes | BrandKitId |
input | Yes | TemplateBuildInput |
input_mode | No | How new manual work starts. Only source input accepts this field. Omit it when the source comes from a saved template or an existing chat. {"type":"string","enum":["blank","html"]} |
output | No | TemplateOutputIntent |
Schema rules: {"type":"object","if":{"required":["input_mode"]},"then":{"properties":{"input":{"properties":{"type":{"const":"source"}}}}},"additionalProperties":false}.
TemplateMessageCreate
| Field | Required | Description and type |
|---|---|---|
input | Yes | TemplateBuildInput |
output | No | TemplateOutputIntent |
Schema rules: {"type":"object","additionalProperties":false}.
TemplateMessage
| Field | Required | Description and type |
|---|---|---|
id | Yes | TemplateMessageId |
state | Yes | {"type":"string","enum":["queued","running","previewing","succeeded","failed","cancelled"]} |
phase | Yes | {"type":"string","enum":["generate","candidate","review","final"]} |
input_type | Yes | {"type":"string","enum":["prompt","html","image","source"]} |
credits | Yes | {"type":"integer","enum":[0,25,50]} |
preview_id | Yes | {"type":["string","null"],"pattern":"^(pdf|image)_[0-9a-f]{32}$"} |
output | Yes | {"oneOf":[{"$ref":"#/components/schemas/TemplateOutput"},{"type":"null"}]} — TemplateOutput |
review_count | Yes | {"type":"integer","minimum":0,"maximum":5} |
max_reviews | Yes | {"type":"integer","minimum":0,"maximum":5} |
input_text | No | {"type":"string","maxLength":65536} |
repair_code | No | The last safe generation or render code that blocked this message. Present while a repair is in progress and after a failed message. It never holds customer content. {"type":"string","pattern":"^[a-z][a-z0-9_]{0,63}$"} |
failure_category | Yes | {"type":["string","null"],"enum":["provider","validation","renderer","unsupported_input","internal",null]} |
failure_code | Yes | {"type":["string","null"],"pattern":"^[a-z][a-z0-9_]{0,63}$"} |
Schema rules: {"type":"object","additionalProperties":false}.
TemplateBuild
| Field | Required | Description and type |
|---|---|---|
id | Yes | TemplateBuildId |
brand_kit_id | Yes | BrandKitId |
current_draft | Yes | {"type":"boolean"} |
current_message_id | Yes | {"oneOf":[{"$ref":"#/components/schemas/TemplateMessageId"},{"type":"null"}]} — TemplateMessageId |
published_template_id | Yes | {"oneOf":[{"$ref":"#/components/schemas/TemplateId"},{"type":"null"}]} — TemplateId |
message | Yes | TemplateMessage |
Schema rules: {"type":"object","additionalProperties":false}.
TemplateBuildDraft
| Field | Required | Description and type |
|---|---|---|
source | Yes | {"type":"string","maxLength":1048576} |
sample_data | Yes | {"type":"object"} |
schema | Yes | {} |
output | Yes | TemplateOutput |
Schema rules: {"type":"object","additionalProperties":false}.
TemplatePublication
| Field | Required | Description and type |
|---|---|---|
template_id | Yes | TemplateId |
version | Yes | {"type":"integer","minimum":1} |
Schema rules: {"type":"object","additionalProperties":false}.
Shared errors, headers, and authentication schemes are in shared types and security.