API
Store-level stock, price and delivery ETA for Zepto, Blinkit, Swiggy Instamart and Flipkart Minutes. Base URL is this site. Create a key under API keys.
Basics
- Auth:
Authorization: Bearer qc_…(orX-API-Key). - Billing: 1 credit per product per location answered. Anything we can't answer (
UNKNOWN) and products the platform doesn't sell there (NOT_LISTED) are free. A one-off run reuses an answer from the last 5 minutes when one exists. Three ways to buy answers: a one-off run, a schedule (a run at set times), or a watch (continuous; 1 credit per store per refresh, only for stores that got a fresh answer). - Rate limit: 100 requests per minute per account; 429 carries
Retry-After. - Statuses:
IN_STOCK,OUT_OF_STOCK,NOT_LISTED(the store doesn't carry it),STORE_CLOSED,UNSERVICEABLE(no delivery to that point),UNKNOWN. inventoryis an exact unit count where the platform exposes one (Zepto);max_cart_qtyis a per-order cap, not stock.- Errors:
{"error":{"code","message"}}with 401, 402 (no credits), 404, 422, 429.
GET/api/v1/item?url=…&lat=…&lon=…
One product at one point, answered live. Waits up to wait seconds (default and max 25); if it isn't done by then you get 202 and a run_id to poll.
curl -H "Authorization: Bearer $QC_KEY" \
"$BASE/api/v1/item?lat=12.9352&lon=77.6245&url=https://www.zepto.com/pn/x/pvid/aad60fd4-b197-4a5a-a407-70700a95a704"
{
"run_id": 812, "platform": "zepto", "product": "Wellcore Creatine | 33 servings",
"location": {"lat": 12.9352, "lon": 77.6245, "name": "12.9352, 77.6245"},
"status": "IN_STOCK", "price_inr": 539, "mrp_inr": 699, "inventory": 4, "max_cart_qty": 6,
"eta_minutes": 8, "fetched_at": "2026-09-28T14:45:02Z", "done": true, "charged": 1
}POST/api/v1/runs
Up to 500 (product, point) pairs in one go. Returns 202 with an id; poll it.
curl -X POST -H "Authorization: Bearer $QC_KEY" -H "content-type: application/json" "$BASE/api/v1/runs" \
-d '{"items":[{"url":"https://blinkit.com/prn/x/prid/707701","lat":28.7043,"lon":77.1217}]}'
{"id": 813, "status": "running", "poll": "/api/v1/runs/813"}GET/api/v1/runs/{id}
status is running or done; items[] have the same fields as /item. charged is set once done.
POST/api/v1/watches
Keep a product fresh across every store in a city and get a webhook on every status change (Telegram gets restocks only). Costs 1 credit per store per refresh; the watch pauses when credits run out.
curl -X POST -H "Authorization: Bearer $QC_KEY" -H "content-type: application/json" "$BASE/api/v1/watches" \
-d '{"url":"https://www.zepto.com/pn/x/pvid/…","city":"bangalore","every_s":300,
"webhook_url":"https://example.com/hooks/stock"}'
{"id": 31, "webhook_secret": "whsec_…"} # shown onceBilled per refresh interval, afterwards, only for stores that got a fresh answer; the watch pauses before an interval your balance couldn't cover.
GET /api/v1/watches lists them, DELETE /api/v1/watches/{id} removes one. every_s: 60, 300, 900 or 3600. Optional alert_on: restock (default) or change; max_price in paise alerts only at or below it.
POST/api/v1/schedules
A run that starts itself at set IST times and delivers its report. Each run is billed like a normal run; if your balance can't cover one, that run is skipped (and you're told), not partly run.
curl -X POST -H "Authorization: Bearer $QC_KEY" -H "content-type: application/json" "$BASE/api/v1/schedules" \
-d '{"name":"morning sweep","urls":["https://www.zepto.com/pn/x/pvid/…"],"city":"bangalore",
"hours":[9,18],"minute":0,"webhook_url":"https://example.com/hooks/report"}'
{"id": 4, "credits_per_run_max": 102, "webhook_secret": "whsec_…"}Use points ([[lat,lon],…]) instead of city for specific spots. GET /api/v1/schedules lists, DELETE /api/v1/schedules/{id} removes. When a run finishes you get run.completed with every item (same fields as /runs/{id}, prices in paise).
WEBHOOKstock.changed
POST <your url>
x-qc-event: stock.changed
x-qc-signature: sha256=<hex HMAC-SHA256 of the raw body with your webhook_secret>
{"event":"stock.changed","platform":"zepto","listing":{"id":7,"name":"…","url":"…"},
"store":{"id":2,"name":"BLR-Bommanahalli","serves":["Arekere","Hongasandra"]},
"from":"OUT_OF_STOCK","to":"IN_STOCK","price":53900,"mrp":69900,"inventory":4,"at":1790600000}Prices in webhooks are in paise. Verify before trusting:
import hmac, hashlib
ok = hmac.compare_digest(
"sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest(),
request.headers["x-qc-signature"])Failed deliveries retry with backoff (2, 4, 8… minutes) up to 6 attempts.
GET/api/v1/credits
{"balance": 9412}