Skip to main content
A conversation is scoped to one project at creation and that binding is fixed, exactly as it is in the app. Everything Addison can see comes from that project’s data, files, and knowledge, so attach what you need before you start asking. Responses stream as server-sent events. Send Accept: text/event-stream and set client timeouts to at least 120 seconds. Product-side docs: Addison.

POST /v1/projects/{project_id}/conversations

Start a conversation and stream the response.

POST /v1/projects/{project_id}/conversations/{chat_id}/messages

Send a follow-up and stream the reply.

GET /v1/projects/{project_id}/conversations

List conversations.

GET /v1/projects/{project_id}/conversations/{chat_id}

Fetch a conversation and its messages.

GET /v1/chat-models

List available models and the effort levels each supports.

POST /v1/projects/{project_id}/files/uploads

Upload a file into the project a conversation reads from.
Recovering a dropped stream. If the connection drops mid-response, don’t re-send the message. Re-stream the events you missed instead:

GET /v1/projects/{project_id}/conversations/{chat_id}/messages/{message_id}/events

Re-stream a message’s events after a dropped connection.
Sending while Addison is busy. A conversation runs one message at a time. If you send while a previous message is still running, on_busy decides what happens:
  • on_busy: "queue" (the default) durably queues your message to run next. The reply stream opens immediately with a status event carrying message: "queued", its queuedMessageId, and its position; heartbeats keep the connection alive; then the reply streams once the turn dispatches. Keep the connection open — a queued reply waits as long as the message ahead of it runs.
  • on_busy: "reject" returns a 409 with code conversation_busy and the activeMessageId instead, so you can wait and retry yourself.
These fields apply to follow-up messages; starting a conversation never waits, because a new conversation is never busy. While your message waits, queue.updated events report its position, and held: true if a Stop paused the queue — it will not run until the queue is resumed. On follow-up messages, send a stable idempotency_key per logical message so a retry resumes the same queued message rather than creating a duplicate. If the connection drops before the queued message has bound an assistant message id, reconnect by re-sending with the same idempotency_key, or poll the queued message directly. Starting a conversation is not retry-safe: a retry after a lost response can create a second conversation.

GET /v1/projects/{project_id}/conversations/{chat_id}/queue

List the messages waiting to run.

GET /v1/projects/{project_id}/conversations/{chat_id}/queue/{queued_message_id}

Show one queued message and its bound reply once it starts.

POST /v1/projects/{project_id}/conversations/{chat_id}/messages/{message_id}/cancel

Stop an in-progress reply (needs confirm=true). Pauses the queue if messages are waiting.

POST /v1/projects/{project_id}/conversations/{chat_id}/queue/resume

Resume a queue that a Stop paused.

DELETE /v1/projects/{project_id}/conversations/{chat_id}/queue/{queued_message_id}

Withdraw a waiting message before it runs (needs confirm=true).
GET /v1/projects/{project_id}/conversations/{chat_id} also reports activeTurn, queuedTurns, and queueHeld so you can see what is running and waiting. Rating a response. The thumbs-up / thumbs-down controls in the app are this endpoint:

POST /v1/projects/{project_id}/conversations/{chat_id}/messages/{message_id}/feedback

Submit feedback on an assistant message.
Invoking a / skill directly from the API is not supported yet. Describe the job in the message instead.