API guide
Our API follows the OpenAI chat completions format, so the SDKs and tools you already use work unchanged. Change the base URL and the model id.
The API opens with our first models. The examples below show exactly how it will work.
Direct API
- Base URL
https://api.blazingnodes.com/v1- Authentication
Authorization: Bearer $BLAZINGNODES_API_KEY- Endpoints
POST /chat/completions(streaming and non-streaming) andGET /models(our model list with prices and limits, in OpenRouter's provider format; OpenAI SDKs read it as is)- Request ids
- Every response carries an
x-request-idheader. Quote it when you contact support.
curl https://api.blazingnodes.com/v1/chat/completions \
-H "Authorization: Bearer $BLAZINGNODES_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "google/gemma-4-26b-a4b-it",
"messages": [{"role": "user", "content": "Summarize this ticket in one line."}],
"stream": true
}'import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.blazingnodes.com/v1",
api_key=os.environ["BLAZINGNODES_API_KEY"],
)
resp = client.chat.completions.create(
model="google/gemma-4-26b-a4b-it",
messages=[{"role": "user", "content": "Summarize this ticket in one line."}],
)
print(resp.choices[0].message.content)
print(resp.usage) # prompt, completion and cached prompt tokensThrough OpenRouter
Once we are listed, call our models with your OpenRouter key. To pin requests to BlazingNodes, set the provider order and turn fallbacks off. The provider name blazingnodes applies once the listing is approved.
curl https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "google/gemma-4-26b-a4b-it",
"messages": [{"role": "user", "content": "Summarize this ticket in one line."}],
"provider": {"order": ["blazingnodes"], "allow_fallbacks": false}
}'Token usage and caching
Every response reports token usage, including the last chunk of a stream. When the start of your prompt matches a recent request (the same system prompt or chat history), those tokens come from the prefix cache, are reported ascached_tokens and are billed at the cached-input rate.
"usage": {
"prompt_tokens": 1830,
"completion_tokens": 42,
"total_tokens": 1872,
"prompt_tokens_details": { "cached_tokens": 1536 }
}In a stream, the last chunk has an empty choices array and the usage object, followed bydata: [DONE]. A stream that ends without [DONE] was cut off; retry it.
data: {"id":"chatcmpl-1","object":"chat.completion.chunk","choices":[],"usage":{"prompt_tokens":1830,"completion_tokens":42,"total_tokens":1872,"prompt_tokens_details":{"cached_tokens":1536}}}
data: [DONE]Errors and limits
| Status | What happened | What to do |
|---|---|---|
400 | The request is invalid: longer than the context we serve, or a parameter outside the rules below. | Fix the request; do not retry it unchanged. |
401 | The key in the Authorization header was not recognized. | Check the key, or create a new one. |
404 | The model id is not served here (code model_not_found). | Check the id on the Models page. |
413 | The request body is larger than 2 MB. | Send a smaller request. |
429 | The node is at capacity or your key is over its limit. Sent before any work starts (type rate_limit_error, code rate_limit_exceeded). | Retry after the Retry-After header (seconds). |
502 | The model server was unreachable or failed mid-response. We treat each one as an incident. | Retry with backoff and check the status page. |
Errors use the OpenAI format: an error object withmessage, type,param and code.
HTTP/1.1 429 Too Many Requests
Retry-After: 1
x-request-id: 4f2a9c1e7b3d4a58
{
"error": {
"message": "Capacity is full; retry shortly.",
"type": "rate_limit_error",
"param": null,
"code": "rate_limit_exceeded"
}
}Request rules
nandbest_ofmust be 1, and beam search is not supported: one request returns one completion.max_tokensandmax_completion_tokensmust be whole numbers from 1 to the model's output limit (listed on the Models page at launch). If you set neither, the limit applies; long prompts still fit, because the output is capped to the context that is left.streammust betrue,falseornull.tools,tool_choiceandresponse_formatmust be well formed: a JSON schema must describe an object (64 KB at most), and you can send up to 128 named function tools (256 KB in total). A namedtool_choicemust name one of the tools you sent. Anything else returns 400.- JSON schemas in
response_formatand in tool parameters are compiled into a grammar, so their size is limited: nesting depth 10, 1000 properties, 1000 enum values, length and item bounds up to 4096, and patterns up to 256 characters with no repeat count above 256.patternPropertiesandpropertyNamesare not supported. Patterns are checked for their total expanded size, size bounds must be whole numbers from 0 to 4096, and only local references are allowed:$refmust be#,#/$defs/<name>or#/definitions/<name>, and$defsnames may not contain/,~or%. Larger schemas return 400. NaNandInfinityare not valid anywhere in a request body and return 400.- Messages are text only. At most 8
stopstrings and 300logit_biasentries. The request body may be at most 2 MB (413 above that). - Fields outside the OpenAI chat API are ignored, except
top_k,min_p,repetition_penalty,include_reasoningandreasoning_effort. Inchat_template_kwargs, onlyenable_thinkingis passed through, to turn reasoning on or off.
Long requests stay open: whenever the model is silent, for example while it processes a long prompt, streaming responses send SSE comment lines (: keep-alive) that SSE clients ignore, so proxies do not drop the connection.