> For the complete documentation index, see [llms.txt](https://docs.otari.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.otari.ai/api-reference/responses.md).

# Responses

## Create Response

> OpenAI-compatible Responses endpoint.\
> \
> Supports MCP tool-use loops, sandboxed code execution, and SearXNG\
> web\_search.

```json
{"openapi":"3.1.0","info":{"title":"otari","version":"0.33.0"},"security":[{"ApiKeyAuth":[]},{"XApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"description":"Enter your API key here (sent as Otari-Key header).","in":"header","name":"Otari-Key","type":"apiKey"},"XApiKeyAuth":{"description":"Anthropic-native clients send credentials here (no Bearer prefix).","in":"header","name":"x-api-key","type":"apiKey"}},"schemas":{"ResponsesRequest":{"additionalProperties":true,"description":"OpenAI Responses API-compatible request.\n\nThe wire fields are derived from any-llm's ``ResponsesParams`` (see\n``_schema_derive``) so the schema cannot silently drop a param any-llm\nforwards. Gateway-internal fields (``mcp_servers``, ``mcp_server_ids``,\n``guardrails``, ``tools_header``, ``max_tool_iterations``) opt the request\ninto gateway-managed MCP / sandbox / web_search / guardrails without\nchanging the upstream wire shape. They're stripped before the request is\nforwarded.","properties":{"background":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Background"},"context_management":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Context Management"},"conversation":{"anyOf":[{"type":"string"},{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Conversation"},"frequency_penalty":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Frequency Penalty"},"guardrails":{"anyOf":[{"items":{"$ref":"#/components/schemas/GuardrailConfig"},"maxItems":8,"type":"array"},{"type":"null"}],"title":"Guardrails"},"include":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Include"},"input":{"title":"Input"},"instructions":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instructions"},"max_output_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Output Tokens"},"max_tool_calls":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Tool Calls"},"max_tool_iterations":{"anyOf":[{"maximum":25,"minimum":1,"type":"integer"},{"type":"null"}],"title":"Max Tool Iterations"},"mcp_server_ids":{"anyOf":[{"items":{"format":"uuid","type":"string"},"maxItems":50,"type":"array"},{"type":"null"}],"title":"Mcp Server Ids"},"mcp_servers":{"anyOf":[{"items":{"$ref":"#/components/schemas/McpServerConfig"},"type":"array"},{"type":"null"}],"title":"Mcp Servers"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"description":"Tags for cost attribution, recorded on the request's usage rows and filterable in the usage API: up to 16 string pairs, keys up to 64 characters and values up to 512. A null value is ignored. LiteLLM's nested `spend_logs_metadata` object is also read, and wins over a flat key of the same name; it is never forwarded to the provider.","title":"Metadata"},"model":{"title":"Model","type":"string"},"parallel_tool_calls":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Parallel Tool Calls"},"presence_penalty":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Presence Penalty"},"previous_response_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Previous Response Id"},"prompt_cache_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt Cache Key"},"prompt_cache_retention":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt Cache Retention"},"reasoning":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Reasoning"},"response_format":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Response Format"},"safety_identifier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Safety Identifier"},"service_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Tier"},"session_label":{"anyOf":[{"maxLength":255,"type":"string"},{"type":"null"}],"description":"Optional caller-supplied label for a run, experiment or conversation, which names the session the request's trace is grouped under. Stripped before the request is forwarded upstream to the provider.","title":"Session Label"},"store":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Store"},"stream":{"default":false,"title":"Stream","type":"boolean"},"stream_options":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Stream Options"},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature"},"text":{"anyOf":[{},{"type":"null"}],"title":"Text"},"tool_choice":{"anyOf":[{"type":"string"},{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Tool Choice"},"tools":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Tools"},"tools_header":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tools Header"},"top_logprobs":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Top Logprobs"},"top_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Top P"},"truncation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Truncation"},"user":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User"}},"required":["model","input"],"title":"ResponsesRequest","type":"object"},"GuardrailConfig":{"description":"A single guardrail check the caller wants the gateway to enforce.\n\nURL safety: when ``url`` is supplied it is validated by\n:func:`gateway.services.guardrails.run_input_guardrails` (not here at parse\ntime — the check does a DNS lookup that must be awaited) with the same\nSSRF guard used for MCP server URLs (loopback allowed by default for\nsame-host sidecars; gated by ``OTARI_MCP_ALLOW_LOOPBACK`` /\n``OTARI_MCP_ALLOW_PRIVATE_HOSTS``). Most deployments omit ``url`` and rely\non the operator-set ``OTARI_GUARDRAILS_URL`` instead.","properties":{"mode":{"default":"monitor","enum":["block","monitor"],"title":"Mode","type":"string"},"on":{"items":{"enum":["input","output"],"type":"string"},"title":"On","type":"array"},"on_unavailable":{"default":"block","enum":["block","monitor"],"title":"On Unavailable","type":"string"},"profile":{"maxLength":128,"minLength":1,"title":"Profile","type":"string"},"url":{"anyOf":[{"minLength":1,"type":"string"},{"type":"null"}],"title":"Url"},"validate_kwargs":{"additionalProperties":true,"title":"Validate Kwargs","type":"object"}},"required":["profile"],"title":"GuardrailConfig","type":"object"},"McpServerConfig":{"description":"Inline MCP server configuration accepted by generation requests.\n\nStreamable HTTP transport. The `url` must be reachable from the gateway process.\n\nURL safety (SSRF guard against private/link-local/reserved IP ranges, plus\nrejecting plain ``http://`` when ``authorization_token`` is set) is\nenforced by :func:`gateway.services.url_safety.validate_mcp_url`, called\nfrom the async request pipeline (``prepare_gateway_tools``) rather than\nhere at parse time: the safety check does a DNS lookup, which must be\nawaited so it can't block the event loop, and Pydantic validators run\nsynchronously during request-body parsing.","properties":{"allowed_tools":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Tools"},"authorization_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization Token"},"name":{"maxLength":128,"minLength":1,"title":"Name","type":"string"},"purpose_hint":{"anyOf":[{"maxLength":2000,"type":"string"},{"type":"null"}],"title":"Purpose Hint"},"url":{"minLength":1,"title":"Url","type":"string"}},"required":["name","url"],"title":"McpServerConfig","type":"object"},"HTTPValidationError":{"properties":{"code":{"const":"invalid_request","description":"Stable error code, also sent as the Otari-Error-Code header.","title":"Code","type":"string"},"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"title":"Detail","type":"array"}},"title":"HTTPValidationError","type":"object"},"ValidationError":{"properties":{"ctx":{"title":"Context","type":"object"},"input":{"title":"Input"},"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"title":"Location","type":"array"},"msg":{"title":"Message","type":"string"},"type":{"title":"Error Type","type":"string"}},"required":["loc","msg","type"],"title":"ValidationError","type":"object"}}},"paths":{"/api/v1/responses":{"post":{"description":"OpenAI-compatible Responses endpoint.\n\nSupports MCP tool-use loops, sandboxed code execution, and SearXNG\nweb_search.","operationId":"responses-create_response","parameters":[{"description":"A unique value, such as a UUID, that makes a non-streaming request safe to retry. A retry with the same key and body returns the original response, request ID and cost without calling the provider or billing again. A retry while the original is still running is answered 409 with Retry-After. Reusing a key for a different body is refused with 422. Ignored for streaming requests and on a deployment without OTARI_SECRET_KEY, which encrypts the stored response.","in":"header","name":"Idempotency-Key","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A unique value, such as a UUID, that makes a non-streaming request safe to retry. A retry with the same key and body returns the original response, request ID and cost without calling the provider or billing again. A retry while the original is still running is answered 409 with Retry-After. Reusing a key for a different body is refused with 422. Ignored for streaming requests and on a deployment without OTARI_SECRET_KEY, which encrypts the stored response.","title":"Idempotency-Key"}},{"description":"Tags for cost attribution, as comma-separated `key=value` pairs (`agent=bug-fix,run=1234`), for a client that cannot set the body's `metadata`. Keys and values are percent-decoded, so either may carry an encoded `,` or `=`, and a non-ASCII character must be encoded. Whitespace around a pair is ignored, and a repeated header is read as one list. The bounds are the body's: up to 16 pairs, keys up to 64 characters and values up to 512, counted after merging with the body's tags, which win on the same key. Never forwarded to the provider.","in":"header","name":"Otari-Tags","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Tags for cost attribution, as comma-separated `key=value` pairs (`agent=bug-fix,run=1234`), for a client that cannot set the body's `metadata`. Keys and values are percent-decoded, so either may carry an encoded `,` or `=`, and a non-ASCII character must be encoded. Whitespace around a pair is ignored, and a repeated header is read as one list. The bounds are the body's: up to 16 pairs, keys up to 64 characters and values up to 512, counted after merging with the body's tags, which win on the same key. Never forwarded to the provider.","title":"Otari-Tags"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponsesRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"summary":"Create Response","tags":["responses"]}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.otari.ai/api-reference/responses.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
