{"openapi":"3.1.1","info":{"title":"InterOdin API","version":"1.0.0","description":"OpenAI- and Anthropic-compatible API for the Odin model family. Point an existing SDK at the base URL and use an `io-sk-` key, sent as `Authorization: Bearer` or `x-api-key` (`x-api-key` wins if both are sent, on every endpoint)."},"servers":[{"url":"https://api.interodin.com","description":"Production"}],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"tags":[{"name":"Chat Completions","description":"OpenAI Chat Completions format."},{"name":"Responses","description":"OpenAI Responses format. Stateless: nothing is stored."},{"name":"Messages","description":"Anthropic Messages format."},{"name":"Models","description":"Available models."}],"paths":{"/v1/chat/completions":{"post":{"operationId":"createChatCompletion","tags":["Chat Completions"],"summary":"Create chat completion","description":"Generates the next assistant message. With `stream: true` the reply is sent as server-sent events: each `data:` line is a `ChatCompletionChunk`, the last chunk carries `usage`, and the stream ends with `data: [DONE]`.","parameters":[{"name":"x-interodin-session-id","in":"header","required":false,"description":"Optional prompt-cache routing hint, honoured on every generation endpoint (including `count_tokens`). Send the same opaque value (for example a conversation id, at most 128 characters recommended) on every request of one conversation. Never put prompts, personal data or secrets in it.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateChatCompletionRequest"},"examples":{"basic":{"value":{"model":"odin-v1","messages":[{"role":"user","content":"Say hello in Romanian."}]}}}}}},"responses":{"200":{"description":"A chat completion, or an event stream when `stream` is true.","headers":{"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletion"}},"text/event-stream":{"schema":{"type":"string","description":"`data: <ChatCompletionStreamPayload JSON>` lines, then `data: [DONE]`."}}}},"400":{"description":"`invalid_request`, `content_refused`, `unsupported_parameter`, `image_input_not_supported`, `unsupported_content`, `context_length_exceeded`. Rate-limit headers are present only on errors derived from the model's response (for example `context_length_exceeded`); request validation errors are raised before the rate-limit step and carry none.","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"invalid_request":{"value":{"error":{"message":"The request is invalid.","type":"invalid_request_error","code":"invalid_request","param":null}}},"content_refused":{"value":{"error":{"message":"The model declined this request. Rephrase it and try again.","type":"invalid_request_error","code":"content_refused","param":null}}},"unsupported_parameter":{"value":{"error":{"message":"A request parameter is not supported.","type":"invalid_request_error","code":"unsupported_parameter","param":null}}},"image_input_not_supported":{"value":{"error":{"message":"This model does not accept image input.","type":"invalid_request_error","code":"image_input_not_supported","param":null}}},"unsupported_content":{"value":{"error":{"message":"This content type (file or document input) is not supported.","type":"invalid_request_error","code":"unsupported_content","param":null}}},"context_length_exceeded":{"value":{"error":{"message":"The request exceeds the model's context window. Shorten the input or lower the maximum output tokens.","type":"invalid_request_error","code":"context_length_exceeded","param":null}}}}}}},"401":{"description":"`invalid_api_key`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"invalid_api_key":{"value":{"error":{"message":"Invalid or missing API key.","type":"authentication_error","code":"invalid_api_key","param":null}}}}}}},"402":{"description":"`insufficient_credits`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"insufficient_credits":{"value":{"error":{"message":"Your organization has no remaining credit. Top up to continue.","type":"insufficient_quota","code":"insufficient_credits","param":null}}}}}}},"403":{"description":"`model_not_allowed`, `key_spend_limit_reached`, `organization_suspended`. Rate-limit headers are present for `key_spend_limit_reached` only.","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"model_not_allowed":{"value":{"error":{"message":"This API key is not allowed to use this model.","type":"permission_error","code":"model_not_allowed","param":null}}},"key_spend_limit_reached":{"value":{"error":{"message":"This API key has reached its monthly spend limit.","type":"permission_error","code":"key_spend_limit_reached","param":null}}},"organization_suspended":{"value":{"error":{"message":"This organization is suspended. Contact support.","type":"permission_error","code":"organization_suspended","param":null}}}}}}},"404":{"description":"`model_not_found`, `not_found`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"model_not_found":{"value":{"error":{"message":"The requested model does not exist.","type":"invalid_request_error","code":"model_not_found","param":null}}},"not_found":{"value":{"error":{"message":"Not found.","type":"invalid_request_error","code":"not_found","param":null}}}}}}},"413":{"description":"`request_too_large`. Rate-limit headers are present only when the 413 came from the model.","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"request_too_large":{"value":{"error":{"message":"The request body exceeds the 10 MB limit.","type":"invalid_request_error","code":"request_too_large","param":null}}}}}}},"429":{"description":"`rate_limit_exceeded`, `concurrency_limit`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"},"retry-after":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"rate_limit_exceeded":{"value":{"error":{"message":"Rate limit exceeded. Retry after the number of seconds in the Retry-After header.","type":"rate_limit_error","code":"rate_limit_exceeded","param":null}}},"concurrency_limit":{"value":{"error":{"message":"Too many concurrent requests for this organization. Retry shortly.","type":"rate_limit_error","code":"concurrency_limit","param":null}}}}}}},"500":{"description":"`internal_error`. Some `internal_error` responses are raised before the rate-limit step and carry no rate-limit headers.","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"internal_error":{"value":{"error":{"message":"Internal error. Please retry.","type":"api_error","code":"internal_error","param":null}}}}}}},"502":{"description":"`upstream_unavailable`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"upstream_unavailable":{"value":{"error":{"message":"The model is temporarily unavailable. Please retry.","type":"api_error","code":"upstream_unavailable","param":null}}}}}}},"504":{"description":"`timeout`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"timeout":{"value":{"error":{"message":"The model did not respond in time. Please retry.","type":"api_error","code":"timeout","param":null}}}}}}}}}},"/v1/responses":{"post":{"operationId":"createResponse","tags":["Responses"],"summary":"Create response","description":"Generates a model response. Responses are never stored: `store` is always `false`, `previous_response_id` is rejected, and there is no endpoint to retrieve or delete a response. Send the whole conversation in `input` each time.","parameters":[{"name":"x-interodin-session-id","in":"header","required":false,"description":"Optional prompt-cache routing hint, honoured on every generation endpoint (including `count_tokens`). Send the same opaque value (for example a conversation id, at most 128 characters recommended) on every request of one conversation. Never put prompts, personal data or secrets in it.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateResponseRequest"},"examples":{"basic":{"value":{"model":"odin-v1","input":"Say hello in Romanian."}}}}}},"responses":{"200":{"description":"A response object, or an event stream when `stream` is true.","headers":{"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"text/event-stream":{"schema":{"type":"string","description":"`event: <type>` + `data: <ResponseStreamEvent JSON>` pairs. Usage arrives on `response.completed`."}}}},"400":{"description":"`invalid_request`, `content_refused`, `unsupported_parameter`, `image_input_not_supported`, `unsupported_content`, `context_length_exceeded`. Rate-limit headers are present only on errors derived from the model's response (for example `context_length_exceeded`); request validation errors are raised before the rate-limit step and carry none.","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"invalid_request":{"value":{"error":{"message":"The request is invalid.","type":"invalid_request_error","code":"invalid_request","param":null}}},"content_refused":{"value":{"error":{"message":"The model declined this request. Rephrase it and try again.","type":"invalid_request_error","code":"content_refused","param":null}}},"unsupported_parameter":{"value":{"error":{"message":"A request parameter is not supported.","type":"invalid_request_error","code":"unsupported_parameter","param":null}}},"image_input_not_supported":{"value":{"error":{"message":"This model does not accept image input.","type":"invalid_request_error","code":"image_input_not_supported","param":null}}},"unsupported_content":{"value":{"error":{"message":"This content type (file or document input) is not supported.","type":"invalid_request_error","code":"unsupported_content","param":null}}},"context_length_exceeded":{"value":{"error":{"message":"The request exceeds the model's context window. Shorten the input or lower the maximum output tokens.","type":"invalid_request_error","code":"context_length_exceeded","param":null}}}}}}},"401":{"description":"`invalid_api_key`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"invalid_api_key":{"value":{"error":{"message":"Invalid or missing API key.","type":"authentication_error","code":"invalid_api_key","param":null}}}}}}},"402":{"description":"`insufficient_credits`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"insufficient_credits":{"value":{"error":{"message":"Your organization has no remaining credit. Top up to continue.","type":"insufficient_quota","code":"insufficient_credits","param":null}}}}}}},"403":{"description":"`model_not_allowed`, `key_spend_limit_reached`, `organization_suspended`. Rate-limit headers are present for `key_spend_limit_reached` only.","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"model_not_allowed":{"value":{"error":{"message":"This API key is not allowed to use this model.","type":"permission_error","code":"model_not_allowed","param":null}}},"key_spend_limit_reached":{"value":{"error":{"message":"This API key has reached its monthly spend limit.","type":"permission_error","code":"key_spend_limit_reached","param":null}}},"organization_suspended":{"value":{"error":{"message":"This organization is suspended. Contact support.","type":"permission_error","code":"organization_suspended","param":null}}}}}}},"404":{"description":"`model_not_found`, `not_found`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"model_not_found":{"value":{"error":{"message":"The requested model does not exist.","type":"invalid_request_error","code":"model_not_found","param":null}}},"not_found":{"value":{"error":{"message":"Not found.","type":"invalid_request_error","code":"not_found","param":null}}}}}}},"413":{"description":"`request_too_large`. Rate-limit headers are present only when the 413 came from the model.","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"request_too_large":{"value":{"error":{"message":"The request body exceeds the 10 MB limit.","type":"invalid_request_error","code":"request_too_large","param":null}}}}}}},"429":{"description":"`rate_limit_exceeded`, `concurrency_limit`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"},"retry-after":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"rate_limit_exceeded":{"value":{"error":{"message":"Rate limit exceeded. Retry after the number of seconds in the Retry-After header.","type":"rate_limit_error","code":"rate_limit_exceeded","param":null}}},"concurrency_limit":{"value":{"error":{"message":"Too many concurrent requests for this organization. Retry shortly.","type":"rate_limit_error","code":"concurrency_limit","param":null}}}}}}},"500":{"description":"`internal_error`. Some `internal_error` responses are raised before the rate-limit step and carry no rate-limit headers.","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"internal_error":{"value":{"error":{"message":"Internal error. Please retry.","type":"api_error","code":"internal_error","param":null}}}}}}},"502":{"description":"`upstream_unavailable`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"upstream_unavailable":{"value":{"error":{"message":"The model is temporarily unavailable. Please retry.","type":"api_error","code":"upstream_unavailable","param":null}}}}}}},"504":{"description":"`timeout`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"},"examples":{"timeout":{"value":{"error":{"message":"The model did not respond in time. Please retry.","type":"api_error","code":"timeout","param":null}}}}}}}}}},"/v1/messages":{"post":{"operationId":"createMessage","tags":["Messages"],"summary":"Create message","description":"Anthropic Messages format. Accepts `x-api-key` or `Authorization: Bearer` (`x-api-key` wins if both are sent), query strings such as `?beta=true`, and the `anthropic-version` / `anthropic-beta` headers.","parameters":[{"name":"x-interodin-session-id","in":"header","required":false,"description":"Optional prompt-cache routing hint, honoured on every generation endpoint (including `count_tokens`). Send the same opaque value (for example a conversation id, at most 128 characters recommended) on every request of one conversation. Never put prompts, personal data or secrets in it.","schema":{"type":"string"}},{"name":"anthropic-version","in":"header","required":false,"description":"Accepted for Anthropic SDK compatibility (a date such as `2023-06-01`). Only well-formed values are honoured.","schema":{"type":"string","examples":["2023-06-01"]}},{"name":"anthropic-beta","in":"header","required":false,"description":"Accepted for Anthropic SDK compatibility (comma-separated feature names). Only well-formed values are honoured.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMessageRequest"},"examples":{"basic":{"value":{"model":"odin-v1","max_tokens":1024,"messages":[{"role":"user","content":"Say hello in Romanian."}]}}}}}},"responses":{"200":{"description":"A message, or an event stream when `stream` is true.","headers":{"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}},"text/event-stream":{"schema":{"type":"string","description":"`event: <type>` + `data: <MessageStreamEvent JSON>` pairs."}}}},"400":{"description":"`invalid_request`, `content_refused`, `unsupported_parameter`, `image_input_not_supported`, `unsupported_content`, `context_length_exceeded`. Rate-limit headers are present only on errors derived from the model's response (for example `context_length_exceeded`); request validation errors are raised before the rate-limit step and carry none.","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"invalid_request":{"value":{"type":"error","error":{"type":"invalid_request_error","message":"The request is invalid."}}},"content_refused":{"value":{"type":"error","error":{"type":"invalid_request_error","message":"The model declined this request. Rephrase it and try again."}}},"unsupported_parameter":{"value":{"type":"error","error":{"type":"invalid_request_error","message":"A request parameter is not supported."}}},"image_input_not_supported":{"value":{"type":"error","error":{"type":"invalid_request_error","message":"This model does not accept image input."}}},"unsupported_content":{"value":{"type":"error","error":{"type":"invalid_request_error","message":"This content type (file or document input) is not supported."}}},"context_length_exceeded":{"value":{"type":"error","error":{"type":"invalid_request_error","message":"The request exceeds the model's context window. Shorten the input or lower the maximum output tokens."}}}}}}},"401":{"description":"`invalid_api_key`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"invalid_api_key":{"value":{"type":"error","error":{"type":"authentication_error","message":"Invalid or missing API key."}}}}}}},"402":{"description":"`insufficient_credits`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"insufficient_credits":{"value":{"type":"error","error":{"type":"billing_error","message":"Your organization has no remaining credit. Top up to continue."}}}}}}},"403":{"description":"`model_not_allowed`, `key_spend_limit_reached`, `organization_suspended`. Rate-limit headers are present for `key_spend_limit_reached` only.","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"model_not_allowed":{"value":{"type":"error","error":{"type":"permission_error","message":"This API key is not allowed to use this model."}}},"key_spend_limit_reached":{"value":{"type":"error","error":{"type":"permission_error","message":"This API key has reached its monthly spend limit."}}},"organization_suspended":{"value":{"type":"error","error":{"type":"permission_error","message":"This organization is suspended. Contact support."}}}}}}},"404":{"description":"`model_not_found`, `not_found`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"model_not_found":{"value":{"type":"error","error":{"type":"not_found_error","message":"The requested model does not exist."}}},"not_found":{"value":{"type":"error","error":{"type":"not_found_error","message":"Not found."}}}}}}},"413":{"description":"`request_too_large`. Rate-limit headers are present only when the 413 came from the model.","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"request_too_large":{"value":{"type":"error","error":{"type":"request_too_large","message":"The request body exceeds the 10 MB limit."}}}}}}},"429":{"description":"`rate_limit_exceeded`, `concurrency_limit`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"},"retry-after":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"rate_limit_exceeded":{"value":{"type":"error","error":{"type":"rate_limit_error","message":"Rate limit exceeded. Retry after the number of seconds in the Retry-After header."}}},"concurrency_limit":{"value":{"type":"error","error":{"type":"rate_limit_error","message":"Too many concurrent requests for this organization. Retry shortly."}}}}}}},"500":{"description":"`internal_error`. Some `internal_error` responses are raised before the rate-limit step and carry no rate-limit headers.","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"internal_error":{"value":{"type":"error","error":{"type":"api_error","message":"Internal error. Please retry."}}}}}}},"502":{"description":"`upstream_unavailable`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"upstream_unavailable":{"value":{"type":"error","error":{"type":"api_error","message":"The model is temporarily unavailable. Please retry."}}}}}}},"504":{"description":"`timeout`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"timeout":{"value":{"type":"error","error":{"type":"timeout_error","message":"The model did not respond in time. Please retry."}}}}}}}}}},"/v1/messages/count_tokens":{"post":{"operationId":"countMessageTokens","tags":["Messages"],"summary":"Count message tokens","description":"Counts the input tokens of a Messages request without running the model. Free: never billed, and it works even when the balance is zero. It counts toward rate limits.","parameters":[{"name":"x-interodin-session-id","in":"header","required":false,"description":"Optional prompt-cache routing hint, honoured on every generation endpoint (including `count_tokens`). Send the same opaque value (for example a conversation id, at most 128 characters recommended) on every request of one conversation. Never put prompts, personal data or secrets in it.","schema":{"type":"string"}},{"name":"anthropic-version","in":"header","required":false,"description":"Accepted for Anthropic SDK compatibility (a date such as `2023-06-01`). Only well-formed values are honoured.","schema":{"type":"string","examples":["2023-06-01"]}},{"name":"anthropic-beta","in":"header","required":false,"description":"Accepted for Anthropic SDK compatibility (comma-separated feature names). Only well-formed values are honoured.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountTokensRequest"},"examples":{"basic":{"value":{"model":"odin-v1","messages":[{"role":"user","content":"How many tokens is this?"}]}}}}}},"responses":{"200":{"description":"The input token count.","headers":{"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountTokensResponse"}}}},"400":{"description":"`invalid_request`, `content_refused`, `unsupported_parameter`, `image_input_not_supported`, `unsupported_content`, `context_length_exceeded`. Rate-limit headers are present only on errors derived from the model's response (for example `context_length_exceeded`); request validation errors are raised before the rate-limit step and carry none.","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"invalid_request":{"value":{"type":"error","error":{"type":"invalid_request_error","message":"The request is invalid."}}},"content_refused":{"value":{"type":"error","error":{"type":"invalid_request_error","message":"The model declined this request. Rephrase it and try again."}}},"unsupported_parameter":{"value":{"type":"error","error":{"type":"invalid_request_error","message":"A request parameter is not supported."}}},"image_input_not_supported":{"value":{"type":"error","error":{"type":"invalid_request_error","message":"This model does not accept image input."}}},"unsupported_content":{"value":{"type":"error","error":{"type":"invalid_request_error","message":"This content type (file or document input) is not supported."}}},"context_length_exceeded":{"value":{"type":"error","error":{"type":"invalid_request_error","message":"The request exceeds the model's context window. Shorten the input or lower the maximum output tokens."}}}}}}},"401":{"description":"`invalid_api_key`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"invalid_api_key":{"value":{"type":"error","error":{"type":"authentication_error","message":"Invalid or missing API key."}}}}}}},"402":{"description":"`insufficient_credits`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"insufficient_credits":{"value":{"type":"error","error":{"type":"billing_error","message":"Your organization has no remaining credit. Top up to continue."}}}}}}},"403":{"description":"`model_not_allowed`, `key_spend_limit_reached`, `organization_suspended`. Rate-limit headers are present for `key_spend_limit_reached` only.","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"model_not_allowed":{"value":{"type":"error","error":{"type":"permission_error","message":"This API key is not allowed to use this model."}}},"key_spend_limit_reached":{"value":{"type":"error","error":{"type":"permission_error","message":"This API key has reached its monthly spend limit."}}},"organization_suspended":{"value":{"type":"error","error":{"type":"permission_error","message":"This organization is suspended. Contact support."}}}}}}},"404":{"description":"`model_not_found`, `not_found`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"model_not_found":{"value":{"type":"error","error":{"type":"not_found_error","message":"The requested model does not exist."}}},"not_found":{"value":{"type":"error","error":{"type":"not_found_error","message":"Not found."}}}}}}},"413":{"description":"`request_too_large`. Rate-limit headers are present only when the 413 came from the model.","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"request_too_large":{"value":{"type":"error","error":{"type":"request_too_large","message":"The request body exceeds the 10 MB limit."}}}}}}},"429":{"description":"`rate_limit_exceeded`, `concurrency_limit`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"},"retry-after":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"rate_limit_exceeded":{"value":{"type":"error","error":{"type":"rate_limit_error","message":"Rate limit exceeded. Retry after the number of seconds in the Retry-After header."}}},"concurrency_limit":{"value":{"type":"error","error":{"type":"rate_limit_error","message":"Too many concurrent requests for this organization. Retry shortly."}}}}}}},"500":{"description":"`internal_error`. Some `internal_error` responses are raised before the rate-limit step and carry no rate-limit headers.","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"internal_error":{"value":{"type":"error","error":{"type":"api_error","message":"Internal error. Please retry."}}}}}}},"502":{"description":"`upstream_unavailable`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"upstream_unavailable":{"value":{"type":"error","error":{"type":"api_error","message":"The model is temporarily unavailable. Please retry."}}}}}}},"504":{"description":"`timeout`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"},"x-ratelimit-limit-requests":{"$ref":"#/components/headers/XRatelimitLimitRequests"},"x-ratelimit-remaining-requests":{"$ref":"#/components/headers/XRatelimitRemainingRequests"},"x-ratelimit-reset-requests":{"$ref":"#/components/headers/XRatelimitResetRequests"},"x-ratelimit-limit-tokens":{"$ref":"#/components/headers/XRatelimitLimitTokens"},"x-ratelimit-remaining-tokens":{"$ref":"#/components/headers/XRatelimitRemainingTokens"},"x-ratelimit-reset-tokens":{"$ref":"#/components/headers/XRatelimitResetTokens"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"},"examples":{"timeout":{"value":{"type":"error","error":{"type":"timeout_error","message":"The model did not respond in time. Please retry."}}}}}}}}}},"/v1/models":{"get":{"operationId":"listModels","tags":["Models"],"summary":"List models","description":"Lists the models your key may call. A key restricted to some models lists only those. OpenAI format by default; Anthropic format when the request carries an `anthropic-version` header. It sends `x-request-id` but no rate-limit headers. In practice only `invalid_api_key` (401), `organization_suspended` (403), `not_found` (404) and `internal_error` (500) occur here; the other error statuses are listed for completeness.","parameters":[{"name":"anthropic-version","in":"header","required":false,"description":"When present, the list and any error use the Anthropic format (what Anthropic SDKs expect).","schema":{"type":"string","examples":["2023-06-01"]}}],"responses":{"200":{"description":"The models your key may call.","headers":{"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ModelList"},{"$ref":"#/components/schemas/AnthropicModelList"}]}}}},"400":{"description":"`invalid_request`, `content_refused`, `unsupported_parameter`, `image_input_not_supported`, `unsupported_content`, `context_length_exceeded`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/OpenAIError"},{"$ref":"#/components/schemas/AnthropicError"}]},"examples":{"invalid_request":{"value":{"error":{"message":"The request is invalid.","type":"invalid_request_error","code":"invalid_request","param":null}}},"content_refused":{"value":{"error":{"message":"The model declined this request. Rephrase it and try again.","type":"invalid_request_error","code":"content_refused","param":null}}},"unsupported_parameter":{"value":{"error":{"message":"A request parameter is not supported.","type":"invalid_request_error","code":"unsupported_parameter","param":null}}},"image_input_not_supported":{"value":{"error":{"message":"This model does not accept image input.","type":"invalid_request_error","code":"image_input_not_supported","param":null}}},"unsupported_content":{"value":{"error":{"message":"This content type (file or document input) is not supported.","type":"invalid_request_error","code":"unsupported_content","param":null}}},"context_length_exceeded":{"value":{"error":{"message":"The request exceeds the model's context window. Shorten the input or lower the maximum output tokens.","type":"invalid_request_error","code":"context_length_exceeded","param":null}}}}}}},"401":{"description":"`invalid_api_key`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/OpenAIError"},{"$ref":"#/components/schemas/AnthropicError"}]},"examples":{"invalid_api_key":{"value":{"error":{"message":"Invalid or missing API key.","type":"authentication_error","code":"invalid_api_key","param":null}}}}}}},"402":{"description":"`insufficient_credits`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/OpenAIError"},{"$ref":"#/components/schemas/AnthropicError"}]},"examples":{"insufficient_credits":{"value":{"error":{"message":"Your organization has no remaining credit. Top up to continue.","type":"insufficient_quota","code":"insufficient_credits","param":null}}}}}}},"403":{"description":"`model_not_allowed`, `key_spend_limit_reached`, `organization_suspended`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/OpenAIError"},{"$ref":"#/components/schemas/AnthropicError"}]},"examples":{"model_not_allowed":{"value":{"error":{"message":"This API key is not allowed to use this model.","type":"permission_error","code":"model_not_allowed","param":null}}},"key_spend_limit_reached":{"value":{"error":{"message":"This API key has reached its monthly spend limit.","type":"permission_error","code":"key_spend_limit_reached","param":null}}},"organization_suspended":{"value":{"error":{"message":"This organization is suspended. Contact support.","type":"permission_error","code":"organization_suspended","param":null}}}}}}},"404":{"description":"`model_not_found`, `not_found`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/OpenAIError"},{"$ref":"#/components/schemas/AnthropicError"}]},"examples":{"model_not_found":{"value":{"error":{"message":"The requested model does not exist.","type":"invalid_request_error","code":"model_not_found","param":null}}},"not_found":{"value":{"error":{"message":"Not found.","type":"invalid_request_error","code":"not_found","param":null}}}}}}},"413":{"description":"`request_too_large`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/OpenAIError"},{"$ref":"#/components/schemas/AnthropicError"}]},"examples":{"request_too_large":{"value":{"error":{"message":"The request body exceeds the 10 MB limit.","type":"invalid_request_error","code":"request_too_large","param":null}}}}}}},"429":{"description":"`rate_limit_exceeded`, `concurrency_limit`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/OpenAIError"},{"$ref":"#/components/schemas/AnthropicError"}]},"examples":{"rate_limit_exceeded":{"value":{"error":{"message":"Rate limit exceeded. Retry after the number of seconds in the Retry-After header.","type":"rate_limit_error","code":"rate_limit_exceeded","param":null}}},"concurrency_limit":{"value":{"error":{"message":"Too many concurrent requests for this organization. Retry shortly.","type":"rate_limit_error","code":"concurrency_limit","param":null}}}}}}},"500":{"description":"`internal_error`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/OpenAIError"},{"$ref":"#/components/schemas/AnthropicError"}]},"examples":{"internal_error":{"value":{"error":{"message":"Internal error. Please retry.","type":"api_error","code":"internal_error","param":null}}}}}}},"502":{"description":"`upstream_unavailable`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/OpenAIError"},{"$ref":"#/components/schemas/AnthropicError"}]},"examples":{"upstream_unavailable":{"value":{"error":{"message":"The model is temporarily unavailable. Please retry.","type":"api_error","code":"upstream_unavailable","param":null}}}}}}},"504":{"description":"`timeout`","headers":{"x-interodin-error-code":{"$ref":"#/components/headers/ErrorCode"},"x-request-id":{"$ref":"#/components/headers/RequestId"}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/OpenAIError"},{"$ref":"#/components/schemas/AnthropicError"}]},"examples":{"timeout":{"value":{"error":{"message":"The model did not respond in time. Please retry.","type":"api_error","code":"timeout","param":null}}}}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Your API key: `Authorization: Bearer io-sk-…`. If a request also sends `x-api-key`, `x-api-key` wins."},"apiKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key","description":"Your API key: `x-api-key: io-sk-…`. Wins over `Authorization: Bearer` when both are sent."}},"headers":{"RequestId":{"description":"Unique id of this request (ULID). Sent on every response. Quote it when contacting support.","schema":{"type":"string"}},"ErrorCode":{"description":"The error code, the same value as `error.code` in the OpenAI format. In the Anthropic format several codes share one `error.type`, so branch on this header.","schema":{"type":"string"}},"RetryAfter":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":0}},"XRatelimitLimitRequests":{"description":"Requests allowed per minute, for whichever of your key or organization is closer to its limit. Sent by the generation endpoints once a request has reached the rate-limit step; errors raised earlier (authentication, request validation, model lookup, a model that is not allowed, a suspended organization) carry none.","schema":{"type":"string"}},"XRatelimitRemainingRequests":{"description":"Requests left in the current window. Sent by the generation endpoints once a request has reached the rate-limit step; errors raised earlier (authentication, request validation, model lookup, a model that is not allowed, a suspended organization) carry none.","schema":{"type":"string"}},"XRatelimitResetRequests":{"description":"Time until the request window frees capacity, in whole seconds with an `s` suffix (for example `12s`). Sent by the generation endpoints once a request has reached the rate-limit step; errors raised earlier (authentication, request validation, model lookup, a model that is not allowed, a suspended organization) carry none.","schema":{"type":"string"}},"XRatelimitLimitTokens":{"description":"Tokens (input + output) allowed per minute, for whichever of your key or organization is closer to its limit. Sent by the generation endpoints once a request has reached the rate-limit step; errors raised earlier (authentication, request validation, model lookup, a model that is not allowed, a suspended organization) carry none.","schema":{"type":"string"}},"XRatelimitRemainingTokens":{"description":"Tokens left in the current window. Sent by the generation endpoints once a request has reached the rate-limit step; errors raised earlier (authentication, request validation, model lookup, a model that is not allowed, a suspended organization) carry none.","schema":{"type":"string"}},"XRatelimitResetTokens":{"description":"Time until the token window frees capacity, in whole seconds with an `s` suffix (for example `12s`). Sent by the generation endpoints once a request has reached the rate-limit step; errors raised earlier (authentication, request validation, model lookup, a model that is not allowed, a suspended organization) carry none.","schema":{"type":"string"}}},"schemas":{"PublicModelId":{"type":"string","pattern":"^odin-[a-z0-9.-]+$","description":"A public InterOdin model id, for example `odin-v1`.","examples":["odin-v1"]},"JsonSchemaObject":{"type":"object","description":"A JSON Schema (draft 2020-12) object.","additionalProperties":true},"OpenAIError":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["message","type","code","param"],"properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string","enum":["invalid_request","content_refused","unsupported_parameter","image_input_not_supported","unsupported_content","context_length_exceeded","invalid_api_key","insufficient_credits","model_not_allowed","key_spend_limit_reached","organization_suspended","model_not_found","not_found","request_too_large","rate_limit_exceeded","concurrency_limit","internal_error","upstream_unavailable","timeout"]},"param":{"type":["string","null"]}}}}},"AnthropicError":{"type":"object","required":["type","error"],"properties":{"type":{"type":"string","const":"error"},"error":{"type":"object","required":["type","message"],"properties":{"type":{"type":"string"},"message":{"type":"string"}}}}},"ChatContentPart":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["text","image_url"]},"text":{"type":"string"},"image_url":{"type":"object","properties":{"url":{"type":"string"},"detail":{"type":"string","enum":["auto","low","high"]}},"required":["url"]}},"description":"`image_url` parts are accepted only by models with vision. Odin v1 is text-only: an image in the newest message returns `400 image_input_not_supported`, while an image in a tool message or an earlier turn is replaced by a text note. File input (`file` parts) returns `400 unsupported_content` for every model when it is in the newest message (and is replaced by a note elsewhere)."},"ChatToolCall":{"type":"object","required":["id","type","function"],"properties":{"id":{"type":"string"},"type":{"type":"string","const":"function"},"function":{"type":"object","required":["name","arguments"],"properties":{"name":{"type":"string"},"arguments":{"type":"string","description":"JSON-encoded arguments."}}}}},"ChatMessage":{"type":"object","required":["role"],"properties":{"role":{"type":"string","enum":["system","developer","user","assistant","tool"]},"content":{"anyOf":[{"type":"string"},{"type":"array","items":{"$ref":"#/components/schemas/ChatContentPart"}},{"type":"null"}]},"name":{"type":"string"},"tool_calls":{"type":"array","items":{"$ref":"#/components/schemas/ChatToolCall"}},"tool_call_id":{"type":"string","description":"Required when `role` is `tool`."}}},"ChatTool":{"description":"Function (client) tools and `custom` tools are kept. Any other tool type (web search, file search, code interpreter, MCP and the like) is removed from the request without an error.","anyOf":[{"$ref":"#/components/schemas/ChatFunctionTool"},{"$ref":"#/components/schemas/ChatCustomTool"},{"$ref":"#/components/schemas/ChatOtherTool"},{"$ref":"#/components/schemas/ChatUntypedTool"}]},"ChatUntypedTool":{"type":"object","description":"A tool object with no `type`. The gateway treats it as a client tool and keeps it.","not":{"required":["type"]}},"ChatCustomTool":{"type":"object","description":"A `custom` tool: the model sends free-form text input instead of JSON arguments.","required":["type","custom"],"properties":{"type":{"type":"string","const":"custom"},"custom":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"description":{"type":"string"},"format":{"type":"object"}}}}},"ChatOtherTool":{"type":"object","description":"Any other tool type. Accepted, then removed from the request without an error.","required":["type"],"properties":{"type":{"type":"string","not":{"enum":["function","custom"]}}}},"ChatFunctionTool":{"type":"object","required":["type","function"],"properties":{"type":{"type":"string","const":"function"},"function":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"description":{"type":"string"},"parameters":{"$ref":"#/components/schemas/JsonSchemaObject"},"strict":{"type":"boolean"}}}}},"ChatResponseFormat":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["text","json_object","json_schema"]},"json_schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"description":{"type":"string"},"schema":{"$ref":"#/components/schemas/JsonSchemaObject"},"strict":{"type":"boolean"}}}}},"CreateChatCompletionRequest":{"type":"object","required":["model","messages"],"properties":{"model":{"type":"string","description":"Model id, for example `odin-v1`.","examples":["odin-v1"]},"messages":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/ChatMessage"}},"stream":{"type":"boolean","default":false,"description":"Stream the reply as server-sent events."},"stream_options":{"type":"object","properties":{"include_usage":{"type":"boolean","description":"Always on: the last chunk carries `usage`."}}},"max_tokens":{"type":"integer","minimum":1,"description":"Clamped to the model maximum. 0 or less returns 400."},"max_completion_tokens":{"type":"integer","minimum":1,"description":"Alias of `max_tokens`. 0 or less returns 400."},"temperature":{"type":"number","minimum":0,"maximum":2},"top_p":{"type":"number","minimum":0,"maximum":1},"stop":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"},"maxItems":4}]},"seed":{"type":"integer"},"presence_penalty":{"type":"number","minimum":-2,"maximum":2},"frequency_penalty":{"type":"number","minimum":-2,"maximum":2},"tools":{"type":"array","items":{"$ref":"#/components/schemas/ChatTool"},"description":"Function tools and `custom` tools. Any other tool type is removed from the request without an error, as are `web_search_options` and a `tool_choice` that names a removed tool."},"store":{"type":"boolean","description":"Ignored: nothing is stored. Always sent as `false`."},"metadata":{"type":"object","description":"Ignored and not forwarded."},"tool_choice":{"anyOf":[{"type":"string","enum":["none","auto","required"]},{"type":"object","required":["type","function"],"properties":{"type":{"type":"string","const":"function"},"function":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}}}},{"type":"object","required":["type","custom"],"properties":{"type":{"type":"string","const":"custom"},"custom":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}}}}]},"parallel_tool_calls":{"type":"boolean"},"response_format":{"$ref":"#/components/schemas/ChatResponseFormat"},"reasoning_effort":{"type":"string","enum":["none","minimal","low","medium","high","xhigh","max"],"description":"Reasoning is on or off, with no levels. `none` turns it off on Odin Flash; it does not on Odin v1. The other values are accepted and change nothing."},"include_reasoning":{"type":"boolean","description":"Set `false` to omit `reasoning` from the reply. Reasoning tokens are still billed as output."},"prompt_cache_key":{"type":"string","maxLength":1024,"description":"Prompt-cache routing hint. Same value for every request of one conversation. Forwarded only as a hash specific to your organization; not stored. A string of at most 1024 characters is accepted, `null` removes the field and any other value returns `400 invalid_request`."},"user":{"type":"string","maxLength":1024,"description":"Your end-user id. Forwarded only as a hash specific to your organization; not stored. A string of at most 1024 characters is accepted, `null` removes the field and any other value returns `400 invalid_request`."},"safety_identifier":{"type":"string","maxLength":1024,"description":"A stable identifier for the end user, for abuse detection. Forwarded only as a hash specific to your organization; not stored. A string of at most 1024 characters is accepted, `null` removes the field and any other value returns `400 invalid_request`."}}},"ChatUsage":{"type":"object","required":["prompt_tokens","completion_tokens","total_tokens"],"properties":{"prompt_tokens":{"type":"integer","minimum":0},"completion_tokens":{"type":"integer","minimum":0},"total_tokens":{"type":"integer","minimum":0},"prompt_tokens_details":{"type":["object","null"],"properties":{"cached_tokens":{"type":"integer","minimum":0,"description":"Input tokens read from the prompt cache."}}},"completion_tokens_details":{"type":["object","null"],"properties":{"reasoning_tokens":{"type":"integer","minimum":0}}}}},"ChatCompletion":{"type":"object","required":["id","object","created","model","choices"],"properties":{"id":{"type":"string"},"object":{"type":"string","const":"chat.completion"},"created":{"type":"integer"},"model":{"$ref":"#/components/schemas/PublicModelId"},"choices":{"type":"array","items":{"type":"object","required":["index","message","finish_reason"],"properties":{"index":{"type":"integer"},"message":{"type":"object","required":["role","content"],"properties":{"role":{"type":"string","const":"assistant"},"content":{"type":["string","null"]},"reasoning":{"type":["string","null"],"description":"The reasoning trace, when returned."},"refusal":{"type":["string","null"]},"tool_calls":{"type":"array","items":{"$ref":"#/components/schemas/ChatToolCall"}}}},"finish_reason":{"type":["string","null"],"enum":["stop","length","tool_calls","content_filter",null]}}}},"usage":{"$ref":"#/components/schemas/ChatUsage"}}},"ChatCompletionChunk":{"type":"object","required":["id","object","created","model","choices"],"properties":{"id":{"type":"string"},"object":{"type":"string","const":"chat.completion.chunk"},"created":{"type":"integer"},"model":{"$ref":"#/components/schemas/PublicModelId"},"choices":{"type":"array","items":{"type":"object","required":["index","delta"],"properties":{"index":{"type":"integer"},"delta":{"type":"object","properties":{"role":{"type":"string","const":"assistant"},"content":{"type":["string","null"]},"reasoning":{"type":["string","null"]},"tool_calls":{"type":"array","items":{"type":"object","required":["index"],"properties":{"index":{"type":"integer"},"id":{"type":"string"},"type":{"type":"string","const":"function"},"function":{"type":"object","properties":{"name":{"type":"string"},"arguments":{"type":"string"}}}}}}}},"finish_reason":{"type":["string","null"],"enum":["stop","length","tool_calls","content_filter",null]}}}},"usage":{"anyOf":[{"$ref":"#/components/schemas/ChatUsage"},{"type":"null"}],"description":"Present on the final chunk only."}}},"ChatCompletionStreamPayload":{"description":"The JSON in each `data:` line of a Chat Completions stream. The stream ends with `data: [DONE]`. A failure mid-stream is sent as an error object.","anyOf":[{"$ref":"#/components/schemas/ChatCompletionChunk"},{"$ref":"#/components/schemas/OpenAIError"}]},"ResponseInputItem":{"type":"object","description":"A message (`role` + `content`), a `function_call` you received earlier, or a `function_call_output` with your tool result. `item_reference` items return `400 invalid_request`; `input_image` parts return `400 image_input_not_supported` on text-only models; `input_file` parts return `400 unsupported_content`.","properties":{"type":{"type":"string","enum":["message","function_call","function_call_output","reasoning"]},"role":{"type":"string","enum":["system","developer","user","assistant"]},"content":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["input_text","input_image","output_text"]},"text":{"type":"string"},"image_url":{"type":"string"}}}}]},"call_id":{"type":"string"},"name":{"type":"string"},"arguments":{"type":"string"},"output":{"type":"string"}}},"ResponseTool":{"description":"Function (client) tools and `custom` tools are kept. Hosted and server tools (web search, file search, code interpreter, MCP and others) are removed from the request without an error.","anyOf":[{"$ref":"#/components/schemas/ResponseFunctionTool"},{"$ref":"#/components/schemas/ResponseCustomTool"},{"$ref":"#/components/schemas/ResponseOtherTool"},{"$ref":"#/components/schemas/ResponseUntypedTool"}]},"ResponseUntypedTool":{"type":"object","description":"A tool object with no `type`. The gateway treats it as a client tool and keeps it.","not":{"required":["type"]}},"ResponseCustomTool":{"type":"object","description":"A `custom` tool: the model sends free-form text input instead of JSON arguments.","required":["type","name"],"properties":{"type":{"type":"string","const":"custom"},"name":{"type":"string"},"description":{"type":"string"},"format":{"type":"object"}}},"ResponseOtherTool":{"type":"object","description":"Any other tool type. Accepted, then removed from the request without an error.","required":["type"],"properties":{"type":{"type":"string","not":{"enum":["function","custom"]}}}},"ResponseFunctionTool":{"type":"object","required":["type","name"],"properties":{"type":{"type":"string","const":"function"},"name":{"type":"string"},"description":{"type":"string"},"parameters":{"$ref":"#/components/schemas/JsonSchemaObject"},"strict":{"type":"boolean"}}},"CreateResponseRequest":{"type":"object","required":["model","input"],"properties":{"model":{"type":"string","examples":["odin-v1"]},"input":{"anyOf":[{"type":"string"},{"type":"array","items":{"$ref":"#/components/schemas/ResponseInputItem"}}]},"instructions":{"type":"string","description":"System-level instructions."},"stream":{"type":"boolean","default":false},"store":{"type":"boolean","description":"Responses are never stored. Any value you send is treated as `false`."},"previous_response_id":{"type":"string","deprecated":true,"description":"Not supported. Requests that set it fail with `400 unsupported_parameter`. Send the full conversation in `input`."},"conversation":{"deprecated":true,"description":"Not supported. Requests that set it fail with `400 unsupported_parameter`."},"background":{"type":"boolean","deprecated":true,"description":"Not supported. `true` fails with `400 unsupported_parameter`."},"prompt":{"type":"object","deprecated":true,"description":"Stored prompt templates are not supported. Requests that set it fail with `400 invalid_request`."},"tools":{"type":"array","items":{"$ref":"#/components/schemas/ResponseTool"},"description":"Function tools and `custom` tools. Hosted tools (web search, file search, code interpreter, MCP and others) are removed from the request without an error, as is a `tool_choice` that names a removed tool."},"tool_choice":{"anyOf":[{"type":"string","enum":["none","auto","required"]},{"type":"object","required":["type","name"],"properties":{"type":{"enum":["function","custom"]},"name":{"type":"string"}}}]},"parallel_tool_calls":{"type":"boolean"},"text":{"type":"object","properties":{"format":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["text","json_object","json_schema"]},"name":{"type":"string"},"schema":{"$ref":"#/components/schemas/JsonSchemaObject"},"strict":{"type":"boolean"}}}}},"reasoning":{"description":"Reasoning is on or off, with no levels. `effort: none` turns it off on Odin Flash; it does not on Odin v1. The other values change nothing.","type":"object","properties":{"effort":{"type":"string","enum":["none","minimal","low","medium","high","xhigh","max"]}}},"max_output_tokens":{"type":"integer","minimum":1,"description":"Clamped to the model maximum. 0 or less returns 400."},"temperature":{"type":"number","minimum":0,"maximum":2},"top_p":{"type":"number","minimum":0,"maximum":1},"metadata":{"type":"object","description":"Accepted and ignored: not forwarded."},"prompt_cache_key":{"type":"string","maxLength":1024,"description":"Prompt-cache routing hint. Same value for every request of one conversation. Forwarded only as a hash specific to your organization; not stored. A string of at most 1024 characters is accepted, `null` removes the field and any other value returns `400 invalid_request`."},"user":{"type":"string","maxLength":1024,"description":"Your end-user id. Forwarded only as a hash specific to your organization; not stored. A string of at most 1024 characters is accepted, `null` removes the field and any other value returns `400 invalid_request`."},"safety_identifier":{"type":"string","maxLength":1024,"description":"A stable identifier for the end user, for abuse detection. Forwarded only as a hash specific to your organization; not stored. A string of at most 1024 characters is accepted, `null` removes the field and any other value returns `400 invalid_request`."}}},"ResponseOutputItem":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["message","function_call","reasoning"]},"id":{"type":"string"},"status":{"type":"string"},"role":{"type":"string","const":"assistant"},"content":{"type":"array","items":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["output_text","refusal","reasoning_text"]},"text":{"type":"string"},"annotations":{"type":"array","items":{"type":"object"}}}}},"summary":{"type":"array","items":{"type":"object"}},"call_id":{"type":"string"},"name":{"type":"string"},"arguments":{"type":"string"}},"allOf":[{"if":{"properties":{"type":{"const":"function_call"}},"required":["type"]},"then":{"required":["call_id","name","arguments"]}}]},"ResponseUsage":{"type":"object","required":["input_tokens","output_tokens","total_tokens"],"properties":{"input_tokens":{"type":"integer","minimum":0},"input_tokens_details":{"type":"object","properties":{"cached_tokens":{"type":"integer","minimum":0}}},"output_tokens":{"type":"integer","minimum":0},"output_tokens_details":{"type":"object","properties":{"reasoning_tokens":{"type":"integer","minimum":0}}},"total_tokens":{"type":"integer","minimum":0}}},"Response":{"type":"object","required":["id","object","created_at","status","model","output"],"properties":{"id":{"type":"string"},"object":{"type":"string","const":"response"},"created_at":{"type":"integer"},"status":{"type":"string","enum":["completed","incomplete","failed","in_progress","queued"]},"model":{"$ref":"#/components/schemas/PublicModelId"},"output":{"type":"array","items":{"$ref":"#/components/schemas/ResponseOutputItem"}},"usage":{"anyOf":[{"$ref":"#/components/schemas/ResponseUsage"},{"type":"null"}]},"store":{"type":"boolean","const":false},"error":{"type":["object","null"]},"incomplete_details":{"type":["object","null"]}}},"ResponseStreamEvent":{"type":"object","description":"One server-sent event of a Responses stream (`event:` line = `type`). Usage arrives on `response.completed`.","required":["type"],"properties":{"type":{"type":"string"},"sequence_number":{"type":"integer"}},"allOf":[{"if":{"properties":{"type":{"enum":["response.created","response.in_progress","response.completed","response.failed","response.incomplete"]}},"required":["type"]},"then":{"required":["response"],"properties":{"response":{"$ref":"#/components/schemas/Response"}}}},{"if":{"properties":{"type":{"const":"response.completed"}},"required":["type"]},"then":{"properties":{"response":{"required":["usage"],"properties":{"usage":{"$ref":"#/components/schemas/ResponseUsage"}}}}}},{"if":{"properties":{"type":{"enum":["response.output_item.added","response.output_item.done"]}},"required":["type"]},"then":{"required":["output_index","item"],"properties":{"item":{"$ref":"#/components/schemas/ResponseOutputItem"}}}},{"if":{"properties":{"type":{"enum":["response.output_text.delta","response.function_call_arguments.delta"]}},"required":["type"]},"then":{"required":["delta"],"properties":{"delta":{"type":"string"}}}},{"if":{"properties":{"type":{"const":"error"}},"required":["type"]},"then":{"required":["message"],"properties":{"code":{"type":["string","null"]},"message":{"type":"string"}}}}]},"MessageContentBlockParam":{"type":"object","required":["type"],"description":"`text`, `image` (vision models only; Odin v1 returns `400 image_input_not_supported` for an image in the newest message, and replaces one in a tool result or an earlier turn with a text note), `tool_use`, `tool_result`, `thinking`. `document` blocks return `400 unsupported_content` for every model when they are in the newest message. `cache_control` is accepted and ignored: caching is automatic.","properties":{"type":{"type":"string","enum":["text","image","tool_use","tool_result","thinking","redacted_thinking"]},"text":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"input":{"type":"object"},"tool_use_id":{"type":"string"},"content":{},"is_error":{"type":"boolean"},"cache_control":{"type":"object"}}},"MessageTool":{"description":"A client tool (no `type`, or `type: \"custom\"`) is kept. A tool with any other `type` is accepted and removed from the request without an error.","anyOf":[{"$ref":"#/components/schemas/MessageCustomTool"},{"$ref":"#/components/schemas/MessageOtherTool"}]},"MessageCustomTool":{"type":"object","required":["name","input_schema"],"properties":{"type":{"type":"string","const":"custom"},"name":{"type":"string"},"description":{"type":"string"},"input_schema":{"$ref":"#/components/schemas/JsonSchemaObject"}}},"MessageOtherTool":{"type":"object","description":"A typed server tool such as web search, bash, text editor or computer use.","required":["type"],"properties":{"type":{"type":"string","not":{"const":"custom"}}}},"CreateMessageRequest":{"type":"object","required":["model","max_tokens","messages"],"properties":{"model":{"type":"string","examples":["odin-v1"]},"messages":{"type":"array","minItems":1,"items":{"type":"object","required":["role","content"],"properties":{"role":{"type":"string","enum":["user","assistant"]},"content":{"anyOf":[{"type":"string"},{"type":"array","items":{"$ref":"#/components/schemas/MessageContentBlockParam"}}]}}}},"system":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"object","required":["type","text"],"properties":{"type":{"const":"text"},"text":{"type":"string"}}}}]},"tools":{"type":"array","items":{"$ref":"#/components/schemas/MessageTool"},"description":"Client tools: tools with no `type` or with `type: \"custom\"` (`name`, `description`, `input_schema`). The web search tool (`type: \"web_search_20250305\"`, at most 5 searches per request, billed per search) is also kept. Tools with any other `type` (code execution, bash, text editor, computer use) and `mcp_servers` are removed from the request without an error."},"tool_choice":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["auto","any","tool","none"]},"name":{"type":"string"}}},"thinking":{"type":"object","description":"Thinking is on or off. `disabled` turns it off on both models. `budget_tokens` does not cap it.","required":["type"],"properties":{"type":{"type":"string","enum":["enabled","disabled","adaptive"]},"budget_tokens":{"type":"integer","minimum":1024},"display":{"type":"string","enum":["summarized","omitted"]}}},"output_config":{"type":"object","description":"Accepted and ignored: thinking has no levels.","properties":{"effort":{"type":"string","enum":["low","medium","high","xhigh","max"]}}},"max_tokens":{"type":"integer","minimum":1,"description":"Clamped to the model maximum. 0 or less returns 400."},"stream":{"type":"boolean","default":false},"temperature":{"type":"number","minimum":0,"maximum":1},"top_p":{"type":"number","minimum":0,"maximum":1},"top_k":{"type":"integer","minimum":1},"stop_sequences":{"type":"array","items":{"type":"string"}},"metadata":{"type":"object","description":"Only `user_id` is forwarded, and only as a hash specific to your organization. Other keys are dropped, and a `metadata` that is not an object is ignored.","properties":{"user_id":{"type":"string","maxLength":1024,"description":"Your end-user id. A string of at most 1024 characters is accepted; anything else returns `400 invalid_request`."}}}}},"CountTokensRequest":{"type":"object","required":["model","messages"],"properties":{"model":{"type":"string","examples":["odin-v1"]},"messages":{"type":"array","minItems":1,"items":{"type":"object","required":["role","content"],"properties":{"role":{"type":"string","enum":["user","assistant"]},"content":{"anyOf":[{"type":"string"},{"type":"array","items":{"$ref":"#/components/schemas/MessageContentBlockParam"}}]}}}},"system":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"object","required":["type","text"],"properties":{"type":{"const":"text"},"text":{"type":"string"}}}}]},"tools":{"type":"array","items":{"$ref":"#/components/schemas/MessageTool"},"description":"Client tools: tools with no `type` or with `type: \"custom\"` (`name`, `description`, `input_schema`). The web search tool (`type: \"web_search_20250305\"`, at most 5 searches per request, billed per search) is also kept. Tools with any other `type` (code execution, bash, text editor, computer use) and `mcp_servers` are removed from the request without an error."},"tool_choice":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["auto","any","tool","none"]},"name":{"type":"string"}}},"thinking":{"type":"object","description":"Thinking is on or off. `disabled` turns it off on both models. `budget_tokens` does not cap it.","required":["type"],"properties":{"type":{"type":"string","enum":["enabled","disabled","adaptive"]},"budget_tokens":{"type":"integer","minimum":1024},"display":{"type":"string","enum":["summarized","omitted"]}}},"output_config":{"type":"object","description":"Accepted and ignored: thinking has no levels.","properties":{"effort":{"type":"string","enum":["low","medium","high","xhigh","max"]}}}}},"CountTokensResponse":{"type":"object","required":["input_tokens"],"properties":{"input_tokens":{"type":"integer","minimum":0}}},"MessageContentBlock":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["text","thinking","redacted_thinking","tool_use"]},"text":{"type":"string"},"thinking":{"type":"string"},"signature":{"type":"string"},"data":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"input":{"type":"object"}}},"MessageUsage":{"type":"object","required":["input_tokens","output_tokens"],"properties":{"input_tokens":{"type":"integer","minimum":0},"output_tokens":{"type":"integer","minimum":0},"cache_creation_input_tokens":{"type":["integer","null"],"minimum":0},"cache_read_input_tokens":{"type":["integer","null"],"minimum":0,"description":"Input tokens read from the prompt cache."}}},"Message":{"type":"object","required":["id","type","role","model","content","stop_reason","usage"],"properties":{"id":{"type":"string"},"type":{"type":"string","const":"message"},"role":{"type":"string","const":"assistant"},"model":{"$ref":"#/components/schemas/PublicModelId"},"content":{"type":"array","items":{"$ref":"#/components/schemas/MessageContentBlock"}},"stop_reason":{"type":["string","null"],"enum":["end_turn","max_tokens","stop_sequence","tool_use","pause_turn","refusal",null]},"stop_sequence":{"type":["string","null"]},"usage":{"$ref":"#/components/schemas/MessageUsage"}}},"MessageStreamEvent":{"description":"One server-sent event of a Messages stream. The `event:` line repeats `type`.","anyOf":[{"type":"object","required":["type","message"],"properties":{"type":{"type":"string","const":"message_start"},"message":{"$ref":"#/components/schemas/Message"}}},{"type":"object","required":["type","index","content_block"],"properties":{"type":{"type":"string","const":"content_block_start"},"index":{"type":"integer"},"content_block":{"$ref":"#/components/schemas/MessageContentBlock"}}},{"type":"object","required":["type","index","delta"],"properties":{"type":{"type":"string","const":"content_block_delta"},"index":{"type":"integer"},"delta":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["text_delta","input_json_delta","thinking_delta","signature_delta"]},"text":{"type":"string"},"partial_json":{"type":"string"},"thinking":{"type":"string"},"signature":{"type":"string"}}}}},{"type":"object","required":["type","index"],"properties":{"type":{"type":"string","const":"content_block_stop"},"index":{"type":"integer"}}},{"type":"object","required":["type","delta","usage"],"properties":{"type":{"type":"string","const":"message_delta"},"delta":{"type":"object","properties":{"stop_reason":{"type":["string","null"]},"stop_sequence":{"type":["string","null"]}}},"usage":{"type":"object","required":["output_tokens"],"properties":{"output_tokens":{"type":"integer","minimum":0},"input_tokens":{"type":["integer","null"]},"cache_read_input_tokens":{"type":["integer","null"]}}}}},{"type":"object","required":["type"],"properties":{"type":{"type":"string","const":"message_stop"}}},{"type":"object","required":["type"],"properties":{"type":{"type":"string","const":"ping"}}},{"$ref":"#/components/schemas/AnthropicError"}]},"Model":{"type":"object","required":["id","object","created","owned_by"],"properties":{"id":{"$ref":"#/components/schemas/PublicModelId"},"object":{"type":"string","const":"model"},"created":{"type":"integer","description":"Unix timestamp of when the model was added."},"owned_by":{"type":"string","const":"interodin"}}},"ModelList":{"type":"object","required":["object","data"],"properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Model"}}}},"AnthropicModel":{"type":"object","required":["type","id","display_name","created_at"],"properties":{"type":{"type":"string","const":"model"},"id":{"$ref":"#/components/schemas/PublicModelId"},"display_name":{"type":"string","examples":["Odin v1"]},"created_at":{"type":"string","format":"date-time"}}},"AnthropicModelList":{"type":"object","description":"Returned when the request carries an `anthropic-version` header (Anthropic SDKs).","required":["data","has_more","first_id","last_id"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AnthropicModel"}},"has_more":{"type":"boolean","const":false},"first_id":{"type":["string","null"]},"last_id":{"type":["string","null"]}}}}}}