Rank
Where does a domain rank for a keyword? Returns the best organic position in the top N and every matching result.
POST
https://api.serpkite.com/v1/rank
Credits: 7 for the top 100 (priced like /v1/search depth)
A convenience endpoint for rank trackers: it fetches the top num organic results (default 100) and returns only what matched your domain, so you don't have to parse 100 results yourself. Subdomains match (blog.example.com counts for example.com).
For large keyword sets, queue them through POST /v1/batches with endpoint: "search" and num: 100 at half price. See Rank tracking.
Request body
| Parameter | Type | Default | Description |
|---|---|---|---|
q required | string | The keyword. | |
domain required | string | Domain to find, e.g. "example.com". Subdomains match. | |
num | integer | 100 | How deep to check. One of: 10, 20, 30, 50, 100. |
country | string | us | Country code. |
language | string | en | Language code. |
location | string | Canonical location for local rankings. | |
device | string | desktop | Device to search as. One of: desktop, mobile. |
max_age | integer | Accept a cached result up to this many seconds old (half price). |
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/rank \
-H "Authorization: Bearer $SERPKITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"q":"best espresso machine 2026","domain":"example.com","country":"us"}'Response fields
| Field | Type | Description |
|---|---|---|
request | object | The normalised request, with defaults filled in: endpoint, engine, q, country, language, location, num, page, device, autocorrect… |
domain | string | The normalised domain that was searched for. |
position | integer | null | Best organic position, or null if not in the checked results. |
matches[] | array | Every matching result: position, title, link. |
checked | integer | How many organic results were inspected. |
meta | object | request_id, credits_used, cached, cached_at, engine (the provider that answered), route (provider attempts, see Search providers), latency_ms, parse_quality (ok, partial, empty), resolved_urls. |
Every billed response also carries credit and latency headers
(X-Credits-Used, X-Credits-Remaining, X-Request-Id…).
Example response
{
"request": {
"endpoint": "rank",
"engine": "google",
"q": "best espresso machine 2026",
"country": "us",
"language": "en",
"num": 100
},
"domain": "example.com",
"position": 1,
"matches": [
{
"position": 1,
"title": "The Best Espresso Machines of 2026, Tested and Reviewed",
"link": "https://www.example.com/best-espresso-machines"
},
{
"position": 14,
"title": "Espresso grinder buying guide",
"link": "https://www.example.com/grinders"
}
],
"checked": 100,
"meta": {
"request_id": "req_01J8ZK4M6Q2V7",
"credits_used": 7,
"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.
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | A parameter is missing or invalid. |
| 401 | unauthorized | The API key is missing, invalid or revoked. |
| 402 | insufficient_credits | Your balance is too low. Buy a pack or wait for the monthly free grant. |
| 429 | rate_limited | Too many requests per second for your plan. Retry after the Retry-After header. |
| 503 | upstream_error | Google could not be fetched or parsed. Not billed; retry after Retry-After. |
Notes
- Failed and empty searches are refunded, like every other endpoint.