SKILL.md
CAST AI Rate Limits
Overview
The CAST AI REST API enforces rate limits per API key. The autoscaler agent communicates cluster state at 15-second intervals. For custom API integrations, implement exponential backoff and request queuing to avoid hitting limits.
Prerequisites
- CAST AI API key configured
- Understanding of the API endpoints you call
Rate Limit Behavior
| Aspect | Value |
|---|---|
| Rate limit scope | Per API key |
| Response on limit | HTTP 429 with Retry-After header |
| Agent sync interval | Every 15 seconds |
| Recommended polling | No more than once per 30 seconds |
Instructions
Step 1: Detect Rate Limits from Response Headers
async function castaiRequest(path: string): Promise<Response> {
const response = await fetch(`https://api.cast.ai${path}`, {
headers: { "X-API-Key": process.env.CASTAI_API_KEY! },
});
// Log rate limit headers for monitoring
const remaining = response.headers.get("X-RateLimit-Remaining");
const reset = response.headers.get("X-RateLimit-Reset");
if (remaining) {
console.log(`Rate limit remaining: ${remaining}, resets: ${reset}`);
}
if (response.status === 429) {
const retryAfter = parseInt(response.headers.get("Retry-After") ?? "5");
throw new RateLimitError(retryAfter);
}
return response;
}
class RateLimitError extends Error {
constructor(public retryAfterSeconds: number) {
super(`Rate limited. Retry after ${retryAfterSeconds}s`);
}
}
Step 2: Exponential Backoff with Jitter
async function withBackoff<T>(
fn: () => Promise<T>,
maxRetries = 5
): Promise<T> {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (err) {
if (attempt === maxRetries) throw err;
let delayMs: number;
if (err instanceof RateLimitError) {
delayMs = err.retryAfterSeconds * 1000;
} else {
delayMs = Math.min(1000 * Math.pow(2, attempt), 30000);
}
// Add jitter to prevent thundering herd
delayMs += Math.random() * 1000;
console.log(`Retry ${attempt + 1}/${maxRetries} in ${delayMs}ms`);
await new Promise((r) => setTimeout(r, delayMs));
}
}
throw new Error("Unreachable");
}
