API REFERENCE

REST API v1

Authenticate with a Bearer token. All responses are JSON.
Base URL: https://whiteboxhq.ai/api/v1

Authentication

Every request must include an Authorization header with your API key as a Bearer token. Generate API keys from your dashboard after signing up.

Keys prefixed wb_live_ hit production. Keys prefixed wb_test_ run against the sandbox — decisions are simulated and not billed.

Header
Authorization: Bearer wb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
POST

/api/v1/decide

Submit a single classification query. By default runs asynchronously — add sync=true for inline results.

Request Body
Field Type Required Description
input string yes The text to classify
options array yes Array of classification labels to choose from
prompt string no Optional system prompt to guide classification
runs integer no Number of consensus runs. Range: 3–25. Default: 7
threshold float no Confidence threshold for auto-approval. Range: 0.5–0.99. Default: 0.75
sync boolean no If true, blocks until result is ready. Default: false
models array no Array of model IDs to use. Overrides defaults. See /api/v1/models for available models.
Async Response · 202
{
  "id": "dec_9f3a21d8b4c7",
  "status": "pending",
  "created_at": "2026-04-27T14:32:00Z"
}
Sync Response · 200
{
  "id": "dec_9f3a21d8b4c7",
  "value": "household_cleaning",
  "confidence": 0.831,
  "verdict": "above_threshold",
  "runs": [
    { "model": "gpt-4o-mini", "choice": "household_cleaning", "logprob": -0.12 },
    { "model": "claude-3-haiku", "choice": "household_cleaning", "logprob": -0.09 }
  ],
  "escalated": false,
  "cost_usd": 0.01,
  "latency_ms": 1243
}
Code Examples

Python SDK and NPM package coming soon — use plain HTTP libraries for now.

curl
Python (requests)
TypeScript (fetch)
curl -X POST https://whiteboxhq.ai/api/v1/decide \
  -H "Authorization: Bearer wb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "input": "Rose-scented dish brush, bamboo handle, 250g",
    "options": ["household_cleaning", "personal_care", "kitchen"],
    "runs": 7,
    "threshold": 0.75,
    "sync": true
  }'
import requests

resp = requests.post(
    "https://whiteboxhq.ai/api/v1/decide",
    headers={
        "Authorization": "Bearer wb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "Content-Type": "application/json",
    },
    json={
        "input": "Rose-scented dish brush, bamboo handle, 250g",
        "options": ["household_cleaning", "personal_care", "kitchen"],
        "runs": 7,
        "threshold": 0.75,
        "sync": True,
    },
)

data = resp.json()
print(data["value"])       # "household_cleaning"
print(data["confidence"])  # 0.831
const resp = await fetch("https://whiteboxhq.ai/api/v1/decide", {
  method: "POST",
  headers: {
    "Authorization": "Bearer wb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    input: "Rose-scented dish brush, bamboo handle, 250g",
    options: ["household_cleaning", "personal_care", "kitchen"],
    runs: 7,
    threshold: 0.75,
    sync: true,
  }),
});

const data = await resp.json();
console.log(data.value);       // "household_cleaning"
console.log(data.confidence);  // 0.831
Custom Model Selection

Override the default model rotation by passing a models array.

curl
curl -X POST https://whiteboxhq.ai/api/v1/decide \
  -H "Authorization: Bearer wb_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "input": "suspicious transaction at 3AM",
    "options": ["legitimate", "suspicious", "fraudulent"],
    "models": ["openai/gpt-4o", "anthropic/claude-sonnet-4", "mistralai/mistral-large"],
    "runs": 9,
    "threshold": 0.85,
    "sync": true
  }'
POST

/api/v1/decide/bulk

Submit up to 100 classification queries at once. Results are processed asynchronously. Optionally provide a webhook_url to receive a POST when the batch completes.

