Rate limits
The API is rate limited per key to keep the sending fleet healthy for everyone. Interactive verify and finder calls run at a real-time pace; large lists belong in a bulk job, which we pace safely on our side.
Rule of thumb. Fire single verifies for interactive flows (a signup form, a CRM lookup). For anything over a few hundred addresses, send a bulk job instead of a tight loop, it is faster, cheaper on connections, and will not trip the limiter.
The limit
Each API key can make up to 9,600 requests per minute (160 a second on average), measured over a sliding 60-second window. Requests without a key are counted per IP address. The limit is a safety net against runaway loops, set well above what any real integration needs; it is not a pricing tier.
When you hit the limit
Over-limit requests return 429 Too Many Requests with a Retry-After header. Wait that long, or back off and retry: wait a moment, then double the wait on each repeat (exponential backoff) up to about a minute.
async function withRetry(fn, tries = 5) {
let wait = 500;
for (let i = 0; i < tries; i++) {
const res = await fn();
if (res.status !== 429) return res;
await new Promise((r) => setTimeout(r, wait));
wait *= 2;
}
throw new Error("rate limited");
}Idempotency
Send an Idempotency-Key header on a single verify, batch verify, bulk upload or single finder request and a retry with the same key replays the prior response with no re-charge and no re-probe, so a network blip never double-bills you. Keys belong to your account and are remembered for 24 hours.
curl -X POST "https://api.primeverifier.com/v1/verify/single" \
-H "X-API-KEY: pk_live_your_api_key" \
-H "Idempotency-Key: 9f2c-1a7b-...." \
-H "Content-Type: application/json" \
-d '{ "email": "jane.doe@acme.com" }'