What error code does the API return when out of credits?

Last updated May 20, 2026API

When your Valid Email Checker account hits zero credits across every bucket, the API stops accepting new verification requests and responds with HTTP 402 Payment Required. The error body identifies the cause as Insufficient credits and includes your current balance so you can log it and decide what to do next.

The exact response shape

json
{
  "error": "Insufficient credits",
  "current_balance": 0,
  "message": "Please purchase more credits to continue"
}
FieldTypeMeaning
errorstringAlways "Insufficient credits". Stable across releases; safe to match on.
current_balancenumberTotal credits across all buckets at the moment the request was rejected. Will be 0 most of the time; occasionally 1 or 2 for a request that needed more than the residual.
messagestringHuman-readable hint. Do not match on the exact string; it may evolve.

When does this fire?

  • /verify-single request when your total balance is below 1 credit.
  • /verify-bulk request when your total balance is below the email count in the request. For example, submitting 500 emails with only 200 credits triggers 402 immediately — the entire bulk is rejected, no partial deduction.
  • Mid-flight on a bulk task in progress, the background worker pauses the task and surfaces an out-of-credits state on the next get-results poll. The task stays paused until you top up; you can also cancel it from the dashboard.

Why 402 and not 403?

HTTP 402 (Payment Required) was reserved in the original spec for exactly this situation — a request that would succeed except the caller has not paid enough. Most APIs that hit this scenario use either 402 or 429 in practice. Valid Email Checker uses 402 because it signals a billing condition (top up to fix) rather than an abuse condition (back off and retry). The distinction matters when your client-side retry logic decides what to do next.

How to handle 402 in client code

javascript
const response = await fetch(
  'https://app.validemailchecker.com/api/verify-single',
  { /* ...headers and body... */ }
);

if (response.status === 402) {
  const data = await response.json();
  // Do NOT retry immediately — top-up is required first.
  notifyAdminToTopUp(data.current_balance);
  pauseIntegrationUntilCreditsAvailable();
  return;
}

Two things to avoid:

  • Do not retry the request in a tight loop — the balance will not change without human intervention.
  • Do not silently swallow the error. Surface it to whoever owns the integration so they can top up before the queue backs up.

Setting up a low-balance alert

Catch the problem before 402 fires
The Valid Email Checker dashboard offers an auto-refill option (under Buy Credits) that tops up your PAYG balance whenever it drops below a threshold you set. For most production integrations, enabling auto-refill at the 500-credit threshold means you never see a 402 in the wild. Cheaper than monitoring for the error and reacting after the fact.

Credits-used response field on success

On a successful /verify-single response, the body includes credits_used: 1. If you want to track running balance client-side, decrement your local counter on every successful call and use the dashboard Credits History as the periodic source of truth. The exact remaining balance after a request is not echoed in the response; query the dashboard or build a lightweight Supabase view if you need it programmatically.

What does NOT trigger 402

  • Rate limits — those return 429. See what error code when rate-limited.
  • A revoked or suspended key — that returns 403. See revoked-key error.
  • An unknown verification result — that refunds the credit automatically, so it stays a 200 OK response with credits_used: 0.

Next steps