Batches

POST /v1/batches runs many Soldgraph searches in one call. Poll one batch ID for every result, get a price summary per search, or download all rows as CSV.

POST https://api.soldgraph.com/v1/batches

Send many searches in one call and get one batch ID back. Use it to price a whole list of items.

A batch is a list of ordinary searches. Each one is cached, charged and refunded exactly as if you had sent it by itself.

#Create a batch

Create a batch
curl -X POST "https://api.soldgraph.com/v1/batches" \  -H "Authorization: Bearer $SOLDGRAPH_KEY" \  -H "Content-Type: application/json" \  -H "Idempotency-Key: gpu-prices-2026-10-05" \  -d '{    "defaults": { "endpoint": "ebay/sold", "country": "uk", "condition": "used", "count": 120 },    "searches": [      { "q": "RX 580 4GB" },      { "q": "GTX 1660 Ti" },      { "q": "Ryzen 7 5800X", "count": 60 }    ]  }'
  • searches is the list. Each search needs an endpoint, like ebay/sold or mercari/sold, plus the same inputs that route takes as a GET.
  • defaults are inputs applied to every search. A search can override any of them.
  • pages is an eBay shorthand. { "q": "RX 580", "pages": 3 } becomes three searches, for pages 1, 2 and 3. The most is 10. A page past the last one comes back failed with page_out_of_range and costs nothing. A bigger count usually gets the same rows in fewer searches.
  • Send Content-Type: application/json. The body can be up to 256 KB.

The answer is 202 with the batch, or 200 when every search was already cached. The Location header holds the batch's URL.

If any search is invalid, the whole batch is refused with 422 and nothing is charged. error.index says which search to fix:

One bad search
{ "error": { "code": "unsupported_or_invalid_query", "index": 2 } }

#Get the results

Poll a batch
curl "https://api.soldgraph.com/v1/batches/BATCH_ID?wait=20" \  -H "Authorization: Bearer $SOLDGRAPH_KEY"

wait holds the call open for up to 20 seconds and answers as soon as every search has settled. Poll again while status is pending.

A finished batch
{  "batch_id": "00000000-0000-4000-8000-000000000002",  "status": "complete",  "created_at": "2026-10-05T14:02:11+00:00",  "counts": { "pending": 0, "complete": 2, "failed": 0, "rejected": 1 },  "credits": 2,  "items": [    {      "index": 0, "endpoint": "ebay/sold", "q": "RX 580 4GB",      "request_id": "00000000-0000-4000-8000-000000000003",      "status": "complete", "cached": false, "credits": 1, "rows": 120,      "summary": { "priced_count": 120, "currency": "GBP", "median": 57.9, "low": 16.15, "high": 249.99,        "earliest_sold_date": "2026-09-16", "latest_sold_date": "2026-10-04", "best_offer_accepted_count": 20 }    },    { "index": 1, "endpoint": "ebay/sold", "q": "GTX 1660 Ti",      "request_id": "00000000-0000-4000-8000-000000000004",      "status": "complete", "cached": true, "credits": 1, "rows": 96, "summary": { "priced_count": 96, "currency": "GBP", "median": 74.5, "low": 30, "high": 140, "earliest_sold_date": "2026-09-20", "latest_sold_date": "2026-10-04", "best_offer_accepted_count": 11 } },    { "index": 2, "endpoint": "ebay/sold", "q": "Ryzen 7 5800X",      "request_id": null, "status": "rejected", "cached": false, "credits": 0,      "error": { "code": "too_many_pending" } }  ]}

Each search has one of four states:

statusMeaningCost
pendingStill running.Holds 1 request until it settles.
completeDone. rows and, on eBay, summary are filled in.1 request
failedThe search ran and failed. error.code is a job error.0
rejectedThe search was not accepted, for example because your allowance ran out. error.code says why.0
  • By default you get each search's summary, not its rows. That keeps a big batch small.
  • Add include=results to get every search's full result in the same answer.
  • Each request_id is an ordinary job. You can read one search at /v1/jobs/REQUEST_ID.
  • index is the position after pages is expanded.
  • A search with error.code of not_submitted was cut off before it was sent. Send the same batch again with the same Idempotency-Key and only the missing searches run.

#Download as CSV

All rows as one file
curl "https://api.soldgraph.com/v1/batches/BATCH_ID?format=csv" \  -H "Authorization: Bearer $SOLDGRAPH_KEY" -o prices.csv
  • The file has one line per listing from every complete search, with search_index and q in the first two columns.
  • Prices become two columns, like displayed_price_amount and displayed_price_currency.
  • CSV is ready once nothing is pending. Before that you get 409 result_not_ready.
  • One job works the same way: /v1/jobs/REQUEST_ID?format=csv.
  • Text that starts with =, +, - or @ gets a leading ', so a spreadsheet shows it as text.

#Limits and cost

  • Size. A batch can hold as many searches as your plan allows pending at once: 10 on Free, 25 on Starter, 50 on Pro, 100 on Business and 200 on Scale. pages counts as one search per page. A bigger batch returns 422 batch_too_large.
  • Cost. One request per search that completes, cache hits included. Failed and rejected searches are free.
  • Rate limit. Creating a batch is one API call toward your 60 per minute, however many searches it holds. Each poll is one call.
  • Pending cap. Searches in a batch count toward your pending cap like any others. If you already have searches pending, some of the batch can come back rejected with too_many_pending. Send those again once the rest finish.
  • Retries. Send an Idempotency-Key. A retry with the same key and body returns the same batch. The same key with a different body returns 409 idempotency_conflict.