Overview
| Method | Path | Auth | Purpose |
|---|---|---|---|
| POST | /v1/chat/completions | Key | Generate a response |
| GET | /v1/models | Key | List model ids |
| GET | /v1/usage | Key | This key's month spend, cap and remaining |
| GET | /v1/pricing | Public | Current prices per model |
| GET | /v1/status | Public | Live flag and lane states |
Base URL https://api.failure.fail/v1 (also https://failure.fail/v1). Auth with Authorization: Bearer <key> or x-api-key: <key>. Bodies are JSON.
POST /v1/chat/completions
OpenAI Chat Completions compatible. Standard Chat Completions fields are accepted; the ones that matter most:
| Field | Type | Notes |
|---|---|---|
| model | string, required | failure-tempest-1-flash, failure-tempest-1 or failure-tempest-1-max |
| messages | array, required | System, user and assistant messages, as in the OpenAI API |
| stream | boolean | Server-sent events; working as reasoning_content deltas |
| stream_options | object | Accepted; the final usage chunk is sent regardless |
| temperature | number | 0 makes exact repeats eligible for the response cache |
| max_tokens | integer | Ceiling on the answer length |
| tools, tool_choice | array, object | Tool-call requests go to a single tool-capable model, not fused |
Request headers
| Header | Notes |
|---|---|
| x-tempest-cache: on | off | on caches the response at any temperature; off bypasses the cache |
Example
curl https://api.failure.fail/v1/chat/completions \
-H "Authorization: Bearer $FAILURE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "failure-tempest-1",
"messages": [
{"role": "system", "content": "You are a careful assistant."},
{"role": "user", "content": "Is 2^61 - 1 prime? Show the check."}
]
}'
Response
{
"id": "chatcmpl-...",
"object": "chat.completion",
"created": 1793750400,
"model": "failure-tempest-1",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "Yes. 2^61 - 1 is a Mersenne prime ..." },
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 24,
"completion_tokens": 310,
"prompt_tokens_details": { "cached_tokens": 0 },
"completion_tokens_details": { "reasoning_tokens": 240 },
"cost": 0.00942
},
"tempest": {
"task": "...",
"difficulty": "...",
"stage": "...",
"cache": "...",
"billed_usd": 0.00942
}
}
Illustrative values. usage.cost and tempest.billed_usd are in USD.
The tempest object
| Field | Meaning |
|---|---|
| task | What the brief decided the prompt is asking for |
| difficulty | The difficulty the router and brief settled on |
| stage | The furthest pipeline stage the request reached |
| cache | Whether the response cache served this answer |
| billed_usd | What this request cost you |
Streaming chunks follow chat.completion.chunk; see streaming.
GET /v1/models
curl https://api.failure.fail/v1/models -H "Authorization: Bearer $FAILURE_API_KEY"
{
"object": "list",
"data": [
{ "id": "failure-tempest-1-flash", "object": "model" },
{ "id": "failure-tempest-1", "object": "model" },
{ "id": "failure-tempest-1-max", "object": "model" }
]
}
GET /v1/usage
The calling key's spend this month, its cap, what remains, and a per-model breakdown.
curl https://api.failure.fail/v1/usage -H "Authorization: Bearer $FAILURE_API_KEY"
Illustrative shape:
{
"month": "2026-11",
"spend_usd": 12.40,
"cap_usd": 50,
"remaining_usd": 37.60,
"models": { "failure-tempest-1": { "spend_usd": 12.40 } }
}
GET /v1/pricing
Public. Prices per 1M tokens for each model, plus billing notes.
curl https://api.failure.fail/v1/pricing
{
"models": {
"failure-tempest-1-flash": { "input": 3, "cached_input": 0.3, "output": 15 },
"failure-tempest-1": { "input": 5, "cached_input": 0.5, "output": 30 },
"failure-tempest-1-max": { "input": 10, "cached_input": 1, "output": 60 }
},
"notes": ["..."]
}
Launch draft prices; they may change. Read them from this endpoint rather than hardcoding.
GET /v1/status
Public. Whether the API is live and the state of each lane in the panel.
curl https://api.failure.fail/v1/status
Illustrative shape:
{
"live": false,
"lanes": {
"fable": { "label": "Claude Fable 5.5", "model": "...", "ready": false },
"opus": { "label": "Claude Opus 5.5", "model": "...", "ready": false },
"astra": { "label": "GPT-6 Astra 6.2", "model": "...", "ready": false },
"argon": { "label": "Gemini 4 Argon", "model": "...", "ready": false }
}
}
Errors
| Status | Type | When |
|---|---|---|
| 400 | invalid_request_error | Bad request body |
| 401 | invalid_api_key | Missing, wrong or revoked key |
| 402 | insufficient_quota | Monthly spend cap reached |
| 404 | invalid_request_error | Unknown model or route |
| 503 | service_unavailable | Not live yet, or restarting |
Shape: { "error": { "message", "type" } }. Handling patterns in errors.