Phone check

Line-level facts about a single number, without running a platform sweep.

Request

Send the number in E.164 form where you can. Spaces, brackets and dashes are stripped.

POST /v2/phone
curl -X POST https://api.digifootprint.dev/v2/phone \
  -H "Authorization: Bearer dfp_live_..." \
  -H "Content-Type: application/json" \
  -d '{"phone": "+14155552671"}'
200 OK
{
  "lookupId": "aaf935d9-8a21-4fff-bffd-8cea2fdf4ea1",
  "phone": {
    "number": "+14155552671",
    "valid": true,
    "e164": "+14155552671",
    "nationalFormat": "(415) 555-2671",
    "callingCode": "1",
    "countryCode": "US",
    "carrier": "T-Mobile USA",
    "lineType": "mobile",
    "isVoip": false,
    "voipClass": null,
    "mcc": "310",
    "mnc": "260",
    "disposable": null,
    "ported": null,
    "simSwap": null,
    "callForwarding": null,
    "callerName": null,
    "exposureRisk": "none",
    "exposureDetails": [],
    "reserved": false,
    "risk": { "score": 0 }
  }
}

What comes back

Digital Footprint analyses phone numbers for risk. We do not provide calling, SMS, SIM or any telecom service.

The phone object is the same one POST /v2/lookup returns with {"checks": {"phone": true}}: validity, the number in E.164 and national format, country and calling code, carrier and line type, and a risk score. Add "checks": {"riskSignals": true} for the named signals.

Carrier-network fields are null unless a source answered them. mcc/mnc, disposable, ported, simSwap, callForwarding and callerName come from carrier-grade sources that do not cover every country or plan. null means not checked, never “no”.

Fictional and reserved numbers

We detect fictional and example numbers (such as +1 202 555 0123) and flag them in the result.

POST /v2/phone
curl -X POST https://api.digifootprint.dev/v2/phone \
  -H "Authorization: Bearer dfp_live_..." \
  -H "Content-Type: application/json" \
  -d '{"phone": "+12025550123"}'
200 OK (trimmed)
{
  "lookupId": "...",
  "phone": {
    "number": "+12025550123",
    "valid": true,
    "e164": "+12025550123",
    "nationalFormat": "(202) 555-0123",
    "callingCode": "1",
    "countryCode": "US",
    "reserved": true,
    "...": "..."
  }
}

The two VOIP fields

isVoip is the shorthand; voipClass is the signal. Both are returned because they answer different questions. A company’s phone system and a number somebody created in an app thirty seconds ago are both isVoip: true, and they mean opposite things.

voipClass separates them. fixed is a business line tied to an address. nonFixed is a number anyone can mint on demand, which is the category that turns up in signup fraud:

App-minted virtual number
{
  "valid": true,
  "lineType": "nonFixedVoip",
  "isVoip": true,
  "voipClass": "nonFixed"
}

voipClass is null when the line is not VOIP at all, and also when the answering source cannot make that distinction. Most sources cannot, and inferring it from a number range would be a guess rather than an answer.

null is not false

isVoip can be null. If the line type could not be established, you get null rather than false. Gate on isVoip === false rather than on a falsy check, or an unknown line will read as a confirmed real one.

Speed

A cold check measures around a second, and a repeat check inside the cache window around 30ms. The cold figure is one round trip to a carrier data source, so it varies with where your traffic originates.

Billing

One phone check is billed as one phone module unit and appears in your history with its own lookupId. To get these fields alongside a full platform sweep instead, use POST /v2/lookup with {"checks": {"phone": true}}.