How it works
MarkdownWhat happens to a request between your application and the model.
Full guide
Send requests to the Ailoot API as you would send them directly to OpenAI, Anthropic, or Google. Ailoot checks your key and balance, forwards the request to the model, returns its response in the same format, and charges for actual usage.
One key, three formats
The format is determined by the request path, not the model. You can call the same Claude model through OpenAI Chat, OpenAI Responses, or Anthropic Messages; the response uses the format of the path you called.
| Format | Path | Clients that use it |
|---|---|---|
| OpenAI Chat Completions | /v1/chat/completions | OpenAI SDK, most chats and editors, n8n, LangChain |
| OpenAI Responses | /v1/responses | Codex CLI, OpenAI Agents SDK, newer SDK versions |
| Anthropic Messages | /v1/messages | Claude Code, Anthropic SDK, Zed, Cline |
| Gemini | /v1beta/models/{model}:generateContent | Gemini CLI, Google GenAI SDK |
Billing: a reserve and one charge
- Before sending a new text request, Ailoot reserves an estimate of the input and a typical response, taking into account the limit (
max_tokens) and the exact model’s terms. If the reserve cannot fit within the available balance or key limit, the forwarded response limit can be reduced only for a model and method that actually respect it, and never below 256 tokens or the applicable minimum output length in tokens. Image, video and audio output retain a reserve for the full cost of the result. - After the response, there is one charge based on actual usage. Any unused reserve is released to your balance immediately.
- If the response costs more than the reserve, the difference is taken from the available balance. Your balance never goes below zero.
- If there is not enough money even for the minimum reserve, the request is not sent. You receive a clear 402 error, and nothing is charged.
- An error that leaves no result is not billed.
For details and a calculation example, see Reserves and charges.
Errors with a Request ID
Every response receives a request ID in the X-Request-ID header and error message. Errors use the JSON format of the API you called, so SDKs recognize them correctly. If something goes wrong, send the Request ID to support so we can find the request within a minute.
{
"code": "API_KEY_REQUIRED",
"error": {
"code": "invalid_api_key",
"message": "No API key was sent with the request. Nothing was charged. Please check that the full key is sent in the Authorization header as \"Bearer <key>\". Request ID: 3b28d3de-5b02-4d07-9f3c-4b9a7d0e68d6.",
"param": null,
"reason": "invalid_api_key",
"request_id": "3b28d3de-5b02-4d07-9f3c-4b9a7d0e68d6",
"type": "invalid_request_error"
},
"message": "No API key was sent with the request. Nothing was charged. …"
}Streaming and timeouts
Streaming responses (stream: true) use Server-Sent Events. Ailoot delivers billed text responses after calculating their cost. With stream: true the format is still streaming (SSE), but the text arrives as one block when the model finishes, rather than word by word. If a response takes longer than about 15 seconds, Chat Completions, Responses, and Messages streams first send : ping control lines, roughly every 10 seconds, followed by a : ailoot-charged-usd … line containing the amount charged and then the data itself. SDKs skip these control lines.
Gemini format has no control lines: the :streamGenerateContent response arrives in full after the cost is calculated. Allow extra time in client timeouts for reasoning models; several minutes is normal.
Response headers
X-Request-ID is included in every response. Ailoot adds the other headers to billed text responses:
| Header | Contents |
|---|---|
X-Request-ID | Request ID, which support will ask for |
X-Ailoot-Charged-USD | Amount charged for this request, in dollars |
X-Ailoot-Output-Tokens | Number of billed response tokens |
X-Ailoot-Max-Tokens-Capped | The reduced response limit applied because the balance could not cover the full reserve |
X-Ailoot-Notice-Code, X-Ailoot-Notice | An explanation if the response stopped at its length limit |
If the stream has already started with control lines, these details arrive in a comment line before the data rather than in a header.
Prompt caching
If the model supports caching, resending a long prefix such as system instructions or documents may cost less. Cache read and write prices are shown on the model’s card in the catalog. Cache hits are determined by the model developer; Ailoot does not guarantee them.