Rate Limits
1 request/minute, 30 requests/day, the X-RateLimit headers, and backoff.
Rate Limits
The live endpoint GET /v1/graph-stats/chart is metered per user:
| Window | Limit |
|---|---|
| Per minute | 1 request |
| Per day | 30 requests |
The public demo (/v1/demo/chart) and health (/health) endpoints are
unmetered — use the demo endpoint freely while developing.
Rate-limit headers
Every response on the live endpoint (both 200 and 429) carries these headers:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Per-minute request ceiling (1). |
X-RateLimit-Remaining | Requests left in the current minute window. |
X-RateLimit-Daily-Limit | Per-day request ceiling (30). |
X-RateLimit-Daily-Remaining | Requests left today. |
X-RateLimit-Reset | Unix epoch seconds when the current minute window resets. |
On a 429, an additional Retry-After header tells you how many seconds to
wait before retrying.
The 429 body
A throttled request returns the standard error envelope. The per-minute limit uses code
RATE_LIMITED; exhausting the daily quota uses DAILY_QUOTA_EXCEEDED:
{
"success": false,
"errors": [
{ "code": "RATE_LIMITED", "message": "rate limit exceeded: 1 request/minute. Retry in 47s." }
],
"data": null,
"meta": { "generated_at": "2026-07-15T09:32:11Z" }
}Retry / backoff example
Respect Retry-After; stop retrying once the daily quota is exhausted (there is no
point waiting seconds for a limit that resets tomorrow):
import time
import requests
URL = "https://graph-api.skyliferesearch.com/v1/graph-stats/chart"
def get_graph_stats(token, params=None, max_retries=5):
headers = {"Authorization": f"Bearer {token}"}
for _ in range(max_retries):
r = requests.get(URL, headers=headers, params=params)
if r.status_code != 429:
r.raise_for_status()
return r.json()
code = (r.json().get("errors") or [{}])[0].get("code")
if code == "DAILY_QUOTA_EXCEEDED":
raise RuntimeError("daily quota exhausted — try again tomorrow")
wait = int(r.headers.get("Retry-After", "60"))
time.sleep(wait)
raise RuntimeError("still rate-limited after retries")Tips
- Because the live endpoint allows only one request per minute, batch your needs
into a single call: request all metrics at once, or useperiods>1to pull a rolling
time series in one shot instead of polling. - Develop and test against
/v1/demo/chart(unmetered), then switch to the live
endpoint for real data.
Updated about 3 hours ago