API documentation
One HTTPS endpoint and one API key for chat, embeddings, rerank, text-to-speech and transcription. Requests and responses follow the OpenAI wire format, so the official OpenAI SDKs and most frameworks work by changing the base URL. Every response on this page was captured from the live API.
Base URL and endpoints
https://api.inferenceapis.com/v1/openai/v1 is accepted as well, so a Groq-style base URL works with only the host changed. The model field selects the model; each model also answers to the ids other providers use for it (see models and aliases).
| Endpoint | Purpose | Auth |
|---|---|---|
POST /v1/chat/completions | Chat and reasoning: streaming, tool calling, JSON output | Key |
POST /v1/responses | The same chat models through the OpenAI Responses API, for Codex CLI and newer SDK code | Key |
POST /v1/messages | The same chat models through the Anthropic Messages API, for Claude Code and Anthropic SDKs | Key |
POST /v1/embeddings | Text to vectors for search and RAG | Key |
POST /v1/rerank | Score passages against a query | Key |
POST /v1/audio/speech | Text to speech, returns audio bytes | Key |
POST /v1/audio/transcriptions | Speech to text, multipart upload | Key |
GET /v1/voices?model=… | Voices of a speech model | Key |
GET /v1/models | Every accepted model id with its canonical id | None |
GET /health | Liveness check | None |
Authentication
Send your key as a Bearer token. Create an account, add funds on the Billing page, then copy the key from the API Keys page.
Authorization: Bearer $INFERENCE_API_KEYQuickstart
This example uses GPT-OSS 120B. Any chat model id from the catalog works in its place.
curl https://api.inferenceapis.com/v1/chat/completions \
-H "Authorization: Bearer $INFERENCE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-oss-120b",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello! What can you do?"}
]
}'
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.inferenceapis.com/v1",
api_key=os.environ["INFERENCE_API_KEY"],
)
response = client.chat.completions.create(
model="openai/gpt-oss-120b",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello! What can you do?"},
],
)
print(response.choices[0].message.content)
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.inferenceapis.com/v1",
apiKey: process.env.INFERENCE_API_KEY,
});
const response = await client.chat.completions.create({
model: "openai/gpt-oss-120b",
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "Hello! What can you do?" },
],
});
console.log(response.choices[0].message.content);
Chat completions
POST /v1/chat/completions takes the OpenAI request body. These fields are passed through; others the model does not understand are ignored by it.
| Parameter | Type | Notes |
|---|---|---|
model required | string | Canonical id or an alias |
messages required | array | Roles system, user, assistant, tool |
max_tokens | integer | Counts reasoning tokens too. Use a few hundred or more on reasoning models |
temperature, top_p | number | Sampling controls |
stream | boolean | Server-sent events; usage arrives in the final chunk |
tools, tool_choice | array, string|object | OpenAI function-calling format |
response_format | object | json_object or json_schema |
reasoning_effort | string | "none" switches thinking off on any model; low, medium, high are passed to models that grade effort |
stop, seed | string|array, integer | Stop sequences; seed for more reproducible sampling |
{
"id": "p1fXe5T-z1gNr-a3c9ade91f80e802",
"object": "chat.completion",
"created": 1789664554,
"model": "openai/gpt-oss-120b",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello and welcome to you!",
"tool_calls": [],
"reasoning": "User asks: \"Say hello in five words.\" ..."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 75,
"completion_tokens": 125,
"total_tokens": 200,
"prompt_tokens_details": { "cached_tokens": 66 },
"completion_tokens_details": { "reasoning_tokens": 110 }
}
}Reasoning models. GPT-OSS, DeepSeek and GLM think before they answer. The thinking is returned next to content, in reasoning on GPT-OSS and in reasoning_content on DeepSeek and GLM, and it is billed as completion tokens; usage.completion_tokens_details.reasoning_tokens says how many. If max_tokens is too small the budget is spent on thinking and content comes back empty. Llama 3.3 70B does not reason and has neither field.
Images. Qwen3-VL 235B accepts images in a message's content array, in the OpenAI format: {"type": "image_url", "image_url": {"url": "https://…"}} or a data:image/png;base64,… URI. Images bill as input tokens. The other chat models are text-only and will ignore or reject image parts.
Switching thinking off. Send reasoning_effort: "none" on any model. Each model family honours a different parameter for this and ignores the others, so the gateway translates; "minimal", reasoning: {"enabled": false} and thinking: {"type": "disabled"} are accepted too, and the X-Thinking: off response header confirms it. GPT-OSS cannot be switched off and goes to its lowest effort instead. Measured effect per model: model capabilities.
Streaming
Set "stream": true. Each event is a data: line with a chunk; text arrives in choices[0].delta.content and reasoning in delta.reasoning or delta.reasoning_content. The last chunk before [DONE] has an empty choices array and the usage object, so streamed requests can be metered without counting tokens yourself. You do not need to set stream_options.
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.inferenceapis.com/v1", api_key=os.environ["INFERENCE_API_KEY"])
stream = client.chat.completions.create(
model="zai-org/GLM-5.3-Flash",
messages=[{"role": "user", "content": "Explain SSE in two sentences."}],
max_tokens=600,
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
if chunk.usage: # final chunk: choices is empty, usage is set
print("\n", chunk.usage.prompt_tokens, "in /", chunk.usage.completion_tokens, "out")data: {"id":"8757ca82","object":"chat.completion.chunk","model":"zai-org/GLM-5.3-Flash","choices":[{"index":0,"delta":{"content":null},"finish_reason":"stop"}]}
data: {"id":"8757ca82","object":"chat.completion.chunk","model":"zai-org/GLM-5.3-Flash","choices":[],"usage":{"prompt_tokens":15,"completion_tokens":129,"total_tokens":144,"completion_tokens_details":{"reasoning_tokens":123}}}
data: [DONE]Tool calling
All five chat models returned a correct tool_calls entry for this request when we tested them on September 17, 2026. Arguments arrive as a JSON string. In a stream they arrive as delta.tool_calls fragments to concatenate.
import json, os
from openai import OpenAI
client = OpenAI(base_url="https://api.inferenceapis.com/v1", api_key=os.environ["INFERENCE_API_KEY"])
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]},
},
}]
messages = [{"role": "user", "content": "What is the weather in Paris?"}]
first = client.chat.completions.create(model="openai/gpt-oss-120b", messages=messages, tools=tools, max_tokens=800)
call = first.choices[0].message.tool_calls[0] # name="get_weather", arguments='{"city": "Paris"}'
args = json.loads(call.function.arguments)
messages += [first.choices[0].message,
{"role": "tool", "tool_call_id": call.id, "content": json.dumps({"city": args["city"], "temp_c": 18})}]
final = client.chat.completions.create(model="openai/gpt-oss-120b", messages=messages, tools=tools, max_tokens=800)
print(final.choices[0].message.content)JSON and structured output
Both forms of response_format work on every chat model here. With json_schema the reply is constrained to your schema. Mention JSON in the prompt as well, and leave room in max_tokens for the reasoning that happens first.
# JSON mode: any valid JSON object
resp = client.chat.completions.create(
model="deepseek-ai/DeepSeek-V4-Flash",
messages=[{"role": "user", "content": "Return a JSON object with keys city and country for Paris."}],
response_format={"type": "json_object"},
max_tokens=800,
)
# Schema-constrained: the reply must match your schema
resp = client.chat.completions.create(
model="deepseek-ai/DeepSeek-V4-Flash",
messages=[{"role": "user", "content": "Give me a person named Ada, age 36."}],
response_format={"type": "json_schema", "json_schema": {"name": "person", "schema": {
"type": "object",
"properties": {"name": {"type": "string"}, "age": {"type": "integer"}},
"required": ["name", "age"], "additionalProperties": False}}},
max_tokens=800,
)
print(resp.choices[0].message.content) # {"name": "Ada", "age": 36}Responses API
POST /v1/responses serves every chat model through OpenAI's newer Responses format, streaming included. It exists because some clients speak nothing else, Codex CLI among them. Requests are translated to chat completions on our side, so pricing and models are identical. It is stateless: send the whole conversation in input on every call, as Codex does. previous_response_id, store, background mode and OpenAI-hosted tools such as web search are not supported; function tools and Codex's freeform tools are. Two Codex-only request shapes are translated so that they work on every model: MCP servers and sub-agent tools, which Codex sends inside a namespace wrapper, are expanded and each call comes back with its namespace restored; Multi-Agent V2 agent_message hand-offs become user messages. Details and per-model test results: MCP tools in Codex on a custom provider.
resp = client.responses.create(
model="deepseek-ai/DeepSeek-V4-Flash",
instructions="You are a terse assistant.",
input="Name three uses of a reranker.",
max_output_tokens=800,
reasoning={"effort": "low"},
)
print(resp.output_text)
print(resp.usage.input_tokens, resp.usage.output_tokens)model = "zai-org/GLM-5.3"
model_provider = "inferenceapis"
[model_providers.inferenceapis]
name = "Inference APIs"
base_url = "https://api.inferenceapis.com/v1"
env_key = "INFERENCE_API_KEY"
wire_api = "responses"We ran a real Codex CLI task, write a script, run it, report the output, through this route on every large model here. Setup details: Codex CLI.
Messages API (Anthropic format)
POST /v1/messages serves every chat model through the Anthropic Messages format, streaming included, with x-api-key or a bearer token. It exists because Claude Code speaks nothing else. Requests are translated to chat completions on our side, so models and prices are the same as everywhere else here. System prompts, text and image blocks, tool_use and tool_result, tool_choice (auto, any, tool, none), stop_sequences and output_format are translated. thinking: {type: "enabled"} (or adaptive) leaves the model's reasoning on and streams it as thinking blocks; no thinking field switches it off, as in Anthropic's own semantics. Replayed thinking blocks are dropped on the way in; every model here accepts the history without them. Anthropic-hosted server tools (web search, computer use, text editor, code execution), mcp_servers, container and the Batches API are not supported; dropped fields are listed in the X-Tools-Dropped and X-Dropped-Params response headers. POST /v1/messages/count_tokens returns an estimate. Errors use Anthropic's envelope ({"type":"error","error":{"type":…,"message":…}}).
import os
from anthropic import Anthropic
client = Anthropic(base_url="https://api.inferenceapis.com", api_key=os.environ["INFERENCE_API_KEY"])
msg = client.messages.create(
model="deepseek-ai/DeepSeek-V4.1-Flash",
max_tokens=1024,
thinking={"type": "enabled", "budget_tokens": 2048}, # omit to switch the model's reasoning off
tools=[{"name": "read_file", "description": "Read a file.", "input_schema": {"type": "object", "properties": {"path": {"type": "string"}}, "required": ["path"]}}],
messages=[{"role": "user", "content": "What is in /app/config.json?"}],
)
print(msg.stop_reason, [b.type for b in msg.content]) # tool_use ['thinking', 'tool_use']export ANTHROPIC_BASE_URL="https://api.inferenceapis.com"
export ANTHROPIC_AUTH_TOKEN="your-key"
export ANTHROPIC_MODEL="zai-org/GLM-5.3"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="deepseek-ai/DeepSeek-V4.1-Flash"
claudeClaude Code 2.1.275 completed a real task (run the tests, fix two bugs, run them again) through this route on eight models, at 1 to 6 cents per run. Setup, per-model timings and the things to know: Claude Code.
Embeddings
POST /v1/embeddings follows the OpenAI request: model, input as a string or an array of up to 1,024 strings, optional dimensions and encoding_format. Billing is per input token. We do not meter requests per minute or per day; a load test sustained 2 to 4 million tokens per minute on BGE-M3, and the gateway retries by itself when the backend is briefly saturated (details). Vectors from different models are not comparable, so OpenAI's model ids are deliberately not aliased; choose BGE-M3 or Qwen3 Embedding 8B and re-embed once.
resp = client.embeddings.create(
model="BAAI/bge-m3",
input=["The cat sat on the mat.", "Le chat est sur le tapis."],
)
vectors = [d.embedding for d in resp.data] # 2 vectors of 1,024 floats
print(resp.usage.total_tokens)
# Qwen3 Embedding lets you choose the vector length
short = client.embeddings.create(model="Qwen/Qwen3-Embedding-8B", input="hello", dimensions=512)Rerank
POST /v1/rerank takes a query and up to 1,000 documents and returns a relevance score from 0 to 1 for each, best first. Use it after an embedding search: fetch 20 to 100 candidates, rerank, keep the top few for the prompt. Optional fields: top_n and return_documents. Billing is per token read by the model, reported in usage.total_tokens. Model: Qwen3 Reranker 8B.
curl https://api.inferenceapis.com/v1/rerank \
-H "Authorization: Bearer $INFERENCE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen3-Reranker-8B",
"query": "What is the capital of France?",
"documents": ["Bananas are yellow.", "Paris is the capital of France.", "Berlin is in Germany."],
"top_n": 2
}'
# {"object":"list","model":"Qwen/Qwen3-Reranker-8B",
# "results":[{"index":1,"relevance_score":0.978},{"index":2,"relevance_score":0.00002}],
# "usage":{"total_tokens":251}}Text to speech
POST /v1/audio/speech returns audio bytes. The response is the complete file; chunked audio streaming is not supported yet.
| Parameter | Type | Notes |
|---|---|---|
model required | string | hexgrad/Kokoro-82M or canopylabs/orpheus-3b-0.1-ft; tts-1 is an alias of Kokoro |
input required | string | Up to 20,000 characters per request |
voice | string | Defaults to af_heart (Kokoro) or tara (Orpheus). The Kokoro voice prefix sets the language |
response_format | string | mp3 (default), wav or raw PCM |
speed | number | Playback speed multiplier, for example 1.1 |
language | string | Optional pronunciation hint, for example ja |
curl https://api.inferenceapis.com/v1/audio/speech \
-H "Authorization: Bearer $INFERENCE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "hexgrad/Kokoro-82M", "voice": "af_heart", "input": "Hello there, this is a test.", "response_format": "mp3"}' \
--output hello.mp3 -D -
# HTTP/1.1 200 OK
# Content-Type: audio/mpeg
# X-Usage-Characters: 28Billing is per Unicode character of input, reported in the X-Usage-Characters response header. Voices: GET /v1/voices?model=hexgrad/Kokoro-82M with your key, or the voices by language pages.
Speech to text
POST /v1/audio/transcriptions takes a multipart upload: mp3, mp4, m4a, wav, webm, ogg or flac, up to 100 MB. Billing is per minute of audio, measured from the file before it is transcribed.
| Field | Type | Notes |
|---|---|---|
model required | string | openai/whisper-large-v3 or nvidia/parakeet-tdt-0.6b-v3; whisper-1 is an alias of Whisper Large v3 |
file required | file | The audio |
language | string | ISO 639-1 code. Skips detection; matters on short clips and for languages detection confuses (see accuracy by language) |
prompt | string | Names and jargon spelled the way you want them |
response_format | string | json (default), verbose_json, text, srt, vtt |
timestamp_granularities[] | array | segment and/or word, with verbose_json |
temperature | number | 0 to 1 |
diarize | boolean | Speaker labels (Whisper Large v3 only): every word gets a speaker, segments become speaker turns with a speaker field, plus speakers and the upstream speaker_segments. Forces verbose_json unless you ask for text, srt or vtt, which carry SPEAKER_00: labels. diarization and speaker_labels are accepted as aliases. Measured results |
min_speakers, max_speakers | integer | Hints for the diarizer; with diarize only |
curl https://api.inferenceapis.com/v1/audio/transcriptions \
-H "Authorization: Bearer $INFERENCE_API_KEY" \
-F "model=openai/whisper-large-v3" \
-F "file=@hello.mp3" \
-F "language=en" \
-F "response_format=verbose_json" \
-F "timestamp_granularities[]=word"{
"language": "en",
"duration": 1.83,
"text": "Hello there, this is a test.",
"words": [
{ "word": "Hello", "start": 0.06, "end": 0.26 },
{ "word": "there,", "start": 0.36, "end": 0.60 }
]
}Models and aliases
GET /v1/models needs no key and lists every id the API accepts. Each entry carries canonical, the id it resolves to, and type, which decides the endpoint. An alias bills at the canonical model's rate.
{ "object": "list", "data": [
{ "id": "openai/gpt-oss-120b", "object": "model", "type": "chat", "canonical": "openai/gpt-oss-120b" },
{ "id": "gpt-oss-120b", "object": "model", "type": "chat", "canonical": "openai/gpt-oss-120b" }
]}| Model | Canonical id | Also accepted | Endpoint |
|---|---|---|---|
| GPT-OSS 120B | openai/gpt-oss-120b |
gpt-oss-120b | chat/completions, responses |
| DeepSeek V4 Flash | deepseek-ai/DeepSeek-V4-Flash |
deepseek-v4-flash, deepseek-ai/DeepSeek-V4-Flash-0731, deepseek-v3, deepseek-ai/DeepSeek-V3 | chat/completions, responses |
| DeepSeek V4.1 Flash | deepseek-ai/DeepSeek-V4.1-Flash |
deepseek-v4.1-flash, deepseek-flash | chat/completions, responses |
| GLM 5.3 Flash | zai-org/GLM-5.3-Flash |
glm-5.3-flash | chat/completions, responses |
| Llama 3.3 70B Instruct | meta-llama/Llama-3.3-70B-Instruct-Turbo |
llama-3.3-70b, llama-3.3-70b-instruct, llama-3.3-70b-versatile, llama-3.1-8b-instant | chat/completions, responses |
| GLM 5.3 | zai-org/GLM-5.3 |
glm-5.3 | chat/completions, responses |
| DeepSeek V4 Pro | deepseek-ai/DeepSeek-V4-Pro |
deepseek-v4-pro, deepseek-ai/DeepSeek-V4-Pro-0813 | chat/completions, responses |
| MiniMax M3 | MiniMaxAI/MiniMax-M3 |
minimax-m3 | chat/completions, responses |
| Kimi K2.7 Code | moonshotai/Kimi-K2.7-Code |
kimi-k2.7-code | chat/completions, responses |
| GPT-OSS 20B | openai/gpt-oss-20b |
gpt-oss-20b | chat/completions, responses |
| Qwen3.8 Flash | Qwen/Qwen3.8-Flash |
qwen3.8-flash | chat/completions, responses |
| Qwen3-VL 235B | Qwen/Qwen3-VL-235B-A22B-Instruct |
qwen3-vl, qwen3-vl-235b | chat/completions, responses |
| Kokoro 82M | hexgrad/Kokoro-82M |
kokoro, kokoro-82m, tts-1 | audio/speech |
| Orpheus 3B | canopylabs/orpheus-3b-0.1-ft |
orpheus, orpheus-3b | audio/speech |
| Whisper Large v3 | openai/whisper-large-v3 |
whisper-large-v3, whisper-large-v3-turbo, whisper-1, whisper | audio/transcriptions |
| Parakeet TDT 0.6B v3 | nvidia/parakeet-tdt-0.6b-v3 |
parakeet, parakeet-tdt-0.6b-v3 | audio/transcriptions |
| Voxtral Small 24B | mistralai/Voxtral-Small-24B-2507 |
voxtral, voxtral-small, voxtral-small-24b | audio/transcriptions |
| Voxtral Mini 3B | mistralai/Voxtral-Mini-3B-2507 |
voxtral-mini, voxtral-mini-3b | audio/transcriptions |
| BGE-M3 | BAAI/bge-m3 |
bge-m3 | embeddings |
| Qwen3 Embedding 8B | Qwen/Qwen3-Embedding-8B |
qwen3-embedding-8b | embeddings |
| Qwen3 Reranker 8B | Qwen/Qwen3-Reranker-8B |
qwen3-reranker-8b | rerank |
Errors
Errors use the OpenAI envelope, so SDK exception types map as usual (AuthenticationError, NotFoundError and so on). Check for error before reading choices.
{
"error": {
"message": "Model 'nope' not found. See GET /v1/models.",
"type": "invalid_request_error",
"param": null,
"code": "model_not_found"
}
}| Status | code | Meaning | Retry? |
|---|---|---|---|
| 400 | wrong_endpoint | The model exists but belongs to another endpoint, for example a speech model sent to chat | No |
| 400 | — | Body is not valid JSON, or a required field is missing | No |
| 401 | missing_api_key, invalid_api_key | No Bearer token, or the key is not recognised | No |
| 402 | insufficient_balance | Prepaid balance is zero. Add credits | After topping up |
| 404 | model_not_found | The id is not in GET /v1/models | No |
| 413 | input_too_long, file_too_large | More than 20,000 characters of speech input, or an upload over 100 MB | No, split the input |
| 429 | upstream_rate_limited | Rare: the inference backend is saturated for that model. We do not meter your requests | Yes, honour Retry-After |
| 502 | upstream_error, upstream_auth | The inference backend failed; the message says how | Yes, with backoff |
| 503 | model_unavailable | The model is listed but not being served right now | Yes, or use another model |
Your requests and tokens are not metered per minute or per day, so a 429 here never means you used up a quota; it means the backend is busy and a retry will work. Validation errors from the model itself, such as a prompt longer than the context window, come back as 400 with the backend's message. For the errors other providers return, see the provider error reference.
Limits
| Limit | Value |
|---|---|
| Requests or tokens per minute or per day | Not metered. Abusive traffic may be throttled |
| Context window | Per model, from 131K tokens (GPT-OSS 120B, Llama 3.3 70B) to 1M tokens (the DeepSeek V4 and GLM 5.3 models); each model page states its own |
| Embedding inputs | 1,024 texts per request; 8K tokens each on BGE-M3, 32K on Qwen3 Embedding |
| Rerank documents | 1,000 per request |
| Speech input | 20,000 characters per request |
| Audio upload | 100 MB per request |
| Spend | Your prepaid balance; requests return 402 at zero |
Billing and usage
Usage is paid from prepaid credits; top up on the Billing page. Each request is metered once it completes: chat on prompt plus completion tokens, speech on input characters, transcription on audio minutes, at the rates on the pricing page. Cached input is discounted. When the beginning of your prompt matches a recent request, the backend reuses its work and reports the count in usage.prompt_tokens_details.cached_tokens; those tokens bill at the model's cached-input rate, which is about 80 to 98 percent below its normal input rate. Nothing needs switching on. It matters most for agents and long chats that resend a growing conversation every turn: keep the start of the prompt identical between requests and most of each turn is cached. A request that fails with a 4xx is not charged. What is stored per request is the model id, the unit counts, the cost and the time; prompts, audio and outputs are not retained, by us or by the GPU providers: zero data retention applies end to end (details).
Spend controls: limits, alerts and cost per request
Every key can carry a spend limit (USD per day, week, calendar month, or lifetime), an expiry date, a list of allowed models, and can be paused. The account as a whole can carry its own daily, weekly or monthly limit, and you get an email at 80% and 100% of any limit and when the balance drops below a threshold you choose (default $1). All of it is set on the API Keys page or through the MCP server. Periods reset at 00:00 UTC; the week starts on Monday.
When a limit is hit the request is refused before it costs anything: 402 with code key_spend_limit_reached or account_spend_limit_reached, a Retry-After header counting down to the reset and an X-Spend-Limit-Resets-At header. A paused key returns 403 key_paused, an expired one 403 key_expired, and a model outside a key's list 403 model_not_allowed. Other keys on the account keep working when only one key's limit is reached.
Cost on every response. Non-streamed responses carry X-Cost-USD (this request) and X-Balance-Remaining headers, plus X-Key-Spend-Remaining and X-Account-Spend-Remaining when a limit is set. The JSON usage object gains a cost field in USD on chat completions (including the final chunk of a stream), Responses, Messages, embeddings and rerank.
GET /v1/usage returns the balance, spend today, this week, this month and over the last N days (?days=30), the account limit with its reset time, every key's limit, spend and status, and a by-model breakdown. It works even when the balance is zero or a limit is reached, so an agent that receives a 402 can read exactly why and when it clears.
curl -s https://api.inferenceapis.com/v1/usage -H "Authorization: Bearer $INFERENCE_API_KEY"Not supported yet
Stored responses and OpenAI-hosted tools on the Responses API, image generation, the Batch and Files APIs, fine-tuning, real-time or streaming transcription and streamed audio output. If one of these blocks you, say so; requests decide what gets built next.
