Credits & Rate Limits
How credits are billed, which actions cost how much, and what rate limits apply.
Rankion bills paid API actions through a simple credit system. Pure read endpoints (GET lists, status polls, detail views) are always free — you only pay for what consumes tokens, external APIs, or GPU time.
What are credits?
- One platform-wide unit. Whether article generation, AI visibility run, backlink pull, or image edit — everything is billed in credits.
- Team balance. Credits attach to the team, not the user. All tokens in the same team draw from the same pool.
- Pre-charge. Credits are reserved/charged at job dispatch time — not after completion. This prevents race conditions, but it also means an aborted job does not automatically refund credits.
Credit mechanics
In Laravel terms, every paid endpoint sits behind the credits:N middleware. It checks the team balance, charges, and only then lets the controller run.
credits:Nmiddleware → chargesNcredits before the job dispatch. If the team drops belowN, the API replies directly with402 Insufficient Creditswithout dispatching the job.- Inline refreshes (e.g. keyword explorer with
?cache=false) charge a flat 50 credits directly — the cache bust is the expensive operation. - Async jobs (HTTP
202) are already paid by the time the response arrives. The background worker inherits the booking; a worker crash does not auto-refund.
Credit costs (selection)
| Action | Endpoint | Credits |
|---|---|---|
| Generate article | POST /v1/articles/{id}/generate |
5 |
| Optimize article | POST /v1/articles/{id}/optimize |
5 |
| Repurpose article (one or all formats) | POST /v1/articles/{id}/repurpose |
3 |
| Standalone article | POST /v1/generate/article |
5 |
| Generate image | POST /v1/generate/image |
5 |
| Edit image (OpenAI Edits) | POST /v1/images/{id}/edit |
10 |
| Keyword research | POST /v1/keywords/research |
5 |
| Keyword A-Z expand | POST /v1/keywords/{id}/expand |
10 |
| Keyword Explorer (seed pull) | POST /v1/explorer |
50 |
| Explorer cache bust | ?cache=false on explorer GETs |
50 |
| Content Audit | POST /v1/content-audits |
10 |
| Competitor Analysis | POST /v1/competitor-analyses |
20 |
| Analyze internal links | POST /v1/projects/{id}/internal-links/analyze |
5 |
| Content Optimizer Analyze / Apply | POST /v1/content-optimizer/analyze · .../apply |
5 / 5 |
| AI Scanner Detect | POST /v1/ai-scanner/detect |
2 |
| Humanize article | POST /v1/ai-scanner/humanize |
5 |
| Humanize text (standalone) | POST /v1/humanize |
8 |
| Generate content brief | POST /v1/tracking-projects/{id}/prompts/{p}/generate-brief |
3 |
| Community scan | POST /v1/community/scan |
5 |
| Bulk generation (article series) | POST /v1/bulk-generations |
15 |
| Pipeline (multi-stage) | POST /v1/pipelines |
20 |
| Page Deep Audit (Vision + AI render) | POST /v1/page-audit |
30 + up to 3×15 |
| Tracking project report | POST /v1/tracking-projects/{id}/generate-report |
10 |
| Platform-gap diagnose | POST /v1/tracking-projects/{id}/insights/platform-gap/{platform}/diagnose |
1 |
| GSC sync | POST /v1/google/gsc/properties/{p}/sync |
1 |
| Agentic chat | POST /v1/agentic/chat |
varies (depends on tools used) |
Full list:
docs/API_REFERENCE.md— all 137 endpoints including the credit column. Live table: rankion.ai/settings/api-documentation.
Insufficient credits — HTTP 402
If the team balance is not enough for the action, the API responds with 402 Payment Required:
{
"message": "Insufficient credits",
"error": "insufficient_credits",
"required": 10,
"available": 4
}
The job is not dispatched, the caller can inform the user or top up credits. You can fetch the current balance any time via the credits API.
Credits API
# Current balance + plan info
curl -H "Authorization: Bearer $TOKEN" "$BASE/credits"
# Booking history (paginated)
curl -H "Authorization: Bearer $TOKEN" "$BASE/credits/history"
Example response for GET /v1/credits:
{
"data": {
"balance": 1240,
"plan": "growth",
"monthly_allotment": 5000,
"renews_at": "2026-05-15T00:00:00Z"
}
}
GET /v1/credits/history returns per entry: created_at, delta (negative = consumption, positive = top-up), endpoint, reference_id (e.g. the article ID), balance_after. With this you can attribute exactly which action consumed which credits.
Rate limits
In addition to the credit system there is a classic per-token request limit:
- ~60 requests per minute per token as the default for
auth:sanctumroutes. - If the client exceeds the limit, the API responds with
429 Too Many Requestsplus aRetry-Afterheader. - Polling loops on async jobs should therefore never be more aggressive than every 5 seconds — and always with exponential backoff on
429.
Specific endpoints have stricter limits, e.g.:
POST /v1/tracking-projects/{id}/generate-report→ 1 request / 30 min / project. Otherwise429 {error: "rate_limited"}.- Public share unlock (
POST /share/{token}/unlock) → 5 / minute (brute-force protection).
Tips for keeping costs down
- Use the cache. Explorer and similar endpoints cache for 60 min — only use
?cache=falseif you really need fresh data. - Async-poll before re-dispatching. Before a second
POST /generate, always check viaGETwhether the first job is already running (status == processing). Otherwise you pay twice. - Use
include=where supported — saves round-trips and third-party quota costs.
Continue with Projects API · back to Authentication.