Authenticate API requests to raise your rate limits, and handle throttling gracefully.
The public REST API works anonymously, but authenticated requests get a higher, dedicated rate limit. This page covers key creation, request authentication, and 429 handling.
Rate limit tiers
| Tier | How to authenticate | Limit (per IP or key) |
|---|---|---|
| Anonymous | None | ~10 requests/second, shared across your IP |
| API key | Authorization: Bearer <key> header | ~50 requests/second, dedicated to your key |
| EaaS / self-hosted | Instance-level configuration | Configurable per instance |
Limits are applied per second with a small burst allowance. Exceeding them returns 429 Too Many Requests.
Create an API key
- Sign in at xdcscan.io.
- Open Account β API keys and create a key.
- Store it securely β it is shown only once.
Or create one programmatically with the Account API:
curl -X POST https://xdcscan.io/account/api/v1/user/api-keys -H "Authorization: Bearer YOUR_SESSION_TOKEN" -H "Content-Type: application/json" -d '{"name": "production-backend"}'Authenticate requests
Send the key as a bearer token. The same key works on both the REST API and the Account API:
curl https://xdcscan.io/api/v2/stats -H "Authorization: Bearer $OPENSCAN_API_KEY"Handling 429 responses
When throttled, the API returns 429 with a Retry-After header (seconds to wait). Back off and retry rather than hammering the endpoint:
async function apiWithRetry(path, attempts = 5) {
for (let i = 0; i < attempts; i++) {
const res = await fetch("https://xdcscan.io" + path, {
headers: {
Authorization: "Bearer " + process.env.OPENSCAN_API_KEY,
},
});
if (res.status !== 429) return res.json();
const retryAfter = Number(res.headers.get("Retry-After") || 2 ** i);
await new Promise((r) => setTimeout(r, retryAfter * 1000));
}
throw new Error("Rate limited after " + attempts + " attempts");
}Best practices
- Cache aggressively. Chain stats and token metadata change slowly; cache them for 10β60 seconds instead of refetching per user request.
- Paginate, donβt poll. When syncing history, walk
next_page_paramsto completion and resume later from the newest known item instead of re-fetching everything. - Keep keys server-side. Never embed an API key in frontend code that ships to browsers β proxy requests through your backend.
- Rotate keys. Create a new key, deploy it, then revoke the old one. Keys can be revoked any time from Account β API keys.
- One key per service. Separate keys make usage attribution and revocation easier.
Security notes
- Keys grant read access to public chain data plus your account features (watchlists, private tags). Treat them like passwords.
- If a key leaks, revoke it immediately via the Account API:
DELETE /account/api/v1/user/api-keys/{id}.