Skip to main content

Phone Number Parsing & Validation API (libphonenumber Data)

REAL DATA

Parse and validate phone numbers from libphonenumber's numbering-plan metadata: E.164, national and RFC 3966 forms, number type, possible vs valid. No key.

Authoritative reference data or standards computation

Base URL
/api/phone-numbers
Capabilities
4 routes
Last updated
July 30, 2026
Data sources · 3

GET /api/phone-numbers/parse

Everything is decided from the pinned numbering-plan metadata. Nothing here contacts a network, an operator or a database, so a valid verdict means the number is inside a published range — never that it is assigned, in service or reachable.

Live requestRuns against the public API
No key required
GET/api/phone-numbers/parse?value=%2B45+32+12+34+56

Request parameters

The number as written: international (+45 32 12 34 56), national (0151 12345678 with country=DE), or a tel: URI. A literal plus sign must be sent as %2B, because a query string decodes + as a space. The accepted separators are space, TAB, NO-BREAK SPACE, - . ( ) / \, the U+2010–U+2015 dashes and the full-width forms + - ( ); every Unicode decimal digit is accepted and mapped to ASCII. Any other character is reported as NOT_A_NUMBER and named. The 32-character cap is this endpoint's own and is stricter than libphonenumber's 250 on purpose.

Default region for a number written in national form, as a CLDR two-letter region code (case-insensitive; these are ISO 3166-1 alpha-2 plus the exceptionally reserved AC and TA and the user-assigned XK). Ignored with a warning when value already carries its own plus-prefixed calling code. 001 is accepted as input only so that it can be rejected with an explanation: it is the non-geographical pseudo-region, not a place you dial from.

Additionally report whether the number is valid for this specific type, in validForType. Left null when omitted.

Advanced response options4 options

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

Return all fields except these (comma-separated).

Pretty-print the JSON response.

Drop the envelope: return the raw array/object without data/meta wrapper.

Response

Example parameters are ready. Send the request to inspect the live response.

Route reference

Code samples Ready-to-copy requests in 4 languages
Choose a code sample language
curl "https://randomapi.dev/api/phone-numbers/parse?value=%2B45%2032%2012%2034%2056"
const res = await fetch("https://randomapi.dev/api/phone-numbers/parse?value=%2B45%2032%2012%2034%2056");
const { data, meta } = await res.json();
import requests

data = requests.get("https://randomapi.dev/api/phone-numbers/parse?value=%2B45%2032%2012%2034%2056").json()["data"]
$json = json_decode(file_get_contents(
  "https://randomapi.dev/api/phone-numbers/parse?value=%2B45%2032%2012%2034%2056"
), true);
$data = $json["data"];
Parameters Route-specific request inputs 3
value string required

The number as written: international (+45 32 12 34 56), national (0151 12345678 with country=DE), or a tel: URI. A literal plus sign must be sent as %2B, because a query string decodes + as a space. The accepted separators are space, TAB, NO-BREAK SPACE, - . ( ) / \, the U+2010–U+2015 dashes and the full-width forms + - ( ); every Unicode decimal digit is accepted and mapped to ASCII. Any other character is reported as NOT_A_NUMBER and named. The 32-character cap is this endpoint's own and is stricter than libphonenumber's 250 on purpose.

allowed: 1 – 32
example: value=+45 32 12 34 56
country string

Default region for a number written in national form, as a CLDR two-letter region code (case-insensitive; these are ISO 3166-1 alpha-2 plus the exceptionally reserved AC and TA and the user-assigned XK). Ignored with a warning when value already carries its own plus-prefixed calling code. 001 is accepted as input only so that it can be rejected with an explanation: it is the non-geographical pseudo-region, not a place you dial from.

allowed: 2 – 3
example: country=DE
validateForType enum

Additionally report whether the number is valid for this specific type, in validForType. Left null when omitted.

allowed: fixedLine | mobile | fixedLineOrMobile | tollFree | premiumRate | sharedCost | voip | personalNumber | pager | uan | voicemail
example: validateForType=mobile
Universal parameters Shared response and formatting options 4
fields list

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

example: fields=input,parsed
exclude list

Return all fields except these (comma-separated).

example: exclude=metadataUpdated
pretty boolean

Pretty-print the JSON response.

default: false
example: pretty=true
unwrap boolean

Drop the envelope: return the raw array/object without data/meta wrapper.

default: false
example: unwrap=true
Response schema Fields returned in each record 26
input string

The value exactly as supplied, byte for byte, so a mis-encoded plus sign is visible.

example: +45 32 12 34 56

parsed boolean

Whether a country calling code and a national significant number could be extracted. False is a record, not an error.

example: true

failureReason string nullable

NOT_A_NUMBER · MISSING_REGION · INVALID_COUNTRY_CODE · TOO_SHORT_AFTER_IDD · TOO_SHORT_NSN · TOO_LONG · UNSUPPORTED_TEL_PARAMETER. The first, third, fourth, fifth and sixth are libphonenumber's own NumberParseException.ErrorType values; MISSING_REGION and UNSUPPORTED_TEL_PARAMETER are this endpoint's, and both are listed as divergences on this page. null when parsed is true.

example: null

failureDetail string nullable

One sentence naming the offending value and the rule it broke. null when parsed is true.

example: null

countryCallingCode string nullable

The country calling code with its leading plus sign.

example: +45

region string nullable

The CLDR region that owns the number, 001 for a non-geographical calling code, or null when no region on the calling code publishes a range that covers it. These are CLDR ids, not strictly ISO 3166-1: AC, TA and XK appear too.

example: DK

regionCandidates string[]

Every region sharing the calling code, in the order the number is tested against them (the main region first). One entry for an unshared code, empty when nothing parsed. An ambiguous +1 answer is visible here rather than hidden.

example: ["DK"]

nationalNumber string nullable

The national significant number, digits only, with leading zeros preserved. This is libphonenumber's getNationalSignificantNumber(): upstream stores the digits as an integer plus an italianLeadingZero flag and re-inserts the zeros on read, and every length test and pattern match runs against the re-assembled string. Here it is a string throughout — the same value, one representation.

example: 32123456

nationalPrefixStripped string nullable

The trunk prefix removed from the input, or null when none was — including for the 110 territories that publish no nationalPrefix at all (Denmark and Italy among them), where a leading 0 is part of the number and is never removed.

example: null

carrierCode string nullable

A carrier-selection code captured by the region's nationalPrefixForParsing rule (Brazil and Argentina style; 44 territories publish such a rule, 32 of them with a transform). Only ever captured from national-form input, reported and never re-inserted into a formatted number.

example: null

extension string nullable

Digits from a trailing ;ext= parameter. That is the only extension syntax this endpoint parses — x123, ext. 123, #123 and anexo 123 are not recognised.

example: null

isPossible boolean

Length-only verdict, true for both IS_POSSIBLE and IS_POSSIBLE_LOCAL_ONLY, matching libphonenumber's isPossibleNumber.

example: true

possibleReason string nullable

libphonenumber's ValidationResult verbatim — IS_POSSIBLE, IS_POSSIBLE_LOCAL_ONLY, TOO_SHORT, INVALID_LENGTH or TOO_LONG — so you can see which check decided. Upstream can also return INVALID_COUNTRY_CODE here; this endpoint cannot, because an unrecognised calling code is reported as parsed: false with failureReason INVALID_COUNTRY_CODE instead. null when parsed is false: a length verdict for a number that never parsed would be an invention.

example: IS_POSSIBLE

isValid boolean

Whether the national significant number matches a range region publishes for one of its number types. False whenever numberType is unknown or no region resolved. It says nothing about whether the line exists: a valid number may be unassigned, ported, disconnected or simply unreachable.

example: true

numberType string nullable

fixedLine · mobile · fixedLineOrMobile · tollFree · premiumRate · sharedCost · voip · personalNumber · pager · uan · voicemail · unknown. null only when parsed is false. fixedLineOrMobile is common rather than exotic — it is returned whenever a region's fixed-line and mobile ranges both cover the number, which is true for Denmark, the United States and dozens of others.

example: fixedLineOrMobile

validForType boolean nullable

Whether the number is valid for the type named by validateForType, using libphonenumber's own getNumberDescByType mapping (fixedLineOrMobile reads the fixed-line range, falling back to mobile where a region publishes no fixed-line data). A fixedLineOrMobile number can therefore be validForType: true for mobile. null when validateForType was not sent.

