CookbookBatch in Python

Run a batch end to end in Python

⚠️
Preview — this feature is being built; the design below is the spec.

Classify 10,000 support tickets overnight at the batch price: build the input file, upload it, create the batch, wait, and read the results.

import json, os, time
import requests
 
API = "https://app.syntic.ai/v1"
H = {"Authorization": f"Bearer {os.environ['SYNTIC_API_KEY']}"}
 
# 1. One request per line, each with your own custom_id
with open("tickets.jsonl", "w") as f:
    for t in load_tickets():                      # your data
        f.write(json.dumps({
            "custom_id": f"ticket-{t['id']}",
            "endpoint": "/v1/chat/completions",
            "body": {
                "model": "Amara Quick",
                "max_tokens": 5,
                "messages": [
                    {"role": "system", "content": "Reply with one word: billing, technical, account or other."},
                    {"role": "user", "content": t["text"]},
                ],
            },
        }) + "\n")
 
# 2. Upload it
with open("tickets.jsonl", "rb") as f:
    up = requests.post(f"{API}/files", headers=H, files={"file": f}, data={"purpose": "batch"}).json()
 
# 3. Create the batch
batch = requests.post(f"{API}/batches", headers={**H, "Idempotency-Key": "tickets-2026-11-05"},
                      json={"input_file_id": up["id"]}).json()
 
# 4. Wait (or subscribe to the batch.completed webhook instead)
while batch["status"] not in ("completed", "expired", "canceled", "failed"):
    time.sleep(60)
    batch = requests.get(f"{API}/batches/{batch['id']}", headers=H).json()
 
# 5. Read results, matching on custom_id
labels, failed = {}, []
with requests.get(f"{API}/batches/{batch['id']}/results", headers=H, stream=True) as r:
    for line in r.iter_lines():
        row = json.loads(line)
        if row["result"]["type"] == "succeeded":
            labels[row["custom_id"]] = row["result"]["response"]["body"]["choices"][0]["message"]["content"].strip()
        else:
            failed.append(row["custom_id"])
print(len(labels), "classified;", len(failed), "to resubmit")

Notes

  • Results arrive in any order; never rely on line position.
  • Resubmit only failed ids, in a new batch.
  • The Idempotency-Key makes step 3 safe to retry after a network error.
  • Delete results containing personal data once stored, with Delete a batch.
Was this page helpful?