Phone check

You are reading the v1 reference. v1 keeps working unchanged; new capabilities (several identities per request, risk scores, richer module data) are in v2. See migrating from v1.

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 /v1/phone
curl -X POST https://api.digifootprint.dev/v1/phone \
  -H "Authorization: Bearer dfp_live_..." \
  -H "Content-Type: application/json" \
  -d '{"phone": "+14155552671"}'
200 OK
{
  "lookupId": "aaf935d9-8a21-4fff-bffd-8cea2fdf4ea1",
  "query": "+14155552671",
  "phoneDetails": {
    "valid": true,
    "carrier": "T-Mobile USA",
    "lineType": "mobile",
    "countryCode": "US",
    "isVoip": false,
    "voipClass": null
  }
}

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 lookup and appears in your history with its own lookupId. To get these fields alongside a full platform sweep instead, use POST /v1/lookup with {"checks": {"phone": true}}.