MENAVerify

Usage and rate limits

What a call costs, what the ceilings are, and how to stay inside them.

What a call costs

Nothing. Verification is free for every account, with no limit on the number of checks.

CallCostLimit
Any /v1/verify/* endpointFreePer-second ceiling on the key
/v1/verify/*/batchFreeUp to 100 items per call
/v1/playground/*Free3 checks per visitor per day without an account
/v1/account/*, health probesFree—

Each verify call still counts toward your usage — one check, or one per batch item — so the dashboard can show what your integration is doing. The count is reported as meta.credits_used on every response.

The playground allowance

The playground behind the landing page needs no account, so it gives each visitor 3 free checks, which reset 24 hours after the first one. They are counted against both the visitor's IP address and their browser fingerprint, and whichever has used more decides, so clearing storage or switching networks does not reset them. Once they are spent the playground answers 429 with free_checks_exhausted.

Create a free account to keep going: signed-in checks, in the playground and through an API key, are unlimited.

Reading your position

Every successful verification carries one header:

HeaderMeaning
X-RateLimit-LimitRequests per second allowed for the calling key

For history, the dashboard's usage endpoint breaks down requests, checks and verdicts by day.

When you hit a limit

Exceeding the per-second ceiling returns 429 with rate_limited.

Retry a 429 with exponential backoff and jitter — a fixed delay across many workers just rebuilds the spike:

async function verify(value, attempt = 0) {
  const res = await fetch(url, { ...options, body: JSON.stringify({ value }) });
  if (res.status !== 429 || attempt >= 4) return res;

  const wait = 2 ** attempt * 100 + Math.random() * 100;
  await new Promise((resolve) => setTimeout(resolve, wait));
  return verify(value, attempt + 1);
}

Going faster

Batch instead of looping. One call with 100 items spends a single request against the rate limit, where 100 calls would spend 100. Each type has its own batch endpoint, so the items share one value type:

curl https://api.menaverify.com/v1/verify/phone/batch \
  -H "Authorization: Bearer $MENAVERIFY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"items": [{"country": "AE", "value": "+971501234567"}, {"country": "AE", "value": "+971502345678"}]}'

An item the service cannot handle reports its own reason inside the envelope instead of failing the whole request.

Filter locally first. Input that could never be valid — wrong length, impossible characters — can be rejected in your own code before it reaches the API.

Use a single API key for your integration and keep it in your backend service. Development and test suites should still use the same credential flow, but they should not be stored in browsers or client-side apps.

On this page