Skip to main content

Rate limits

Limits are per API key:
ScopeLimitWhy
All requests120 / minuteGeneral ceiling.
Census writes (PUT /census, POST/PATCH members)20 / minuteCensus writes fan out to rating and (post-enrollment) live records. Batch with PUT /census instead of looping POST /members.
Quote creates (POST /quotes)60 / hourQuotes are persistent records; don’t use them as a pricing calculator in a loop.
Exceeding a limit returns 429 rate_limited with a Retry-After header (seconds):
HTTP/1.1 429 Too Many Requests
Retry-After: 12

{ "error": "rate_limited", "message": "Rate limit exceeded. Retry after 12 seconds." }
Honor Retry-After rather than guessing your own backoff; it reflects the actual window. These limits are sized for steady-state integrations (a nightly full-roster sync for hundreds of employers fits comfortably); if a bulk migration needs more, ask your partner engineer for a temporary raise rather than building a throttle dance. Failed authentication is throttled separately: requests with a missing, malformed, revoked, or unknown API key are limited to 30 attempts per minute per source IP, after which the API returns 429 rate_limited instead of 401. Authenticated traffic is unaffected by this limiter. If you see it during development, check that your key is loaded correctly rather than retrying.

Idempotency

Every POST and PUT endpoint accepts an Idempotency-Key header:
curl -X POST https://www.getprescience.com/api/partner/v1/groups/grp_8c2f41d09a3e/enrollments \
  -H "Authorization: Bearer $PRESCIENCE_API_KEY" \
  -H "Idempotency-Key: enroll-acme-1" \
  -H "Content-Type: application/json" \
  -d '{ "quoteId": "qt_5b9e2c7f10ad", "signatory": { "name": "Dana Park", "email": "dana@acme.com" } }'
Semantics:
  • 24-hour replay window. A repeated key within 24 hours returns the stored response (same status code, same body) without re-executing anything.
  • Key is free-form. Any unique string up to 255 chars. UUIDs work; deterministic keys derived from your own entity IDs (enroll-{companyId}-{quoteId}) work better, because retries after a process crash regenerate the same key.
  • Scoped to your partner account. No cross-partner collisions to worry about.
Use it everywhere, but always on the calls that create things an employer will see: POST /groups, POST /enrollments. A timeout is not a failure; the request may have landed. With an idempotency key, the retry answers that question safely. Without one, you’re left querying state to find out.
Idempotency replays return the stored response even if it was an error. If you fix a bad request, send the corrected payload under a new key.