Pipelines: processing data in bulk
You'll end up with a script that runs 10,000 reviews from a CSV through an AI model and writes each one's tone, topic and summary to a new spreadsheet.
You need: a separate fetch_... key (create one), a balance — $1 covers 10,000 reviews on DeepSeek (top up), Python 3.10+, a CSV with the columns id and text.
- 1Put a limit on the key
Dashboard → API keys: set a daily spend limit (say, $3) and allow only the models you need. The limit stops the script if it goes in circles.
- 2Install the library and set the keybash
pip install openai export ZUKKO_API_KEY="fetch_your_key"Windows (PowerShell):
$env:ZUKKO_API_KEY="fetch_your_key". - 3Save the script
File
classify_reviews.py, next toreviews.csv:classify_reviews.py""" Classify customer reviews from a CSV file through the Zukko API. Run: pip install openai export ZUKKO_API_KEY="fetch_..." python classify_reviews.py reviews.csv results.csv --limit 50 # a trial run first python classify_reviews.py reviews.csv results.csv # then everything The input CSV needs the columns id and text. You can stop the script and run it again: rows already present in results.csv are skipped. """ import argparse import asyncio - 4Test on 50 rowsbash
python classify_reviews.py reviews.csv results.csv --limit 50Check
results.csvby eye. Multiply the amount spent by 200 to get the price of all 10,000 rows. - 5Run the whole filebash
python classify_reviews.py reviews.csv results.csvFinished rows are skipped. If it stops, run the same command again.
1Which model to use
Change the model in MODEL. Pick by trial: the same 50 rows through two candidates.
| Model | Price per 1M tokens, input / output | When |
|---|---|---|
deepseek-v4.1-flash | $0.03 / $0.10 | the default |
claude-haiku-5-5 | $0.05 / $0.20 | DeepSeek failed the trial |
claude-sonnet-5-standard | $0.2 per any token | you need Sonnet's strength; no cache discount, but cheaper than claude-sonnet-5-5 here |
claude-sonnet-5-5 | $0.4 / $2 | tricky labeling |
2No code: n8n and Make
- 1Set up the HTTP request
n8n: HTTP Request node, Make: HTTP → Make a request.
POSTtohttps://api.zukko.pro/v1/chat/completions. Headers:Authorization: Bearer fetch_your_key,Content-Type: application/json,Idempotency-Key— for examplereviews-v1-plus the row id. - 2Set the request bodyjson
{ "model": "deepseek-v4.1-flash", "response_format": { "type": "json_object" }, "max_tokens": 200, "messages": [ { "role": "system", "content": "You classify customer reviews. Reply with JSON only: {\"sentiment\": \"positive|neutral|negative\", \"topic\": \"delivery|quality|price|support|other\", \"summary\": \"gist in up to 15 words\"}" }, { "role": "user", "content": "REVIEW TEXT" } ] }Replace
REVIEW TEXTwith the sheet field. In n8n useJSON.stringify(...), or a quote mark in a review breaks the JSON. - 3Parse the answer
choices[0].message.contentis a string with JSON. Make: JSON → Parse JSON, n8n: a Code or Edit Fields node. - 4Turn on retries
Retry on error in the node settings, batches of 5–10 rows, a spend limit on the key.
3If it doesn't work
| What you see | What to do |
|---|---|
402 insufficient_balance | Top up and run again — finished rows are skipped |
429 key_daily_limit_reached | Your key limit kicked in. Raise it or wait for 00:00 UTC |
Many 429 without a key-limit code | Lower CONCURRENCY to 5 |
422 idempotency_conflict | You changed the prompt — bump PROMPT_VERSION |
| Frequent "bad JSON" | Use claude-haiku-5-5 or a strict schema |
KeyError: 'id' or 'text' | Rename the columns in the first row of the CSV |
403 model_not_allowed_for_key | Add the model in the key settings |