Skip to content

New Official SDKs for TypeScript, Python and Go

SerpKite
Get API key
Docs menu / Batches

Batches

Queue up to 100 requests for one endpoint at half price, then poll GET /v1/batches/{id} or get a signed webhook.

POST https://api.serpkite.com/v1/batches Credits: Half the realtime price; polling is free
View as Markdown

Send one endpoint and 1–100 requests (the same bodies the realtime endpoint takes). The answer is 202 Accepted with batches: one entry per request, in order, each either a batch job or an error object (for example a request that failed validation). Each job is billed at 0.5× the realtime price, and failed jobs are refunded.

Poll GET /v1/batches/{id} (free) with a job id, or follow its poll_url, until status is done or failed. Or pass webhook_url (or set an account webhook) and we POST each finished job, signed with X-SerpKite-Signature. See Batch requests and Webhooks.

Request body

ParameterTypeDefaultDescription
endpoint requiredstringEndpoint every request runs against. One of: search, images, videos, news, maps, places, reviews, shopping, scholar, patents, autocomplete, lens, webpage.
requests requiredarray1–100 request objects with the same fields as the realtime endpoint (e.g. {"q":"…","country":"de"}).
webhook_urlstringWhere each finished job is POSTed (event batch.completed). Defaults to the account webhook set in the dashboard.

Example request

Authenticate with Authorization: Bearer $SERPKITE_API_KEY (GET requests may pass ?api_key= instead). The official SDKs read SERPKITE_API_KEY for you. See Authentication.

curl https://api.serpkite.com/v1/batches \
  -H "Authorization: Bearer $SERPKITE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"endpoint":"search","requests":[{"q":"best espresso machine","country":"us"},{"q":"best espresso machine","country":"de","language":"de"}],"webhook_url":"https://example.com/hooks/serpkite"}'

# then poll a job (free)
curl https://api.serpkite.com/v1/batches/0192f7a4-6c1e-7b3a-9d2f-5e8a1c4b7d90 \
  -H "Authorization: Bearer $SERPKITE_API_KEY"

Response fields

FieldTypeDescription
batches[]array202 response: one entry per request, in order. Each is a job (fields below) or {"error":{"code","message"}}.
idstringJob ID (UUID).
statusstringqueued, running, done or failed.
endpointstringThe endpoint the job runs, e.g. /v1/search.
created_atstringISO 8601 timestamp.
completed_atstring | nullWhen the job finished.
credits_usednumberCredits charged (0.5× the realtime price; 0 if failed).
poll_urlstringhttps://api.serpkite.com/v1/batches/<id>.
webhook_urlstring | nullWhere the result is POSTed.
webhook_statusstring | nullpending, delivered or failed.
errorobject | nullcode and message when status is failed.
resultobject | nullThe same body the realtime endpoint returns (request, results, …, meta). Present when done; kept for 24 hours.

Example response

200 OK · illustrative
{
  "id": "0192f7a4-6c1e-7b3a-9d2f-5e8a1c4b7d90",
  "status": "done",
  "endpoint": "/v1/search",
  "created_at": "2026-09-29T08:00:00Z",
  "completed_at": "2026-09-29T08:03:12Z",
  "credits_used": 0.5,
  "poll_url": "https://api.serpkite.com/v1/batches/0192f7a4-6c1e-7b3a-9d2f-5e8a1c4b7d90",
  "webhook_url": null,
  "webhook_status": null,
  "error": null,
  "result": {
    "request": {
      "endpoint": "search",
      "engine": "google",
      "q": "best espresso machine",
      "country": "us",
      "language": "en"
    },
    "results": [
      "…"
    ],
    "related_searches": [],
    "meta": {
      "request_id": "req_01J8ZK4M6Q2V7",
      "credits_used": 0.5,
      "cached": false,
      "engine": "google",
      "latency_ms": 1034,
      "parse_quality": "ok",
      "resolved_urls": true
    }
  }
}

Errors

Errors use one shape: {"error":{"code","message","request_id"}}. Errors are never billed. Full list in Errors.

StatusCodeMeaning
400invalid_requestA parameter is missing or invalid.
401unauthorizedThe API key is missing, invalid or revoked.
402insufficient_creditsYour balance is too low. Buy a pack or wait for the monthly free grant.
404not_foundThe batch job does not exist, belongs to another account, or its result has expired.
429rate_limitedToo many requests per second for your plan. Retry after the Retry-After header.
503upstream_errorGoogle could not be fetched or parsed. Not billed; retry after Retry-After.

Notes

  • GET /v1/batches/{id} is free. Poll every few seconds at most; jobs target completion within 15 minutes.
  • Realtime endpoints reject JSON arrays; send many queries through this endpoint instead.
  • The official SDKs wrap both calls: sk.batches.create(…) and sk.batches.wait(id).