Rate Limits
VerifNow enforces quotas per billing period and concurrent request limits to ensure fair usage and API stability. This guide explains the limits for each plan and how to handle them.
Plans & limits
| Plan | Validations per billing period | Concurrent requests | Max active API keys | Overage behavior |
|---|---|---|---|---|
| FREE | 500 | 1 | 1 | Blocked |
| STARTER | 10,000 | 1 | 2 | Billed per unit |
| GROWTH | 50,000 | 2 | 5 | Billed per unit |
| PRO | 150,000 | 10 | 20 | Billed per unit |
How quotas work
- FREE plan: once you reach 500 validations in your billing period, subsequent requests are blocked with a
429response. - Paid plans (STARTER, GROWTH, PRO): requests above the included quota are not blocked. Instead, they are billed per unit at the end of the billing period.
- Quota reset: quotas reset at the start of each billing period. The billing period is tied to your subscription start date — for example, if your subscription started on the 4th, quotas reset every 4th of the month for a monthly subscription.
Limits are per API key. If you have multiple keys, each key shares your account quota.
Concurrent request limits
Each plan has a maximum number of simultaneous (concurrent) requests that can be in-flight at the same time. If you exceed this limit, the API returns a 429 Too Many Requests response — regardless of your plan.
| Plan | Max concurrent requests |
|---|---|
| FREE | 1 |
| STARTER | 1 |
| GROWTH | 2 |
| PRO | 10 |
Unlike quota limits (which only block FREE plans), concurrent request limits apply to all plans. If you send more simultaneous requests than your plan allows, the extra requests will be rejected with a 429 status.
For service protection, non-PRO plans (FREE, STARTER, GROWTH) are also subject to shared per-server concurrency controls. This means a request from a non-PRO plan can occasionally receive a 429 even if it is the only request currently in flight for that API key, or even if you are still within your plan’s documented concurrent request limit.
A 429 on a non-PRO plan does not always mean you exhausted your quota or exceeded your own per-plan concurrency. It can also be a temporary server-side protection to preserve capacity for higher-service tiers. In that case, retry the request after a short backoff.
API key limits
Each plan has a maximum number of active API keys you can have at the same time:
| Plan | Max active API keys |
|---|---|
| FREE | 1 |
| STARTER | 2 |
| GROWTH | 5 |
| PRO | 20 |
If you need more API keys, consider upgrading your plan at app.verifnow.io .
Rate limit headers
Every API response includes headers so you can monitor your current usage:
HTTP/2 200
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 413
X-RateLimit-Reset: 1705315200| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum validations allowed in the current billing period |
X-RateLimit-Remaining | Validations remaining before the quota is reached |
X-RateLimit-Reset | Unix timestamp when the billing period resets |
When you hit the quota (FREE plan)
If you are on the FREE plan and exceed your quota, the API returns 429 Too Many Requests:
{
"error": {
"code": "quota_exceeded",
"message": "Rate limit exceeded. Please upgrade your plan or try again later.",
"status": 429
}
}When you exceed concurrent request limits (all plans)
If you send more simultaneous requests than your plan allows, the API returns 429 Too Many Requests with a concurrency_exceeded error code. The same status can also be returned for temporary server-side concurrency protection on non-PRO plans.
{
"error": {
"code": "concurrency_exceeded",
"message": "Too many concurrent requests. Please retry later.",
"status": 429
}
}Tip: If you receive this error, either reduce the number of in-flight requests for your API key or retry after a short backoff. On FREE, STARTER, and GROWTH, this error can also happen because of temporary shared server pressure. For higher concurrency and stronger service guarantees, consider upgrading your plan.
Overage on paid plans
On paid plans (STARTER, GROWTH, PRO), requests above the included quota are allowed and will be billed at the per-unit rate at the end of the billing period.
HTTP/2 200
X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 0
X-Quota-Overage: truePaid plan users: requests will not be blocked due to quota overage. Overage usage is billed at the end of your billing period.
Reading rate limit headers
JavaScript
async function validateEmailWithQuotaCheck(email: string) {
const response = await fetch('https://api.verifnow.io/api/v1/validate/email', {
method: 'POST',
headers: {
'X-API-KEY': process.env.VERIFNOW_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({ value: email }),
})
// Log quota info
const remaining = response.headers.get('X-RateLimit-Remaining')
const resetAt = response.headers.get('X-RateLimit-Reset')
console.log(`Quota: ${remaining} validations remaining, resets at ${new Date(Number(resetAt) * 1000).toISOString()}`)
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') ?? '5'
throw new Error(`Request rejected because of quota or concurrency limits. Retry in ${retryAfter} seconds.`)
}
return response.json()
}Proactive quota monitoring
Use this pattern to monitor your quota usage and alert when you’re running low:
class VerifNowClient {
private remaining = Infinity
private resetAt = 0
private readonly apiKey: string
constructor(apiKey: string) {
this.apiKey = apiKey
}
async validate(email: string) {
// Warn if we're running low on quota
if (this.remaining < 50 && this.remaining > 0) {
console.warn(`⚠️ Low quota: only ${this.remaining} validations remaining`)
}
const response = await fetch('https://api.verifnow.io/api/v1/validate/email', {
method: 'POST',
headers: {
'X-API-KEY': this.apiKey,
'Content-Type': 'application/json',
},
body: JSON.stringify({ value: email }),
})
// Update local state from headers
this.remaining = Number(response.headers.get('X-RateLimit-Remaining') ?? Infinity)
this.resetAt = Number(response.headers.get('X-RateLimit-Reset') ?? 0)
if (!response.ok) {
throw new Error(`API error: ${response.status}`)
}
return response.json()
}
}Best practices
- Monitor
X-RateLimit-Remainingin every response — don’t wait for a 429 to find out - Implement exponential backoff — especially for
429responses caused by concurrency or temporary server-side protection on non-PRO plans. See Error Handling - Cache results — if you’ve already validated an email recently, reuse the result
- Upgrade your plan if you consistently exceed your quota — visit app.verifnow.io
- Track your usage in the dashboard under Usage & Billing
Bulk (batch) validation is not yet available. For now, validate one item at a time via the API.
Quota reset schedule
Quotas are reset at the start of each billing period, aligned with your subscription start date:
- Monthly subscription started on the 4th: quota resets on the 4th of each month
- Monthly subscription started on the 15th: quota resets on the 15th of each month
This is different from a calendar-month reset. Check the X-RateLimit-Reset header or your dashboard for the exact reset date.