# Responses > Send text, images, files and tools through the Responses API, and continue stored responses for 30 days. Section: Developers. Web page: https://docs.katara.com/developers/responses/ `POST https://api.katara.com/v1/responses` takes the OpenAI Responses request shape and is served by Katara Cortex. Routing, payment and charges follow the same rules as [Chat Completions](https://docs.katara.com/start/api.txt); a request with a key is paid with that key, one without a key per request with [x402](https://docs.katara.com/developers/x402.txt#the-responses-api). The OpenAI SDKs and the Vercel AI SDK work against it with `https://api.katara.com/v1` as the base URL. ```sh curl 'https://api.katara.com/v1/responses' \ -H "Authorization: Bearer $KATARA_API_KEY" \ -H 'Content-Type: application/json' \ -d '{ "model": "katara/cortex", "input": "Explain a Merkle tree in two sentences.", "max_output_tokens": 200 }' ``` Read assistant text from `output` items whose `type` is `message`, then from their `content` parts whose `type` is `output_text`. A reply can also hold function calls, reasoning items and web search calls. ## Model names Any `model` is accepted, including the GPT names OpenAI clients send by default, and Katara Cortex serves it ([Model names in requests](https://docs.katara.com/concepts/models.txt#model-names-in-requests)). The reply's `model` is `katara/cortex`. A request paid with [x402](https://docs.katara.com/developers/x402.txt#choosing-a-model) may name `katara/cortex-genius` or `katara/cortex-smart` to fix the model; its reply still names `katara/cortex`, and a key that names either is refused. ## Input `input` is a string or an array of typed items. Message roles are `user`, `assistant`, `system` and `developer`. A message's content is text or typed parts: `input_text`, `output_text` and `refusal`; `input_image` by `image_url` or `file_id`; `input_file` by `file_id` or `file_data`; and `input_audio`. Files are uploaded through [`/v1/files`](https://docs.katara.com/developers/media.txt). `instructions` is sent as a system message. ## Tools Function tools use a flat declaration: ```json { "type": "function", "name": "read_file", "parameters": { "type": "object", "properties": { "path": { "type": "string" } }, "required": ["path"] } } ``` A returned `function_call` carries `call_id`, `name` and `arguments` as JSON text. Run the tool in your application, then send the call and its result in the next request, or send only the result with `previous_response_id`: ```json [ {"type":"message","role":"user","content":"Read README.txt"}, {"type":"function_call","call_id":"call_1","name":"read_file","arguments":"{\"path\":\"README.txt\"}"}, {"type":"function_call_output","call_id":"call_1","output":"Project setup instructions"} ] ``` Each result must match an outstanding call. A `function_call_output` can be a string or a list of parts, images and files included. Besides `function`, Katara takes `custom` tools (freeform input, with a grammar described to the model), `namespace` tools (one level deep), `tool_search` and `web_search`. `tool_choice` takes `auto`, `none`, `required`, a named function or custom tool, and `allowed_tools`; `parallel_tool_calls: false` gets at most one call per reply. Hosted tools Katara does not run are refused with `400 unsupported_tool` naming the tool: `file_search`, `mcp`, `computer`, `computer_use` and `computer_use_preview`, `code_interpreter`, `image_generation`, `local_shell`, `shell` and `apply_patch`. ## Web search A `web_search` tool (`web_search_preview` and the dated variants too) lets the model search the web through Katara. `max_tool_calls` lowers the cap of five searches per request, and `filters.allowed_domains` or `filters.blocked_domains` narrows the results. Each search comes back as a `web_search_call` item with its sources, and the answer's `output_text` carries `url_citation` annotations for the pages it quotes. In a stream the item opens with `response.web_search_call.in_progress` and `response.web_search_call.searching` when the search starts, and ends with `response.web_search_call.completed` once its results are in. Once the model asks to search, the rest of the request is served by Katara's managed models only. If it then ends without an answer, the searches and the model calls after the first are not charged. Search needs a key; [Web search](https://docs.katara.com/developers/tools.txt#web-search) has the price and when it is offered. ## Reasoning and other fields `reasoning` (any `effort`, `summary`) is accepted and changes nothing: Katara Cortex decides how much the model reasons. Reasoning comes back as `reasoning` items, with `summary_text` when you asked for a summary. Reasoning items can be sent back in history. `include` values are accepted; Katara returns no encrypted reasoning, and `encrypted_content` sent back is dropped. `text.format` takes `text`, `json_object` or `json_schema`, and `text.verbosity` is accepted. `background: true` is accepted and answered when the reply is complete. `truncation`, `metadata`, `user`, `safety_identifier`, `service_tier`, `stream_options`, `top_logprobs`, `prompt_cache_retention`, `context_management`, `client_metadata` and `access_programs` are accepted. `prompt_cache_key` keeps a conversation on the model whose cache holds its start ([Caching](https://docs.katara.com/concepts/cortex.txt#caching)). A stored `prompt` template is refused. Any other field is refused with `400 unsupported_parameter` naming it. ## Streaming and charges Set `stream: true` for server-sent events. Each event has a name, JSON `data` and a `sequence_number`. The stream starts with `response.created` and `response.in_progress`. Text arrives in `response.output_text.delta`, tool arguments in `response.function_call_arguments.delta` and `response.custom_tool_call_input.delta`, and reasoning in `response.reasoning_text.delta` or the summary events. Wait for `response.completed`, `response.incomplete` or `response.failed`; a closed connection is not enough to establish completion. An incomplete response names `max_output_tokens` or `content_filter` in `incomplete_details.reason`. A failed stream's `error.code` is one of the codes in [Errors](https://docs.katara.com/developers/errors.txt). The final response carries `usage` (`input_tokens`, with `cached_tokens` and `cache_write_tokens` under `input_tokens_details`; `output_tokens`, with `reasoning_tokens`; `total_tokens`) and the `katara` object with the charge. See [Usage and cost](https://docs.katara.com/developers/usage.txt). ## Stored responses A response is stored unless the request sends `store: false`, and is kept 30 days from when it was created, then deleted. Reading or continuing it does not extend that. Stored responses are kept in their own store, apart from ordinary logs. - With a key, a response belongs to the key's account, and only keys of that account can read, continue or delete it. - Without a key, a response belongs to nobody: no account or payer address is kept with it, and whoever holds its id can read, continue or delete it. Treat the id as a secret. The routes: - `previous_response_id` continues from a stored response: its input and output become the start of the new request. - `conversation` (an id, or `{"id": ...}`) continues from the latest stored response in that conversation. It needs a key. - `GET /v1/responses/{response_id}` returns a stored response. `?stream=true` is refused. - `GET /v1/responses/{response_id}/input_items` lists its input items, newest first, or oldest first with `order=asc`. - `DELETE /v1/responses/{response_id}` deletes it and answers `{"object": "response.deleted"}`. - `POST /v1/responses/{response_id}/cancel` answers `400 response_not_cancellable`: every response has finished by the time it is answered. A response that is missing, expired, deleted or someone else's is `404 response_not_found`; as `previous_response_id` it is `404 previous_response_not_found`. If saving a response fails, the reply is still delivered; only the continuation is lost. ## Errors Format errors are `400` with `param` naming the field: `invalid_json`, `invalid_type`, `invalid_value`, `unsupported_parameter`, `unsupported_tool`, and `invalid_request` for a malformed or oversized body. Payment and capacity errors are those of [Chat Completions](https://docs.katara.com/developers/errors.txt), passed through unchanged: `402 insufficient_quota` when the funds cannot cover the request, `429 provider_rate_limited`, `500` when every candidate's reply failed or was refused, and `503` with `Retry-After`.