docs: add Responses API reference#2440
Conversation
Document the /v1/responses endpoints (create, get) including streaming SSE events, structured context (x_context), and multi-turn conversation support via previous_response_id. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request adds documentation for the new Responses API, covering endpoints for creating and retrieving responses with support for streaming and multi-turn conversations. Feedback indicates that the documentation contains several inaccuracies: the stated OpenAI SDK compatibility is misleading, the 'Structured context' feature is currently unimplemented and inconsistently described, and the error response list for the GET endpoint is incomplete and contains incorrect error descriptions.
|
|
||
| ## Responses API | ||
|
|
||
| Routes through the full agent loop — tools, memory, safety, and server-side conversation state are all active. Compatible with any standard OpenAI SDK via `client.responses.create()`. |
There was a problem hiding this comment.
The claim that this API is "Compatible with any standard OpenAI SDK via client.responses.create()" is misleading. Official OpenAI SDKs (such as the Python and Node.js libraries) do not have a responses resource or a create method under that name. While the request/response format may be similar to OpenAI's, users will need to use generic HTTP request methods (e.g., client.post) to interact with this specific endpoint.
| ### Structured context | ||
|
|
||
| The `input` field accepts a structured `context` object alongside the user message. Use this to pass machine-readable state that the agent should act on, without relying solely on natural language. | ||
|
|
||
| **Request:** | ||
|
|
||
| ```json | ||
| { | ||
| "model": "claude-sonnet-4-5-20250514", | ||
| "input": "Go ahead with the transfer", | ||
| "previous_response_id": "resp_...", | ||
| "x_context": { | ||
| "notification_response": { | ||
| "notification_id": "msg_123", | ||
| "action": "approved", | ||
| "original_signal": "convert_now", | ||
| "score": 72, | ||
| "rate": 85.42, | ||
| "amount_usd": 1000 | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| The agent receives the context prepended to the user message: | ||
|
|
||
| ``` | ||
| [Context: notification_response — notification_id: msg_123, action: approved, | ||
| original_signal: convert_now, score: 72, rate: 85.42, amount_usd: 1000] | ||
| Go ahead with the transfer | ||
| ``` | ||
|
|
||
| The `context` payload is persisted in message metadata for auditability. |
There was a problem hiding this comment.
This section describes a "Structured context" feature using an x_context field that is not currently implemented in the backend. The ResponsesRequest struct in src/channels/web/responses_api.rs does not define an x_context field, and the handler does not contain logic to process it or prepend it to the user message as described. Additionally, the text states the context object is accepted within the input field, while the example shows x_context as a top-level field. This section should be removed or updated to reflect the actual capabilities of the API.
|
|
||
| **Response:** `200 OK` — same shape as the create response object above. | ||
|
|
||
| **Errors:** `400` (empty input), `401` (missing or invalid bearer token), `404` (response ID not found or not owned by caller), `500` (internal error) |
There was a problem hiding this comment.
The error list for the GET endpoint is missing the 503 Service Unavailable status code, which is returned by the implementation when the database is not configured (see src/channels/web/responses_api.rs, line 1061). Also, the 400 error on a GET request typically refers to an invalid response ID rather than "empty input."
| **Errors:** `400` (empty input), `401` (missing or invalid bearer token), `404` (response ID not found or not owned by caller), `500` (internal error) | |
| Errors: 400 (invalid response ID), 401 (missing or invalid bearer token), 404 (response ID not found or not owned by caller), 503 (database not configured), 500 (internal error) |
There was a problem hiding this comment.
Pull request overview
Adds missing internal documentation for the OpenAI-compatible Responses API in docs/internal/USER_MANAGEMENT_API.md, intended to describe how clients can create and retrieve agent-loop-backed responses (including SSE streaming and multi-turn continuation).
Changes:
- Documented
POST /v1/responsesrequest/response shapes and SSE event names. - Added guidance for multi-turn via
previous_response_idand response retrieval viaGET /v1/responses/{id}. - Added a “Structured context” subsection (currently documented as
x_context).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "id": "resp_<uuid>", | ||
| "object": "response", | ||
| "created_at": 1743000000, | ||
| "model": "claude-sonnet-4-5-20250514", |
There was a problem hiding this comment.
The response example shows "model": "claude-sonnet-4-5-20250514", but responses from this endpoint currently use model: "default" (and the create handler rejects non-default models). Please align the example response model value with actual behavior to avoid confusing SDK users.
| "model": "claude-sonnet-4-5-20250514", | |
| "model": "default", |
| ### Structured context | ||
|
|
||
| The `input` field accepts a structured `context` object alongside the user message. Use this to pass machine-readable state that the agent should act on, without relying solely on natural language. | ||
|
|
||
| **Request:** | ||
|
|
||
| ```json | ||
| { | ||
| "model": "claude-sonnet-4-5-20250514", | ||
| "input": "Go ahead with the transfer", | ||
| "previous_response_id": "resp_...", | ||
| "x_context": { | ||
| "notification_response": { | ||
| "notification_id": "msg_123", | ||
| "action": "approved", | ||
| "original_signal": "convert_now", | ||
| "score": 72, | ||
| "rate": 85.42, | ||
| "amount_usd": 1000 | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
The docs describe a x_context request field that is prepended to the user message and persisted, but the current Responses API request type does not accept/process x_context (unknown JSON fields are ignored and nothing is added to message metadata). Please either remove/mark this section as not yet supported, or implement x_context handling so the described behavior is true.
| **Status values:** `completed` | `failed` | ||
|
|
There was a problem hiding this comment.
status can be in_progress during streaming (the server emits response.created with an in-progress response object), but the docs list only completed | failed. Please include in_progress as a possible status value (at least for streaming events).
| **Status values:** `completed` | `failed` | |
| **Status values:** `in_progress` | `completed` | `failed` | |
| For streaming responses, expect `status: "in_progress"` on the initial `response.created` event and until the response reaches a terminal state of `completed` or `failed`. |
| **Response:** `200 OK` — same shape as the create response object above. | ||
|
|
||
| **Errors:** `400` (empty input), `401` (missing or invalid bearer token), `404` (response ID not found or not owned by caller), `500` (internal error) | ||
|
|
There was a problem hiding this comment.
The documented GET errors don’t match the handler behavior: 400 is returned for an invalid response_id format (not “empty input”), and 503 is possible when the database isn’t configured. Also, this endpoint returns OpenAI-style JSON errors ({ "error": { ... } }), which differs from the plain-text ## Error Format section below—please clarify the Responses API error shape here to avoid misleading clients.
| ```json | ||
| { | ||
| "model": "claude-sonnet-4-5-20250514", | ||
| "input": "What's a good time to send money to India?", | ||
| "stream": true, | ||
| "previous_response_id": null | ||
| } | ||
| ``` | ||
|
|
||
| | Field | Type | Notes | | ||
| |-------|------|-------| | ||
| | `model` | string | LLM model to use. Pass `"default"` to use the server-configured model | | ||
| | `input` | string or array | User message as a string, or a messages array (see below) | | ||
| | `stream` | boolean | `true` for SSE, `false` for blocking (120s timeout) | | ||
| | `previous_response_id` | string | Pass the previous `id` to continue a conversation thread | |
There was a problem hiding this comment.
The examples/documentation imply callers can choose an arbitrary model (e.g., claude-sonnet-4-5-20250514), but the current POST /v1/responses implementation rejects any model other than "default" with a 400. Please update the request example and model field notes to reflect that only "default" is supported right now (or change the endpoint if model selection is intended).
Summary
docs/internal/USER_MANAGEMENT_API.mdPOST /v1/responses(create) andGET /v1/responses/{id}(retrieve)x_context), multi-turn viaprevious_response_id, and error codesNotes
The Admin API, Auth, Tokens, Profile, Secrets, and Usage sections from the same spec were already documented — only the Responses API was missing. Requires #2167 to be merged for Responses API to fully work
Test plan
🤖 Generated with Claude Code