Not live yet. Failure Tempest 1 is waiting on its model lanes. Until every lane has its key,
POST /v1/chat/completions returns 503 service_unavailable with the message “not live yet”. Everything on this page is the contract you can build against today. Check status for the live flag.1. Create an account
Sign up for a Failure ID at /signup with the invite key the lab sent you (no key? ask for one). Turn on two-factor straight away — see authentication.
2. Create an API key
Then open the Console → Keys and create a key. It is shown once. We store only a hash, so if you lose it you make a new one. Set a monthly spend cap on it while you are there.
export FAILURE_API_KEY="paste-your-key-here"
3. Send a request with curl
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."}
]
}'
The response is a standard chat.completion object, with a tempest object alongside usage that tells you what the pipeline did.
4. Python
pip install openai
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.failure.fail/v1",
api_key=os.environ["FAILURE_API_KEY"],
)
resp = client.chat.completions.create(
model="failure-tempest-1",
messages=[{"role": "user", "content": "Is 2^61 - 1 prime? Show the check."}],
)
print(resp.choices[0].message.content)
print(resp.usage)
5. TypeScript
npm install openai
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.failure.fail/v1",
apiKey: process.env.FAILURE_API_KEY,
});
const resp = await client.chat.completions.create({
model: "failure-tempest-1",
messages: [{ role: "user", content: "Is 2^61 - 1 prime? Show the check." }],
});
console.log(resp.choices[0].message.content);
console.log(resp.usage);
6. Stream it
Fused answers take longer than a single model on hard prompts. Stream so your users see the working as it happens: it arrives as reasoning_content deltas before the answer arrives as content.
stream = client.chat.completions.create(
model="failure-tempest-1",
messages=[{"role": "user", "content": "Plan a zero-downtime Postgres major upgrade."}],
stream=True,
)
for chunk in stream:
if chunk.choices:
delta = chunk.choices[0].delta
working = getattr(delta, "reasoning_content", None)
if working:
print(working, end="", flush=True)
if delta.content:
print(delta.content, end="", flush=True)
if chunk.usage:
print("\n", chunk.usage)
More in streaming.