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
POSTorPATCHretries these only when you pass anidempotencyKey, since the first attempt may already have written. - Not safe even with a key:
webhooks.create,webhooks.listenandexport.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 withmaxRetries: 0. Checkwebhooks.list()before you retrywebhooks.create. A repeatedexport.createonly reads your data again (nothing is stored). A repeatedwebhooks.listenis a second CLI listener: remove it withwebhooks.unlisten(id), or it is swept after 5 minutes without a heartbeat. - 429s: when
Retry-Afteris 60 seconds or less, the SDK waits that long and retries (up tomaxRetries). A longer wait, or none given, throwsCStarRateLimitErrorat 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;
}