example: null

canBeInternationallyDialled boolean nullable

False when the number falls inside the region's noInternationalDialling range (33 regions publish one). True for a non-geographical code and for an unresolved region, because there is then no such range to fail.

example: true

mobileNumberPortableRegion boolean nullable

Upstream's per-region portability flag (107 regions). True means the number's prefix does not identify the serving operator — the reason this endpoint ships no carrier lookup.

example: true

lengths object

{ actual, possible, localOnly } — actual is the national significant number's length, possible is the union of the number-type lengths published by the calling code's MAIN region (the metadata libphonenumber's own possible-number check reads, which is why a Bermuda number is measured against the NANP set), and localOnly are the subscriber-only lengths that produce IS_POSSIBLE_LOCAL_ONLY.

example: {"actual":8,"possible":[8],"localOnly":[]}

e164 string nullable

Plus sign, calling code and national significant number, no separators. E.164 has no extension field, so an extension never appears here.

example: +4532123456

international string nullable

Calling code, a space, then the nationally grouped national significant number.

example: +45 32 12 34 56

national string nullable

National form with the trunk prefix re-applied by the matching format rule. The grouping is canonical, not the input's: +4915112345678 comes back as 01511 2345678 even when the caller wrote 0151 12345678.

example: 32 12 34 56

rfc3966 string nullable

A tel: URI. Deliberate divergence: libphonenumber emits visual separators (tel:+45-32-12-34-56); this endpoint emits the unseparated form, which is equally valid RFC 3966 global-number-digits and is what lets its own output round-trip back through value. An extension is appended as ;ext=.

example: tel:+4532123456

notes string[]

Record-level advisories about this number: a shared calling code, a merged fixed-line/mobile range, number portability, a subscriber-only length, a non-geographical code, a captured carrier code, no matching formatting rule (distinguishing a calling code with no rules at all from one whose rules did not match these digits), or a range that cannot be dialled internationally. Named notes rather than warnings so it can never be confused with meta.warnings, which carries request-level advisories. Empty for an unremarkable number.

example: ["Denmark's fixed-line and mobile ranges both cover this number, so its type is reported as fixedLineOrMobile rather than guessing between them."]

metadataVersion string

The pinned libphonenumber release this answer came from. Every parse and format decision in the response is a property of this snapshot and nothing else.

example: v9.0.35

metadataUpdated string (ISO 8601 date)

The date that release was published upstream.

example: 2026-07-17

Documented examples

Build-generated requests and complete responses
7
A Danish number in international form
GET /api/phone-numbers/parse?value=%2B45%2032%2012%2034%2056
{
  "data": {
    "input": "+45 32 12 34 56",
    "parsed": true,
    "failureReason": null,
    "failureDetail": null,
    "countryCallingCode": "+45",
    "region": "DK",
    "regionCandidates": [
      "DK"
    ],
    "nationalNumber": "32123456",
    "nationalPrefixStripped": null,
    "carrierCode": null,
    "extension": null,
    "isPossible": true,
    "possibleReason": "IS_POSSIBLE",
    "isValid": true,
    "numberType": "fixedLineOrMobile",
    "validForType": null,
    "canBeInternationallyDialled": true,
    "mobileNumberPortableRegion": true,
    "lengths": {
      "actual": 8,
      "possible": [
        8
      ],
      "localOnly": []
    },
    "e164": "+4532123456",
    "international": "+45 32 12 34 56",
    "national": "32 12 34 56",
    "rfc3966": "tel:+4532123456",
    "notes": [
      "Denmark's fixed-line and mobile ranges both cover this number, so its type is reported as fixedLineOrMobile rather than guessing between them.",
      "Denmark operates mobile number portability, so this number's range does not identify the serving operator."
    ],
    "metadataVersion": "v9.0.35",
    "metadataUpdated": "2026-07-17"
  },
    …
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
A German mobile written nationally, with the trunk prefix stripped
GET /api/phone-numbers/parse?value=0151%2012345678&country=DE
{
  "data": {
    "input": "0151 12345678",
    "parsed": true,
    "failureReason": null,
    "failureDetail": null,
    "countryCallingCode": "+49",
    "region": "DE",
    "regionCandidates": [
      "DE"
    ],
    "nationalNumber": "15112345678",
    "nationalPrefixStripped": "0",
    "carrierCode": null,
    "extension": null,
    "isPossible": true,
    "possibleReason": "IS_POSSIBLE",
    "isValid": true,
    "numberType": "mobile",
    "validForType": null,
    "canBeInternationallyDialled": true,
    "mobileNumberPortableRegion": true,
    "lengths": {
      "actual": 11,
      "possible": [
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15
      ],
      "localOnly": [
        2,
    …
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
Possible but not valid: right length, unassigned range
GET /api/phone-numbers/parse?value=%2B4511111111
{
  "data": {
    "input": "+4511111111",
    "parsed": true,
    "failureReason": null,
    "failureDetail": null,
    "countryCallingCode": "+45",
    "region": "DK",
    "regionCandidates": [
      "DK"
    ],
    "nationalNumber": "11111111",
    "nationalPrefixStripped": null,
    "carrierCode": null,
    "extension": null,
    "isPossible": true,
    "possibleReason": "IS_POSSIBLE",
    "isValid": false,
    "numberType": "unknown",
    "validForType": null,
    "canBeInternationallyDialled": true,
    "mobileNumberPortableRegion": true,
    "lengths": {
      "actual": 8,
      "possible": [
        8
      ],
      "localOnly": []
    },
    "e164": "+4511111111",
    "international": "+45 11111111",
    "national": "11111111",
    "rfc3966": "tel:+4511111111",
    "notes": [
      "Denmark operates mobile number portability, so this number's range does not identify the serving operator.",
      "No numberFormat rule matches these digits: calling code +45 publishes 1 rule (in Denmark's metadata), and a rule applies only when both its leadingDigits prefix and its own digit pattern match. The national form is therefore the ungrouped national significant number and formatRuleUsed is null."
    ],
    "metadataVersion": "v9.0.35",
    "metadataUpdated": "2026-07-17"
  },
    …
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
A +1 number and the 25 regions that share the code
GET /api/phone-numbers/parse?value=%2B1%20441%20296%201234
{
  "data": {
    "input": "+1 441 296 1234",
    "parsed": true,
    "failureReason": null,
    "failureDetail": null,
    "countryCallingCode": "+1",
    "region": "BM",
    "regionCandidates": [
      "US",
      "AG",
      "AI",
      "AS",
      "BB",
      "BM",
      "BS",
      "CA",
      "DM",
      "DO",
      "GD",
      "GU",
      "JM",
      "KN",
      "KY",
      "LC",
      "MP",
      "MS",
      "PR",
      "SX",
      "TC",
      "TT",
      "VC",
      "VG",
      "VI"
    ],
    "nationalNumber": "4412961234",
    "nationalPrefixStripped": null,
    "carrierCode": null,
    "extension": null,
    "isPossible": true,
    …
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
Too short for the plan
GET /api/phone-numbers/parse?value=%2B45321
{
  "data": {
    "input": "+45321",
    "parsed": true,
    "failureReason": null,
    "failureDetail": null,
    "countryCallingCode": "+45",
    "region": "DK",
    "regionCandidates": [
      "DK"
    ],
    "nationalNumber": "321",
    "nationalPrefixStripped": null,
    "carrierCode": null,
    "extension": null,
    "isPossible": false,
    "possibleReason": "TOO_SHORT",
    "isValid": false,
    "numberType": "unknown",
    "validForType": null,
    "canBeInternationallyDialled": true,
    "mobileNumberPortableRegion": true,
    "lengths": {
      "actual": 3,
      "possible": [
        8
      ],
      "localOnly": []
    },
    "e164": "+45321",
    "international": "+45 321",
    "national": "321",
    "rfc3966": "tel:+45321",
    "notes": [
      "Denmark operates mobile number portability, so this number's range does not identify the serving operator.",
      "No numberFormat rule matches these digits: calling code +45 publishes 1 rule (in Denmark's metadata), and a rule applies only when both its leadingDigits prefix and its own digit pattern match. The national form is therefore the ungrouped national significant number and formatRuleUsed is null."
    ],
    "metadataVersion": "v9.0.35",
    "metadataUpdated": "2026-07-17"
  },
    …
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
Is the number valid for the mobile type?
GET /api/phone-numbers/parse?value=%2B4915112345678&validateForType=mobile
{
  "data": {
    "input": "+4915112345678",
    "parsed": true,
    "failureReason": null,
    "failureDetail": null,
    "countryCallingCode": "+49",
    "region": "DE",
    "regionCandidates": [
      "DE"
    ],
    "nationalNumber": "15112345678",
    "nationalPrefixStripped": null,
    "carrierCode": null,
    "extension": null,
    "isPossible": true,
    "possibleReason": "IS_POSSIBLE",
    "isValid": true,
    "numberType": "mobile",
    "validForType": true,
    "canBeInternationallyDialled": true,
    "mobileNumberPortableRegion": true,
    "lengths": {
      "actual": 11,
      "possible": [
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15
      ],
      "localOnly": [
        2,
    …
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
tel: URI with an extension
GET /api/phone-numbers/parse?value=tel%3A%2B441212345678%3Bext%3D123
{
  "data": {
    "input": "tel:+441212345678;ext=123",
    "parsed": true,
    "failureReason": null,
    "failureDetail": null,
    "countryCallingCode": "+44",
    "region": "GB",
    "regionCandidates": [
      "GB",
      "GG",
      "IM",
      "JE"
    ],
    "nationalNumber": "1212345678",
    "nationalPrefixStripped": null,
    "carrierCode": null,
    "extension": "123",
    "isPossible": true,
    "possibleReason": "IS_POSSIBLE",
    "isValid": true,
    "numberType": "fixedLine",
    "validForType": null,
    "canBeInternationallyDialled": true,
    "mobileNumberPortableRegion": true,
    "lengths": {
      "actual": 10,
      "possible": [
        7,
        9,
        10
      ],
      "localOnly": [
        4,
        5,
        6,
        8
      ]
    },
    "e164": "+441212345678",
    …
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}

GET /api/phone-numbers/format

Formatting is not validation: a possible-but-unassigned number formats perfectly, and isValid is the only field here that speaks to validity. fromRegion implements libphonenumber's formatOutOfCountryCallingNumber, and formatRuleUsed exposes which published rule produced the grouping.

Live requestRuns against the public API
No key required
GET/api/phone-numbers/format?value=%2B4532123456

Request parameters

The number as written: international (+45 32 12 34 56), national (0151 12345678 with country=DE), or a tel: URI. A literal plus sign must be sent as %2B, because a query string decodes + as a space. The accepted separators are space, TAB, NO-BREAK SPACE, - . ( ) / \, the U+2010–U+2015 dashes and the full-width forms + - ( ); every Unicode decimal digit is accepted and mapped to ASCII. Any other character is reported as NOT_A_NUMBER and named. The 32-character cap is this endpoint's own and is stricter than libphonenumber's 250 on purpose.

Default region for a number written in national form, as a CLDR two-letter region code (case-insensitive; these are ISO 3166-1 alpha-2 plus the exceptionally reserved AC and TA and the user-assigned XK). Ignored with a warning when value already carries its own plus-prefixed calling code. 001 is accepted as input only so that it can be rejected with an explanation: it is the non-geographical pseudo-region, not a place you dial from.

Which of the four canonical presentations lands in formatted. All four are always returned in their own fields.

Produce outOfCountry: how a caller in this region dials the number, using that region's own IDD prefix. A two-letter region code with numbering metadata; 001 is rejected with an explanation rather than silently ignored, because nobody dials from a non-geographical calling code.

Advanced response options4 options

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

Return all fields except these (comma-separated).

Pretty-print the JSON response.

Drop the envelope: return the raw array/object without data/meta wrapper.

Response

Example parameters are ready. Send the request to inspect the live response.

Route reference

Code samples Ready-to-copy requests in 4 languages
Choose a code sample language
curl "https://randomapi.dev/api/phone-numbers/format?value=%2B4532123456"
const res = await fetch("https://randomapi.dev/api/phone-numbers/format?value=%2B4532123456");
const { data, meta } = await res.json();
import requests

data = requests.get("https://randomapi.dev/api/phone-numbers/format?value=%2B4532123456").json()["data"]
$json = json_decode(file_get_contents(
  "https://randomapi.dev/api/phone-numbers/format?value=%2B4532123456"
), true);
$data = $json["data"];
Parameters Route-specific request inputs 4
value string required

The number as written: international (+45 32 12 34 56), national (0151 12345678 with country=DE), or a tel: URI. A literal plus sign must be sent as %2B, because a query string decodes + as a space. The accepted separators are space, TAB, NO-BREAK SPACE, - . ( ) / \, the U+2010–U+2015 dashes and the full-width forms + - ( ); every Unicode decimal digit is accepted and mapped to ASCII. Any other character is reported as NOT_A_NUMBER and named. The 32-character cap is this endpoint's own and is stricter than libphonenumber's 250 on purpose.

allowed: 1 – 32
example: value=+4532123456
country string

Default region for a number written in national form, as a CLDR two-letter region code (case-insensitive; these are ISO 3166-1 alpha-2 plus the exceptionally reserved AC and TA and the user-assigned XK). Ignored with a warning when value already carries its own plus-prefixed calling code. 001 is accepted as input only so that it can be rejected with an explanation: it is the non-geographical pseudo-region, not a place you dial from.

allowed: 2 – 3
example: country=DE
style enum

Which of the four canonical presentations lands in formatted. All four are always returned in their own fields.

default: e164
allowed: e164 | international | national | rfc3966
example: style=national
fromRegion string

Produce outOfCountry: how a caller in this region dials the number, using that region's own IDD prefix. A two-letter region code with numbering metadata; 001 is rejected with an explanation rather than silently ignored, because nobody dials from a non-geographical calling code.

allowed: 2 – 3
example: fromRegion=US
Universal parameters Shared response and formatting options 4
fields list

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

example: fields=input,parsed
exclude list

Return all fields except these (comma-separated).

example: exclude=metadataUpdated
pretty boolean

Pretty-print the JSON response.

default: false
example: pretty=true
unwrap boolean

Drop the envelope: return the raw array/object without data/meta wrapper.

default: false
example: unwrap=true
Response schema Fields returned in each record 23
input string

The value exactly as supplied, byte for byte, so a mis-encoded plus sign is visible.

example: +45 32 12 34 56

parsed boolean

Whether a country calling code and a national significant number could be extracted. False is a record, not an error.

example: true

failureReason string nullable

NOT_A_NUMBER · MISSING_REGION · INVALID_COUNTRY_CODE · TOO_SHORT_AFTER_IDD · TOO_SHORT_NSN · TOO_LONG · UNSUPPORTED_TEL_PARAMETER. The first, third, fourth, fifth and sixth are libphonenumber's own NumberParseException.ErrorType values; MISSING_REGION and UNSUPPORTED_TEL_PARAMETER are this endpoint's, and both are listed as divergences on this page. null when parsed is true.

example: null

failureDetail string nullable

One sentence naming the offending value and the rule it broke. null when parsed is true.

example: null

countryCallingCode string nullable

The country calling code with its leading plus sign.

example: +45

region string nullable

The CLDR region that owns the number, 001 for a non-geographical calling code, or null when no region on the calling code publishes a range that covers it. These are CLDR ids, not strictly ISO 3166-1: AC, TA and XK appear too.

example: DK

nationalNumber string nullable

The national significant number, digits only, with leading zeros preserved. This is libphonenumber's getNationalSignificantNumber(): upstream stores the digits as an integer plus an italianLeadingZero flag and re-inserts the zeros on read, and every length test and pattern match runs against the re-assembled string. Here it is a string throughout — the same value, one representation.

example: 32123456

extension string nullable

Digits from a trailing ;ext= parameter. That is the only extension syntax this endpoint parses — x123, ext. 123, #123 and anexo 123 are not recognised.

example: null

e164 string nullable

Plus sign, calling code and national significant number, no separators and no extension.

example: +4532123456

international string nullable

Calling code, a space, then the nationally grouped national significant number.

example: +45 32 12 34 56

national string nullable

National form with the trunk prefix re-applied by the matching format rule, in canonical grouping.

example: 32 12 34 56

rfc3966 string nullable

A tel: URI built from the E.164 form, with ;ext= appended when an extension was parsed. Upstream's visual separators are a deliberate divergence documented on this page.

example: tel:+4532123456

formatted string nullable

The one of the four forms named by style. All four are always returned in their own fields as well.

example: +4532123456

style string

Echo of the resolved style: e164 · international · national · rfc3966.

example: e164

outOfCountry string nullable

How a caller in fromRegion dials this number, i.e. libphonenumber's formatOutOfCountryCallingNumber. null unless fromRegion was sent. Dialling a +1 number from another NANP region gives 1 followed by the national form; dialling a number on your own calling code gives the plain national form.

example: null

internationalPrefixUsed string nullable

The IDD digits actually placed in front of outOfCountry. null when fromRegion publishes neither a preferredInternationalPrefix nor an internationalPrefix that is a single literal prefix — 35 regions publish a multi-branch IDD pattern such as Brazil's 00(?:1[245]|2[1-35]|31|4[13]|[56]5|99) or Indonesia's 00[89], and for those libphonenumber falls back to the plus-prefixed international form rather than inventing a carrier-select code. Six regions publish a wait-for-tone marker, which is passed through verbatim (Russia, Kazakhstan, Belarus, Tajikistan and Turkmenistan use 8~10, Ukraine 0~0).

example: null

formatSourceRegion string nullable

The region whose availableFormats produced the grouping. Formatting always uses the MAIN region of the calling code, never the resolved region: 44 territories publish no formatting rules of their own, and for 39 of them this differs from region — a Bermuda number is grouped by the United States' NANP rules.

example: DK

formatRuleUsed string nullable

The numberFormat pattern that matched, or null when none did — in which case national is the ungrouped national significant number. Two situations produce a null, and notes says which: the calling code publishes no rules at all, which is true of +247, +290, +500, +686 and +690 and therefore of every number on them; or it publishes rules and none of them matched, because a rule applies only when both its leadingDigits prefix and its own digit pattern match. Denmark's single rule is gated on a leading digit of 2–9, so +4511111111 formats without it.

example: (\d{2})(\d{2})(\d{2})(\d{2})

isPossible boolean

Length-only verdict, repeated here because formatting is not validation.

example: true

isValid boolean

Whether the number matches a published range. A possible-but-unassigned number formats perfectly, so this is the only field on the route that speaks to validity — and it still says nothing about reachability.

example: true

notes string[]

Record-level advisories about this number: a shared calling code, a merged fixed-line/mobile range, number portability, a subscriber-only length, a non-geographical code, a captured carrier code, no matching formatting rule (distinguishing a calling code with no rules at all from one whose rules did not match these digits), or a range that cannot be dialled internationally. Named notes rather than warnings so it can never be confused with meta.warnings, which carries request-level advisories. Empty for an unremarkable number.

example: ["Denmark's fixed-line and mobile ranges both cover this number, so its type is reported as fixedLineOrMobile rather than guessing between them."]

metadataVersion string

The pinned libphonenumber release this answer came from. Every parse and format decision in the response is a property of this snapshot and nothing else.

example: v9.0.35

metadataUpdated string (ISO 8601 date)

The date that release was published upstream.

example: 2026-07-17

Documented examples

Build-generated requests and complete responses
6
All four canonical forms of one number
GET /api/phone-numbers/format?value=%2B4532123456
{
  "data": {
    "input": "+4532123456",
    "parsed": true,
    "failureReason": null,
    "failureDetail": null,
    "countryCallingCode": "+45",
    "region": "DK",
    "nationalNumber": "32123456",
    "extension": null,
    "e164": "+4532123456",
    "international": "+45 32 12 34 56",
    "national": "32 12 34 56",
    "rfc3966": "tel:+4532123456",
    "formatted": "+4532123456",
    "style": "e164",
    "outOfCountry": null,
    "internationalPrefixUsed": null,
    "formatSourceRegion": "DK",
    "formatRuleUsed": "(\\d{2})(\\d{2})(\\d{2})(\\d{2})",
    "isPossible": true,
    "isValid": true,
    "notes": [
      "Denmark's fixed-line and mobile ranges both cover this number, so its type is reported as fixedLineOrMobile rather than guessing between them.",
      "Denmark operates mobile number portability, so this number's range does not identify the serving operator."
    ],
    "metadataVersion": "v9.0.35",
    "metadataUpdated": "2026-07-17"
  },
  "meta": {
    "endpoint": "phone-numbers",
    "route": "/format",
    "params": {
      "value": "+4532123456",
      "style": "e164"
    },
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
National form with the trunk prefix restored
GET /api/phone-numbers/format?value=%2B4915112345678&style=national
{
  "data": {
    "input": "+4915112345678",
    "parsed": true,
    "failureReason": null,
    "failureDetail": null,
    "countryCallingCode": "+49",
    "region": "DE",
    "nationalNumber": "15112345678",
    "extension": null,
    "e164": "+4915112345678",
    "international": "+49 1511 2345678",
    "national": "01511 2345678",
    "rfc3966": "tel:+4915112345678",
    "formatted": "01511 2345678",
    "style": "national",
    "outOfCountry": null,
    "internationalPrefixUsed": null,
    "formatSourceRegion": "DE",
    "formatRuleUsed": "(\\d{4})(\\d{7})",
    "isPossible": true,
    "isValid": true,
    "notes": [
      "Germany operates mobile number portability, so this number's range does not identify the serving operator."
    ],
    "metadataVersion": "v9.0.35",
    "metadataUpdated": "2026-07-17"
  },
  "meta": {
    "endpoint": "phone-numbers",
    "route": "/format",
    "params": {
      "value": "+4915112345678",
      "style": "national"
    },
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
RFC 3966 tel: URI
GET /api/phone-numbers/format?value=%2B14155552671&style=rfc3966
{
  "data": {
    "input": "+14155552671",
    "parsed": true,
    "failureReason": null,
    "failureDetail": null,
    "countryCallingCode": "+1",
    "region": "US",
    "nationalNumber": "4155552671",
    "extension": null,
    "e164": "+14155552671",
    "international": "+1 415-555-2671",
    "national": "(415) 555-2671",
    "rfc3966": "tel:+14155552671",
    "formatted": "tel:+14155552671",
    "style": "rfc3966",
    "outOfCountry": null,
    "internationalPrefixUsed": null,
    "formatSourceRegion": "US",
    "formatRuleUsed": "(\\d{3})(\\d{3})(\\d{4})",
    "isPossible": true,
    "isValid": true,
    "notes": [
      "Calling code +1 is shared by 25 regions, so the region was resolved in libphonenumber's own order (US first): a region with a leadingDigits prefix wins on that prefix, otherwise on matching one of its published ranges. regionCandidates lists all of them.",
      "United States's fixed-line and mobile ranges both cover this number, so its type is reported as fixedLineOrMobile rather than guessing between them.",
      "United States operates mobile number portability, so this number's range does not identify the serving operator."
    ],
    "metadataVersion": "v9.0.35",
    "metadataUpdated": "2026-07-17"
  },
  "meta": {
    "endpoint": "phone-numbers",
    "route": "/format",
    "params": {
      "value": "+14155552671",
      "style": "rfc3966"
    },
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
How to dial a Danish number from the United States
GET /api/phone-numbers/format?value=%2B4532123456&fromRegion=US
{
  "data": {
    "input": "+4532123456",
    "parsed": true,
    "failureReason": null,
    "failureDetail": null,
    "countryCallingCode": "+45",
    "region": "DK",
    "nationalNumber": "32123456",
    "extension": null,
    "e164": "+4532123456",
    "international": "+45 32 12 34 56",
    "national": "32 12 34 56",
    "rfc3966": "tel:+4532123456",
    "formatted": "+4532123456",
    "style": "e164",
    "outOfCountry": "011 45 32 12 34 56",
    "internationalPrefixUsed": "011",
    "formatSourceRegion": "DK",
    "formatRuleUsed": "(\\d{2})(\\d{2})(\\d{2})(\\d{2})",
    "isPossible": true,
    "isValid": true,
    "notes": [
      "Denmark's fixed-line and mobile ranges both cover this number, so its type is reported as fixedLineOrMobile rather than guessing between them.",
      "Denmark operates mobile number portability, so this number's range does not identify the serving operator."
    ],
    "metadataVersion": "v9.0.35",
    "metadataUpdated": "2026-07-17"
  },
  "meta": {
    "endpoint": "phone-numbers",
    "route": "/format",
    "params": {
      "value": "+4532123456",
      "style": "e164",
      "fromRegion": "US"
    },
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
Dialling from a country with no single IDD prefix
GET /api/phone-numbers/format?value=%2B4532123456&fromRegion=BR
{
  "data": {
    "input": "+4532123456",
    "parsed": true,
    "failureReason": null,
    "failureDetail": null,
    "countryCallingCode": "+45",
    "region": "DK",
    "nationalNumber": "32123456",
    "extension": null,
    "e164": "+4532123456",
    "international": "+45 32 12 34 56",
    "national": "32 12 34 56",
    "rfc3966": "tel:+4532123456",
    "formatted": "+4532123456",
    "style": "e164",
    "outOfCountry": "+45 32 12 34 56",
    "internationalPrefixUsed": null,
    "formatSourceRegion": "DK",
    "formatRuleUsed": "(\\d{2})(\\d{2})(\\d{2})(\\d{2})",
    "isPossible": true,
    "isValid": true,
    "notes": [
      "Denmark's fixed-line and mobile ranges both cover this number, so its type is reported as fixedLineOrMobile rather than guessing between them.",
      "Denmark operates mobile number portability, so this number's range does not identify the serving operator."
    ],
    "metadataVersion": "v9.0.35",
    "metadataUpdated": "2026-07-17"
  },
  "meta": {
    "endpoint": "phone-numbers",
    "route": "/format",
    "params": {
      "value": "+4532123456",
      "style": "e164",
      "fromRegion": "BR"
    },
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
A Bermuda number formatted by the main NANP region's rules
GET /api/phone-numbers/format?value=%2B14412961234
{
  "data": {
    "input": "+14412961234",
    "parsed": true,
    "failureReason": null,
    "failureDetail": null,
    "countryCallingCode": "+1",
    "region": "BM",
    "nationalNumber": "4412961234",
    "extension": null,
    "e164": "+14412961234",
    "international": "+1 441-296-1234",
    "national": "(441) 296-1234",
    "rfc3966": "tel:+14412961234",
    "formatted": "+14412961234",
    "style": "e164",
    "outOfCountry": null,
    "internationalPrefixUsed": null,
    "formatSourceRegion": "US",
    "formatRuleUsed": "(\\d{3})(\\d{3})(\\d{4})",
    "isPossible": true,
    "isValid": true,
    "notes": [
      "Calling code +1 is shared by 25 regions, so the region was resolved in libphonenumber's own order (US first): a region with a leadingDigits prefix wins on that prefix, otherwise on matching one of its published ranges. regionCandidates lists all of them.",
      "Bermuda operates mobile number portability, so this number's range does not identify the serving operator."
    ],
    "metadataVersion": "v9.0.35",
    "metadataUpdated": "2026-07-17"
  },
  "meta": {
    "endpoint": "phone-numbers",
    "route": "/format",
    "params": {
      "value": "+14412961234",
      "style": "e164"
    },
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}

GET /api/phone-numbers/countries

All 254 territories in the snapshot, including the nine non-geographical 001 rows, in (region, callingCode) order. A row carries every published range with its own lengths and example number, so at most 100 rows come back per request — use 'offset' to page and a warning reports the total. Filters are filters: an unmatched calling code returns an empty list with a warning, never a substitute row.

Live requestRuns against the public API
No key required
GET/api/phone-numbers/countries

Request parameters

Keep only this CLDR region (case-insensitive), or 001 for the non-geographical rows. An unknown code is a 400, because a silent empty list would look like a data gap.

Keep only rows on this calling code, with or without a leading plus sign. An unassigned code returns an empty list — this is a filter, not a lookup; use /calling-code for the honest 404.

Keep only regions that publish a range of this kind. The eleventh id, noInternationalDialling, is a dialling restriction rather than a number type.

Keep only regions where upstream flags mobile number portability (true) or does not (false).

Case- and diacritic-insensitive substring match over countryName and region. Rows with a null countryName are matched on their region code alone.

Skip this many matches before returning rows. The snapshot holds more plans than one page can carry, so ?offset=100 continues where the first page stopped.

Advanced response options6 options

Limit the number of returned records (1–100). Defaults to 100.

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

Return all fields except these (comma-separated).

Response format: json envelope, ndjson (one record per line) or csv.

Pretty-print the JSON response.

Drop the envelope: return the raw array/object without data/meta wrapper.

Response

Example parameters are ready. Send the request to inspect the live response.

Route reference

Code samples Ready-to-copy requests in 4 languages
Choose a code sample language
curl "https://randomapi.dev/api/phone-numbers/countries"
const res = await fetch("https://randomapi.dev/api/phone-numbers/countries");
const { data, meta } = await res.json();
import requests

data = requests.get("https://randomapi.dev/api/phone-numbers/countries").json()["data"]
$json = json_decode(file_get_contents(
  "https://randomapi.dev/api/phone-numbers/countries"
), true);
$data = $json["data"];
Parameters Route-specific request inputs 6
country string

Keep only this CLDR region (case-insensitive), or 001 for the non-geographical rows. An unknown code is a 400, because a silent empty list would look like a data gap.

allowed: 2 – 3
example: country=DK
callingCode string

Keep only rows on this calling code, with or without a leading plus sign. An unassigned code returns an empty list — this is a filter, not a lookup; use /calling-code for the honest 404.

allowed: 1 – 4
example: callingCode=+1
type enum

Keep only regions that publish a range of this kind. The eleventh id, noInternationalDialling, is a dialling restriction rather than a number type.

allowed: fixedLine | mobile | pager | tollFree | premiumRate | sharedCost | personalNumber | voip | uan | voicemail | noInternationalDialling
example: type=voip
mobileNumberPortable boolean

Keep only regions where upstream flags mobile number portability (true) or does not (false).

example: mobileNumberPortable=true
search string

Case- and diacritic-insensitive substring match over countryName and region. Rows with a null countryName are matched on their region code alone.

allowed: 1 – 40
example: search=united
offset int

Skip this many matches before returning rows. The snapshot holds more plans than one page can carry, so ?offset=100 continues where the first page stopped.

default: 0
allowed: 0 – 300
example: offset=100
Universal parameters Shared response and formatting options 6
count int

Limit the number of returned records (1–100). Defaults to 100.

default: 100
allowed: 1 – 100
example: count=3
fields list

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

example: fields=region,countryName
exclude list

Return all fields except these (comma-separated).

example: exclude=formatRuleCount
format enum

Response format: json envelope, ndjson (one record per line) or csv.

default: json
allowed: json | ndjson | csv
example: format=csv
pretty boolean

Pretty-print the JSON response.

default: false
example: pretty=true
unwrap boolean

Drop the envelope: return the raw array/object without data/meta wrapper.

default: false
example: unwrap=true
Response schema Fields returned in each record 13
region string

CLDR region code, or 001 for a non-geographical calling code. Nine rows share 001 and are distinguished by their calling code, which is why this dataset is keyed by (region, callingCode) rather than by region.

example: DK

countryName string nullable

English short name joined from the bundled ISO 3166-1 dataset that /api/countries serves. null for the nine 001 rows and for AC, TA and XK, which have no ISO 3166-1 officially assigned entry — twelve null rows in total, never invented.

example: Denmark

callingCode string

The country calling code with its leading plus sign.

example: +45

zone integer

ITU-T E.164 world numbering zone, 1–9 — simply the first digit of the calling code. It is also the key the bundled dataset is split by.

example: 4

mainCountryForCallingCode boolean

Upstream's mainCountryForCode. Exactly twelve rows are true, one per shared calling code, and the main region's rules format every number on that code.

example: true

regionsSharingCallingCode integer

How many rows share this calling code: 1 for 203 of the 215 codes, 25 for +1.

example: 1

internationalPrefix string nullable

The IDD pattern exactly as published — a bare literal for most regions, a regex for 35 of them (Indonesia's is 00[89]) — or null for the nine rows that publish none.

example: 00

nationalPrefix string nullable

The trunk prefix, or null for the 110 regions that publish none. The only values in the snapshot are 0 (113 regions), 1 (26), 8 (4) and 06 (1). Denmark is null: it has no trunk prefix, and a leading 0 on a Danish number is part of the number.

example: null

mobileNumberPortable boolean

Upstream's portability flag; true for 107 regions.

example: true

possibleLengths integer[]

The union of every number type's national lengths, ascending. Computed rather than read: the XML publishes no generalDesc lengths, and libphonenumber's build tool derives them the same way — excluding noInternationalDialling, which is a dialling restriction rather than a number type. Values range 4–17 in this snapshot; the shorter subscriber-only lengths in numberTypes[].localOnlyLengths go down to 2 and are not repeated here.

example: [8]

numberTypes object[]

One entry per published range: { type, possibleLengths, localOnlyLengths, exampleNumber, exampleE164 }. The eleventh id, noInternationalDialling, is a dialling restriction rather than a number type and carries no example. exampleNumber is upstream's own example national significant number — libphonenumber's FAQ warns that some of them reach real subscribers, so do not call them.

example: [{"type":"fixedLine","possibleLengths":[8],"localOnlyLengths":[],"exampleNumber":"32123456","exampleE164":"+4532123456"}]

formatSourceRegion string

The region whose formatting rules apply to numbers on this calling code — itself, or the main region of its calling code. It differs from region for exactly 39 rows.

example: DK

formatRuleCount integer

How many numberFormat rules formatSourceRegion publishes (759 rules across the snapshot; 1 for Denmark, 0 for the five calling codes with no rules anywhere).

example: 1

Documented examples

Build-generated requests and complete responses
7
The first page of numbering plans
GET /api/phone-numbers/countries
{
  "data": [
    {
      "region": "001",
      "countryName": null,
      "callingCode": "+800",
      "zone": 8,
      "mainCountryForCallingCode": false,
      "regionsSharingCallingCode": 1,
      "internationalPrefix": null,
      "nationalPrefix": null,
      "mobileNumberPortable": false,
      "possibleLengths": [
        8
      ],
      "numberTypes": [
        {
          "type": "tollFree",
          "possibleLengths": [
            8
          ],
          "localOnlyLengths": [],
          "exampleNumber": "12345678",
          "exampleE164": "+80012345678"
        }
      ],
      "formatSourceRegion": "001",
      "formatRuleCount": 1
    },
    {
      "region": "001",
      "countryName": null,
      "callingCode": "+808",
      "zone": 8,
      "mainCountryForCallingCode": false,
      "regionsSharingCallingCode": 1,
      "internationalPrefix": null,
      "nationalPrefix": null,
      "mobileNumberPortable": false,
      "possibleLengths": [
    …
    ]
  }
}
The second page
GET /api/phone-numbers/countries?offset=100
{
  "data": [
    {
      "region": "GY",
      "countryName": "Guyana",
      "callingCode": "+592",
      "zone": 5,
      "mainCountryForCallingCode": false,
      "regionsSharingCallingCode": 1,
      "internationalPrefix": "001",
      "nationalPrefix": null,
      "mobileNumberPortable": false,
      "possibleLengths": [
        7
      ],
      "numberTypes": [
        {
          "type": "fixedLine",
          "possibleLengths": [
            7
          ],
          "localOnlyLengths": [],
          "exampleNumber": "2201234",
          "exampleE164": "+5922201234"
        },
        {
          "type": "mobile",
          "possibleLengths": [
            7
          ],
          "localOnlyLengths": [],
          "exampleNumber": "6091234",
          "exampleE164": "+5926091234"
        },
        {
          "type": "tollFree",
          "possibleLengths": [
            7
          ],
          "localOnlyLengths": [],
    …
    ]
  }
}
The 25 regions on +1
GET /api/phone-numbers/countries?callingCode=%2B1
{
  "data": [
    {
      "region": "AG",
      "countryName": "Antigua and Barbuda",
      "callingCode": "+1",
      "zone": 1,
      "mainCountryForCallingCode": false,
      "regionsSharingCallingCode": 25,
      "internationalPrefix": "011",
      "nationalPrefix": "1",
      "mobileNumberPortable": true,
      "possibleLengths": [
        10
      ],
      "numberTypes": [
        {
          "type": "fixedLine",
          "possibleLengths": [
            10
          ],
          "localOnlyLengths": [
            7
          ],
          "exampleNumber": "2684601234",
          "exampleE164": "+12684601234"
        },
        {
          "type": "mobile",
          "possibleLengths": [
            10
          ],
          "localOnlyLengths": [
            7
          ],
          "exampleNumber": "2684641234",
          "exampleE164": "+12684641234"
        },
        {
          "type": "pager",
    …
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
One country's plan in full
GET /api/phone-numbers/countries?country=DK
{
  "data": [
    {
      "region": "DK",
      "countryName": "Denmark",
      "callingCode": "+45",
      "zone": 4,
      "mainCountryForCallingCode": false,
      "regionsSharingCallingCode": 1,
      "internationalPrefix": "00",
      "nationalPrefix": null,
      "mobileNumberPortable": true,
      "possibleLengths": [
        8
      ],
      "numberTypes": [
        {
          "type": "fixedLine",
          "possibleLengths": [
            8
          ],
          "localOnlyLengths": [],
          "exampleNumber": "32123456",
          "exampleE164": "+4532123456"
        },
        {
          "type": "mobile",
          "possibleLengths": [
            8
          ],
          "localOnlyLengths": [],
          "exampleNumber": "34412345",
          "exampleE164": "+4534412345"
        },
        {
          "type": "tollFree",
          "possibleLengths": [
            8
          ],
          "localOnlyLengths": [],
    …
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
Regions that publish a VoIP range
GET /api/phone-numbers/countries?type=voip&count=100
{
  "data": [
    {
      "region": "001",
      "countryName": null,
      "callingCode": "+870",
      "zone": 8,
      "mainCountryForCallingCode": false,
      "regionsSharingCallingCode": 1,
      "internationalPrefix": null,
      "nationalPrefix": null,
      "mobileNumberPortable": false,
      "possibleLengths": [
        9,
        12
      ],
      "numberTypes": [
        {
          "type": "mobile",
          "possibleLengths": [
            9,
            12
          ],
          "localOnlyLengths": [],
          "exampleNumber": "301234567",
          "exampleE164": "+870301234567"
        },
        {
          "type": "voip",
          "possibleLengths": [
            9
          ],
          "localOnlyLengths": [],
          "exampleNumber": "201234567",
          "exampleE164": "+870201234567"
        }
      ],
      "formatSourceRegion": "001",
      "formatRuleCount": 1
    },
    …
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
Calling codes and trunk prefixes only, as CSV
GET /api/phone-numbers/countries?fields=region,callingCode,nationalPrefix&format=csv
region,callingCode,nationalPrefix
001,+800,
001,+808,
001,+870,
001,+878,
001,+881,
001,+882,
001,+883,
001,+888,
001,+979,
AC,+247,
AD,+376,
AE,+971,0
AF,+93,0
AG,+1,1
AI,+1,1
AL,+355,0
AM,+374,0
AO,+244,
AR,+54,0
AS,+1,1
AT,+43,0
AU,+61,0
AW,+297,
AX,+358,0
AZ,+994,0
BA,+387,0
BB,+1,1
BD,+880,0
BE,+32,0
BF,+226,
BG,+359,0
BH,+973,
BI,+257,
BJ,+229,
BL,+590,0
BM,+1,1
BN,+673,
BO,+591,0
BQ,+599,
    …
GU,+1,1
GW,+245,
Regions with mobile number portability
GET /api/phone-numbers/countries?mobileNumberPortable=true
{
  "data": [
    {
      "region": "AG",
      "countryName": "Antigua and Barbuda",
      "callingCode": "+1",
      "zone": 1,
      "mainCountryForCallingCode": false,
      "regionsSharingCallingCode": 25,
      "internationalPrefix": "011",
      "nationalPrefix": "1",
      "mobileNumberPortable": true,
      "possibleLengths": [
        10
      ],
      "numberTypes": [
        {
          "type": "fixedLine",
          "possibleLengths": [
            10
          ],
          "localOnlyLengths": [
            7
          ],
          "exampleNumber": "2684601234",
          "exampleE164": "+12684601234"
        },
        {
          "type": "mobile",
          "possibleLengths": [
            10
          ],
          "localOnlyLengths": [
            7
          ],
          "exampleNumber": "2684641234",
          "exampleE164": "+12684641234"
        },
        {
          "type": "pager",
    …
    ]
  }
}

GET /api/phone-numbers/calling-code

Live requestRuns against the public API
No key required
GET/api/phone-numbers/calling-code?code=45

Request parameters

A country calling code, with or without a leading plus sign (45, +45, 1, 800). One to three digits; an unassigned code is an honest 404.

Advanced response options4 options

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

Return all fields except these (comma-separated).

Pretty-print the JSON response.

Drop the envelope: return the raw array/object without data/meta wrapper.

Response

Example parameters are ready. Send the request to inspect the live response.

Route reference

Code samples Ready-to-copy requests in 4 languages
Choose a code sample language
curl "https://randomapi.dev/api/phone-numbers/calling-code?code=45"
const res = await fetch("https://randomapi.dev/api/phone-numbers/calling-code?code=45");
const { data, meta } = await res.json();
import requests

data = requests.get("https://randomapi.dev/api/phone-numbers/calling-code?code=45").json()["data"]
$json = json_decode(file_get_contents(
  "https://randomapi.dev/api/phone-numbers/calling-code?code=45"
), true);
$data = $json["data"];
Parameters Route-specific request inputs 1
code string required

A country calling code, with or without a leading plus sign (45, +45, 1, 800). One to three digits; an unassigned code is an honest 404.

allowed: 1 – 4
example: code=+1
Universal parameters Shared response and formatting options 4
fields list

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

example: fields=callingCode,zone
exclude list

Return all fields except these (comma-separated).

example: exclude=metadataUpdated
pretty boolean

Pretty-print the JSON response.

default: false
example: pretty=true
unwrap boolean

Drop the envelope: return the raw array/object without data/meta wrapper.

default: false
example: unwrap=true
Response schema Fields returned in each record 10
callingCode string

The country calling code with its leading plus sign.

example: +1

zone integer

ITU-T E.164 world numbering zone, 1–9 — the first digit of the calling code.

example: 1

regionCount integer

How many rows the snapshot publishes on this calling code.

example: 25

mainRegion string nullable

The mainCountryForCode region, whose formatting rules apply to every number on the code. null for a non-geographical code, whose only row is 001.

example: US

isNonGeographic boolean

True for the nine codes whose only row is 001 — 800, 808, 870, 878, 881, 882, 883, 888 and 979. They belong to services, not countries.

example: false

regions object[]

{ region, countryName, main, leadingDigits } per row, in resolution order. leadingDigits is the region-level prefix pattern that claims a number for a non-main region on a shared code; 36 rows publish one, the rest are decided by full range matching.

example: [{"region":"US","countryName":"United States","main":true,"leadingDigits":null}]

resolutionOrder string[]

The exact order a parsed number is tested against the regions: the main region first, then upstream's document order. Six of the twelve shared codes list their main region later in the source file, so this is not simply alphabetical.

example: ["US","AG","AI"]

possibleLengths integer[]

The union of every region's possible national lengths on this code, ascending. It is a union, so a code can carry a length only one of its regions publishes — +1 shows 7 and 10 because Canada publishes both.

example: [7,10]

metadataVersion string

The pinned libphonenumber release this answer came from. Every parse and format decision in the response is a property of this snapshot and nothing else.

example: v9.0.35

metadataUpdated string (ISO 8601 date)

The date that release was published upstream.

example: 2026-07-17

Documented examples

Build-generated requests and complete responses
3
Denmark — a code with one region
GET /api/phone-numbers/calling-code?code=45
{
  "data": {
    "callingCode": "+45",
    "zone": 4,
    "regionCount": 1,
    "mainRegion": "DK",
    "isNonGeographic": false,
    "regions": [
      {
        "region": "DK",
        "countryName": "Denmark",
        "main": true,
        "leadingDigits": null
      }
    ],
    "resolutionOrder": [
      "DK"
    ],
    "possibleLengths": [
      8
    ],
    "metadataVersion": "v9.0.35",
    "metadataUpdated": "2026-07-17"
  },
  "meta": {
    "endpoint": "phone-numbers",
    "route": "/calling-code",
    "params": {
      "code": "+45"
    },
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
+1 — the 25-region NANP, in resolution order
GET /api/phone-numbers/calling-code?code=%2B1
{
  "data": {
    "callingCode": "+1",
    "zone": 1,
    "regionCount": 25,
    "mainRegion": "US",
    "isNonGeographic": false,
    "regions": [
      {
        "region": "US",
        "countryName": "United States",
        "main": true,
        "leadingDigits": null
      },
      {
        "region": "AG",
        "countryName": "Antigua and Barbuda",
        "main": false,
        "leadingDigits": "268"
      },
      {
        "region": "AI",
        "countryName": "Anguilla",
        "main": false,
        "leadingDigits": "264"
      },
      {
        "region": "AS",
        "countryName": "American Samoa",
        "main": false,
        "leadingDigits": "684"
      },
      {
        "region": "BB",
        "countryName": "Barbados",
        "main": false,
        "leadingDigits": "246"
      },
      {
        "region": "BM",
    …
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}
+800 — a non-geographical code with no country behind it
GET /api/phone-numbers/calling-code?code=800
{
  "data": {
    "callingCode": "+800",
    "zone": 8,
    "regionCount": 1,
    "mainRegion": null,
    "isNonGeographic": true,
    "regions": [
      {
        "region": "001",
        "countryName": null,
        "main": true,
        "leadingDigits": null
      }
    ],
    "resolutionOrder": [
      "001"
    ],
    "possibleLengths": [
      8
    ],
    "metadataVersion": "v9.0.35",
    "metadataUpdated": "2026-07-17"
  },
  "meta": {
    "endpoint": "phone-numbers",
    "route": "/calling-code",
    "params": {
      "code": "+800"
    },
    "generatedAt": "2026-07-30T15:14:08.000Z"
  }
}

About this API

Coverage & behavior

A valid number is not a working number. Everything here is decided from a pinned snapshot of libphonenumber's numbering-plan metadata (release v9.0.35, 2026-07-17). There is no HLR or LRN lookup, no carrier query, no SMS or voice probe and no network call of any kind while your request is served, so isValid: true means exactly one thing: the national significant number falls inside a range the numbering-plan authority has published for that country. The line may be unassigned, ported, disconnected or simply switched off. libphonenumber's own FAQ says not to rely on validity to decide whether a number is currently assigned and reachable, and neither should you.

Possible vs valid is the distinction reachability vendors blur. isPossible is a length-only test against the lengths a region publishes; isValid additionally requires the digits to match one of that region's published type patterns. possibleReason carries libphonenumber's own ValidationResult verbatim — IS_POSSIBLE, IS_POSSIBLE_LOCAL_ONLY, TOO_SHORT, INVALID_LENGTH, TOO_LONG — so you can see which check decided. +4511111111 is possible and invalid; a seven-digit +1 number is IS_POSSIBLE_LOCAL_ONLY and invalid.

Do not confuse this with /api/phones. The names are close and the promises are opposite: /api/phones generates mock numbers for fixtures, while this endpoint answers questions about a number you supply and generates nothing. Nothing here is invented — every verdict, format and example number comes out of the pinned metadata snapshot.

The four routes

Route What it answers
/parse one number → region, national significant number, possible-vs-valid verdict, number type, all four formats
/format the four canonical presentations, which format rule produced the grouping, and how to dial the number from another country
/countries every numbering plan in the snapshot: calling code, trunk prefix, lengths per type, example numbers
/calling-code one calling code: which regions share it, in the order a number is resolved against them

Paging /countries. A row carries every range the territory publishes, with its own lengths and example number, so 254 of them is a large payload. At most 100 rows come back per request; offset skips that many matches (?offset=100 for the second page) and a warning reports how many matched in total.

Things that surprise people, and that this endpoint states rather than hides

Trunk prefixes are not universal. 110 of the 254 territories publish no nationalPrefix at all — Denmark and Italy among them. 0151 12345678 with country=DE becomes +4915112345678 and reports nationalPrefixStripped: "0", because Germany publishes nationalPrefix="0". The same shape in Denmark does not: 032 12 34 56 with country=DK keeps its zero, the national significant number is the nine-digit 032123456, and the honest answer is TOO_LONG — Denmark publishes exactly one possible length, 8. An Italian leading zero is likewise part of the number: +39 0432 123456 has the national significant number 0432123456.

fixedLineOrMobile is the common case. Whenever a region's fixed-line and mobile ranges both cover a number, that is what getNumberType returns — including for the Danish example above and for most of the United States. A test that expects fixedLine for a specific number has usually not been run against the actual patterns.

Formatting uses the main region of the calling code, not the resolved region. 44 territories publish no formatting rules of their own; for 39 of them the rules come from a different region, so a Bermuda number is grouped by the United States' NANP rules and formatSourceRegion says so. Five calling codes — +247, +290, +500, +686, +690 — have no rules anywhere, so their national form is the ungrouped national significant number and formatRuleUsed is null.

A +1 number can belong to any of 25 regions. region is resolved in libphonenumber's own order (main region US first): a region that publishes a region-level leadingDigits prefix — 36 rows do, including most of the NANP — wins on that prefix, and the rest win by matching one of their published ranges. regionCandidates always lists the full ordered set so an ambiguous answer is visible. When no region on a shared code claims the number, region is null and isValid is false rather than a region being guessed — that is what happens to +44 1481 123456. The order is not simply alphabetical either: six of the twelve shared codes list their main region later in the source file, and /calling-code exposes the real resolutionOrder.

The national significant number can be 17 digits, not 15. ITU-T E.164 caps a number at 15 digits; libphonenumber's MAX_LENGTH_FOR_NSN is 17, because longer numbers were found in service in Germany. This endpoint follows the implementation, and says so.

possibleLengths is computed, not read. No generalDesc in the XML carries possibleLengths; the union of the ten number types' lengths is derived exactly as libphonenumber's build tool derives it, with noInternationalDialling excluded and the local-only union reduced by the national one.

Region ids are CLDR, not ISO 3166-1. They include the exceptionally reserved AC and TA and the user-assigned XK, plus 001 for the nine non-geographical calling codes (800, 808, 870, 878, 881, 882, 883, 888, 979). In the other direction, seven ISO countries have no numbering metadata at all — AQ, BV, GS, HM, PN, TF and UM. The XML explains two of them: French Southern Territories (TF) for lack of information about its numbering plan, and Pitcairn (PN) because its fifty inhabitants use satellite phones. countryName is null for the twelve rows with no ISO 3166-1 officially assigned entry rather than invented.

Deliberately not included

Reachability of any kind. libphonenumber's carrier and geocoding datasets: prefix-to-carrier is broken by number portability (107 regions flag it, and mobileNumberPortableRegion surfaces that per answer) and prefix-to-city is wrong for every ported and every mobile number. Time zone for a prefix — use /api/timezones. Short numbers: ShortNumberMetadata.xml is not bundled, so 112, 911 and premium short codes come back TOO_SHORT with a detail that says why. Alternate formats: PhoneNumberAlternateFormats.xml is not bundled, which affects nothing about parsing (only digits are ever examined) and means national uses the primary rule only. As-you-type formatting, free-text number finding and number matching. Vanity letters1-800-FLOWERS is not converted; the letter is named as NOT_A_NUMBER. Extension spellings other than a trailing ;ext=. Carrier-selection codes are reported when a region's parsing rule captures one and never re-inserted into a formatted number. Example numbers are upstream's own, and libphonenumber admits some of them reach real people — do not call them. And this is not a generator: for fake numbers in fixtures, use /apis/phones.

Divergences from libphonenumber

Six behavioural divergences, plus one narrowing of the input grammar:

  1. MISSING_REGION — upstream folds "national form, no default region" into INVALID_COUNTRY_CODE; it gets its own reason here because it is a caller mistake with a different fix.
  2. UNSUPPORTED_TEL_PARAMETER — upstream accepts ;phone-context= and several extension spellings. Only a single trailing ;ext= with one to seven digits is parsed here, so this endpoint's own rfc3966 output round-trips through its own value parser.
  3. rfc3966 carries no visual separators — upstream emits tel:+45-32-12-34-56; this endpoint emits tel:+4532123456. Both satisfy RFC 3966 global-number-digits; only the second one round-trips.
  4. An unknown or 001 country/fromRegion is a 400 — upstream logs a warning and silently falls back to the international format. A silent fallback in an HTTP API is a wrong answer with a 200 on it.
  5. A 32-character input cap instead of upstream's 250.
  6. Viability is measured in digits, not in punctuation. Upstream's isViablePhoneNumber refuses an input as NOT_A_NUMBER before parsing begins unless it is either exactly two bare digits or holds at least three digits. This endpoint applies the digit half of that rule — fewer than two digits anywhere, or a leading plus with fewer than three, is NOT_A_NUMBER — but not the punctuation half, so a two-digit input written with a separator (45- with country=DK) is parsed here and answered with possibleReason: "TOO_SHORT" where upstream would refuse it outright.

The accepted separator set is this endpoint's own. The characters listed under value are the whole grammar. Upstream's VALID_PUNCTUATION is wider in most places — it tolerates ~, [, ], an x used as a separator, U+00AD, U+200B, U+2060, U+2212, the full-width and , and the ideographic space U+3000, among others — and narrower in one: it does not accept a backslash, which this endpoint does. So a handful of exotically punctuated inputs that upstream parses come back here as NOT_A_NUMBER with the offending character named, which is the answer this endpoint prefers to a silent reinterpretation.

Everything else is a record, not an exception: any value of 1–32 characters comes back with parsed, failureReason and failureDetail filled in. The filters on /countries are filters — zero matches is an empty list with a warning, never a substitute row — and /calling-code answers an unassigned code with an honest 404.

Provenance. The upstream XML is pinned by release tag and SHA-256 (d23c3c086390be1d…, 981,394 bytes) and regenerated by a committed parity script that also re-checks every structural invariant this page claims. metadataVersion and metadataUpdated ride on every /parse and /format record, so a refresh is visible in the response and not only in a changelog. libphonenumber is Apache-2.0; the notice, the statement of our modifications and the non-affiliation statement are in the dataset headers and on /notices.

Use it for

  • Normalise a signup phone field to E.164 before storing it, and reject what cannot be normalised
  • Explain to a support team why a number is 'valid' yet unreachable, using possibleReason and isValid side by side
  • Show a caller the exact digits to dial from their own country, including the right IDD prefix
  • Build a country picker from the real numbering plans: calling code, trunk prefix and per-type lengths
  • Decide which of 25 +1 regions a North American number belongs to, with the ambiguity visible

Frequently asked questions

Does a valid phone number mean the line is active?

No. Validity here means the national significant number falls inside a range the numbering-plan authority has published for that country. libphonenumber's own FAQ says not to rely on it to determine whether numbers are currently assigned to a specific user and reachable — and there is no HLR lookup, no carrier query and no network call of any kind in this endpoint.

What is the difference between a possible and a valid phone number?

isPossible is a length-only test against the lengths that region publishes; isValid additionally requires the digits to match one of that region's published type patterns. possibleReason carries libphonenumber's own verdict (IS_POSSIBLE, IS_POSSIBLE_LOCAL_ONLY, TOO_SHORT, INVALID_LENGTH, TOO_LONG), so you can see which check decided.

Which country does a +1 number belong to?

+1 is shared by 25 regions. region is resolved in libphonenumber's own order (main region US first): a region that publishes a leadingDigits prefix — most of the NANP does — wins on that prefix, and the rest win by matching one of their published ranges. Every candidate is listed in regionCandidates, so an ambiguous answer is visible rather than hidden.

How do I convert a national phone number to E.164?

Send the number and its country: /parse?value=0151%2012345678&country=DE returns e164: "+4915112345678", with the trunk prefix that was removed reported in nationalPrefixStripped ("0" here). Countries that publish no trunk prefix — Denmark, Italy and 108 others — report null and have nothing stripped.

Is this the same as libphonenumber?

It uses the same Apache-2.0 numbering-plan metadata and reproduces parse, isPossibleNumberWithReason, isValidNumber, getNumberType and the four formats. It deliberately does not ship libphonenumber's carrier, geocoding, timezone or short-number data, its as-you-type formatter, its free-text number finder or its vanity-letter conversion, and every behavioural divergence — six of them, plus a narrower separator set — is listed on this page.

How current is the phone numbering data?

It is a pinned snapshot — release v9.0.35 of 2026-07-17 — and the version and date ride on every /parse and /format response as metadataVersion and metadataUpdated. Upstream releases roughly fortnightly; a committed parity script re-verifies the pin byte-for-byte and reports when a newer release exists.

Standards & references