Usage and credit tracking
Your integration can know its credit balance and rate-limit headroom without any extra request: both arrive with every screenshot response. This page lists every usage field the API returns, where it appears, and how to watch it without wasting requests. It is part of the API documentation. For what costs a credit and how billing periods work, read credits and billing.
GET /v1/usage
GET /v1/usage returns an account summary: the plan, the credit balance for the current period, the period dates and the rate limit of the account, which all its keys share. It uses no credit and works when the balance is zero. It counts toward the per-minute rate limit like any API request.
Authenticate with an rs_live_ key as a Bearer token. A signed URL does not work on this endpoint; it returns missing_credentials.
curl -sS https://api.renderscreenshot.com/v1/usage \ -H "Authorization: Bearer $RS_API_KEY"
{ "account": { "name": "Acme Inc" }, "plan": { "id": "starter", "name": "Starter", "credits": 2500 }, "credits": 2500, "used": 312, "remaining": 2188, "period_start": "2026-10-05T08:00:00Z", "period_end": "2026-11-05T08:00:00Z", "rate_limit": { "limit": 60, "remaining": 59, "reset": 1792644660, "window": 60 } }
| Field | Meaning |
|---|---|
account.name |
The account name |
plan.id, plan.name |
The plan, for example free / Free |
plan.credits |
The plan's allowance per period |
credits |
The allowance for the current period. A Free account whose owner has not verified the email has 0. |
used |
Credits used in the current period |
remaining |
Credits left in the current period, never below 0 |
period_start, period_end |
The current period in ISO 8601 UTC. Free plan: the calendar month, because credits reset on the first day at 00:00 UTC. Paid plans: the subscription period of the last paid invoice, or null until the first invoice after sign-up is recorded. |
rate_limit.limit |
Requests allowed per minute on your plan |
rate_limit.remaining |
Requests left in the current minute for this key |
rate_limit.reset |
Unix time when the minute window resets |
rate_limit.window |
Window length in seconds (60) |
The CLI uses this endpoint for rs login and rs whoami.
Where usage data appears
| Field | Where | Meaning |
|---|---|---|
X-Credits-Used |
Header on image and PDF responses | Credits this request used: 1 for a render, 0 for a reused render |
X-Credits-Remaining |
Header on image and PDF responses | Credits left in the current period after this request |
usage.credits |
JSON body (Accept: application/json) |
Same as X-Credits-Used |
usage.remaining |
JSON body | Same as X-Credits-Remaining |
usage.credits, usage.remaining |
GET /v1/batch/:id |
Credits used by the batch so far, and the account balance now |
X-RateLimit-Limit |
Header on every authenticated API response | Requests allowed per minute on your plan |
X-RateLimit-Remaining |
Header on every authenticated API response | Requests left in the current minute |
X-RateLimit-Reset |
Header on every authenticated API response | Unix time when the minute window resets |
Retry-After |
Header on 429 responses | Seconds to wait before the next request |
The balance is shared by everyone on the account and by every API key. A JSON response looks like this:
{ "id": "req_0f1e2d3c4b5a6978", "status": "completed", "image": { "url": "https://cdn.renderscreenshot.com/screenshots/ab/cd/abcd1234_1760500000000.png", "width": 1200, "height": 630, "size": 48213, "format": "png" }, "cache": { "hit": false, "key": "screenshots/ab/cd/abcd1234_1760500000000.png", "url": "https://cdn.renderscreenshot.com/screenshots/ab/cd/abcd1234_1760500000000.png", "expires_at": "2026-10-16T12:00:00Z" }, "usage": { "credits": 1, "remaining": 2499 } }
When credits run out
Once the balance reaches zero, a screenshot request fails before any render, with HTTP 403:
{ "error": { "type": "authorization_error", "code": "insufficient_credits", "message": "Account has no remaining credits", "retryable": false, "docs": "https://renderscreenshot.com/docs/errors/insufficient-credits" }, "request_id": "5e9a1c3d-7b2f-4e80-a6d4-c1b03f8e2a95" }
A batch is checked up front: if it needs more credits than you have, the whole batch is refused with the same code, and the message says how many it needs. Retrying does not help until the period resets or the plan changes.
Reading usage in code
This Python function uses only the standard library. It reads usage from the JSON response, warns below a threshold and turns insufficient_credits into its own exception, so a worker can pause the queue instead of failing each job. Tested on 2026-10-15 with Python 3.14 against a local stub that returns the API's JSON and 403 bodies; the third call raised OutOfCredits.
import json import os import urllib.error import urllib.request API = 'https://api.renderscreenshot.com/v1/screenshot' LOW_WATER = 100 # warn below this many credits class OutOfCredits(Exception): pass def screenshot_json(payload): req = urllib.request.Request( API, data=json.dumps(payload).encode(), headers={ 'Authorization': f"Bearer {os.environ['RS_API_KEY']}", 'Content-Type': 'application/json', 'Accept': 'application/json', }, ) try: with urllib.request.urlopen(req, timeout=60) as res: body = json.load(res) except urllib.error.HTTPError as e: error = json.load(e)['error'] if e.code == 403 and error['code'] == 'insufficient_credits': raise OutOfCredits(error['message']) from None raise usage = body['usage'] # {"credits": 0 or 1, "remaining": n} if usage['remaining'] < LOW_WATER: print(f"warning: {usage['remaining']} RenderScreenshot credits left") return body['image']['url'] print(screenshot_json({'url': 'https://example.com', 'preset': 'og_card'}))
For a Node.js wrapper that tracks X-Credits-Remaining on image responses, see the credit guard in credits and billing.
Polling advice
- Do not poll for the balance. It changes only when you render, and every render response already reports it. Store the last value you saw, and call
GET /v1/usageonly when a separate job needs a fresh summary, at most every few minutes. - Never render just to read the balance. A screenshot request made for that reason costs a credit.
- Throttle alerts. Warn once when the balance crosses a threshold, not on every request after that.
- Use the rate-limit headers to pace bursts. When
X-RateLimit-Remainingreaches 0, wait untilX-RateLimit-Resetinstead of collecting 429 responses. Limits per plan are on the rate limits page. - Poll batches, not the account. For a running batch, poll
GET /v1/batch/:idevery few seconds, or set a webhook and do not poll at all. See batch. - For history, use the dashboard. The Usage page charts daily and hourly requests, formats and error rates. The Logs page shows each request with the credits it used. See the dashboard overview.
Last verified 2026-10-18 against the API routes, the usage endpoint and the response builder.