Messages
Anthropic's Messages API, served so that Anthropic's clients and Claude Code run on HIPS's catalog models (decided 2026-10-29). A claude-* id is unknown on HIPS and answered so, never mapped to another model. The request is served by the chat completions route's own path, so the key, the requirement headers, the limits, the quote, placement and the response headers are those of chat completions; a field the route does not take is a 400 in Anthropic's wording.
/v1/messagesservedAnthropic's Messages API, with x-api-key and anthropic-version: 2023-06-01, in Anthropic's error shape.
# HIPS_BASE_URL is https://ai.hips.com/v1curl "$HIPS_BASE_URL/messages" \ -H "x-api-key: $HIPS_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "Content-Type: application/json" \ -d "{\"model\":\"$HIPS_MODEL\",\"max_tokens\":256,\"messages\":[{\"role\":\"user\",\"content\":\"Explain GPU inference in two sentences.\"}]}"Parts list: Request headers
x-api-keyAcceptedA workspace API key or a person's access token, as Anthropic's clients send it, on this route alone.
Authorization: Bearerworks too; both sent with different values is a 401invalid_api_key, and neither is a 401missing_api_key. Aninference_onlykey and a token with theinferencescope reach the route.anthropic-versionRequired2023-06-01. Absent is a 400missing_required_parameterwith Anthropic's wording,anthropic-version: header is required; another value is a 400invalid_valuenaming the one served.anthropic-betaRead, never refusedThe body's fields decide what is asked for: each field a beta adds is accepted or refused by the rules below.
x-hips-pool, x-hips-pricing-mode, x-hips-region, x-hips-fallbackAcceptedThe requirements, as on chat completions. A person's token takes the workspace's tool defaults.
A query string on the path (Claude Code sends ?beta=true) is ignored. The answer carries the response headers of chat completions, and on a whole answer x-hips-cost-micros and x-hips-latency-ms.
Parts list: Fields
modelRequiredA catalog id, an alias, a pinned id or a router name; unknown is a 404
not_found_errornaming the model.max_tokensRequiredA positive integer, the output cap. Over the model's
max_output_tokensit is a 400 in Anthropic's wording:max_tokens: <asked> > <maximum>, which is the maximum allowed number of output tokens for <model>.messagesRequired, non-emptyRoles
userandassistant, in the content blocks below; the last message is ausermessage. Asystemrole is a 400:messages: Unexpected role "system". The allowed roles are "user" or "assistant". Use the top-levelsystemparameter for the initial system prompt.systemAcceptedA string, or an array of
textblocks.streamAcceptedtruestreams the events below; absent orfalseanswers whole.temperature, top_pAcceptedNumbers from 0 to 1, Anthropic's range.
stop_sequencesAcceptedAt most 16 strings (decided 2026-11-01); more is a 400
invalid_value,stop_sequences: List should have at most 16 items.toolsAcceptedClient tools (
name,description,input_schema,cache_control,type: "custom"), on a model that advertisestoolsin the pool the request resolves to. Anamematches^[a-zA-Z0-9_-]{1,128}$. A server tool, and a field a beta adds to a tool (defer_loading,strict,input_examples,allowed_callers,eager_input_streaming), is a 400tools.<n>.<field>: Extra inputs are not permitted.tool_choiceAcceptedauto,any,toolwith itsname, ornone;disable_parallel_tool_use: trueasks for at most one call.thinkingAccepted, ignoredadaptive,enabled(withbudget_tokens) anddisabledare accepted and change nothing (decided 2026-11-01): no thinking block is returned.metadatauser_id accepted, discardedNever stored, logged or sent to a worker. Any other member is a 400.
cache_controlAccepted where Anthropic places it{"type": "ephemeral"}onsystemblocks, content blocks and tools, as satisfied. Attlis a 400: HIPS promises no cache lifetime.top_k, context_management, output_config, output_format, safeguards, service_tier, container, mcp_servers, speed, inference_geoRejected, 400 unsupported_parameterIn Anthropic's wording,
<name>: Extra inputs are not permitted, a nested field named by its path.Any other nameRejected, 400 unknown_parameterIn the same wording.
| Content block | In | Rule |
|---|---|---|
A string content, text | user, assistant | Text; citations is a 400 |
image | user | A base64 source of image/jpeg, image/png, image/gif or image/webp, on a model that advertises vision. A url source is a 400 invalid_value: HIPS never fetches an image address |
tool_use | assistant | A call the model made earlier, replayed |
tool_result | user | The result of a call, a string or text and image blocks; is_error is accepted |
thinking, redacted_thinking, document, search_result, server_tool_use and any other type | A 400 naming the block's type |
- Content block
- A string
content,text - In
user,assistant- Rule
- Text;
citationsis a 400
- Content block
image- In
user- Rule
- A
base64source ofimage/jpeg,image/png,image/giforimage/webp, on a model that advertisesvision. Aurlsource is a 400invalid_value: HIPS never fetches an image address
- Content block
tool_use- In
assistant- Rule
- A call the model made earlier, replayed
- Content block
tool_result- In
user- Rule
- The result of a call, a string or
textandimageblocks;is_erroris accepted
- Content block
thinking,redacted_thinking,document,search_result,server_tool_useand any othertype- In
- Rule
- A 400 naming the block's
type
Parts list: The message object
idThe request id,
req_..., asx-hips-request-id.modelThe pinned id served, as
x-hips-model; under a router, the model it chose.contentA
textblock with the model's text, when it wrote any, then onetool_useblock per call (id,name,input). Arguments that are not JSON are given as a JSON string, never repaired.stop_reason, stop_sequencetool_use,max_tokens,stop_sequencewith the sequence where the engine names it, elseend_turn.pause_turnandrefusalare never sent.usageinput_tokens(the input not read from a cache),cache_read_input_tokens(the cached tokens billed,0today),cache_creation_input_tokens(always0),output_tokens.
stream: true answers 200 with text/event-stream, each event as event: <type> and one data: line, relayed as the engine writes it. Nothing is sent before a worker answers, so a refusal before the first byte is an ordinary status and body. A ping event goes out while nothing else has been sent for the keep-alive interval. message_delta carries the cumulative usage and the hips object (cost_micros, latency_ms, quote), which Anthropic's clients ignore. A failure after the stream started is one event: error with the error object below, attempt_failed when the worker stopped, and the stream closes without message_stop; nothing is billed for it.
Streamed events
event: message_startdata: {"type":"message_start","message":{"id":"req_...","type":"message","role":"assistant","model":"<pinned id>","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":0,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":0}}} event: content_block_startdata: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}} event: content_block_deltadata: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"..."}} event: content_block_stopdata: {"type":"content_block_stop","index":0} event: message_deltadata: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":0,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":0},"hips":{"cost_micros":0,"latency_ms":0,"quote":"quote_..."}} event: message_stopdata: {"type":"message_stop"}Every refusal on this route and the paths under it, the gateway's own included, is in Anthropic's shape, with the statuses and codes of the Errors page; code is an extension Anthropic's clients ignore, and request_id is x-hips-request-id.
Error
{ "type": "error", "error": { "type": "invalid_request_error", "message": "anthropic-version: header is required", "code": "missing_required_parameter" }, "request_id": "req_..."}| Status | `type` on this route |
|---|---|
| 400 | invalid_request_error |
| 401 | authentication_error |
| 402 | billing_error |
| 403 | permission_error |
| 404 | not_found_error |
| 429 | rate_limit_error, with retry-after in whole seconds |
| 503 | overloaded_error, with status 503: Anthropic's 529 is not used |
| 500 | api_error |
- Status
- 400
- `type` on this route
invalid_request_error
- Status
- 401
- `type` on this route
authentication_error
- Status
- 402
- `type` on this route
billing_error
- Status
- 403
- `type` on this route
permission_error
- Status
- 404
- `type` on this route
not_found_error
- Status
- 429
- `type` on this route
rate_limit_error, withretry-afterin whole seconds
- Status
- 503
- `type` on this route
overloaded_error, with status 503: Anthropic's 529 is not used
- Status
- 500
- `type` on this route
api_error
A prompt longer than the model's context is worded as Anthropic words it, so a client compacts the conversation or lowers max_tokens: prompt is too long: <prompt> tokens > <context> maximum, or input length and max_tokens exceed context limit: <prompt> + <max_tokens> > <context>, decrease input length or max_tokens and try again. The prompt is never truncated.
What is not served
| Route | Answer |
|---|---|
POST /v1/messages/count_tokens | 404 route_not_available (Count tokens) |
POST /v1/messages/batches and its routes, Anthropic's Files and Models APIs | 404 route_not_found; models are listed by `GET /v1/models` in OpenAI's shape |
- Route
POST /v1/messages/count_tokens- Answer
- 404
route_not_available(Count tokens)
- Route
POST /v1/messages/batchesand its routes, Anthropic's Files and Models APIs- Answer
- 404
route_not_found; models are listed by `GET /v1/models` in OpenAI's shape
| Status | Type | Code | Situation | Retry |
|---|---|---|---|---|
| 400 | invalid_request_error | missing_required_parameter | A required field or header is absent; param names it | No |
| 400 | invalid_request_error | invalid_value | A value is out of range or malformed: stop with more than 16 entries, a prompt_cache_key over 512 characters, a string holding a lone surrogate escape, a router name with an empty or unknown suffix, both max_tokens names with different values | No |
| 400 | invalid_request_error | unknown_parameter | A field the gateway does not know, at any depth; param names it | No |
| 400 | invalid_request_error | unsupported_parameter | A known field HIPS does not accept, or a feature the named model does not advertise in the pool the request resolves to; param names it and message names the model | No |
| 400 | invalid_request_error | context_length_exceeded | The prompt is over the model's context_length, or over the largest window any GPU serves it at now, that limit and the prompt's count in the message; the prompt is never truncated. On embeddings and rerank, an input longer than the model reads at once, never cut | No |
| 400 | invalid_request_error | max_tokens_exceeded | max_tokens (on Responses max_output_tokens) over the model's max_output_tokens | No |
| 400 | invalid_request_error | guardrail_blocked | A content moderation guardrail with block found prompt injection or a sensitive pattern; param names the message and the error's guardrail member names the guardrail, the check and the pattern's type, never the matched text. Before any model ran, uncharged | No |
| 401 | authentication_error | missing_api_key | No Authorization header, or not a bearer (on Messages, no x-api-key either) | No |
| 401 | authentication_error | invalid_api_key | Unknown, malformed or revoked key or person's token; on Messages, x-api-key and Authorization carrying different values. The message never says which | No |
| 402 | billing_error | insufficient_credit | The balance does not cover the request's maximum cost at the bound quote | After a top-up |
| 402 | billing_error | budget_exceeded | A budget guardrail of the workspace, the key or the person is at its limit with block; the error carries guardrail and resets_at (null for a budget that never resets). Never a payment challenge | After resets_at, or once the limit is raised |
| 403 | permission_error | model_not_allowed, region_not_allowed | A model, or a region requirement, that an access guardrail keeps out, the guardrail named in the error's guardrail member | No |
| 404 | not_found_error | model_not_found | Unknown catalog id, alias, pinned id or dep_; another workspace's dep_; a name starting with hips-router that is not one of the four routers | No |
| 429 | rate_limit_error | rate_limit_exceeded | A rate limit; param is requests, tokens, uploads, batches (batches created per hour) or knowledge_search; Retry-After | Yes, after Retry-After |
| 503 | overloaded_error | no_capacity | No eligible worker under the request's requirements, in any pool the requirements allow; Retry-After. The message says what those pools can do now: a GPU that fits the model takes it when free or loads it when asked, which can take minutes or longer; or nothing can serve it, and a retry sooner than the given delay gets the same answer | Yes, after the given delay |
| 503 | overloaded_error | overloaded | Eligible workers exist and every one is saturated, or the queue is full; Retry-After | Yes |
| 500 | api_error | attempt_failed | Every attempt failed for a reason that is not the client's and retries are exhausted. Nothing billed | Once |
- Status
- 400
- Type
invalid_request_error- Code
missing_required_parameter- Situation
- A required field or header is absent;
paramnames it - Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
invalid_value- Situation
- A value is out of range or malformed:
stopwith more than 16 entries, aprompt_cache_keyover 512 characters, a string holding a lone surrogate escape, a router name with an empty or unknown suffix, bothmax_tokensnames with different values - Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
unknown_parameter- Situation
- A field the gateway does not know, at any depth;
paramnames it - Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
unsupported_parameter- Situation
- A known field HIPS does not accept, or a feature the named model does not advertise in the pool the request resolves to;
paramnames it andmessagenames the model - Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
context_length_exceeded- Situation
- The prompt is over the model's
context_length, or over the largest window any GPU serves it at now, that limit and the prompt's count in the message; the prompt is never truncated. On embeddings and rerank, an input longer than the model reads at once, never cut - Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
max_tokens_exceeded- Situation
max_tokens(on Responsesmax_output_tokens) over the model'smax_output_tokens- Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
guardrail_blocked- Situation
- A content moderation guardrail with
blockfound prompt injection or a sensitive pattern;paramnames the message and the error'sguardrailmember names the guardrail, the check and the pattern's type, never the matched text. Before any model ran, uncharged - Retry
- No
- Status
- 401
- Type
authentication_error- Code
missing_api_key- Situation
- No
Authorizationheader, or not a bearer (on Messages, nox-api-keyeither) - Retry
- No
- Status
- 401
- Type
authentication_error- Code
invalid_api_key- Situation
- Unknown, malformed or revoked key or person's token; on Messages,
x-api-keyandAuthorizationcarrying different values. The message never says which - Retry
- No
- Status
- 402
- Type
billing_error- Code
insufficient_credit- Situation
- The balance does not cover the request's maximum cost at the bound quote
- Retry
- After a top-up
- Status
- 402
- Type
billing_error- Code
budget_exceeded- Situation
- A budget guardrail of the workspace, the key or the person is at its limit with
block; the error carriesguardrailandresets_at(nullfor a budget that never resets). Never a payment challenge - Retry
- After
resets_at, or once the limit is raised
- Status
- 403
- Type
permission_error- Code
model_not_allowed,region_not_allowed- Situation
- A model, or a region requirement, that an access guardrail keeps out, the guardrail named in the error's
guardrailmember - Retry
- No
- Status
- 404
- Type
not_found_error- Code
model_not_found- Situation
- Unknown catalog id, alias, pinned id or
dep_; another workspace'sdep_; a name starting withhips-routerthat is not one of the four routers - Retry
- No
- Status
- 429
- Type
rate_limit_error- Code
rate_limit_exceeded- Situation
- A rate limit;
paramisrequests,tokens,uploads,batches(batches created per hour) orknowledge_search;Retry-After - Retry
- Yes, after
Retry-After
- Status
- 503
- Type
overloaded_error- Code
no_capacity- Situation
- No eligible worker under the request's requirements, in any pool the requirements allow;
Retry-After. The message says what those pools can do now: a GPU that fits the model takes it when free or loads it when asked, which can take minutes or longer; or nothing can serve it, and a retry sooner than the given delay gets the same answer - Retry
- Yes, after the given delay
- Status
- 503
- Type
overloaded_error- Code
overloaded- Situation
- Eligible workers exist and every one is saturated, or the queue is full;
Retry-After - Retry
- Yes
- Status
- 500
- Type
api_error- Code
attempt_failed- Situation
- Every attempt failed for a reason that is not the client's and retries are exhausted. Nothing billed
- Retry
- Once
Related sheets
- Sheet
- 17 of 19
- Detail
- D
- Updated
- 2026-11-11