Parse, validate, and normalize any phone number worldwide using a single API call.
curl installed (or any HTTP client — Python examples included below)Let's validate a US phone number in international format. Copy and paste this into your terminal:
curl -s -X POST /api/v1/phone-validation/validate \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"rawInput": "+1 (415) 555-2671",
"defaultRegion": "US"
}' | python3 -m json.tool
Expected response:
{
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"originalInput": "+1 (415) 555-2671",
"sanitizedInput": "+14155552671",
"extension": null,
"parseStatus": "SUCCESS",
"possible": true,
"valid": true,
"overallDecision": "ACCEPTED",
"resultCode": "VALID",
"resultMessage": "Phone number is valid",
"countryCode": 1,
"regionCode": "US",
"numberType": "FIXED_LINE_OR_MOBILE",
"e164": "+14155552671",
"internationalFormat": "+1 415-555-2671",
"nationalFormat": "(415) 555-2671",
"rfc3966": "tel:+1-415-555-2671",
"warnings": [],
"errors": [],
"metadataVersion": "8.13.35",
"processingTimeMs": 12
}
parseStatus |
Whether the number could be parsed: SUCCESS, NOT_A_NUMBER, TOO_SHORT, TOO_LONG. |
valid |
Whether the number matches the country's numbering plan (length + pattern). |
overallDecision |
Policy decision: ACCEPTED, ACCEPTED_WITH_WARNINGS, REJECTED, or REVIEW. |
numberType |
Carrier classification: MOBILE, FIXED_LINE, VOIP, TOLL_FREE, etc. |
e164 |
The canonical E.164 format — best for storage and deduplication. |
regionCode |
ISO 3166-1 alpha-2 country code (e.g., US, GB, JP). |
When the input lacks a country code, pass defaultRegion:
curl -s -X POST /api/v1/phone-validation/validate \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"rawInput": "020 7946 0958",
"defaultRegion": "GB"
}'
Response will show "regionCode": "GB", "e164": "+442079460958", and "numberType": "FIXED_LINE".
curl -s -X POST /api/v1/phone-validation/validate \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"rawInput": "+1 555 123"}'
Response: "parseStatus": "TOO_SHORT", "valid": false, "overallDecision": "REJECTED".
curl -s -X POST /api/v1/phone-validation/validate \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"rawInput": "+81 90-1234-5678"}'
Response: "regionCode": "JP", "numberType": "MOBILE", "nationalFormat": "090-1234-5678".
curl -s -X POST /api/v1/phone-validation/validate \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"rawInput": "not-a-phone-number"}'
{
"parseStatus": "NOT_A_NUMBER",
"possible": false,
"valid": false,
"overallDecision": "REJECTED",
"resultCode": "PARSE_FAILURE",
"resultMessage": "Input could not be parsed as a phone number",
"errors": ["NOT_A_NUMBER"]
}
If you exceed your plan's rate limit, you'll receive:
HTTP/1.1 429 Too Many Requests
Retry-After: 1
{
"error": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Retry after 1 second."
}
Always check for 429 status and respect the Retry-After header.
import requests
API_BASE = ""
HEADERS = {
"Content-Type": "application/json",
"X-API-Key": "YOUR_API_KEY"
}
def validate_phone(raw_input, region=None):
payload = {"rawInput": raw_input}
if region:
payload["defaultRegion"] = region
resp = requests.post(
f"{API_BASE}/api/v1/phone-validation/validate",
json=payload, headers=HEADERS, verify=False
)
resp.raise_for_status()
return resp.json()
result = validate_phone("+1 415 555 2671")
print(f"Valid: {result['valid']}, E.164: {result['e164']}")
curl -s -X POST /api/v1/phone-validation/validate-batch \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"defaultRegion": "US",
"items": [
{"rawInput": "+1 415 555 2671", "itemId": "lead-001"},
{"rawInput": "020 7946 0958", "defaultRegion": "GB", "itemId": "lead-002"},
{"rawInput": "invalid", "itemId": "lead-003"}
]
}'
{
"requestId": "b2c3d4e5-f6a7-...",
"totalCount": 3,
"validCount": 2,
"invalidCount": 1,
"warningCount": 0,
"results": [ ... ]
}