Credits & rate limits
Credits
| Action | Credits |
|---|---|
Manual POST …/leads with status: "created" | −1 |
Manual lead duplicate / excluded | 0 |
Maps POST /campaigns launch | 0 at launch; −1 per email lead found later |
| Start / pause / send / list / get | 0 |
Insufficient credits → 403 insufficient_credits (never HTTP 402).
Check balance with GET /credits.
Rate limits
Fixed 60-second windows. On 429, the response includes Retry-After (seconds) and often details.retryAfterSeconds.
Per API key (defaults)
| Class | Applies to | Default RPM |
|---|---|---|
global | All authenticated routes | 120 |
add_lead | POST …/leads | 60 |
patch_lead | PATCH …/leads/:id | 60 |
create_campaign | POST /campaigns | 6 |
campaign_control | POST …/start, POST …/pause | 20 |
inbox_send | POST /inbox/messages | 10 |
Pre-auth (before key resolves)
Protects against credential stuffing: IP and key-fingerprint buckets (defaults 60/min and 30/min). Failures still return 429 rate_limited.
Idempotency
Optional header on:
POST /campaigns/:id/leadsPOST /inbox/messages
Idempotency-Key: <client-unique-string>
| Rule | Detail |
|---|---|
| Max length | 128 characters |
| Replay | Same key + same body → same 200 response |
| Mismatch | Same key + different body → 409 conflict |
| In progress | Same key still running → 409 conflict (retry shortly) |
| TTL | About 24 hours |
Invalid / too-long keys → 400 validation_error.
Pagination
| Query | Default | Max |
|---|---|---|
limit | 50 | 100 |
cursor | — | Opaque string from previous nextCursor |
Response field: nextCursor (string or null). Invalid/expired cursor → 400 validation_error.
Request size
Max body size: 131072 bytes (128 KiB). Over → 413 validation_error with details.maxBytes.