Hoosha Chat API
Chat with GPT 6.1 Terra, Gemini 3.8 Flash, DeepSeek V4.1 Flash, GLM 5.3 FlashX and Muse Spark 1.3 through one endpoint that speaks the OpenAI Chat Completions format. Any OpenAI SDK works: point it at Hoosha and use your Hoosha key.
Quickstart
Code
Code
Authentication
Send your key as Authorization: Bearer sk-hoosha-…. Keys are created and
revoked in the Hoosha developer console; the same key works for the media API.
Twenty failed key authentications from one IP address lock that address out
of key authentication for 15 minutes, answered with 429 rate_limit_exceeded.
Models
Each model always runs on the same provider. Requests are never rerouted to another model or another provider.
| model | context | max output | input | cached input | output |
|---|---|---|---|---|---|
gpt-6.1-terra | 922,000 | 128,000 | 121.33 | 6.07 | 606.63 |
muse-spark-1.3-contributor | 1,048,576 | 131,072 | 12.13 | 0.24 | 24.27 |
deepseek-v4.1-flash-1017 | 1,048,576 | 131,072 | 18.20 | 0.36 | 72.80 |
gemini-3.8-flash | 1,048,576 | 65,536 | 90.99 | 9.10 | 454.97 |
glm-5.3-flashx | 1,048,576 | 131,072 | 44.89 | 10.92 | 151.66 |
Context and max output are in tokens; prices are credits per million tokens.
Reasoning tokens are billed as output
tokens. A repeated prompt prefix that the provider has cached is billed at the
cached input price; on gpt-6.1-terra, writing a long prefix to the cache
costs 1.25x the input price. GET /models returns the same figures.
muse-spark-1.3-contributor is Meta's contributor tier: Meta uses the inputs
sent to it to train its models. Do not send it data you cannot share.
Billing
Every request draws on your Hoosha credit balance; there is no free allowance.
- When a request arrives, its largest possible cost (input plus
max_tokensof output) is held from your balance. If the balance cannot cover it, the request fails with402 insufficient_creditsand nothing is charged. - When the model finishes, the hold settles to the exact cost of the tokens used and the rest returns to your balance.
- Credit balances are whole numbers, so fractions of a credit carry over to
your next request.
usage.cost_creditsreports the exact cost of each one. If a request ever costs more than its hold and your balance cannot cover the difference, the difference is carried too and added to your next hold.
A request that fails is not charged. A non-streaming request that has not
finished after 110 seconds returns 504 timeout and is not charged either.
A streaming request is charged for the tokens the model produced, even if you
close the connection early or the stream reaches its 9-minute limit.
Streaming
Set stream: true to receive server-sent events in the OpenAI chunk format,
ending with data: [DONE]. Add stream_options: {"include_usage": true} to
get a final chunk with an empty choices array and the usage object. While
a model is thinking, the stream sends : keep-alive comment lines every
15 seconds; SSE clients ignore them.
If the model fails before it sends anything, the request gets an ordinary
HTTP error instead of a stream. A failure after the stream has started
arrives as a final data: event holding the error envelope, without
[DONE]; OpenAI SDKs raise it as an APIError. A stream that reaches
9 minutes from the request ends the same way, with code timeout.
Prefer streaming for long answers: a non-streaming request must finish within 110 seconds.
Reasoning
All five models can reason before they answer. Steer the effort with
reasoning_effort (none, minimal, low, medium, high, xhigh).
Muse, Gemini and GLM always reason, so they refuse none; use minimal for
the least reasoning. Reasoning tokens count against max_tokens, so a small
max_tokens can end a reply before it starts (finish_reason: length).
Readable reasoning, when the model shares it, arrives as reasoning_content
on the message or the stream delta. Some models also return
reasoning_details, opaque blocks you can send back on the assistant message
in the next request to keep the model's chain of thought; dropping them is
allowed.
Tools, images and JSON
- Tools. Pass
toolswith function definitions; calls come back intool_callswithfinish_reason: tool_calls. Send results back asrole: toolmessages with the matchingtool_call_id. - Images. Add
image_urlparts to a user message, as anhttps://URL or a base64 data URL of a PNG, JPEG, GIF or WebP image. Images are passed to the model as you sent them; Hoosha does not download your URLs. Up to 32 images per request. - JSON.
response_format: {"type": "json_object"}works on every model.json_schemaworks on every model exceptdeepseek-v4.1-flash-1017, which answers400 unsupported_value.
Decisions
POST /decisions runs Jev, TypeSafe's decision model. Jev does not write
text. You send the content to judge as state and ask named questions
about it; each answer comes back typed, with calibrated probabilities your
code can branch on. Requests and responses follow OpenRouter's Decisions
API, with Hoosha ids and prices in credits.
| model | context | input | output |
|---|---|---|---|
jev-1.14 | 262,144 | 5.10 | 0.00 |
Prices are credits per million tokens. Jev bills input only, and images
count as input tokens. usage.cost_credits reports the exact cost of each
decision, which is held and settled like a chat request, with fractions of
a credit carried over. A decision that has not finished after 110 seconds
returns 504 timeout and is not charged.
| Question type | Asks | Answer |
|---|---|---|
noul | Is this statement true? Optional criteria with true and false. | noul, the probability of yes |
choice | Which option fits? criteria maps each option to a description. | choice, probabilities, confidence |
score | Where does it fall on a scale? criteria lists the levels, lowest first. | score, probabilities, legend, confidence |
box | Where is it in an image? | box with top, bottom, left and right as fractions of the image |
Images go in assets as plain base64 PNG or JPEG, keyed by a reference
string. Write the reference wherever the image belongs in state,
instructions or criteria; an asset that is never referenced is
rejected, and every occurrence sends the image again. Each image must be
256 to 1,568 pixels on each side, and TypeSafe marks images and box as
early features whose format can change. Jev reads other languages, but its
accuracy is best in English.
Parameters a model does not use
The OpenAI sampling parameters (temperature, top_p, stop, seed,
presence_penalty, frequency_penalty) are accepted on every model. A model
that does not support one ignores it; each model's supported_parameters in
GET /models lists what it honors. Fields outside this reference are rejected
with 400 unsupported_parameter, except store and metadata, which are
accepted and ignored, and any field sent as null.
Limits
| Limit | Value |
|---|---|
| Requests | 60 per minute per account |
GET /models requests | 120 per minute per account |
| Requests in flight | 4 per account, chat and decisions together |
| Request body | 20 MB |
| Images | 32 per request |
| Tools | 128 per request |
max_tokens default | 8,192, or the model's maximum if lower |
| Non-streaming request | 110 seconds |
| Streaming request | 9 minutes |
| Messages | 2,048 per request |
| Stop sequences | 4 |
| Decision requests | 120 per minute per account |
| Questions per decision | 64 |
| Images per decision | 16 |
Errors
Errors use the OpenAI envelope, so OpenAI SDKs raise their usual typed exceptions:
Code
| Status | code | When |
|---|---|---|
| 400 | unsupported_parameter, invalid_value, unsupported_value, null | The request is invalid; param names the field. |
| 400 | context_length_exceeded | The messages do not fit the model's context window. |
| 400 | upstream_rejected | The model rejected the request, for example an unreadable image. |
| 401 | invalid_api_key | The key is missing, invalid, revoked or expired. |
| 402 | insufficient_credits | Your balance cannot cover the request's maximum cost. |
| 404 | model_not_found | The model id is not in GET /models. |
| 413 | request_too_large | The body is larger than 20 MB, or the model refused its size. |
| 415 | null | The body was not sent as application/json. |
| 429 | rate_limit_exceeded, concurrency_limit_exceeded, upstream_rate_limited | Too many requests; wait for Retry-After. |
| 502 | upstream_error | The model failed. Nothing was charged; retrying is safe. |
| 503 | service_unavailable, model_unavailable | Chat or the model is temporarily unavailable. Nothing was charged. |
| 504 | timeout | The model did not answer in time. Nothing was charged. |
A 504 timeout carries x-should-retry: false, which the OpenAI SDKs obey:
retrying the same long request would time out again. Stream it instead.