Chat completions
For open-weight language models the public API is OpenAI-compatible, so OpenAI client SDKs work with a HIPS key, base URL and model id. Compatibility is a request and response shape, validated per endpoint, model and client version; it is never a model list.
/v1/chat/completionspreviewChat completion, streamed or not. The first route built and the first validated.
- Nothing is silently dropped. A field that would change the model's output or the bill and that HIPS or the named model cannot honor is a 400, never ignored.
- Nothing is silently substituted. The model served is the model named. No fallback to another model, ever.
- A requirement is never weakened to make a request succeed.
The body is OpenAI's. A 400 names the field in param and the model in message when the refusal depends on the model.
Parts list: Fields
modelRequiredA catalog id, an alias, a pinned id or a
dep_id.messagesRequired, non-emptyRoles
system,developer,user,assistant,tool.contenta string or an array of parts. Text parts always;image_urlparts only on a model that advertisesvision;input_audioandfileparts are a 400unsupported_parameter(audio goes through the task API).streamAcceptedServer-sent events, one
data:line per chunk, thendata: [DONE].stream_optionsAccepted with stream: trueinclude_usagehonored. Withoutstreama 400unsupported_value.max_completion_tokens, max_tokensAcceptedBoth names; both given and different is a 400
invalid_value. Over the model'smax_output_tokensis a 400max_tokens_exceeded. Absent: the model's default from its entry.temperature, top_p, stop, seed, presence_penalty, frequency_penaltyAcceptedPassed to the engine.
stopup to the count in the model's entry.seedis best effort; determinism is not promised across workers.nAccepted as 1Any other value is a 400
unsupported_value: one answer per request, so the quote and the bill are one line.response_formatAcceptedtextalways;json_objecton a model advertisingjson_object;json_schemawithname,schemaandstricton a model advertisingjson_schema. Otherwise a 400unsupported_parameternaming the feature.tools, tool_choice, parallel_tool_callsAcceptedOn a model advertising
tools(andparallel_tool_callsfor the third). Shapes are OpenAI's, unchanged.logprobs, top_logprobsAcceptedOn a model advertising
logprobs.logit_biasAcceptedOn a model advertising
logit_bias.reasoning_effortAcceptedOn a model advertising
reasoning; otherwise a 400unsupported_parameter.userAccepted, discardedIt changes neither the output nor the bill. Not stored. Stated here so the discard is not silent.
store, metadataRejected, 400 stateful_not_supportedThe gateway stores no bodies.
functions, function_callRejected, 400 unsupported_parameterOpenAI's deprecated names;
toolsis the shape.modalities, audio, prediction, web_search_options, service_tierRejected, 400 unsupported_parameterAudio and media go through the task API; pools and pricing modes are headers, not a tier.
Any other nameRejected, 400 unknown_parameterTypos are caught, not ignored.
| Value | Form | Resolves to |
|---|---|---|
| Catalog id | <family>-<size>[-<variant>], lowercase | The current pinned version of that catalog entry; moves with releases |
| Alias | As listed in the entry's hips.aliases | The entry it names |
| Pinned id | <catalog id>-<version> | That version, as long as it is served |
| Deployment id | dep_<base32> | A customer model deployment, or a catalog model pinned to an always-on allocation, of the key's workspace |
- Value
- Catalog id
- Form
<family>-<size>[-<variant>], lowercase- Resolves to
- The current pinned version of that catalog entry; moves with releases
- Value
- Alias
- Form
- As listed in the entry's
hips.aliases - Resolves to
- The entry it names
- Value
- Pinned id
- Form
<catalog id>-<version>- Resolves to
- That version, as long as it is served
- Value
- Deployment id
- Form
dep_<base32>- Resolves to
- A customer model deployment, or a catalog model pinned to an always-on allocation, of the key's workspace
| Situation | Answer |
|---|---|
Unknown id, or another workspace's dep_ | 404 model_not_found |
| A model the plan does not allow, or a route the key's kind excludes | 403 model_not_on_plan or key_scope_denied |
A dep_ whose model is not a language model | 400 not_a_language_model (use POST /v1/tasks) |
A deployment in stopped | 400 deployment_stopped |
A deployment in allocating or loading | 503 deployment_not_ready with Retry-After |
A deployment waiting for its version's tariff (tariff_pending) | 503 deployment_not_ready with Retry-After; the message says the tariff is pending. Nothing is charged |
A deployment in degraded | Served; the state is in GET /v1/models/{id} |
- Situation
- Unknown id, or another workspace's
dep_ - Answer
- 404
model_not_found
- Situation
- A model the plan does not allow, or a route the key's kind excludes
- Answer
- 403
model_not_on_planorkey_scope_denied
- Situation
- A
dep_whose model is not a language model - Answer
- 400
not_a_language_model(usePOST /v1/tasks)
- Situation
- A deployment in
stopped - Answer
- 400
deployment_stopped
- Situation
- A deployment in
allocatingorloading - Answer
- 503
deployment_not_readywithRetry-After
- Situation
- A deployment waiting for its version's tariff (
tariff_pending) - Answer
- 503
deployment_not_readywithRetry-After; the message says the tariff is pending. Nothing is charged
- Situation
- A deployment in
degraded - Answer
- Served; the state is in
GET /v1/models/{id}
The response's model and the x-hips-model header carry the pinned id that was served; x-hips-deployment carries the dep_ id when the request named one.
OpenAI's chat.completion object: id, object, created, model, choices[{index, message{role, content, tool_calls, refusal}, finish_reason, logprobs}], usage.
Parts list: HIPS specifics
idThe request id,
req_..., so a log line and a support question name the same thing.modelThe pinned id served.
finish_reasonstop,length,tool_calls.content_filteris never emitted: HIPS applies no output filter on this route.system_fingerprintOmitted.
usageThe usage object. Money is never in it.
ExtrasIn headers, not in the body, except the streamed
hipsobject.
stream: true answers 200 with Content-Type: text/event-stream, one data: line per chunk in OpenAI's chat.completion.chunk shape, then data: [DONE]. The rules are on Streaming; the final usage chunk with its hips object looks like this:
Final chunk
data: {"id":"req_...","object":"chat.completion.chunk","created":0,"model":"<pinned id>","choices":[],"usage":{"prompt_tokens":0,"completion_tokens":0,"total_tokens":0},"hips":{"cost_micros":0,"latency_ms":0,"quote":"quote_..."}} data: [DONE]Features are advertised per model in GET /v1/models and come from the engine and the model together. Shapes are OpenAI's, unchanged. A feature the model does not advertise is a 400 unsupported_parameter.
| Feature | Request | Response |
|---|---|---|
tools | tools: [{"type":"function","function":{...}}]; tool_choice as auto, none, required or a named function | message.tool_calls with arguments a JSON string; finish_reason: "tool_calls". Streamed as delta.tool_calls by index |
parallel_tool_calls | parallel_tool_calls as true or false | More than one entry in tool_calls |
json_object | response_format: {"type":"json_object"} | content is one JSON document |
json_schema | response_format: {"type":"json_schema","json_schema":{"name","schema","strict": true}} | content validates against the schema; strict: false accepted where the model advertises it |
vision | image_url parts in a user message | As text |
logprobs | logprobs: true, top_logprobs | choices[].logprobs |
reasoning | reasoning_effort | usage.completion_tokens_details.reasoning_tokens |
logit_bias | logit_bias | Applied by the engine |
- Feature
tools- Request
tools: [{"type":"function","function":{...}}];tool_choiceasauto,none,requiredor a named function- Response
message.tool_callswithargumentsa JSON string;finish_reason: "tool_calls". Streamed asdelta.tool_callsbyindex
- Feature
parallel_tool_calls- Request
parallel_tool_callsastrueorfalse- Response
- More than one entry in
tool_calls
- Feature
json_object- Request
response_format: {"type":"json_object"}- Response
contentis one JSON document
- Feature
json_schema- Request
response_format: {"type":"json_schema","json_schema":{"name","schema","strict": true}}- Response
contentvalidates against the schema;strict: falseaccepted where the model advertises it
- Feature
vision- Request
image_urlparts in ausermessage- Response
- As text
- Feature
logprobs- Request
logprobs: true,top_logprobs- Response
choices[].logprobs
- Feature
reasoning- Request
reasoning_effort- Response
usage.completion_tokens_details.reasoning_tokens
- Feature
logit_bias- Request
logit_bias- Response
- Applied by the engine
| Status | Type | Code | Situation | Retry |
|---|---|---|---|---|
| 400 | invalid_request_error | invalid_json | The body is not JSON, or not an object | No |
| 400 | invalid_request_error | missing_required_parameter | A required field is absent; param names it | No |
| 400 | invalid_request_error | invalid_type | A field has the wrong JSON type | No |
| 400 | invalid_request_error | invalid_value | A value is out of range or malformed | 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 OpenAI field HIPS does not accept, or a feature the named model does not advertise | No |
| 400 | invalid_request_error | unsupported_value | n other than 1, stream_options without stream, a message role or part type not accepted | No |
| 400 | invalid_request_error | stateful_not_supported | store, metadata, previous_response_id, conversation | No |
| 400 | invalid_request_error | context_length_exceeded | The prompt is over the model's context_length; the prompt is never truncated | No |
| 400 | invalid_request_error | max_tokens_exceeded | max_tokens over the model's max_output_tokens | No |
| 400 | invalid_request_error | invalid_image | An image part or input cannot be decoded, is of an unsupported type or over the pixel limit | No |
| 400 | invalid_request_error | not_a_language_model | A task model or a task-model deployment named on an OpenAI-compatible route | No |
| 400 | invalid_request_error | deployment_stopped | The dep_ is in stopped; start it in the Console | No |
| 400 | invalid_request_error | invalid_requirement | A requirement header or field with an unknown value | No |
| 400 | invalid_request_error | requirement_conflict | Two requirements that cannot both hold, a header and a hips field that differ, a pool the model is never offered in, personal with an always-on deployment | No |
| 400 | invalid_request_error | stable_price_not_in_force | pricing_mode: stable with no stable price covering this workspace, model and period | No |
| 402 | insufficient_credit | insufficient_credit | The balance does not cover the request's maximum cost at the bound quote. On the free plan with the allowance used, the message names when it resets | After a top-up |
| 403 | permission_error | model_not_on_plan | The model or feature is not in the workspace's plan | No |
| 404 | not_found_error | model_not_found | Unknown catalog id, alias, pinned id or dep_; another workspace's dep_ | No |
| 429 | rate_limit_error | rate_limit_exceeded | A rate limit; param is requests, tokens, units or uploads; Retry-After | Yes, after Retry-After |
| 429 | rate_limit_error | concurrency_limit_exceeded | Too many concurrent streams or active jobs; param is streams or jobs; 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 | Yes |
| 503 | overloaded_error | pool_unavailable | The named pool has no eligible supply for this model now and fallback is off; the other pool may have; Retry-After | Yes, or with fallback |
| 503 | overloaded_error | deployment_not_ready | The dep_ is allocating or loading, or waits for its version's tariff (tariff_pending); Retry-After | Yes |
| 503 | overloaded_error | overloaded | Eligible workers exist and every one is saturated, or the queue is full; Retry-After | Yes |
| 500 | api_error | internal_error | A fault in HIPS. Nothing billed | Once |
| 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
invalid_json- Situation
- The body is not JSON, or not an object
- Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
missing_required_parameter- Situation
- A required field is absent;
paramnames it - Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
invalid_type- Situation
- A field has the wrong JSON type
- Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
invalid_value- Situation
- A value is out of range or malformed
- 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 OpenAI field HIPS does not accept, or a feature the named model does not advertise
- Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
unsupported_value- Situation
nother than 1,stream_optionswithoutstream, a message role or part type not accepted- Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
stateful_not_supported- Situation
store,metadata,previous_response_id,conversation- Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
context_length_exceeded- Situation
- The prompt is over the model's
context_length; the prompt is never truncated - Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
max_tokens_exceeded- Situation
max_tokensover the model'smax_output_tokens- Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
invalid_image- Situation
- An image part or input cannot be decoded, is of an unsupported type or over the pixel limit
- Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
not_a_language_model- Situation
- A task model or a task-model deployment named on an OpenAI-compatible route
- Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
deployment_stopped- Situation
- The
dep_is instopped; start it in the Console - Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
invalid_requirement- Situation
- A requirement header or field with an unknown value
- Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
requirement_conflict- Situation
- Two requirements that cannot both hold, a header and a
hipsfield that differ, a pool the model is never offered in,personalwith an always-on deployment - Retry
- No
- Status
- 400
- Type
invalid_request_error- Code
stable_price_not_in_force- Situation
pricing_mode: stablewith no stable price covering this workspace, model and period- Retry
- No
- Status
- 402
- Type
insufficient_credit- Code
insufficient_credit- Situation
- The balance does not cover the request's maximum cost at the bound quote. On the free plan with the allowance used, the message names when it resets
- Retry
- After a top-up
- Status
- 403
- Type
permission_error- Code
model_not_on_plan- Situation
- The model or feature is not in the workspace's plan
- Retry
- No
- Status
- 404
- Type
not_found_error- Code
model_not_found- Situation
- Unknown catalog id, alias, pinned id or
dep_; another workspace'sdep_ - Retry
- No
- Status
- 429
- Type
rate_limit_error- Code
rate_limit_exceeded- Situation
- A rate limit;
paramisrequests,tokens,unitsoruploads;Retry-After - Retry
- Yes, after
Retry-After
- Status
- 429
- Type
rate_limit_error- Code
concurrency_limit_exceeded- Situation
- Too many concurrent streams or active jobs;
paramisstreamsorjobs;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 - Retry
- Yes
- Status
- 503
- Type
overloaded_error- Code
pool_unavailable- Situation
- The named pool has no eligible supply for this model now and fallback is off; the other pool may have;
Retry-After - Retry
- Yes, or with fallback
- Status
- 503
- Type
overloaded_error- Code
deployment_not_ready- Situation
- The
dep_isallocatingorloading, or waits for its version's tariff (tariff_pending);Retry-After - Retry
- Yes
- 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
internal_error- Situation
- A fault in HIPS. Nothing billed
- Retry
- Once
- 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
- 11 of 13
- Detail
- B
- Updated
- 2026-10-21
- Status
- Preview