Spending and quotas
Which calls cost money, what stops them, and how a refusal tells you exactly why.
Most of this API is free to call: reading domains, keywords, scans, positions and history costs nothing but a rate limit. A smaller set of operations spends real money — buying search-result pages from a data provider, crawling a site, or calling a language model — and those are governed by your subscription.
The API is gated by exactly the same rules as the app. Not an equivalent set of rules: the same code. There is one implementation of every entitlement check and it sits underneath both, so an API key cannot spend anything the subscription does not cover, and nothing is enforced in one place and forgotten in the other.
Which calls spend
| Operation | What it buys | Bounded by |
|---|---|---|
POST /v1/jobs rank_run | Search-result pages for your tracked keywords | Cooldown, in-progress join, cost ceiling |
POST /v1/jobs crawl | Fetching your pages | Page cap, cooldown, cost ceiling |
POST /v1/jobs site_optimization | Language-model analysis of the crawl | Plan capability, cooldown, cost ceiling |
POST /v1/jobs ai_scan | Questions asked of AI assistants | Plan capability, call cap, cost ceiling |
POST /v1/keywords | Nothing immediately — but every future scan | Keyword slots |
POST /v1/scans | Nothing immediately — but multiplies every future scan | Keyword slots, plan dimensions |
Note the last two. Adding a keyword costs nothing today and commits you to fetching it every week from then on, on every engine, device and geography your scans cover. That is why the unit of billing is the slot, not the keyword.
What a spending request passes through
In this order, stopping at the first refusal:
- Capability — does the plan include this at all?
→
entitlement_required - Subscription health — a past-due account stops spending but keeps reading.
→
subscription_inactive - Cost ceiling — the monthly provider-spend cap for the plan.
→
cost_cap_reached - Quota — the metered monthly allowance, consumed atomically.
→
quota_exhausted - Slots — for anything that widens what is tracked.
→
slot_limit_exceeded - Cooldown — how soon the same thing may be re-run.
→
cooldown_active
Every refusal carries the numbers that produced it. A quota refusal is not "402 Payment Required" and nothing else:
{
"type": "https://docs.picorank.com/api/errors/quota_exhausted",
"title": "Monthly quota exhausted",
"status": 402,
"code": "quota_exhausted",
"detail": "This account has used 50 of 50 keyword research lookups for the current period.",
"remedy": "Wait for the reset in meta.resets_at, upgrade, or buy the matching add-on.",
"meta": {
"metric": "research_lookups",
"used": 50,
"limit": 50,
"resets_at": "2026-09-01T00:00:00Z"
},
"request_id": "req_01J8X…",
"documentation_url": "https://docs.picorank.com/api/errors/quota_exhausted"
} Checking before you commit: dry_run
Every endpoint that can spend accepts dry_run: true. It runs all six checks above and reports what
would happen — without queueing work, consuming quota, or spending a cent.
curl -X POST https://api.picorank.com/v1/keywords \
-H "Authorization: Bearer $PICORANK_KEY" \
-H "Content-Type: application/json" \
-d '{"list_id":"…","keywords":["ice cream stockholm"],"dry_run":true}' Use it before bulk imports. Adding 400 keywords and discovering at number 250 that you ran out of slots is a worse experience than being told up front, and a dry run costs nothing.
Slots, precisely
One slot is one keyword × one engine-and-device pairing × one geography, counted across your active scans with no de-duplication between them — because two scans covering the same keyword genuinely fetch it twice and cost twice.
So a single keyword tracked on Google, desktop and mobile, in Stockholm and Gothenburg, is four slots.
GET /v1/slots reports current usage, including capacity reserved by keywords you removed
recently — freed capacity stays held until the end of the billing month, so delete-and-replace cannot exceed what
you paid for.
Watching your usage
GET /v1/account/usage reports consumption against every metered allowance, read from the same counters
the guard checks. Poll it before expensive work rather than inferring your position from previous responses.
The cost ceiling
Separately from per-feature quotas, each account has a monthly ceiling on what we will spend with data providers on
its behalf. It exists so a runaway integration cannot generate an unbounded bill — for you or for us. Reaching it
returns cost_cap_reached with the amount spent, the ceiling
and the reset date. Reading your existing data continues to work; only new spending stops.