AI template chat
Send changes to a template's AI chat, check each draft, and save the draft you choose as the next version.
Give this prompt to your AI agent. The agent does the task for you.
Read https://thirds.ai/docs/api-reference/template-chat and help me choose the right thirds.ai endpoint and write a request. Check the fields and credentials in this reference.
See all API resources or read the PDF generation API guide.
Endpoints
getSavedImageProposal
GET /v1/ai-image-proposals/{message_id}
Read a saved image suggestion
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
message_id | path | Yes | TemplateMessageId |
| Status | Meaning | Body |
|---|---|---|
| 200 | Read a saved image suggestion. | application/json: ChatImageProposal |
| 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 |
applyImageProposal
POST /v1/ai-image-proposals/{message_id}/apply
Keep an image suggestion with an applied layout
Keep this owned successful message’s image suggestion after applying its layout. This call does not generate an image or spend credits. A rejected suggestion can be restored by this explicit action.
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
message_id | path | Yes | TemplateMessageId |
| Status | Meaning | Body |
|---|---|---|
| 200 | Keep an image suggestion with an applied layout. | application/json: ChatImageProposal |
| 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 |
getChatImageProposal
GET /v1/templates/{template_id}/messages/{message_id}/image-proposal
Read a chat image proposal
Read the private prompt and aspect ratio without spending credits. A new chat message rejects an unapplied suggestion. Applied frames stay available to fill later.
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
template_id | path | Yes | TemplateId |
message_id | path | Yes | TemplateMessageId |
| Status | Meaning | Body |
|---|---|---|
| 200 | The current proposal and approval state. | application/json: ChatImageProposal |
| 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 |
rejectChatImageProposal
DELETE /v1/templates/{template_id}/messages/{message_id}/image-proposal
Reject a chat image proposal
Reject a pending image proposal. Rejection makes no image call and spends no image credits. An approved proposal keeps its state.
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
template_id | path | Yes | TemplateId |
message_id | path | Yes | TemplateMessageId |
| Status | Meaning | Body |
|---|---|---|
| 200 | The current proposal and approval state. | application/json: ChatImageProposal |
| 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 |
sendTemplateMessage
POST /v1/templates/{template_id}/messages
Send a template chat message
Send one message to the chat of a saved template. The first message of a template without a chat starts its chat, and then brand_kit_id is required. A later message can name a new brand_kit_id, which becomes the chat kit. A chat has one pending message at a time. It keeps its newest 100 messages; older settled messages drop off. A words or HTML message costs 25 credits. A source image costs 50 credits. The first message of a new blank template costs 50 credits. A source message makes no model call and costs 0 credits. A failed message keeps the previous draft and releases its reservation. All available credits, including free monthly credits, can pay for AI work. An account without enough available credits answers 402 insufficient_credits and holds nothing. Read message.progress for elapsed time, the current stages, and recent successful timing estimates. Estimates use the last 48 hours for the same model route and task when enough samples exist; completion time varies.
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
template_id | path | Yes | TemplateId |
Idempotency-Key | header | Yes | {"type":"string","minLength":1,"maxLength":255,"pattern":"^[ -~]+$"} |
Request body: application/json, TemplateMessageCreate.
| Status | Meaning | Body |
|---|---|---|
| 200 | An earlier matching message was replayed. | application/json: TemplateChatMessage |
| 202 | The message was accepted. | application/json: TemplateChatMessage |
| 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 |
| 429 | 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 |
getTemplateMessage
GET /v1/templates/{template_id}/messages/{message_id}
Get a template chat message
Read one message of the chat with its progress, and the chat state. Poll this until the message is succeeded, failed, or cancelled.
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
template_id | path | Yes | TemplateId |
message_id | path | Yes | TemplateMessageId |
| Status | Meaning | Body |
|---|---|---|
| 200 | The message and the chat state. | application/json: TemplateChatMessage |
| 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/templates/{template_id}/messages/{message_id}
Cancel a pending template message
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
template_id | path | Yes | TemplateId |
message_id | path | Yes | TemplateMessageId |
| Status | Meaning | Body |
|---|---|---|
| 200 | The message was cancelled and its reservation was released. | application/json: TemplateChatMessage |
| 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 |
getTemplateMessageDraft
GET /v1/templates/{template_id}/messages/{message_id}/draft
Get a message draft
Read the final source, sample data, schema, and output of a succeeded message. The response excludes the brand snapshot. Reading it changes no state and costs no credits. Pending, failed, and cancelled messages have no draft.
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
template_id | path | Yes | TemplateId |
message_id | path | Yes | TemplateMessageId |
| Status | Meaning | Body |
|---|---|---|
| 200 | The final draft. Cache-Control is private, no-store. | application/json: TemplateDraft |
| 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 |
applyTemplateMessage
POST /v1/templates/{template_id}/messages/{message_id}/apply
Apply a message result
Record that the customer applied the draft of the current succeeded message. With save true, the default, the draft becomes the next immutable template version. Repeating it for the same message returns the same version. With save false, the call only records the decision, and the caller saves a version later. After either call, chat.current_message_reviewed is true. An empty body means save true.
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
template_id | path | Yes | TemplateId |
message_id | path | Yes | TemplateMessageId |
Request body: application/json, TemplateApplyRequest.
| Status | Meaning | Body |
|---|---|---|
| 200 | This draft was already saved as this version. | application/json: TemplateVersionDetail |
| 201 | The draft was saved as the next template version. | application/json: TemplateVersionDetail |
| 204 | The decision was recorded. No version was saved. | No body |
| 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 |
discardTemplateMessage
POST /v1/templates/{template_id}/messages/{message_id}/discard
Discard a message result
Record that the customer does not want the result of the current message. The template does not change. After this call, chat.current_message_reviewed is true.
Authentication: bearer API key. See authentication.
| Parameter | Location | Required | Rule |
|---|---|---|---|
template_id | path | Yes | TemplateId |
message_id | path | Yes | TemplateMessageId |
| Status | Meaning | Body |
|---|---|---|
| 204 | The decision was recorded. | No body |
| 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
ChatImageProposal
| Field | Required | Description and type |
|---|---|---|
proposal | Yes | {"anyOf":[{"type":"null"},{"type":"object","additionalProperties":false,"required":["prompt","aspect_ratio","target_layer_id"],"properties":{"prompt":{"type":"string"},"aspect_ratio":{"type":"string","enum":["1:1","1:2","2:1","2:3","3:2","3:4","4:3","4:5","5:4","9:16","16:9","9:19.5","19.5:9","9:20","20:9","9:21","21:9"]},"target_layer_id":{"type":"string","maxLength":64,"pattern":"^[A-Za-z][A-Za-z0-9_-]{0,63}$"}}}]} |
state | Yes | {"type":"string","enum":["pending","rejected","approved"]} |
generation_id | Yes | {"type":["string","null"],"pattern":"^aimg_[0-9a-f]{32}$"} |
applied | Yes | {"type":"boolean"} |
Schema rules: {"type":"object","additionalProperties":false}.
TemplateMessageCreate
| Field | Required | Description and type |
|---|---|---|
input | Yes | TemplateMessageInput |
output | No | TemplateOutputIntent |
brand_kit_id | No | The kit of this message and of the chat from now on. The first message of a chat requires it. Omit it to keep the chat kit. BrandKitId |
Schema rules: {"type":"object","additionalProperties":false}.
TemplateApplyRequest
| Field | Required | Description and type |
|---|---|---|
save | No | Save the draft as the next template version. {"type":"boolean","default":true} |
Schema rules: {"type":"object","additionalProperties":false}.
TemplateChatMessage
| Field | Required | Description and type |
|---|---|---|
chat | Yes | TemplateChat |
message | Yes | TemplateMessage |
Schema rules: {"type":"object","additionalProperties":false}.
TemplateDraft
| 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}.
Shared errors, headers, and authentication schemes are in shared types and security.