Product

REST API

Check a phone number against WhatsApp in real time, sub-100ms, from your own code.

What you get

Single number checks

Send a number, get a valid or invalid result back in the same request.

Bulk validation

Upload a CSV through the same API for a full list in one pass.

195+ countries

Just include the country code with the number.

Organized in batches

Every check is saved to your batch, so you never pay to validate the same number twice.

Where it fits

Before a send

Validate a list before a campaign goes out.

At signup

Check a number the moment someone enters it.

Authentication

Every request needs an API key in the x-api-key header. Generate one from Settings → API keys in your dashboard — the raw key is shown once, at creation, so copy it before closing the dialog.

curl https://wavalid.com/api/v1/validate \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phoneNumber": "+14155551234"}'

Requests without a valid key, or with a revoked one, get back 401 Unauthorized. A rate-limited request gets 429 Too Many Requests instead — see Rate limits.

Base URL

https://wavalid.com/api/v1

All endpoints below are relative to this base URL.

Validate a number

POST /validate

Checks a single phone number and deducts one credit if the check completes.

Body

FieldTypeRequiredDescription
phoneNumberstringYesE.164 international format, e.g. +14155551234. Must include the country code.
batchIdnumberNoGroup this check under an existing batch. Omit it and a default batch is used.

Response

{
  "phoneNumber": "+14155551234",
  "status": "valid",
  "creditsRemaining": 482
}

status is one of:

StatusMeaning
validThe number is registered and active on WhatsApp.
invalidThe number is not on WhatsApp.
limitThe check itself hit a provider limit. No credit is deducted.

Example

curl https://wavalid.com/api/v1/validate \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phoneNumber": "+14155551234"}'
const response = await fetch("https://wavalid.com/api/v1/validate", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ phoneNumber: "+14155551234" }),
});
 
const result = await response.json();

Validate numbers in bulk

POST /validate/bulk

Checks up to 100 numbers in one request and deducts one credit per number checked.

Body

FieldTypeRequiredDescription
phoneNumbersstring[]Yes1 to 100 numbers, each in E.164 format.
batchIdnumberNoGroup these checks under an existing batch. Omit it and a default batch is used.

Response

{
  "results": [
    { "phoneNumber": "+14155551234", "status": "valid" },
    { "phoneNumber": "+442071838750", "status": "invalid" }
  ],
  "creditsUsed": 2,
  "creditsRemaining": 480
}

Example

curl https://wavalid.com/api/v1/validate/bulk \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phoneNumbers": ["+14155551234", "+442071838750"]}'

Rate limits

Each API key allows 60 requests per minute. A request over that limit returns 429 Too Many Requests, with a Retry-After header (in seconds) telling you when to try again.

Credits are a separate limit from rate limiting: running out of credits fails a request even if you're well under the rate limit.

Errors

Application errors come back as JSON with a statusCode, a human-readable message, and — where applicable — a stable code you can match on:

{
  "statusCode": 402,
  "message": "You don't have enough credits to validate a number.",
  "code": "insufficientCredits"
}

A 400 is different: it means the request body itself failed validation, and the response instead lists what's wrong per field:

{
  "success": false,
  "error": [
    {
      "path": ["phoneNumber"],
      "message": "Phone number must be in international format, e.g. +14155551234."
    }
  ]
}
StatusWhen it happens
400The request body failed validation — check phoneNumber formatting or array length.
401The API key is missing, invalid, or revoked.
402Your account doesn't have enough credits for the request.
404The batchId you passed doesn't exist, or doesn't belong to your account.
429You've exceeded the rate limit — see Rate limits.

Related

Get API access

Credit-based pricing. No subscription, no minimum.