Responses API request shape
POST /v1/responses accepts the OpenAI Responses request body. The
goal is bit-for-bit compatibility with stock OpenAI clients —
anything you’d send to OpenAI’s /v1/responses you can send to
Kindo’s, with the same semantics.
This page documents what Kindo recognizes and how each field is forwarded.
Required fields
Section titled “Required fields”| Field | Type | Notes |
|---|---|---|
model | string | A model ID from GET /v1/models, or a stored Kindo agent as agent/<agent-id> (see below). |
input | string | array of input items | Plain string for single-turn, or array for multi-message / tool round trips. |
Agent models (agent/<agent-id>)
Section titled “Agent models (agent/<agent-id>)”Passing model: "agent/<agent-id>" invokes one of your stored Kindo
agents instead of a raw model. The agent supplies the model, system
prompt, and tool set; your input is delivered to the run and your
instructions compose with (append after) the agent’s own prompt.
Because the agent’s configuration is pinned, request fields that
would override it — tools, a non-"auto" tool_choice,
conversation, previous_response_id, background, and sampling
parameters such as temperature — are rejected with
400 unsupported_parameter naming the field. Agent invocations
return immediately with status: "in_progress" and are polled or
streamed.
See Invoke Kindo agents with the Responses API for the full walkthrough.
input array items
Section titled “input array items”Each item is one of:
type | Required fields | Notes |
|---|---|---|
message | role, content | role is user, system, assistant, or developer. developer is treated as a system-level instruction (matches OpenAI semantics). |
function_call | call_id, name, arguments | Accepted for conversation-history round-tripping. Re-sending one does not re-execute it. |
function_call_output | call_id, output | Returns a function tool’s result; pair it with the originating function_call.call_id. |
Message content parts
Section titled “Message content parts”A message item’s content is a plain string or an array of typed
parts:
type | Key fields | Notes |
|---|---|---|
input_text | text | Plain text. |
input_image | image_url | A data: URL or fetchable https: URL. Supported on both the stateless and stateful paths. The OpenAI detail hint is accepted; on the stateful path it is not propagated to the model. |
input_file | file_data / file_id / file_url | Stateless path only — forwarded to the upstream provider. On the stateful path (store: true, conversation, or previous_response_id), file parts are not carried to the model; send file content as text instead. |
Data Loss Prevention. If your organization has DLP policies
enabled, request text is scanned and redacted in-flight before it
reaches the model — this is transparent to the caller. File parts
interact with DLP explicitly: an input_file whose content cannot be
inspected (binary file_data, or a file_id/file_url reference) is
rejected with 400 rather than passed through unscanned, while
inline file_data with a text MIME type (text/*, JSON, CSV, source
code) is decoded, redacted, and forwarded. Without DLP enabled, file
parts pass through unmodified on the stateless path.
Standard fields
Section titled “Standard fields”Every field below is forwarded verbatim unless a row says otherwise. Behavior matches OpenAI’s published spec.
| Field | Type | Forwarded? | Notes |
|---|---|---|---|
instructions | string | Yes | System-level instructions. Flow through unmodified by default. |
tools | array | Yes | Mix function, mcp, and any kindo_* tools. Unknown types are forwarded verbatim. mcp tools require the stateful path (store: true or conversation); stateless requests including them are rejected with 400 unsupported_tool_type. |
tool_choice | string | object | Yes | "auto", "none", "required", {type: "function", name: "..."}, or {type: "allowed_tools", ...}. |
stream | boolean | — | Consumed by the route handler to switch into SSE mode (see Streaming). |
store | boolean | Yes | When true, Kindo persists the response and returns a conversation.id. Default false. |
previous_response_id | string | — | Continues the conversation that produced the referenced stored response (only responses created with store: true or conversation can be chained). Mutually exclusive with conversation. Unknown or inaccessible IDs → 404 previous_response_not_found. |
conversation | string | Yes | Existing Kindo-managed conversation ID to continue. Prior history is loaded server-side — send only the new turn in input. Mutually exclusive with previous_response_id. |
parallel_tool_calls | boolean | Yes | Forwarded to the upstream model. |
prompt_cache_key | string | Yes | Forwarded; used by upstream providers that support prompt caching. |
reasoning | object | Yes | OpenAI reasoning controls (e.g. effort). |
text | object | Yes | OpenAI text-output controls (e.g. format, verbosity). |
include | array of strings | Yes | Request additional output items (e.g. encrypted reasoning content). |
truncation | string | Yes | OpenAI truncation policy. |
background | boolean | Yes* | OpenAI background-execution flag. *On the stateful path (store: true or conversation set), background: true is rejected with 400 unsupported_parameter — background execution is not yet supported on Kindo-managed conversations. Omit it or use stream: true. |
service_tier | string | Yes | OpenAI service-tier hint. |
max_output_tokens | integer | Yes | Standard sampling control. |
temperature | number | Yes | Standard sampling control. |
top_p | number | Yes | Standard sampling control. |
n | integer | Yes | Standard sampling control. |
stop | string | array | Yes | Standard sampling control. |
metadata | object | Stored only | Echoed back in the response object. Not forwarded to the model layer. |
Anything not listed above passes through Kindo’s schema verbatim, so new OpenAI-spec additions land at Kindo automatically when supported by the upstream model.
Stripped-on-ingress fields
Section titled “Stripped-on-ingress fields”Kindo strips these fields from the outgoing upstream request to prevent governance-metadata spoofing:
metadatalitellm_metadataproxy_server_request
(metadata is stored and echoed back in the response; it is not forwarded to the model layer — see the row above.)
Response store pruning
Section titled “Response store pruning”When store: true, Kindo persists the response object so it can be
fetched later via GET /v1/responses/{id}. Stored responses are not
kept indefinitely — once a response is pruned (whether by retention
policy expiry or explicit deletion), subsequent fetches by ID return
404 not_found with no error.code set. This is the same status the
endpoint returns for IDs that never existed; the two cases are not
distinguished in the response envelope.
If you need durable access to a response body, capture it from the
original POST /v1/responses call rather than relying on the stored
copy.
See the 404 row in the errors table for the matching error envelope.
Read endpoints
Section titled “Read endpoints”Two GET endpoints accompany POST /v1/responses for stored
responses:
GET /v1/responses/{response_id}
Section titled “GET /v1/responses/{response_id}”Fetches the response object by ID — the polling mechanism for
agent-run responses (resp_run_*) and the way to re-read any stored
response. Add ?stream=true (optionally with starting_after) to
reconnect to the response’s SSE stream instead — see
Streaming → resuming a dropped stream.
GET /v1/responses/{response_id}/input_items
Section titled “GET /v1/responses/{response_id}/input_items”Returns the user input that initiated a stored response, as an OpenAI-style list envelope:
{ "object": "list", "data": [ { "id": "msg_abc123", "type": "message", "role": "user", "content": [{ "type": "input_text", "text": "Summarize CVE-2024-3094." }], "status": "completed" } ], "has_more": false, "first_id": "msg_abc123", "last_id": "msg_abc123"}The list contains the response’s originating user message (an empty
data array when the response had no user input message). has_more
is always false — pagination parameters are not supported on this
endpoint. For the full conversation history around a stored response,
use the Conversations API with the
response’s conversation.id.
Kindo extension fields
Section titled “Kindo extension fields”These are opt-in and documented in detail at Chat Actions extensions:
| Field | Type | Notes |
|---|---|---|
kindo.system_prompt | "agent_default" | "off" | When "agent_default", Kindo prepends its curated operational prompt to your instructions. On stateful requests (store: true, conversation, or previous_response_id), Kindo includes service-managed context with the composed prompt and supplies the current date and timezone with the triggering input. Default "off" does not add either form of service-managed context; client instructions and input remain unchanged. |
tools[].type: "kindo_tools" | sugar entry | Expands at request time to the current set of individual kindo_<name> entries. |
tools[].type: "kindo_<name>" | individual hosted-tool entry | E.g. kindo_shell, kindo_web_search. See Chat Actions extensions for the full list. |
On compacted stateful turns, a service-managed compaction hint may be
appended; it follows composed instructions and other service-managed
prompt guidance. With off, caller instructions are preserved; the
separate compaction hint may still be added.
The kindo block and kindo_* tool types are the only Kindo-specific
additions to the request body. Everything else on this page is stock
OpenAI Responses.
Worked example
Section titled “Worked example”{ "model": "claude-sonnet-4-5-20250929", "input": [ { "type": "message", "role": "developer", "content": "You are a concise security assistant." }, { "type": "message", "role": "user", "content": "Summarize CVE-2024-3094." } ], "tools": [ { "type": "function", "name": "lookup_cve", "description": "Fetch CVE metadata.", "parameters": { "type": "object", "properties": { "id": { "type": "string" } }, "required": ["id"] } } ], "tool_choice": "auto", "store": true, "max_output_tokens": 512, "temperature": 0.2}This request is stock OpenAI Responses. Kindo accepts it identically
to OpenAI’s /v1/responses, plus persists the response and returns a
conversation.id because store: true is set.
See also
Section titled “See also”- Quickstart — minimal client setup.
- Streaming — SSE event types.
- Tool use — function-calling round trip.
- Errors — error envelope.
- Chat Actions extensions —
kindoblock,kindo_*tools, statefulness opt-ins.