Append Message To Task
Append the next user message to an existing task and kick off its next turn.
Phase 1 multi-turn model is task-centric: subsequent user inputs
extend the same task_id rather than creating a new task or a
new conversation_id. This endpoint:
- Validates the path
task_idexists and belongs to the key-bound agent (404task_not_foundotherwise). - Validates
body.agent_idmatches the key-bound agent (404agent_not_foundotherwise). - Rejects the call with 409
task_busyif the task is currentlyRUNNING— the SDK client should pollGET /v1/chat/tasks/{id}until status leaves RUNNING and retry. - Otherwise persists the new user message to
task_chat_messages, updatestask.inputto record this turn’s input, and kicks off the next background turn via the same helper POST uses.
Args:
task_id: Path parameter; the target task’s primary key.
request: Validated :class:AppendMessageRequest. message.content
is guaranteed non-empty by Pydantic.
authed: (Agent, AgentApiKey) from the auth dependency.
db: SQLAlchemy session.
Returns:
:class:AppendMessageResponse with the task identity and an
accepted_at timestamp.
Raises:
V1ApiError 401: missing / invalid / revoked key.
V1ApiError 404: task not found OR not owned by the agent OR
body.agent_id doesn’t match the bound agent.
V1ApiError 409: task_busy — task currently RUNNING.
500: any other unexpected error (V1 envelope via global handler).
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Body
Body for POST /v1/chat/tasks/{task_id}/messages.
Same shape as :class:CreateTaskRequest minus the lack of a
metadata field by default -- callers append a new user
message to an existing task. agent_id is required again
(consistent with the SDK contract: every write carries the
agent_id explicitly for forward-compat with multi-agent keys).
Response
Successful Response
POST /v1/chat/tasks/{task_id}/messages -> 202 Accepted response.
The new user message has been persisted and the next turn queued for background execution; callers poll the same way they would after the initial POST /v1/chat/tasks.
Existing task primary key.
Agent the task is bound to.
Initial status of the new turn, 'running' in the 202 response (the atomic claim inside POST commits the status flip before the response is sent).
UTC timestamp when the server accepted the message and scheduled background execution. Not the message's stored created_at (which may differ slightly due to DB clock).

