On this page

Credits & rate limits

Credits

ActionCredits
Manual POST …/leads with status: "created"−1
Manual POST …/leads/batch−1 per item with status: "created"
Manual lead duplicate / excluded0
Manual POST …/leads/batch-update0
Manual POST …/leads/batch-delete0 (no credit refund)
Maps POST /campaigns launch0 at launch; −1 per email lead found later
Start / pause / send / list / get0
POST /tools/validate-email with mode=mx0
POST /tools/validate-email with mode=full−1 only when ZeroBounce HTTP API returns a usable status; cache / disabled / error / short-circuit → 0
POST /tools/validate-emailsSum of per-item rules (max 100). Out of credits → HTTP 200 with per-item insufficient_credits
POST /tools/enrich-website0

Insufficient credits → single add 403 insufficient_credits (never HTTP 402); add-batch → HTTP 200 with per-item insufficient_credits (not envelope 403). Single validate insufficient for a needed ZeroBounce call → 403 insufficient_credits (never 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)

ClassApplies toDefault RPM
globalAll authenticated routes (including GET /activity, GET /insights/overview)120
add_leadPOST …/leads60
add_leads_batchPOST …/leads/batch10
update_leads_batchPOST …/leads/batch-update6
delete_leads_batchPOST …/leads/batch-delete10
patch_leadPATCH …/leads/:id60
create_campaignPOST /campaigns6
campaign_controlPOST …/start, POST …/pause20
inbox_sendPOST /inbox/messages10
validate_emailPOST /tools/validate-email60
validate_emails_batchPOST /tools/validate-emails10
enrich_websitePOST /tools/enrich-website20

inbox_send RPM is not the only 429 on POST /inbox/messages. Daily send quota and a high-bounce pause also return rate_limited with Retry-After (bounce pause is often about 86400 seconds).

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/leads
  • POST /campaigns/:id/leads/batch
  • POST /campaigns/:id/leads/batch-update
  • POST /campaigns/:id/leads/batch-delete
  • POST /inbox/messages
  • POST /tools/validate-email
  • POST /tools/validate-emails

POST /tools/enrich-website has no idempotency header. Single validate stores a replay only for HTTP 200; a 403 does not stick to the key.

Idempotency-Key: <client-unique-string>
RuleDetail
Max length128 characters
ReplaySame key + same body → same 200 response
MismatchSame key + different body → 409 conflict
In progressSame key still running → 409 conflict (retry shortly)
TTLAbout 24 hours
Add-batch persistOnly if any item is created | duplicate | excluded
Update-batch persistWhen summary.updated > 0
Delete-batch persistWhen summary.deleted > 0
Validate persistSingle POST /tools/validate-email stores a replay only for HTTP 200. A 403 does not stick. Enrich has no idempotency header

Invalid / too-long keys → 400 validation_error.

Pagination

QueryDefaultMax
limit50100
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.