Rate limits are enforced per API key, per day (UTC midnight reset).
Quotas
| Endpoint | Free tier | Paid tier |
|---|---|---|
GET /v1/video (list) | Unlimited | Unlimited |
GET /v1/video/{videoId} (get) | Unlimited | Unlimited |
POST /v1/video/{videoId}/playback-token | 1,000 / day | 0.5 Credit per 1,000 |
GET /v1/video/playback/manifest/{token} | Unlimited (token-gated) | Unlimited |
GET /v1/billing/balance | Unlimited | Unlimited |
GET /v1/billing/usage | Unlimited | Unlimited |
💡 Why only playback tokens are gated
Metadata is cheap and read-mostly. Playback token generation is the real cost surface — every token represents a video session that may stream gigabytes of media. The 1k/day floor is generous for most prototypes; production apps should top up via the dashboard.
Response headers
Every rate-limited response includes:
| Header | Type | Description |
|---|---|---|
X-RateLimit-Limit | integer | Daily quota for the calling key |
X-RateLimit-Remaining | integer | Calls left in the current window |
X-RateLimit-Reset | integer | Unix timestamp of next reset (UTC midnight) |
Retry-After | integer | (429 only) — seconds until quota resets |
Hitting the limit
When you exceed the quota:
HTTP/1.1 429 Too Many Requests
Retry-After: 14400
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1748044800
Content-Type: application/json
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Daily playback-token quota exceeded.",
"status": 429,
"retryAfter": 14400
}
}
Retry pattern
async function generateToken(videoId, apiKey) {
for (let attempt = 0; attempt < 3; attempt++) {
const res = await fetch(
`https://api.ansdev.cloud/v1/video/${videoId}/playback-token`,
{ method: 'POST', headers: { 'x-ansdev-key': apiKey } },
);
if (res.ok) return res.json();
if (res.status !== 429) throw new Error(`HTTP ${res.status}`);
const retryAfter = Number(res.headers.get('Retry-After')) || 60;
await new Promise((r) => setTimeout(r, retryAfter * 1000));
}
throw new Error('Quota exhausted; top up the wallet.');
}
⚠️ Don't loop forever on 429
A RATE_LIMIT_EXCEEDED response means the quota is genuinely gone
for the day. Surface a clear error to the user (or page on-call) and
top up via the dashboard instead of busy-waiting.
Custom limits
Need higher daily quotas? Email hello@ansdev.cloud with your use case. We can raise limits for paid accounts within one business day.