The same models, from your code.

The Prabloe API is one HTTP endpoint that speaks the OpenAI chat shape. Send a list of messages and a model id, get a completion back. If you have ever called an OpenAI-style API, you already know this one.

The API is not open yet. Everything below is real — the request shapes, the models, the limits — but until this launches, calls to it answer 404. Mint a key now and you will be ready the moment it flips on.

Three steps to your first response

  1. 01

    Sign in

    Prabloe signs you in with a code sent to your email — no password to lose. Any Prabloe account can hold API keys.

  2. 02

    Mint a key

    Open Settings › Developer and create a key. It starts with pb_secret_ and is shown once. Store it somewhere your code can read and your repository cannot.

  3. 03

    Send a request

    Put the key in an Authorization: Bearer header and POST to https://www.prabloe.com/api/v1/chat. The quickstart below is a working request.

A secret key is a bearer credential: anyone holding it can spend your allowance. Keep it server-side, never in a browser bundle, and revoke it the moment it leaks — revoking is instant and a new key takes seconds.

Quickstart

One request, three languages. Replace the key, run it, and you have your 200.

curl https://www.prabloe.com/api/v1/chat \
  -H "Authorization: Bearer pb_secret_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-oss-20b",
    "messages": [
      { "role": "user", "content": "Explain a token bucket in two sentences." }
    ]
  }'

The response body is the OpenAI chat-completion shape: choices is an array, and choices[0].message.content holds the text.

Models you can name

Send one of these ids as model — or omit it, since the endpoint only serves one model right now. Every other catalogue id, integrated elsewhere in Prabloe or not, is listed as coming rather than quietly omitted.

Available today
Modelid
GPT-OSS 20BFast, clear answers for everyday questionsgpt-oss-20b

Coming: Claude Opus 5, Claude Fable 5, Claude Sonnet 5, Claude Haiku 4.5, GPT-5.6 Sol, GPT-5.6 Terra, GPT-5.6 Luna, GPT-5.3 Codex, Gemini 3.6 Flash, Gemini 3.5 Flash, Gemini Gemma 4 31B, Gemini Gemma 3 12B, Gemini Gemma 3 4B, Grok 4.5, Grok 4.3, DeepSeek V4 Flash, DeepSeek V4 Pro, DeepSeek Coder 6.7B, Qwen3.7 Max, Qwen3.5 397B, Qwen3 Coder Next, Kimi K3, Kimi K2.6, Nemotron 3.5 Lightning, Nemotron 3 Ultra, Nemotron 3 Super, Nemotron Llama Nemotron Super 49B, Meta Muse Spark 1.1, Meta Llama 4 Maverick, Meta Llama 3.3 70B, Meta Llama 3.2 90B Vision, Meta Llama 3.1 70B. Sending any of these ids gets a 400 with model_not_in_scope, whether or not that model is already live elsewhere on Prabloe.

When it does not return 200

Every failure is JSON with an error.code you can branch on. The code is stable; the message is for humans and may change.

API error codes
error.codeHTTPWhat happened, and what fixes it
invalid_key401The credential is not a pb_secret_ key at all — a pb_publishable_ key, or a secret key sent from a browser. Publishable keys authenticate a hosted app's client tier, not model calls; a secret key seen from a browser is treated as compromised.
key_revoked401No key matched what you sent — unknown, malformed, or genuinely revoked. Mint a fresh one; a revoked key never comes back.
rate_limited429You went past this credential's per-minute allowance. retry-after carries the seconds left in the current window.
insufficient_scope403The credential is valid but is not scoped for chat completions. Add the chat scope to it in the developer console — this is a scope problem, not a bad key, so rotating it will not help.
spend_limit_reached429 or 503429 when this key's own daily budget or dollar cap is spent; 503 when Prabloe's shared platform ceiling is. Either way retry-after: 3600 is sent — both windows roll over at 00:00 UTC.
model_not_in_scope400 or 403400 when the model id is unknown or simply not one this endpoint serves yet (see the table below). 403 only when the id IS the one this route serves but your key's own scope excludes it.
invalid_request400The request body itself is the problem: not valid JSON, stream: true (not supported yet), messages missing/empty/too many/malformed, or the text failed the safety check.
unavailable502 or 503The model provider, not your request, is at fault: 503 when no provider could be reached at all (retry-after: 30), 502 when one responded but with an error, an unreadable body, or an empty completion.

Headers on every response

x-prabloe-ratelimit-requests-limit
How many requests the current window allows.
x-prabloe-ratelimit-requests-remaining
How many are left in it.
x-prabloe-ratelimit-requests-reset
When the window refills, as a UTC timestamp.
retry-after
Seconds to wait, sent whenever the failure has a natural retry time: rate_limited (429, seconds left in the minute), spend_limit_reached (429 or 503, fixed at 3600 — until 00:00 UTC), and unavailable (503 only, fixed at 30).

Rate limits

Limits are per key, not per account: every credential you mint gets its own allowance from zero, so a second key does not share the first one's budget. There is no guest tier on this route — every call needs a live key, so the guest column below is always zero. Windows roll continuously rather than resetting on the hour.

Per-route rate limits for the Prabloe API
RoutePer minutePer day, guestPer day, per key
ChatPOST /api/v1/chat1001000

Read the remaining count off the response headers rather than counting your own calls — it is the number the server actually enforced.