$ DialCode API

One endpoint: send a phone number, get back whether it's real, which country and area it's from, what line type it is, and whether its prefix is currently associated with reported scams. JSON in, JSON out.

Authentication

Every request needs an X-Api-Key header. Get a free key at /api/login - no credit card, no forms beyond an email address for the magic link.

X-Api-Key: dc_your_key

Requests without a valid key get 401 with {"error": "invalid_api_key"}.

Endpoint

GET /v1/phone/{number}

{number} is any phone number in international format. The leading + works as-is in the URL path - no encoding needed (%2B also accepted if your HTTP client encodes it). Numbers sent without the + (e.g. 13214991734) are parsed as international automatically. Numbers without enough digits, or that don't parse to a real dialing plan, return a valid: false result rather than an error.

$ curl https://dialcode.app/v1/phone/+639171234567 \
    -H "X-Api-Key: dc_your_key"

{
  "valid": true,
  "e164": "+639171234567",
  "country": { "code": "PH", "dial_code": "+63", "name": "Philippines" },
  "line_type": "mobile",
  "area": { "code": "917", "name": "Manila" },
  "risk": {
    "scam_risk": "high",
    "scam_types": ["wangiri", "romance"],
    "advice_url": "https://dialcode.app/scam/63-scam",
    "complaints": null,
    "signals": []
  }
}

Response fields

FieldTypeDescription
validbooleanWhether the number parses as a real, dialable number.
e164string | nullNormalized E.164 form. Null when valid is false.
country.codestring | nullISO 3166-1 alpha-2 country code (e.g. PH).
country.dial_codestring | nullInternational dialing code (e.g. +63).
country.namestring | nullCountry name.
line_typestring | nullLine type as detected by number parsing (e.g. mobile, fixed_line).
area.codestring | nullLocal area code, when the country has area-code data and one matches.
area.namestring | nullCity / region for the matched area code.
risk.scam_riskstringlow, medium, or high - the country's overall scam risk rating. unknown when the number does not resolve to a country but a risk prefix matched (e.g. satellite ranges).
risk.scam_typesarray of stringsScam patterns reported for this country (e.g. wangiri, romance). Empty array if none documented.
risk.advice_urlstring | nullLink to the full scam profile page for this country, when one exists.
risk.complaintsobject | nullFTC Do Not Call complaint history for this exact number. Present only for US numbers with at least one reported complaint; null for non-US numbers or numbers with no reports. Fields: total (int), robocalls (int, subset of total), first_reported_on / last_reported_on (date), source (string).
risk.signalsarray of objectsRisk signals detected for this specific number: {code, note} pairs from line-type, known scam prefix ranges, and FTC complaint history. Empty array if none detected. See signal codes below.

Complaint data comes from the FTC's public Do Not Call registry CSVs, ingested daily (weekday publishing schedule - the FTC does not publish weekend files). US numbers only: the Do Not Call registry is a US program.

Signal codes

risk.signals entries come from two layers: line type (detected per-number) and known prefix ranges (detected from the dial code). A number can carry signals from both layers at once.

CodeLayerMeaning
voip_lineline typeVoIP number: cheap to obtain anonymously, common in fraud and SMS-verification bypass.
premium_rate_lineline typePremium-rate number: calling it incurs elevated charges.
shared_cost_lineline typeShared-cost number: partial elevated charges apply.
satellite_rangeprefixSatellite range (+870, +881): very high callback charges, classic wangiri bait.
international_network_rangeprefixInternational network range (+882, +883): ITU non-geographic codes outside normal country dialing plans.
premium_redirect_rangeprefixUK personal numbering range (+4470): missed-call redirect and premium forwarding.
premium_rate_rangeprefixUS 900 premium-rate range (+1900): calls billed at elevated per-minute rates.
ftc_reportedcomplaintsUS number reported to the FTC Do Not Call registry 3 or more times.

Errors

StatuserrorMeaning
401invalid_api_keyMissing or invalid X-Api-Key header.
400unparseable_numberInput is too short (under 4 digits) to attempt a lookup.
429quota_exceededMonthly quota used up for this key.
429rate_limitedPer-minute rate limit exceeded, independent of the monthly quota.

All errors return JSON: {"error": "invalid_api_key"}, {"error": "unparseable_number"}, {"error": "quota_exceeded"}, or {"error": "rate_limited"}.

Limits

Examples

curl

curl https://dialcode.app/v1/phone/+639171234567 \
  -H "X-Api-Key: dc_your_key"

JavaScript (fetch)

const res = await fetch("https://dialcode.app/v1/phone/+639171234567", {
  headers: { "X-Api-Key": "dc_your_key" }
});
const data = await res.json();
console.log(data.risk.scam_risk);

Ruby (Net::HTTP)

require "net/http"
require "json"

uri = URI("https://dialcode.app/v1/phone/+639171234567")
req = Net::HTTP::Get.new(uri)
req["X-Api-Key"] = "dc_your_key"

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
puts data["risk"]["scam_risk"]

Get a free API key →