SERP Data API

The Search Performance API exports the saved search-results page for one tracked keyword, website, search engine and market.


Endpoints

POST https://app.wheremore.com/api/v2/exports/serp
GET  https://app.wheremore.com/api/v2/exports/{export_id}

POST is free. The first successful GET of a non-empty ready export costs 0.5 credits. Repeat GETs of the same immutable export are free. Exports expire after seven days.


Authentication and idempotency

Send X-API-Key: sk_live_...  or Authorization: Bearer sk_live_... .


Every POST requires Idempotency-Key , containing 8 to 128 permitted characters. Retry the identical POST with the same key to receive the same export ID. Use a new key for a different request. Unknown JSON fields are rejected.


JSON fields

Field Required Description
workspace_id Yes Public workspace ID in ws_...  format.
domain Yes Tracked website hostname.
keyword Yes Exact tracked keyword text; matching is case-insensitive.
search_engine Yes google , bing  or yahoo .
market_id Yes Numeric market ID from API Access or the free GET /api/v2/markets  endpoint.
callback_url No Public HTTPS URL notified when the export becomes ready.

Find the market ID

curl "https://app.wheremore.com/api/v2/markets?workspace_id=ws_your_workspace_id&domain=example.com" \
  -H "X-API-Key: sk_live_your_key_here"

Create the export

curl -X POST "https://app.wheremore.com/api/v2/exports/serp" \
  -H "X-API-Key: sk_live_your_key_here" \
  -H "Idempotency-Key: serp-export-2026-08-25-001" \
  -H "Content-Type: application/json" \
  -d '{
    "workspace_id": "ws_your_workspace_id",
    "domain": "example.com",
    "keyword": "organic coffee beans",
    "search_engine": "google",
    "market_id": 12
  }'

HTTP 201 means the snapshot is ready. HTTP 202 means it is pending. Both are free and return an export.id  and status_url .


Retrieve the export

curl "https://app.wheremore.com/api/v2/exports/exp_0123456789abcdef0123456789abcdef" \
  -H "X-API-Key: sk_live_your_key_here"

A pending GET returns HTTP 202 and is free. A ready GET returns HTTP 200 with the saved data . The first paid retrieval reports billing_status: "deducted" ; later GETs report already_deducted , use zero credits and return identical data.


If callback_url  was supplied, its export.ready  message contains only job metadata. Always use authenticated GET for the export data.


Response

{
  "success": true,
  "export": {
    "id": "exp_0123456789abcdef0123456789abcdef",
    "type": "serp",
    "status": "ready",
    "created_at": "2026-08-25T18:00:00Z",
    "ready_at": "2026-08-25T18:00:00Z",
    "expires_at": "2026-09-01T18:00:00Z",
    "status_url": "/api/v2/exports/exp_0123456789abcdef0123456789abcdef"
  },
  "credits_used": 0.5,
  "balance": 999.5,
  "billing_status": "deducted",
  "data": {
    "workspace_id": "ws_your_workspace_id",
    "domain": "example.com",
    "domain_id": 30,
    "queue_id": 101,
    "market_id": 12,
    "keyword": "organic coffee beans",
    "search_engine": "google",
    "market_name": "UK",
    "date": "2026-08-25",
    "your_position": 8,
    "your_url": "https://example.com/coffee",
    "serp_results": [
      {
        "position": 1,
        "url": "https://another.example/result",
        "title": "Example result"
      }
    ],
    "total_results": 20
  },
  "meta": {
    "request_id": "req_example",
    "api_version": "v2",
    "data_contract": "2026-08-25",
    "duration_ms": 18.42
  }
}

The fields inside each serp_results  item reflect the stored SERP record. Consumers should tolerate additional fields being introduced under future data-contract versions.


Interpreting the data

  • date  is the date of the returned stored SERP.
  • your_position  is the selected website’s matching position and can be null  when it was not found in the stored depth.
  • your_url  is the matching ranking URL and can also be null .
  • queue_id  is Wheremore’s internal website/market monitoring configuration.
  • market_id  is the public market identifier supplied in the request.
  • market_name  is its corresponding display name.
  • serp_results  contains the stored result set for that keyword, engine and market.
  • total_results  is the number of result rows returned in this export, not the search engine’s estimated number of pages on the web.

Important limitations

  • The API returns Wheremore’s stored monitoring data, not a new unrestricted search.
  • The keyword must belong to the selected website and canonical market configuration.
  • Market scope matters. The same keyword in another country, language, device or search group is a different monitored context.
  • Results reflect the most recent successfully stored data available for the request.
  • Workspace access is checked again whenever the saved export is retrieved.
  • Search-engine layouts and feature data can vary by engine and monitoring configuration.
  • A missing position is not proof that the page is absent from the whole search engine; it means it was not present in the stored result depth.

Errors

Status Typical cause
400 A parameter is missing or search_engine  is unsupported.
401 The key is invalid, expired or revoked.
402 The shared account has insufficient credits for retrieval.
403 The key cannot access the supplied workspace.
404 The workspace, website, market, keyword or stored result was not found.
409 The request conflicts with a concurrent retrieval.
413 The saved export exceeds the maximum payload size; narrow the request.
429 The key exceeded 60 requests per minute.

Error responses include a request_id . Store it with integration logs.


Troubleshooting

The keyword is not found

  • Confirm it is already tracked in Wheremore.
  • Match the website, search engine and market used by that monitoring configuration.
  • Use the public workspace ID containing that website.
  • Check spelling; text matching is case-insensitive but otherwise uses the tracked keyword.

The market is not found

  • Call GET /api/v2/markets  for the workspace and website.
  • Use the returned numeric market_id .
  • Do not use the internal queue ID or market name in its place.
  • Confirm the market is still enabled.

Data has not updated

  • Confirm the market’s search processing is enabled.
  • Allow the scheduled rank-processing cycle to finish.
  • Poll the saved export ID until it is ready, or create a new export for a later processing cycle.

The callback is not delivered

  • Use a public HTTPS URL on port 443.
  • Accept JSON POST  requests and respond with 2xx .
  • Check callback logs. Wheremore retries failed deliveries.

A repeat retrieval

Repeat GET requests are expected to return HTTP 200 with the same saved data, zero credits used, billing_status: "already_deducted"  and balance: null .


Security

  • Keep API keys server-side.
  • Store them in a secret manager or protected environment variable.
  • Never put a key in browser code or a URL.
  • Revoke an exposed key immediately.
  • Validate the event  and expected workspace in callback payloads before starting retrieval.
  • Make callback processing idempotent because readiness notifications can be retried.
Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.