Request Body
Field Type Required Description
items array yes Array of objects, each with input, and optionally prompt and options overrides
prompt string no Shared default prompt applied to all items
options array no Shared default options applied to all items
runs integer no Consensus runs per item. Range: 3–25. Default: 7
threshold float no Confidence threshold. Range: 0.5–0.99. Default: 0.75
webhook_url string no URL to POST when the batch completes
Response · 202
{
  "id": "bat_7e2c4f1a9b83",
  "status": "processing",
  "total": 50,
  "progress": 0
}
GET /api/v1/batches/:id

Poll for batch status. Returns progress as a percentage.

{
  "id": "bat_7e2c4f1a9b83",
  "status": "completed",
  "total": 50,
  "progress": 100
}
GET /api/v1/batches/:id/results

Returns all decisions for a completed batch.

{
  "batch_id": "bat_7e2c4f1a9b83",
  "decisions": [
    {
      "id": "dec_a1b2c3d4e5f6",
      "input": "Rose-scented dish brush, bamboo handle, 250g",
      "value": "household_cleaning",
      "confidence": 0.831,
      "escalated": false
    }
  ]
}
Webhook Delivery

If webhook_url was provided, WhiteBox will POST to it when the batch completes. The payload includes the batch ID and all decisions. Verify authenticity using the X-WhiteBox-Signature header, which contains an HMAC-SHA256 digest of the request body signed with your API key.

Webhook Payload
# Headers
POST /your/webhook/endpoint
Content-Type: application/json
X-WhiteBox-Signature: sha256=a1b2c3d4e5f6...

# Body
{
  "event": "batch.completed",
  "batch_id": "bat_7e2c4f1a9b83",
  "total": 50,
  "decisions": [
    {
      "id": "dec_a1b2c3d4e5f6",
      "input": "Rose-scented dish brush, bamboo handle, 250g",
      "value": "household_cleaning",
      "confidence": 0.831,
      "escalated": false
    }
  ]
}
Code Example
Submit Batch
Poll Status
curl -X POST https://whiteboxhq.ai/api/v1/decide/bulk \
  -H "Authorization: Bearer wb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Classify this product into a category",
    "options": ["household_cleaning", "personal_care", "kitchen", "garden"],
    "runs": 7,
    "threshold": 0.75,
    "webhook_url": "https://yourapp.com/webhooks/whitebox",
    "items": [
      { "input": "Rose-scented dish brush, bamboo handle, 250g" },
      { "input": "Lavender hand cream, organic, 100ml" },
      { "input": "Stainless steel garden trowel, ergonomic grip" }
    ]
  }'
# Poll for batch status
curl https://whiteboxhq.ai/api/v1/batches/bat_7e2c4f1a9b83 \
  -H "Authorization: Bearer wb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# Fetch results when complete
curl https://whiteboxhq.ai/api/v1/batches/bat_7e2c4f1a9b83/results \
  -H "Authorization: Bearer wb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
GET

/api/v1/decisions/:id

Returns a single decision by its UUID.

curl https://whiteboxhq.ai/api/v1/decisions/dec_9f3a21d8b4c7 \
  -H "Authorization: Bearer wb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Response 200
{
  "id": "dec_9f3a21d8b4c7",
  "value": "household_cleaning",
  "confidence": 0.831,
  "verdict": "above_threshold",
  "runs": [
    { "model": "gpt-4o-mini", "choice": "household_cleaning", "logprob": -0.12 },
    { "model": "claude-3-haiku", "choice": "household_cleaning", "logprob": -0.09 }
  ],
  "escalated": false,
  "cost_usd": 0.01,
  "latency_ms": 1243,
  "created_at": "2026-04-27T14:32:00Z"
}
GET

/api/v1/decisions

Paginated list of your decisions. Most recent first.

Query Parameters
Param Type Default Description
page integer 1 Page number
per_page integer 25 Results per page (max 100)
curl "https://whiteboxhq.ai/api/v1/decisions?page=1&per_page=25" \
  -H "Authorization: Bearer wb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Reviews

GET /api/v1/reviews

List decisions that were escalated for human review. These are decisions where confidence fell below the threshold.

