Appearance
The assistant
The designer's assistant: requests, conversations and proposals.
GET /v1/templates/{id}/assistant
Whether the designer's assistant is on, and whether the caller may ask it.
Needs template.read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | |
environment | query | string |
Responses
| Status | Description | Body |
|---|---|---|
200 | {enabled, agent, allowed, reason?}: agent is the name accepted proposals are attributed to; allowed says whether the caller may ask (a person with template.write); reason says why the assistant is off (agents.assistant). | |
404 | The template is in the trash: {error: "in-trash", message, item}. item, the trash item's id, is there only for callers with template.read. | object |
429 | The request's class is over its rate limit (limits.rate, or the API key's own rateLimits): {error: "rate-limited", class, message, retryAfter}. The MCP tool-call and agent edit limits answer the same body without class. | object |
POST /v1/templates/{id}/assistant
Ask the assistant for proposals for the draft (server-sent events).
Relays the author's prompt to the configured agent provider (agents.assistant: anthropic, http or file) with the draft as context: the document, the selected nodes, its diagnostics and its sample data, each in an <untrusted kind source> envelope, as MCP tool results wrap them, and the recent exchanges of the conversation it continues (at most 10, within a character budget) as history. The answer streams as text/event-stream: ready {agent, conversationId, exchangeId}; message {text}; proposal {id, agent, label, rationale, batch} for each proposal whose batch reads as RFML edit operations, or proposal {agent, label, rationale, invalid} (no id, no batch) for one that doesn't (with the anthropic provider, a batch that doesn't match the ops schema); error {error, message} (provider, rate-limited, overloaded, refused, timeout, too-many-proposals, invalid-event); done {proposals}. Nothing is applied: the designer dry-runs each proposal and the author accepts it with POST …/draft/ops and its id. Needs template.write; agent keys are refused.
The exchange is recorded in the caller's conversation as it streams: conversationId names it, or else the caller's newest conversation of the template in the environment continues, or a first one starts. ready names both (without them when the template store keeps no conversations).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes |
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
environment | string | ||
prompt | string | yes | The author's request. |
selection | array of string | Ids of the selected nodes. | |
conversationId | string | The caller's conversation to continue; by default the newest. |
Responses
| Status | Description | Body |
|---|---|---|
200 | The event stream | string |
400 | No prompt, or one that is too long | |
403 | The caller lacks template.write, or is an agent | |
404 | No such template, or no such conversation of the caller's in the environment, or the template is in the trash (in-trash, see InTrash) | |
429 | The request's class is over its rate limit (limits.rate, or the API key's own rateLimits): {error: "rate-limited", class, message, retryAfter}. The MCP tool-call and agent edit limits answer the same body without class. | object |
503 | The assistant is off: |
GET /v1/templates/{id}/assistant/conversations
The caller's assistant conversations about the template in an environment.
Each person's conversations are their own: nobody else lists, reads, continues or deletes them, administrators included. Agents have none (403). Needs template.read. The newest 200 exchanges per person and template are kept, across its conversations; a conversation that loses its last one goes. Deleting the template deletes them. 503 assistant-history-off when the template store keeps no conversations.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | |
environment | query | string |
Responses
| Status | Description | Body |
|---|---|---|
200 | {environment, conversations: [{id, environment, title, createdAt, updatedAt, exchangeCount}]}, the most recently updated first; title is the first prompt's first line, shortened ("" until there is one). | |
403 | The caller lacks template.read, or is an agent | |
404 | The template is in the trash: {error: "in-trash", message, item}. item, the trash item's id, is there only for callers with template.read. | object |
429 | The request's class is over its rate limit (limits.rate, or the API key's own rateLimits): {error: "rate-limited", class, message, retryAfter}. The MCP tool-call and agent edit limits answer the same body without class. | object |
POST /v1/templates/{id}/assistant/conversations
Start a new conversation.
The new conversation is the caller's newest, so POST …/assistant continues it by default. When the newest has no exchanges yet, it is returned instead of starting another. Needs template.read and a draft.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes |
Request body, optional (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
environment | string |
Responses
| Status | Description | Body |
|---|---|---|
200 | The newest conversation, which is still empty | |
201 | ||
404 | No draft of the template in the environment, or the template is in the trash (in-trash, see InTrash) | |
429 | The request's class is over its rate limit (limits.rate, or the API key's own rateLimits): {error: "rate-limited", class, message, retryAfter}. The MCP tool-call and agent edit limits answer the same body without class. | object |
DELETE /v1/templates/{id}/assistant/conversations
Delete all of the caller's conversations about the template in an environment.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | |
environment | query | string |
Responses
| Status | Description | Body |
|---|---|---|
204 | Deleted (or there were none) | |
404 | The template is in the trash: {error: "in-trash", message, item}. item, the trash item's id, is there only for callers with template.read. | object |
429 | The request's class is over its rate limit (limits.rate, or the API key's own rateLimits): {error: "rate-limited", class, message, retryAfter}. The MCP tool-call and agent edit limits answer the same body without class. | object |
GET /v1/templates/{id}/assistant/conversations/{conversationId}
One of the caller's conversations, with its exchanges.
{id, environment, title, createdAt, updatedAt, exchangeCount, exchanges: [{id, prompt, selection, startedAt, finishedAt?, items}]}, oldest first. items are the answer as the author saw it, with the stream's event shapes: {type: message, text}, {type: error, error, message} (error stopped when the author stopped the answer), and {type: proposal, id?, agent, label, rationale, batch?, invalid?, outcome, expiresAt?, decidedAt?}. outcome is pending, accepted (POST …/draft/ops named it), rejected (POST …/reject), expired (its registry entry expired, after 24 h, undecided) or invalid.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | |
conversationId | path | string | yes | |
environment | query | string |
Responses
| Status | Description | Body |
|---|---|---|
200 | The conversation | |
404 | No such conversation of the caller's in the environment, or the template is in the trash (in-trash, see InTrash) | |
429 | The request's class is over its rate limit (limits.rate, or the API key's own rateLimits): {error: "rate-limited", class, message, retryAfter}. The MCP tool-call and agent edit limits answer the same body without class. | object |
DELETE /v1/templates/{id}/assistant/conversations/{conversationId}
Delete one of the caller's conversations.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | |
conversationId | path | string | yes | |
environment | query | string |
Responses
| Status | Description | Body |
|---|---|---|
204 | Deleted | |
404 | No such conversation of the caller's in the environment, or the template is in the trash (in-trash, see InTrash) | |
429 | The request's class is over its rate limit (limits.rate, or the API key's own rateLimits): {error: "rate-limited", class, message, retryAfter}. The MCP tool-call and agent edit limits answer the same body without class. | object |
POST /v1/templates/{id}/assistant/proposals/{proposalId}/reject
Record that the caller rejected a proposal they were sent.
Marks the proposal rejected in the caller's conversation. It records the author's decision; it changes nothing in the draft. Accepting it later through POST …/draft/ops still marks it accepted.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | |
proposalId | path | string | yes | |
environment | query | string |
Responses
| Status | Description | Body |
|---|---|---|
200 | ||
404 | No such proposal in the caller's conversations, or the template is in the trash (in-trash, see InTrash) | |
409 | The proposal is already decided | |
429 | The request's class is over its rate limit (limits.rate, or the API key's own rateLimits): {error: "rate-limited", class, message, retryAfter}. The MCP tool-call and agent edit limits answer the same body without class. | object |