Documentation menu · batches

Limit batches

A batch with a price ceiling and a deadline. It executes only when the market clears your limit — so off-peak idle capacity does your bulk work at your price.

Create

POST/v1/batches
curl
curl http://localhost:8787/v1/batches \
  -H "Authorization: Bearer $THIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek/deepseek-v4.1-flash",
    "requests": [
      { "custom_id": "row-1", "body": { "messages": [{"role":"user","content":"Summarise: …"}], "max_tokens": 200 } }
    ],
    "limit": { "max_input_price_micro": 50000, "max_output_price_micro": 200000, "min_discount": 70 },
    "deadline": "2026-10-23T06:00:00Z",
    "on_deadline": "expire"
  }'
  • limit — any of max_input_price_micro, max_output_price_micro, min_discount.
  • deadline — ISO-8601 time by which the batch must finish.
  • on_deadline — expire leaves unfinished rows as expired (and unbilled); market runs the remainder at the market price when the deadline arrives.
  • thin — an optional routing policy applied to every row.

The batch object

json
{
  "id": "bat_…",
  "model": "deepseek/deepseek-v4.1-flash",
  "status": "waiting | running | completed | expired | cancelled",
  "limit": { "max_output_price_micro": 200000 },
  "deadline": "2026-10-23T06:00:00Z",
  "on_deadline": "expire",
  "counts": { "total": 1000, "completed": 640, "failed": 2, "pending": 358 },
  "cost_micro": 51230,
  "list_cost_micro": 402100,
  "created_at": "…",
  "completed_at": null,
  "last_market_check": { "at": "…", "best_input_price_micro": 60000, "best_output_price_micro": 240000, "eligible": false }
}

waiting means the market hasn't met your limit yet; last_market_check shows the best price seen and whether it was eligible.

Read and manage

GET/v1/batches
GET/v1/batches/{id}
GET/v1/batches/{id}/results
POST/v1/batches/{id}/cancel
results
{ "data": [ { "custom_id": "row-1", "status": "completed", "response": { … }, "error": null, "cost_micro": 51 } ] }

From the dashboard

Batches can also be created in the dashboard by pasting JSONL — one request per line.