Usage & quota
Your Ranktracker plan sets limits on how much you can track: how many keywords you can have active, and how many data rows those keywords consume. Every tracked keyword counts against these limits, so before you add keywords in bulk it pays to check what you have left.
This guide covers the one endpoint you need for that:
GET /v1/account/usage — how to read it, how the quota
model works, and what happens when you go over.
:::tip New to the API? Start with the Quickstart and Authentication guides. This guide assumes you already have an API key and can make an authenticated request. :::
Read your usage
GET /v1/account/usage returns your plan's current usage and limits. It takes
no parameters — it always reports on the account that owns the API key.
curl https://api.ranktracker.com/v1/account/usage \
-H "Authorization: tkn_usr_your_api_key_here"
import requests
resp = requests.get(
"https://api.ranktracker.com/v1/account/usage",
headers={"Authorization": "tkn_usr_your_api_key_here"},
)
resp.raise_for_status()
usage = resp.json()["data"]["attributes"]
print("Keywords remaining:", usage["keywords"]["remaining"])
const resp = await fetch("https://api.ranktracker.com/v1/account/usage", {
headers: { Authorization: "tkn_usr_your_api_key_here" },
});
const { data } = await resp.json();
console.log("Keywords remaining:", data.attributes.keywords.remaining);
Response
The response is a single JSON:API resource. The quota numbers live under
data.attributes:
{
"data": {
"id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
"type": "usage",
"attributes": {
"apiEnabled": true,
"keywords": {
"usage": 842,
"limit": 1000,
"remaining": 158
},
"dataRows": {
"usage": 4210,
"limit": 5000,
"remaining": 790
},
"onDemand": {
"usage": 12,
"limit": 50,
"remaining": 38
},
"serpAnalyser": {
"usage": 3,
"limit": 25,
"remaining": 22
}
}
}
}
What the fields mean
| Field | Meaning |
|---|---|
apiEnabled | Whether API access is enabled on your plan. If false, other endpoints return 403. |
keywords | Tracked-keyword quota — see below. |
dataRows | Data-row quota — see below. |
onDemand | On-demand ranking-check credits. |
serpAnalyser | SERP Analyser credits. |
Each quota object has the same three integer fields:
usage— how much you've consumed.limit— the ceiling your plan allows.remaining— how much headroom is left (limit - usage).
Keyword credits are rounded to whole numbers, so usage, limit and
remaining are always integers.
Keywords vs. data rows
These are two separate limits, and a keyword create must satisfy both:
- Keywords counts each tracked keyword you have active.
- Data rows counts the underlying tracking rows those keywords generate. A single keyword phrase tracked across more than one search engine, location, language, or device produces one data row per combination.
Because creating keywords tracks the cartesian product
of words × search_engines, one request can consume many data rows. Ten
phrases across three search-engine configurations is 30 data rows, not 10. Keep
that multiplier in mind when you size a bulk import against your dataRows
remaining.
Check quota before you track
Read remaining for both keywords and dataRows and compare against what
your create request will consume before you send it. A create request either
fits entirely or is rejected entirely — it does not partially apply — so
pre-checking avoids a wasted round trip.
import requests
BASE = "https://api.ranktracker.com/v1"
HEADERS = {"Authorization": "tkn_usr_your_api_key_here"}
words = ["running shoes", "trail shoes", "trainers"]
search_engines = [
{"name": "google", "location": "United States", "language": "en", "device": "desktop"},
{"name": "google", "location": "United States", "language": "en", "device": "mobile"},
]
# Tracking the cartesian product of words × search_engines adds one keyword
# (and one data row) per combination, so a create consumes BOTH keyword credits
# and data rows — check both before you send it.
needed = len(words) * len(search_engines)
usage = requests.get(f"{BASE}/account/usage", headers=HEADERS).json()["data"]["attributes"]
if usage["keywords"]["remaining"] < needed or usage["dataRows"]["remaining"] < needed:
raise SystemExit(
f"Need {needed} keyword credits and {needed} data rows; have "
f"{usage['keywords']['remaining']} and {usage['dataRows']['remaining']} remaining."
)
resp = requests.post(
f"{BASE}/domains/DOMAIN_UUID/keywords",
headers=HEADERS,
json={"frequency": "daily", "words": words, "search_engines": search_engines},
)
resp.raise_for_status()
print("Tracked", len(resp.json()["data"]), "keywords")
The usage endpoint reflects the state at the moment you call it. If several
processes add keywords concurrently, treat the pre-check as a guard, not a
guarantee — always be ready to handle a 402 on the create itself (see below).
What happens when you exceed it
If a keyword create would push you over your keyword or data-row limit, the API rejects it with HTTP 402 Payment Required and tracks nothing — the request is all-or-nothing, so no partial set of keywords is created.
curl -i -X POST https://api.ranktracker.com/v1/domains/DOMAIN_UUID/keywords \
-H "Authorization: tkn_usr_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"frequency": "daily",
"words": ["running shoes"],
"search_engines": [
{ "name": "google", "location": "United States", "language": "en", "device": "desktop" }
]
}'
A 402 uses the standard JSON:API error envelope:
{
"errors": [
{
"code": "over_quota",
"status": 402,
"detail": "Adding these keywords would exceed your plan's quota."
}
]
}
To recover, free up room or raise your ceiling, then retry:
- Stop tracking keywords you no longer need. Pause a keyword with a
PATCHthat setstrackedtofalse, or remove it entirely with aDELETE. Re-readGET /v1/account/usageto confirmremaininghas recovered. - Upgrade your plan in your
Ranktracker account to raise
limit.
402 is about plan quota, not authentication or throttling. Retrying the same
request without freeing quota will just fail again. Don't confuse it with a
503 (a throttled request — retry those with backoff, covered in
Errors & rate limits) or a 403 (API access
disabled, indicated by apiEnabled: false here).
Related guides
- Bulk operations — sizing and batching large keyword imports against your quota.
- Errors & rate limits — the full error
envelope,
402,403,503and retry guidance. - Core concepts — the domain, keyword, and search-engine resource model.
- Account reference — the full
GET /v1/account/usageschema.