Retry & rate limits

The SDK retries network failures and 5xx responses for you. It retries a 429 too, when the server's Retry-After is 60 seconds or less. Configure the cap; the rest is automatic.

Defaults

  • Max retries: 3 (configurable via maxRetries).
  • Request timeout: 30 seconds (configurable via timeout).
  • Backoff: exponential (500ms, 1s, 2s, 4s, capped at 8s) plus up to 200ms of jitter.
  • Retry triggers: network errors, request timeouts, and any 5xx response. A POST or PATCH retries these only when you pass an idempotencyKey, since the first attempt may already have written.
  • Not safe even with a key: webhooks.create, webhooks.listen and export.create. The API ignores the key there, but the SDK still retries a network error or 5xx. Leave the key off those calls (without one the SDK doesn't retry them), or use a client made with maxRetries: 0. Check webhooks.list() before you retry webhooks.create. A repeated export.create only reads your data again (nothing is stored). A repeated webhooks.listen is a second CLI listener: remove it with webhooks.unlisten(id), or it is swept after 5 minutes without a heartbeat.
  • 429s: when Retry-After is 60 seconds or less, the SDK waits that long and retries (up to maxRetries). A longer wait, or none given, throws CStarRateLimitError at once, so you can schedule the retry.

Tune the retry cap

client-config.js
import { CStarClient } from '@cstar.help/js';

const cstar = new CStarClient({
  apiKey: process.env.CSTAR_KEY,
  teamId: process.env.CSTAR_TEAM_ID,
  maxRetries: 5,        // Default 3
  timeout: 60_000       // Default 30000 ms
});

Drop maxRetries to 0 if you want to handle retries yourself in a job queue. The SDK will throw on the first failure.

Rate limits

  • Secret keys (sk_live_*, sk_test_*): 1000 req/hour.
  • Publishable keys (pk_live_*, pk_test_*): 100 req/hour.

Every response carries the limit on response headers:

text
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 873
X-RateLimit-Reset: 1714508400      # Unix timestamp when the window resets
X-RateLimit-Window: 3600           # Window size in seconds

Catching 429 yourself

The SDK waits out a 429 only when Retry-After is 60 seconds or less, up to maxRetries times. The hourly limit usually resets further away than that, so a used-up hour throws a typed CStarRateLimitError straight away. Its retryAfter says how long to wait, which suits a job queue better than blocking the call site.

defer-retry.js
import { CStarRateLimitError } from '@cstar.help/js';

try {
  await cstar.tickets.create(payload);
} catch (e) {
  if (e instanceof CStarRateLimitError) {
    // e.retryAfter is in seconds, or undefined if the server didn't say
    queue.enqueue('retry-ticket-create', payload, { delay: (e.retryAfter ?? 60) * 1000 });
    return;
  }
  throw e;
}

Next up