SerpHubAPI

Batch search

POST /v1/batch — up to 5 searches in one request. Each one is billed like a single search, and one failure does not block the others.

POST https://api.serphubapi.com/v1/batch

Run up to 5 searches in one round trip — the same query across several sources, or several queries on one source. Each item is a normal search request and follows the same rules: routing and failover, cache, and billing (failed, empty and cache-hit items cost nothing). One item failing does not stop the others.

Request

ParameterTypeDescription
queriesarrayRequired. 1–5 items. Each item takes the same fields as POST /v1/search: q, engine, type, gl, hl, num, page, time_range, mode, include_content.

The response is always JSON; an item's format is ignored.

curl https://api.serphubapi.com/v1/batch \
  -H "X-API-Key: shapi_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"queries": [
    {"q": "wireless earbuds", "engine": "google", "gl": "us"},
    {"q": "wireless earbuds", "engine": "amazon", "type": "products"},
    {"q": "无线耳机", "engine": "xiaohongshu", "type": "notes"}
  ]}'

Response

200 whenever the request itself is valid — check each item for its own outcome. Items come back in request order.

{
  "results": [
    {
      "query": { "q": "wireless earbuds", "engine": "google", "type": "web" },
      "results": { "organic": [ { "position": 1, "title": "...", "link": "https://..." } ] },
      "meta": { "id": "sch_01J9Z3KQ8W", "status": "success", "service": "google/web", "credits_charged": 10, "cached": false, "time_ms": 812 }
    },
    {
      "query": { "q": "wireless earbuds", "engine": "amazon", "type": "products" },
      "results": { "products": [ { "position": 1, "title": "...", "price": "$29.99" } ] },
      "meta": { "id": "sch_01J9Z3KR2A", "status": "success", "service": "amazon/products", "credits_charged": 10, "cached": false, "time_ms": 1530 }
    },
    {
      "query": { "q": "无线耳机", "engine": "xiaohongshu", "type": "notes" },
      "error": { "code": "insufficient_balance", "message": "..." },
      "meta": { "status": "failed", "credits_charged": 0 }
    }
  ],
  "meta": { "calls": 3, "total_credits_charged": 20 }
}
FieldDescription
results[].queryThe item's q, engine and type, so you can match results to requests.
results[].resultsSame as results in a search response. Present on success.
results[].contentPage content, when the item set include_content.
results[].metaThe item's own meta, as in a search response. Each successful item has its own id, usable with GET /v1/searches/{id}.
results[].errorOn failure: code and message, same codes as Errors. The item costs 0.
meta.total_credits_chargedSum of what all items were charged.

Good to know

  • Items run one after another, so a batch takes about as long as its items combined. For large volumes, send several batches in parallel within your rate limit.
  • Each item is checked against your balance and key limits as it runs. If credits run out mid-batch, the remaining items fail with insufficient_balance and cost nothing.
  • AI sources can be used in a batch through engine (for example "engine": "deepseek"), but each item waits synchronously. Sources that take minutes, such as ChatGPT, may time out; send those through POST /v1/ai-search, which returns an async job.

Errors

The whole request fails only when it is malformed:

HTTPCodeWhen
400validation_errorqueries missing, empty or longer than 5, or an item is invalid
401invalid_api_keyMissing, invalid or disabled key
429rate_limitedRate limit reached