{"openapi":"3.1.0","info":{"title":"EagleAI Opus 5","version":"2.17.1","description":"Server-side proxy to Claude Opus 5 on the Messages API.\n\n**Model.** claude-opus-5. Any other model name is refused with 400 and never forwarded upstream — including models this provider serves on other endpoints.\n\n**Request format.** The Messages API, relayed verbatim. Send `messages`, not `input`, and bound the reply with `max_tokens`, not `max_output_tokens`. Replies are the standard Claude format, unmodified.\n\n**Authentication.** Send the shared secret in the X-API-Key header on every request. A missing header is 401, a wrong one is 403, and the endpoint refuses all traffic if the server has no key configured.\n\n**Per-request limits.** 4000 prompt tokens (7800 characters), 3000 output tokens (max_tokens), 7000 tokens in total, 128 input items, 131072 bytes of request body. Requests above any of these are refused locally with 400 or 413; nothing is silently truncated.\n\n**Throughput.** 5 requests/minute and 4 concurrent upstream calls. Over the rate limit is 429 with Retry-After. Over the concurrency limit, a request waits up to 5s for a slot and is then refused with 429 rather than queued indefinitely.\n\n**Fields not accepted.** inference_geo, mcp_servers, service_tier, speed, tool_choice, tools, cache_control. Each of these changes what a request costs upstream in a way a flat per-request price cannot absorb, so they are refused with 400 rather than silently dropped — a stripped field would return a different answer than the one asked for.\n\n**Thinking.** This model reasons before it answers and those tokens are billed against max_tokens without being returned to you. The endpoint sends effort \"medium\" unless you set output_config yourself. There is no setting that disables thinking on this model, so a reply that spends the whole budget thinking and returns no answer is possible; it is refused with 400 empty_reply and not billed to you.\n\n**Streaming.** Set stream=true for text/event-stream. Frames are relayed unbuffered: message_start carries the input token count, and the terminal message_delta carries the output token count.\n\n**Timeout.** 180s, after which the request returns 504."},"paths":{"/api/v1/opus5/messages":{"post":{"operationId":"createMessage","summary":"Create a message","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["model","messages","max_tokens"],"properties":{"model":{"type":"string","description":"Model to run. Only claude-opus-5 is available on this endpoint.","enum":["claude-opus-5"]},"messages":{"type":"array","items":{"type":"object"},"description":"Messages API conversation: a list of {role, content} objects. At most 128 message/content items, and at most 7800 characters of prompt."},"system":{"description":"System prompt, as a string or a list of content blocks. Counts toward the prompt limits above.","oneOf":[{"type":"string"},{"type":"array","items":{"type":"object"}}]},"stream":{"type":"boolean","default":false,"description":"Stream the reply as Server-Sent Events (text/event-stream). Frames are relayed as they arrive and are not buffered."},"max_tokens":{"type":"integer","minimum":1,"maximum":3000,"description":"Maximum tokens to generate, up to 3000. A larger value is rejected rather than clamped, so a truncated reply is never returned as if it were complete. Omitted means the endpoint cap is applied."},"output_config":{"type":"object","description":"Reasoning controls, passed through to the model. This model thinks before it answers, and those thinking tokens are charged against max_tokens without being returned to you. Omitted, this endpoint sends effort \"medium\" against the full 3000-token budget. There is no effort that disables thinking on this model — \"low\" is the floor — so if a reply comes back with no answer in it at all, this endpoint refuses it with 400 empty_reply rather than billing you for it.","properties":{"effort":{"type":"string","enum":["low","medium","high","xhigh","max"],"default":"medium"}},"additionalProperties":true}},"additionalProperties":true}}}},"responses":{"200":{"description":"Messages API reply, verbatim. When stream=true the body is text/event-stream instead: message_start carries the input token count and the terminal message_delta carries the output token count.","content":{"application/json":{"schema":{"type":"object"}},"text/event-stream":{"schema":{"type":"string"}}}},"400":{"description":"Unsupported model, output limit exceeded, per-request token budget exceeded, worst-case cost above this endpoint's ceiling, or a request field this endpoint does not accept (inference_geo, mcp_servers, service_tier, speed, tool_choice, tools, cache_control)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string","description":"Machine-readable refusal reason: model_not_allowed, model_not_available, request_too_large, too_many_input_items, max_output_tokens_too_large, token_budget_exceeded, cost_guard_exceeded, unsupported_field, empty_reply, upstream_error."}}}}}}}},"401":{"description":"Missing X-API-Key"},"403":{"description":"Invalid X-API-Key"},"413":{"description":"Request body, prompt length or input item count above the limit","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string","description":"Machine-readable refusal reason: model_not_allowed, model_not_available, request_too_large, too_many_input_items, max_output_tokens_too_large, token_budget_exceeded, cost_guard_exceeded, unsupported_field, empty_reply, upstream_error."}}}}}}}},"422":{"description":"Malformed request body"},"429":{"description":"Rate limit (5 requests/minute) or concurrency limit (4 in flight) reached, or the upstream throttled the request. Retry-After says when to come back; it is passed through unchanged when it comes from upstream.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Present on every 429 this proxy generates.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string","description":"Machine-readable refusal reason: model_not_allowed, model_not_available, request_too_large, too_many_input_items, max_output_tokens_too_large, token_budget_exceeded, cost_guard_exceeded, unsupported_field, empty_reply, upstream_error."}}}}}}}},"502":{"description":"Upstream failure"},"503":{"description":"Proxy disabled or not configured"},"504":{"description":"Upstream did not respond within 180s"}}}},"/api/v1/opus5/micro/messages":{"post":{"operationId":"createMessageMicro","summary":"micro tier","description":"The same model at a smaller promise: up to 400 prompt tokens and 1,400 of reply, at 5 requests/minute. Oversized requests are refused with 400 here rather than served at this price — send them to a larger tier.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["model","messages","max_tokens"],"properties":{"model":{"type":"string","description":"Model to run. Only claude-opus-5 is available on this endpoint.","enum":["claude-opus-5"]},"messages":{"type":"array","items":{"type":"object"},"description":"Messages API conversation: a list of {role, content} objects. At most 128 message/content items, and at most 1952 characters of prompt."},"system":{"description":"System prompt, as a string or a list of content blocks. Counts toward the prompt limits above.","oneOf":[{"type":"string"},{"type":"array","items":{"type":"object"}}]},"stream":{"type":"boolean","default":false,"description":"Stream the reply as Server-Sent Events (text/event-stream). Frames are relayed as they arrive and are not buffered."},"max_tokens":{"type":"integer","minimum":1,"maximum":1400,"description":"Maximum tokens to generate, up to 1400. A larger value is rejected rather than clamped, so a truncated reply is never returned as if it were complete. Omitted means the endpoint cap is applied."},"output_config":{"type":"object","description":"Reasoning controls, passed through to the model. This model thinks before it answers, and those thinking tokens are charged against max_tokens without being returned to you. Omitted, this endpoint sends effort \"low\" against the full 1400-token budget. There is no effort that disables thinking on this model — \"low\" is the floor — so if a reply comes back with no answer in it at all, this endpoint refuses it with 400 empty_reply rather than billing you for it.","properties":{"effort":{"type":"string","enum":["low","medium","high","xhigh","max"],"default":"low"}},"additionalProperties":true}},"additionalProperties":true}}}},"responses":{"200":{"description":"Messages API reply, verbatim. When stream=true the body is text/event-stream instead: message_start carries the input token count and the terminal message_delta carries the output token count.","content":{"application/json":{"schema":{"type":"object"}},"text/event-stream":{"schema":{"type":"string"}}}},"400":{"description":"Unsupported model, output limit exceeded, per-request token budget exceeded, worst-case cost above this endpoint's ceiling, or a request field this endpoint does not accept (inference_geo, mcp_servers, service_tier, speed, tool_choice, tools, cache_control)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string","description":"Machine-readable refusal reason: model_not_allowed, model_not_available, request_too_large, too_many_input_items, max_output_tokens_too_large, token_budget_exceeded, cost_guard_exceeded, unsupported_field, empty_reply, upstream_error."}}}}}}}},"401":{"description":"Missing X-API-Key"},"403":{"description":"Invalid X-API-Key"},"413":{"description":"Request body, prompt length or input item count above the limit","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string","description":"Machine-readable refusal reason: model_not_allowed, model_not_available, request_too_large, too_many_input_items, max_output_tokens_too_large, token_budget_exceeded, cost_guard_exceeded, unsupported_field, empty_reply, upstream_error."}}}}}}}},"422":{"description":"Malformed request body"},"429":{"description":"Rate limit (5 requests/minute) or concurrency limit (4 in flight) reached, or the upstream throttled the request. Retry-After says when to come back; it is passed through unchanged when it comes from upstream.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Present on every 429 this proxy generates.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string","description":"Machine-readable refusal reason: model_not_allowed, model_not_available, request_too_large, too_many_input_items, max_output_tokens_too_large, token_budget_exceeded, cost_guard_exceeded, unsupported_field, empty_reply, upstream_error."}}}}}}}},"502":{"description":"Upstream failure"},"503":{"description":"Proxy disabled or not configured"},"504":{"description":"Upstream did not respond within 180s"}}}},"/api/v1/opus5/nano/messages":{"post":{"operationId":"createMessageNano","summary":"nano tier","description":"The same model at a smaller promise: up to 800 prompt tokens and 2,000 of reply, at 3 requests/minute. Oversized requests are refused with 400 here rather than served at this price — send them to a larger tier.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["model","messages","max_tokens"],"properties":{"model":{"type":"string","description":"Model to run. Only claude-opus-5 is available on this endpoint.","enum":["claude-opus-5"]},"messages":{"type":"array","items":{"type":"object"},"description":"Messages API conversation: a list of {role, content} objects. At most 128 message/content items, and at most 3904 characters of prompt."},"system":{"description":"System prompt, as a string or a list of content blocks. Counts toward the prompt limits above.","oneOf":[{"type":"string"},{"type":"array","items":{"type":"object"}}]},"stream":{"type":"boolean","default":false,"description":"Stream the reply as Server-Sent Events (text/event-stream). Frames are relayed as they arrive and are not buffered."},"max_tokens":{"type":"integer","minimum":1,"maximum":2000,"description":"Maximum tokens to generate, up to 2000. A larger value is rejected rather than clamped, so a truncated reply is never returned as if it were complete. Omitted means the endpoint cap is applied."},"output_config":{"type":"object","description":"Reasoning controls, passed through to the model. This model thinks before it answers, and those thinking tokens are charged against max_tokens without being returned to you. Omitted, this endpoint sends effort \"low\" against the full 2000-token budget. There is no effort that disables thinking on this model — \"low\" is the floor — so if a reply comes back with no answer in it at all, this endpoint refuses it with 400 empty_reply rather than billing you for it.","properties":{"effort":{"type":"string","enum":["low","medium","high","xhigh","max"],"default":"low"}},"additionalProperties":true}},"additionalProperties":true}}}},"responses":{"200":{"description":"Messages API reply, verbatim. When stream=true the body is text/event-stream instead: message_start carries the input token count and the terminal message_delta carries the output token count.","content":{"application/json":{"schema":{"type":"object"}},"text/event-stream":{"schema":{"type":"string"}}}},"400":{"description":"Unsupported model, output limit exceeded, per-request token budget exceeded, worst-case cost above this endpoint's ceiling, or a request field this endpoint does not accept (inference_geo, mcp_servers, service_tier, speed, tool_choice, tools, cache_control)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string","description":"Machine-readable refusal reason: model_not_allowed, model_not_available, request_too_large, too_many_input_items, max_output_tokens_too_large, token_budget_exceeded, cost_guard_exceeded, unsupported_field, empty_reply, upstream_error."}}}}}}}},"401":{"description":"Missing X-API-Key"},"403":{"description":"Invalid X-API-Key"},"413":{"description":"Request body, prompt length or input item count above the limit","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string","description":"Machine-readable refusal reason: model_not_allowed, model_not_available, request_too_large, too_many_input_items, max_output_tokens_too_large, token_budget_exceeded, cost_guard_exceeded, unsupported_field, empty_reply, upstream_error."}}}}}}}},"422":{"description":"Malformed request body"},"429":{"description":"Rate limit (3 requests/minute) or concurrency limit (4 in flight) reached, or the upstream throttled the request. Retry-After says when to come back; it is passed through unchanged when it comes from upstream.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Present on every 429 this proxy generates.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string","description":"Machine-readable refusal reason: model_not_allowed, model_not_available, request_too_large, too_many_input_items, max_output_tokens_too_large, token_budget_exceeded, cost_guard_exceeded, unsupported_field, empty_reply, upstream_error."}}}}}}}},"502":{"description":"Upstream failure"},"503":{"description":"Proxy disabled or not configured"},"504":{"description":"Upstream did not respond within 180s"}}}},"/api/v1/opus5/small/messages":{"post":{"operationId":"createMessageSmall","summary":"small tier","description":"The same model at a smaller promise: up to 1,200 prompt tokens and 2,400 of reply, at 2 requests/minute. Oversized requests are refused with 400 here rather than served at this price — send them to a larger tier.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["model","messages","max_tokens"],"properties":{"model":{"type":"string","description":"Model to run. Only claude-opus-5 is available on this endpoint.","enum":["claude-opus-5"]},"messages":{"type":"array","items":{"type":"object"},"description":"Messages API conversation: a list of {role, content} objects. At most 128 message/content items, and at most 5856 characters of prompt."},"system":{"description":"System prompt, as a string or a list of content blocks. Counts toward the prompt limits above.","oneOf":[{"type":"string"},{"type":"array","items":{"type":"object"}}]},"stream":{"type":"boolean","default":false,"description":"Stream the reply as Server-Sent Events (text/event-stream). Frames are relayed as they arrive and are not buffered."},"max_tokens":{"type":"integer","minimum":1,"maximum":2400,"description":"Maximum tokens to generate, up to 2400. A larger value is rejected rather than clamped, so a truncated reply is never returned as if it were complete. Omitted means the endpoint cap is applied."},"output_config":{"type":"object","description":"Reasoning controls, passed through to the model. This model thinks before it answers, and those thinking tokens are charged against max_tokens without being returned to you. Omitted, this endpoint sends effort \"low\" against the full 2400-token budget. There is no effort that disables thinking on this model — \"low\" is the floor — so if a reply comes back with no answer in it at all, this endpoint refuses it with 400 empty_reply rather than billing you for it.","properties":{"effort":{"type":"string","enum":["low","medium","high","xhigh","max"],"default":"low"}},"additionalProperties":true}},"additionalProperties":true}}}},"responses":{"200":{"description":"Messages API reply, verbatim. When stream=true the body is text/event-stream instead: message_start carries the input token count and the terminal message_delta carries the output token count.","content":{"application/json":{"schema":{"type":"object"}},"text/event-stream":{"schema":{"type":"string"}}}},"400":{"description":"Unsupported model, output limit exceeded, per-request token budget exceeded, worst-case cost above this endpoint's ceiling, or a request field this endpoint does not accept (inference_geo, mcp_servers, service_tier, speed, tool_choice, tools, cache_control)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string","description":"Machine-readable refusal reason: model_not_allowed, model_not_available, request_too_large, too_many_input_items, max_output_tokens_too_large, token_budget_exceeded, cost_guard_exceeded, unsupported_field, empty_reply, upstream_error."}}}}}}}},"401":{"description":"Missing X-API-Key"},"403":{"description":"Invalid X-API-Key"},"413":{"description":"Request body, prompt length or input item count above the limit","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string","description":"Machine-readable refusal reason: model_not_allowed, model_not_available, request_too_large, too_many_input_items, max_output_tokens_too_large, token_budget_exceeded, cost_guard_exceeded, unsupported_field, empty_reply, upstream_error."}}}}}}}},"422":{"description":"Malformed request body"},"429":{"description":"Rate limit (2 requests/minute) or concurrency limit (4 in flight) reached, or the upstream throttled the request. Retry-After says when to come back; it is passed through unchanged when it comes from upstream.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Present on every 429 this proxy generates.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string","description":"Machine-readable refusal reason: model_not_allowed, model_not_available, request_too_large, too_many_input_items, max_output_tokens_too_large, token_budget_exceeded, cost_guard_exceeded, unsupported_field, empty_reply, upstream_error."}}}}}}}},"502":{"description":"Upstream failure"},"503":{"description":"Proxy disabled or not configured"},"504":{"description":"Upstream did not respond within 180s"}}}},"/api/v1/opus5/medium/messages":{"post":{"operationId":"createMessageMedium","summary":"medium tier","description":"The same model at a smaller promise: up to 1,600 prompt tokens and 2,800 of reply, at 2 requests/minute. Oversized requests are refused with 400 here rather than served at this price — send them to a larger tier.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["model","messages","max_tokens"],"properties":{"model":{"type":"string","description":"Model to run. Only claude-opus-5 is available on this endpoint.","enum":["claude-opus-5"]},"messages":{"type":"array","items":{"type":"object"},"description":"Messages API conversation: a list of {role, content} objects. At most 128 message/content items, and at most 7800 characters of prompt."},"system":{"description":"System prompt, as a string or a list of content blocks. Counts toward the prompt limits above.","oneOf":[{"type":"string"},{"type":"array","items":{"type":"object"}}]},"stream":{"type":"boolean","default":false,"description":"Stream the reply as Server-Sent Events (text/event-stream). Frames are relayed as they arrive and are not buffered."},"max_tokens":{"type":"integer","minimum":1,"maximum":2800,"description":"Maximum tokens to generate, up to 2800. A larger value is rejected rather than clamped, so a truncated reply is never returned as if it were complete. Omitted means the endpoint cap is applied."},"output_config":{"type":"object","description":"Reasoning controls, passed through to the model. This model thinks before it answers, and those thinking tokens are charged against max_tokens without being returned to you. Omitted, this endpoint sends effort \"low\" against the full 2800-token budget. There is no effort that disables thinking on this model — \"low\" is the floor — so if a reply comes back with no answer in it at all, this endpoint refuses it with 400 empty_reply rather than billing you for it.","properties":{"effort":{"type":"string","enum":["low","medium","high","xhigh","max"],"default":"low"}},"additionalProperties":true}},"additionalProperties":true}}}},"responses":{"200":{"description":"Messages API reply, verbatim. When stream=true the body is text/event-stream instead: message_start carries the input token count and the terminal message_delta carries the output token count.","content":{"application/json":{"schema":{"type":"object"}},"text/event-stream":{"schema":{"type":"string"}}}},"400":{"description":"Unsupported model, output limit exceeded, per-request token budget exceeded, worst-case cost above this endpoint's ceiling, or a request field this endpoint does not accept (inference_geo, mcp_servers, service_tier, speed, tool_choice, tools, cache_control)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string","description":"Machine-readable refusal reason: model_not_allowed, model_not_available, request_too_large, too_many_input_items, max_output_tokens_too_large, token_budget_exceeded, cost_guard_exceeded, unsupported_field, empty_reply, upstream_error."}}}}}}}},"401":{"description":"Missing X-API-Key"},"403":{"description":"Invalid X-API-Key"},"413":{"description":"Request body, prompt length or input item count above the limit","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string","description":"Machine-readable refusal reason: model_not_allowed, model_not_available, request_too_large, too_many_input_items, max_output_tokens_too_large, token_budget_exceeded, cost_guard_exceeded, unsupported_field, empty_reply, upstream_error."}}}}}}}},"422":{"description":"Malformed request body"},"429":{"description":"Rate limit (2 requests/minute) or concurrency limit (4 in flight) reached, or the upstream throttled the request. Retry-After says when to come back; it is passed through unchanged when it comes from upstream.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Present on every 429 this proxy generates.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string","description":"Machine-readable refusal reason: model_not_allowed, model_not_available, request_too_large, too_many_input_items, max_output_tokens_too_large, token_budget_exceeded, cost_guard_exceeded, unsupported_field, empty_reply, upstream_error."}}}}}}}},"502":{"description":"Upstream failure"},"503":{"description":"Proxy disabled or not configured"},"504":{"description":"Upstream did not respond within 180s"}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key"}}},"servers":[{"url":"https://eagleai.online"}]}