Skip to content

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.

FieldTypeNotes
modelstringA model ID from GET /v1/models, or a stored Kindo agent as agent/<agent-id> (see below).
inputstring | array of input itemsPlain string for single-turn, or array for multi-message / tool round trips.

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.

Each item is one of:

typeRequired fieldsNotes
messagerole, contentrole is user, system, assistant, or developer. developer is treated as a system-level instruction (matches OpenAI semantics).
function_callcall_id, name, argumentsAccepted for conversation-history round-tripping. Re-sending one does not re-execute it.
function_call_outputcall_id, outputReturns a function tool’s result; pair it with the originating function_call.call_id.

A message item’s content is a plain string or an array of typed parts:

typeKey fieldsNotes
input_texttextPlain text.
input_imageimage_urlA 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_filefile_data / file_id / file_urlStateless 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. When no DLP policy applies, Kindo does not redact file content on the stateless path. Provider translation can still change its representation: for direct Anthropic deployments, inline UTF-8 text/plain file data becomes text content, without the filename. This conversion does not apply to Anthropic models served through Bedrock. Other file formats remain subject to the selected provider’s input support.

Every field below is forwarded verbatim unless a row says otherwise. Behavior matches OpenAI’s published spec.

FieldTypeForwarded?Notes
instructionsstringYesSystem-level instructions. Flow through unmodified by default.
toolsarrayYesMix 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_choicestring | objectYes"auto", "none", "required", {type: "function", name: "..."}, or {type: "allowed_tools", ...}.
streamboolean—Consumed by the route handler to switch into SSE mode (see Streaming).
storebooleanYesWhen true, Kindo persists the response and returns a conversation.id. Default false.
previous_response_idstring—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.
conversationstringYesExisting 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_callsbooleanYesForwarded to the upstream model.
prompt_cache_keystringYesForwarded; used by upstream providers that support prompt caching.
reasoningobjectYesOpenAI reasoning controls (e.g. effort).
textobjectYesOpenAI text-output controls (e.g. format, verbosity).
includearray of stringsYesRequest additional output items (e.g. encrypted reasoning content).
truncationstringYesOpenAI truncation policy.
backgroundbooleanYes*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_tierstringYesOpenAI service-tier hint.
max_output_tokensintegerYesStandard sampling control.
temperaturenumberYesStandard sampling control.
top_pnumberYesStandard sampling control.
nintegerYesStandard sampling control.
stopstring | arrayYesStandard sampling control.
metadataobjectStored onlyEchoed 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.

Kindo strips these fields from the outgoing upstream request to prevent governance-metadata spoofing:

  • metadata
  • litellm_metadata
  • proxy_server_request

(metadata is stored and echoed back in the response; it is not forwarded to the model layer — see the row above.)

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.

Two GET endpoints accompany POST /v1/responses for stored responses:

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.

These are opt-in and documented in detail at Chat Actions extensions:

FieldTypeNotes
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 entryExpands at request time to the current set of individual kindo_<name> entries.
tools[].type: "kindo_<name>"individual hosted-tool entryE.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.

{
"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.