GET /phone/validate

Validates a phone number in a single call: structural validity, canonical E.164 form, issuing region, national format and line type. Purely offline / structural — backed by the embedded libphonenumber metadata, zero network calls → response in milliseconds.

x402 golden rule: the agent pays for the answer to its question. “This number is invalid” is a successful answer → 200 with valid: false. The 4xx range is reserved for requests the service cannot answer.

Parameters

ParameterTypeRequiredDescription
numberstringyesNumber to validate; E.164 (+33…) or national form
countrystringnoDefault region (ISO 3166-1 alpha-2) for non-E.164 national numbers

200 response — UnifiedResponse

{
  "data": { ... },
  "provenance": {
    "source": "libphonenumber",
    "fetched_at": "2026-06-12T09:30:00Z",
    "freshness": { "kind": "snapshot", "as_of": "2025-06-01T00:00:00Z" }
  }
}
  • provenance.source: stable identifier of the numbering metadata.
  • freshness.kind: always snapshot — the answer comes from local metadata.
  • freshness.as_of: date of the embedded libphonenumber metadata version.

Fields of data

FieldTypeDescription
inputstringThe number as received (after trimming)
validboolStructural validity for its region
e164string | nullCanonical E.164 form if valid, otherwise null
countrystring | nullISO 3166-1 alpha-2 region code if valid, otherwise null
national_formatstring | nullHuman-readable national form if valid, otherwise null
number_typestring | nullLine type if valid, otherwise null (see below)
issuestring | nullDiagnostic code when valid: false

number_type is one of: mobile, fixed_line, fixed_line_or_mobile, voip, toll_free, premium_rate, shared_cost, pager, uan, voicemail, unknown.

Case 1 — valid number

All derived fields are filled in.

{
  "input": "+33612345678",
  "valid": true,
  "e164": "+33612345678",
  "country": "FR",
  "national_format": "06 12 34 56 78",
  "number_type": "mobile",
  "issue": null
}

Case 2 — national number resolved with country

GET /phone/validate?number=06 12 34 56 78&country=FR

{
  "input": "06 12 34 56 78",
  "valid": true,
  "e164": "+33612345678",
  "country": "FR",
  "national_format": "06 12 34 56 78",
  "number_type": "mobile",
  "issue": null
}

Case 3 — invalid number (successful answer → 200)

Derived fields are null; issue carries the diagnostic.

{
  "input": "not a phone",
  "valid": false,
  "e164": null,
  "country": null,
  "national_format": null,
  "number_type": null,
  "issue": "NOT_A_NUMBER"
}

Possible issue codes: BAD_FORMAT, TOO_SHORT, TOO_LONG, NOT_A_NUMBER, UNKNOWN_REGION, INVALID_FOR_REGION.

Errors

StatuscodeCase
400MISSING_PARAMETERnumber parameter missing or empty
500INTERNALInternal error (detail logged, not exposed)
{ "error": "missing or empty required parameter: number", "code": "MISSING_PARAMETER" }