curl https://whiteboxhq.ai/api/v1/reviews \
  -H "Authorization: Bearer wb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Response 200
{
  "reviews": [
    {
      "id": "rev_8a4b1c2d3e5f",
      "decision_id": "dec_9f3a21d8b4c7",
      "input": "Rose-scented dish brush, bamboo handle, 250g",
      "options": ["household_cleaning", "personal_care", "kitchen"],
      "ai_suggestion": "household_cleaning",
      "confidence": 0.62,
      "status": "pending",
      "created_at": "2026-04-27T14:32:00Z"
    }
  ]
}
PATCH /api/v1/reviews/:id

Resolve a review with the correct human-chosen answer.

curl -X PATCH https://whiteboxhq.ai/api/v1/reviews/rev_8a4b1c2d3e5f \
  -H "Authorization: Bearer wb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "answer": "household_cleaning"
  }'
Response 200
{
  "id": "rev_8a4b1c2d3e5f",
  "decision_id": "dec_9f3a21d8b4c7",
  "answer": "household_cleaning",
  "status": "resolved",
  "resolved_at": "2026-04-27T15:01:00Z"
}

Rate Limits

Requests that exceed the limits receive a 429 Too Many Requests response. The Retry-After header indicates when you can retry.

Scope Limit
Authenticated API 60 requests / minute, 600 requests / hour
Unauthenticated 10 requests / minute
Sign-up 5 per hour
429 Response
{
  "error": "rate_limited",
  "message": "Too many requests. Retry after 12 seconds.",
  "retry_after": 12
}

Supported Models

WhiteBox routes each run to a different model for true multi-model consensus. You can list available models via the public endpoint below, or override the defaults by passing a models array in your request.

GET /api/v1/models PUBLIC — no auth required
curl https://whiteboxhq.ai/api/v1/models
Fast Tier — default rotation
Model ID Provider
openai/gpt-4o-mini OpenAI
openai/gpt-4.1-nano OpenAI
anthropic/claude-3.5-haiku Anthropic
meta-llama/llama-3.3-70b-instruct Meta
meta-llama/llama-4-scout Meta
google/gemini-2.0-flash-001 Google
amazon/nova-micro-v1 Amazon
amazon/nova-lite-v1 Amazon
deepseek/deepseek-chat-v3-0324 DeepSeek
mistralai/mistral-small-3.1-24b-instruct Mistral
Accurate Tier — for high-stakes decisions
Model ID Provider
openai/gpt-4o OpenAI
openai/gpt-4.1-mini OpenAI
anthropic/claude-haiku-4.5 Anthropic
anthropic/claude-sonnet-4 Anthropic
meta-llama/llama-3.1-70b-instruct Meta
mistralai/mistral-large Mistral
qwen/qwen-2.5-72b-instruct Qwen
qwen/qwen3-235b-a22b Qwen

SDKs coming soon

Official SDKs for Python and Node.js are in development. Until then, use the REST API directly with any HTTP library. Here is what the interfaces will look like:

Python
# pip install whitebox (coming soon)
from whitebox import Whitebox

wb = Whitebox(api_key="wb_live_...")
result = wb.decide(
    input="Rose-scented dish brush, bamboo handle, 250g",
    options=["household_cleaning", "personal_care", "kitchen"],
)
print(result.value)       # "household_cleaning"
print(result.confidence)  # 0.831
TypeScript
// npm i @whiteboxhq/sdk (coming soon)
import { Whitebox } from '@whiteboxhq/sdk'

const wb = new Whitebox({ apiKey: 'wb_live_...' })
const result = await wb.decide({
  input: 'Rose-scented dish brush, bamboo handle, 250g',
  options: ['household_cleaning', 'personal_care', 'kitchen'],
})
console.log(result.value)       // "household_cleaning"
console.log(result.confidence)  // 0.831

Error Codes

All errors return a JSON body with error and message fields.

Code Meaning Description
400 Bad Request Missing or invalid parameters
401 Unauthorized Missing or invalid API key
402 Insufficient Credits Account balance is zero. Add credits from the dashboard.
404 Not Found Decision, batch, or review not found
429 Rate Limited Too many requests. See Retry-After header.
500 Server Error Internal error. Retry or contact support.