KYC · API reference

Contact & risk

Email Risk

POST/v1/email/verifyemail.verify

Whether an address can receive mail and whether the mailbox exists, flagging temporary inboxes and typos, with a risk level and the reasons behind it.

**Returns**

- mailbox: exists, missing, catch_all or unverified - mail_server: whether the domain can receive mail, and its servers - disposable / free_provider: flags - risk: low, medium or high, with the reasons

**Limits**

- A domain that accepts everything cannot confirm one mailbox; a one-time code proves it. - No personal data beyond the address is needed.

Price: 0.05 credits per successful call.

Body parameters

emailstringrequired

Email.

Returns

The check ran.

Show the EmailVerifyResponse fields
okbooleanrequired

true: the result is in data.

request_idstring
latency_msnumber

How long the check took, in milliseconds.

dataobjectrequired

The answer of Email Risk.

Show 10 fields
emailstring
domainstring
syntax_okboolean
suggestionany
disposableboolean
free_providerboolean
mail_serverobject
Show 2 fields
foundboolean
hostsarray of strings
mailboxstring
deliverablestring
riskobject
Show 2 fields
levelstring
reasonsarray of anys
warningsarray of strings
errorany

Empty on success.

Errors

  • 400A field is missing or not valid.
  • 401No API key, or the key is not valid, expired or revoked.
  • 402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.
  • 403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.
  • 413The image or the request is too large.
  • 429Too many requests for this key: wait Retry-After seconds. Nothing was charged.
  • 5XXThe check could not run. Nothing was charged.
Request
curl -X POST https://verisec.dev/v1/email/verify \
  -H "Authorization: Bearer $VERISEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane.doe@example.com"
  }'
Response · 200
{
  "ok": true,
  "request_id": "req_7c1e2a9b40d35f6e8a12",
  "latency_ms": 1840,
  "data": {
    "email": "jane.doe@example.com",
    "domain": "example.com",
    "syntax_ok": true,
    "suggestion": null,
    "disposable": false,
    "free_provider": false,
    "mail_server": {
      "found": true,
      "hosts": [
        "mx1.example.com",
        "mx2.example.com"
      ]
    },
    "mailbox": "exists",
    "deliverable": "yes",
    "risk": {
      "level": "low",
      "reasons": []
    }
  },
  "warnings": [],
  "error": null
}

Email Accounts

POST/v1/email/footprintemail.footprint

The sites where an email address has an account, found through each site's sign-up and recovery forms.

**Returns**

- count: how many sites - accounts[]: each site and domain, with any recovery hints

**Limits**

- Slow (up to ~150s). A lead for investigation, not proof of ownership.

Price: 0.1 credits per successful call.

Body parameters

emailstringrequired

Email.

Returns

The check ran.

Show the EmailFootprintResponse fields
okbooleanrequired

true: the result is in data.

request_idstring
latency_msnumber

How long the check took, in milliseconds.

dataobjectrequired

The answer of Email Accounts.

Show 3 fields
emailstring
countnumber
accountsarray of objects
Show 4 fields
sitestring
domainstring
recovery_email_hintany
phone_hintany
warningsarray of strings
errorany

Empty on success.

Errors

  • 400A field is missing or not valid.
  • 401No API key, or the key is not valid, expired or revoked.
  • 402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.
  • 403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.
  • 413The image or the request is too large.
  • 429Too many requests for this key: wait Retry-After seconds. Nothing was charged.
  • 5XXThe check could not run. Nothing was charged.
Request
curl -X POST https://verisec.dev/v1/email/footprint \
  -H "Authorization: Bearer $VERISEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane.doe@example.com"
  }'
Response · 200
{
  "ok": true,
  "request_id": "req_7c1e2a9b40d35f6e8a12",
  "latency_ms": 41200,
  "data": {
    "email": "jane.doe@example.com",
    "count": 2,
    "accounts": [
      {
        "site": "example-social",
        "domain": "social.example.com",
        "recovery_email_hint": "j*****@e*****.com",
        "phone_hint": null
      },
      {
        "site": "example-shop",
        "domain": "shop.example.com",
        "recovery_email_hint": null,
        "phone_hint": "+25*******00"
      }
    ]
  },
  "warnings": [],
  "error": null
}

Username Search

POST/v1/osint/usernameosint.username

Public profiles that use a username, across hundreds of sites. Profiles whose page does not actually contain the name are dropped.

**Returns**

- found: profiles kept - common: true when the name is on very many sites, so it says little - profiles[]: each site and URL - left_out: pages dropped because the username is not in their address (a search page is not an account)

**Limits**

- Slow. A shared username is a lead, not proof of one person.

Price: 0.1 credits per successful call.

Body parameters

usernamestringrequired

Username.

topinteger

Sites to check. The most visited sites first.

Returns

The check ran.

Show the OsintUsernameResponse fields
okbooleanrequired

true: the result is in data.

request_idstring
latency_msnumber

How long the check took, in milliseconds.

dataobjectrequired

The answer of Username Search.

Show 5 fields
usernamestring
foundnumber
commonboolean
profilesarray of objects
Show 2 fields
sitestring
urlstring
left_outnumber
warningsarray of strings
errorany

Empty on success.

Errors

  • 400A field is missing or not valid.
  • 401No API key, or the key is not valid, expired or revoked.
  • 402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.
  • 403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.
  • 413The image or the request is too large.
  • 429Too many requests for this key: wait Retry-After seconds. Nothing was charged.
  • 5XXThe check could not run. Nothing was charged.
Request
curl -X POST https://verisec.dev/v1/osint/username \
  -H "Authorization: Bearer $VERISEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "jane_doe",
    "top": 150
  }'
Response · 200
{
  "ok": true,
  "request_id": "req_7c1e2a9b40d35f6e8a12",
  "latency_ms": 68400,
  "data": {
    "username": "jane_doe_88",
    "found": 2,
    "common": false,
    "profiles": [
      {
        "site": "GitHub",
        "url": "https://github.com/jane_doe_88"
      },
      {
        "site": "Example Forum",
        "url": "https://forum.example.com/u/jane_doe_88"
      }
    ],
    "left_out": 1
  },
  "warnings": [],
  "error": null
}

Phone Intelligence

POST/v1/phone/lookupphone.lookup

Whether a number is valid and live, with its format, country, line type, carrier, SMS pumping risk, SIM swap and forwarding, and a risk level. With a name, the carrier is also asked whether the number belongs to that person.

**Returns**

- valid: whether the number is valid - format: E.164, national and international spellings - country: code, name and calling code - line: type and carrier - sms_pumping / sim_swap / call_forwarding: each package, or why it was not available - risk: low, medium or high, with the reasons

**Limits**

- Number with country code, e.g. +250788123456. - Some packages are offered only in certain countries; when not, the field says why. - This does not send an SMS.

Price: 0.08 credits per successful call.

Body parameters

phonestringrequired

Phone. With its country code, for example +250788123456.

first_namestring

First name. With a name, the carrier is asked whether it belongs to that person (some countries only).

last_namestring

Last name.

date_of_birthstring

Date of birth. YYYY-MM-DD.

countrystring

Country. ISO alpha-2, for example RW.

Returns

The check ran.

Show the PhoneLookupResponse fields
okbooleanrequired

true: the result is in data.

request_idstring
latency_msnumber

How long the check took, in milliseconds.

dataobjectrequired

The answer of Phone Intelligence.

Show 12 fields
phonestring
validboolean
formatobject
Show 3 fields
e164string
nationalstring
internationalstring
countryobject
Show 3 fields
codestring
namestring
calling_codestring
locationany
lineobject
Show 4 fields
typestring
carrierstring
mccstring
mncstring
statusstring
sms_pumpingobject
Show 5 fields
scorenumber
carrier_riskstring
blockedboolean
blocked_onany
blocked_last_3_monthsboolean
sim_swapobject
Show 2 fields
availableboolean
reasonstring
call_forwardingobject
Show 2 fields
availableboolean
reasonstring
callerobject
Show 2 fields
availableboolean
reasonstring
riskobject
Show 2 fields
levelstring
reasonsarray of anys
warningsarray of strings
errorany

Empty on success.

Errors

  • 400A field is missing or not valid.
  • 401No API key, or the key is not valid, expired or revoked.
  • 402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.
  • 403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.
  • 413The image or the request is too large.
  • 429Too many requests for this key: wait Retry-After seconds. Nothing was charged.
  • 5XXThe check could not run. Nothing was charged.
Request
curl -X POST https://verisec.dev/v1/phone/lookup \
  -H "Authorization: Bearer $VERISEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+14155550123"
  }'
Response · 200
{
  "ok": true,
  "request_id": "req_7c1e2a9b40d35f6e8a12",
  "latency_ms": 2310,
  "data": {
    "phone": "+250788000000",
    "valid": true,
    "format": {
      "e164": "+250788000000",
      "national": "0788 000 000",
      "international": "+250 788 000 000"
    },
    "country": {
      "code": "RW",
      "name": "Rwanda",
      "calling_code": "+250"
    },
    "location": null,
    "line": {
      "type": "mobile",
      "carrier": "Example Mobile",
      "mcc": "635",
      "mnc": "10"
    },
    "status": "active",
    "sms_pumping": {
      "score": 12,
      "carrier_risk": "low",
      "blocked": false,
      "blocked_on": null,
      "blocked_last_3_months": false
    },
    "sim_swap": {
      "available": false,
      "reason": "Not offered for numbers in this country."
    },
    "call_forwarding": {
      "available": false,
      "reason": "Not offered for numbers in this country."
    },
    "caller": {
      "available": false,
      "reason": "No data for this number."
    },
    "risk": {
      "level": "low",
      "reasons": []
    }
  },
  "warnings": [],
  "error": null
}

Send Phone Code

POST/v1/phone/otp/sendphone.otp.send

Sends a one-time code by SMS to prove the person holds the number.

**Returns**

- status: pending when the code was sent - to / channel: where and how it was sent

**Limits**

- Sends a real SMS, use a number you control for testing.

Price: 0.08 credits per successful call.

Body parameters

phonestringrequired

Phone. A real SMS is sent to this number.

Returns

The check ran.

Show the PhoneOtpSendResponse fields
okbooleanrequired

true: the result is in data.

request_idstring
latency_msnumber

How long the check took, in milliseconds.

dataobjectrequired

The answer of Send Phone Code.

Show 3 fields
statusstring
tostring
channelstring
warningsarray of strings
errorany

Empty on success.

Errors

  • 400A field is missing or not valid.
  • 401No API key, or the key is not valid, expired or revoked.
  • 402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.
  • 403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.
  • 413The image or the request is too large.
  • 429Too many requests for this key: wait Retry-After seconds. Nothing was charged.
  • 5XXThe check could not run. Nothing was charged.
Request
curl -X POST https://verisec.dev/v1/phone/otp/send \
  -H "Authorization: Bearer $VERISEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+14155550123"
  }'
Response · 200
{
  "ok": true,
  "request_id": "req_7c1e2a9b40d35f6e8a12",
  "latency_ms": 910,
  "data": {
    "status": "pending",
    "to": "+250788000000",
    "channel": "sms"
  },
  "warnings": [],
  "error": null
}

Check Phone Code

POST/v1/phone/otp/checkphone.otp.check

Checks the code the person entered against the one that was sent.

**Returns**

- status: approved or failed - valid: true when the code is correct

**Limits**

- Codes expire; a few wrong tries end the attempt.

Free: this call is not charged.

Body parameters

phonestringrequired

Phone.

codestringrequired

Code.

Returns

The check ran.

Show the PhoneOtpCheckResponse fields
okbooleanrequired

true: the result is in data.

request_idstring
latency_msnumber

How long the check took, in milliseconds.

dataobjectrequired

The answer of Check Phone Code.

Show 2 fields
statusstring
validboolean
warningsarray of strings
errorany

Empty on success.

Errors

  • 400A field is missing or not valid.
  • 401No API key, or the key is not valid, expired or revoked.
  • 402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.
  • 403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.
  • 413The image or the request is too large.
  • 429Too many requests for this key: wait Retry-After seconds. Nothing was charged.
  • 5XXThe check could not run. Nothing was charged.
Request
curl -X POST https://verisec.dev/v1/phone/otp/check \
  -H "Authorization: Bearer $VERISEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+14155550123",
    "code": "123456"
  }'
Response · 200
{
  "ok": true,
  "request_id": "req_7c1e2a9b40d35f6e8a12",
  "latency_ms": 640,
  "data": {
    "status": "approved",
    "valid": true
  },
  "warnings": [],
  "error": null
}

IP Risk

POST/v1/screen/ipscreening.ip

Where an IP address is, who runs it, whether it hides the user (VPN, proxy, Tor, data centre), its abuse reports, and a risk level with reasons.

**Returns**

- location: continent, country, region, city, coordinates and time zones - network: ASN, owner, ISP, operator, domain, reverse DNS hostnames, mobile - anonymity: tor, vpn, datacenter, proxy, private relay, blocklisted - reputation: abuse score, reports, reporters, last report, usage, allowlisted; or why unavailable - risk: low, medium or high, with the reasons

**Limits**

- Abuse reports come from an outside source and may occasionally be unavailable; the rest still returns.

Price: 0.06 credits per successful call.

Body parameters

ipstringrequired

IP address. IPv4 or IPv6.

Returns

The check ran.

Show the ScreeningIpResponse fields
okbooleanrequired

true: the result is in data.

request_idstring
latency_msnumber

How long the check took, in milliseconds.

dataobjectrequired

The full result of IP Risk: everything the check found. See the fields listed in the operation.

warningsarray of strings
errorany

Empty on success.

Errors

  • 400A field is missing or not valid.
  • 401No API key, or the key is not valid, expired or revoked.
  • 402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.
  • 403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.
  • 413The image or the request is too large.
  • 429Too many requests for this key: wait Retry-After seconds. Nothing was charged.
  • 5XXThe check could not run. Nothing was charged.
Request
curl -X POST https://verisec.dev/v1/screen/ip \
  -H "Authorization: Bearer $VERISEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "ip": "203.0.113.7"
  }'
Response · 200
{
  "ok": true,
  "request_id": "req_7c1e2a9b40d35f6e8a12",
  "latency_ms": 1260,
  "data": {
    "ip": "203.0.113.42",
    "version": 4,
    "location": {
      "continent": "EU",
      "country_code": "NL",
      "country": "Netherlands",
      "region": "North Holland",
      "city": "Amsterdam",
      "coordinates": {
        "lat": 52.374,
        "lon": 4.8897
      },
      "timezones": [
        "Europe/Amsterdam"
      ]
    },
    "network": {
      "asn": 64500,
      "organization": "Example Hosting B.V.",
      "connection_type": "datacenter",
      "isp": "Example Hosting B.V.",
      "operator": "Example VPN Ltd",
      "domain": "example-hosting.example",
      "hostnames": [
        "vpn-42.example-hosting.example"
      ],
      "mobile": false
    },
    "anonymity": {
      "tor": false,
      "vpn": true,
      "datacenter": true,
      "cloud_provider": null,
      "private_relay": false,
      "relay_region": null,
      "blocklisted": false,
      "proxy": false
    },
    "reputation": {
      "abuse_score": 0,
      "reports": 0,
      "distinct_reporters": 0,
      "last_reported": null,
      "usage": "Data Center/Web Hosting/Transit",
      "allowlisted": false
    },
    "risk": {
      "level": "medium",
      "reasons": [
        "A VPN address.",
        "A data centre or hosting address, not a home or mobile connection."
      ]
    }
  },
  "warnings": [],
  "error": null
}

IP Anonymity

POST/v1/ip/analyzeip.analyze

The fast answer from the platform's own lists only: Tor, VPN, data centre, cloud, private relay, blocklist and the network owner. No outside call, so it is quick.

**Returns**

- anonymity: tor, vpn, datacenter, cloud, private relay and its region, blocklisted - network: ASN, owner, connection type - location: continent, country, region, city, coordinates and time zones - lists_updated: when the lists were refreshed

**Limits**

- Uses local lists only (about 20 ms). For abuse reports too, use IP Risk.

Price: 0.06 credits per successful call.

Body parameters

ipstringrequired

IP address. IPv4 or IPv6.

Returns

The check ran.

Show the IpAnalyzeResponse fields
okbooleanrequired

true: the result is in data.

request_idstring
latency_msnumber

How long the check took, in milliseconds.

dataobjectrequired

The answer of IP Anonymity.

Show 7 fields
ipstring
versionnumber
privateboolean
locationobject
Show 7 fields
continentstring
country_codestring
countrystring
regionstring
citystring
coordinatesobject
Show 2 fields
latnumber
lonnumber
timezonesarray of strings
networkobject
Show 3 fields
asnnumber
organizationstring
connection_typestring
anonymityobject
Show 7 fields
torboolean
vpnboolean
datacenterboolean
cloud_providerany
private_relayboolean
relay_regionany
blocklistedboolean
lists_updatedstring
warningsarray of strings
errorany

Empty on success.

Errors

  • 400A field is missing or not valid.
  • 401No API key, or the key is not valid, expired or revoked.
  • 402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.
  • 403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.
  • 413The image or the request is too large.
  • 429Too many requests for this key: wait Retry-After seconds. Nothing was charged.
  • 5XXThe check could not run. Nothing was charged.
Request
curl -X POST https://verisec.dev/v1/ip/analyze \
  -H "Authorization: Bearer $VERISEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "ip": "203.0.113.7"
  }'
Response · 200
{
  "ok": true,
  "request_id": "req_7c1e2a9b40d35f6e8a12",
  "latency_ms": 24,
  "data": {
    "ip": "203.0.113.42",
    "version": 4,
    "private": false,
    "location": {
      "continent": "EU",
      "country_code": "NL",
      "country": "Netherlands",
      "region": "North Holland",
      "city": "Amsterdam",
      "coordinates": {
        "lat": 52.374,
        "lon": 4.8897
      },
      "timezones": [
        "Europe/Amsterdam"
      ]
    },
    "network": {
      "asn": 64500,
      "organization": "Example Hosting B.V.",
      "connection_type": "datacenter"
    },
    "anonymity": {
      "tor": false,
      "vpn": true,
      "datacenter": true,
      "cloud_provider": null,
      "private_relay": false,
      "relay_region": null,
      "blocklisted": false
    },
    "lists_updated": "2026-10-05T06:00:00Z"
  },
  "warnings": [],
  "error": null
}

Sanctions & PEP Screening

POST/v1/screen/sanctionsscreening.sanctions

Screens a person or company against sanctions, politically exposed person and crime lists. Every detail you give, name, date of birth, nationality, ID number, is scored together, and each result explains why it matched.

**Returns**

- summary: results, matches and top score - results[].score / match: the score and whether it crossed the bar - results[].topics / lists: why it is listed, in the standard risk words (Sanction, PEP, Debarment...), and the lists by their published names - results[].why: per detail you gave (name, birth year or date, country, ID number): whether it raised or lowered the score; for the name, the words that matched exactly, closely or as an equivalent, and the extra words on either side - results[].details: for the first three confirmed matches: aliases, addresses, each sanction (authority, programme, reason, dates), roles, and when the record last changed

**Limits**

- Name-only screening is not a decision, confirm with a date of birth or an identifier. - Up to 5 countries and 5 ID numbers.

Price: 0.8 credits per successful call.

Body parameters

namestringrequired

Name.

schemastring

Type.

PersonCompanyOrganizationLegalEntity
birth_datestring

Date of birth. YYYY, YYYY-MM or YYYY-MM-DD. People only.

countriesarray of strings

Countries. Up to 5 ISO alpha-2 codes (nationality for a person, country for a company).

id_numbersarray of strings

ID numbers. Up to 5: passport, national ID, tax or registration numbers.

limitinteger

Results.

Returns

The check ran.

Show the ScreeningSanctionsResponse fields
okbooleanrequired

true: the result is in data.

request_idstring
latency_msnumber

How long the check took, in milliseconds.

dataobjectrequired

The full result of Sanctions & PEP Screening: everything the check found. See the fields listed in the operation.

warningsarray of strings
errorany

Empty on success.

Errors

  • 400A field is missing or not valid.
  • 401No API key, or the key is not valid, expired or revoked.
  • 402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.
  • 403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.
  • 413The image or the request is too large.
  • 429Too many requests for this key: wait Retry-After seconds. Nothing was charged.
  • 5XXThe check could not run. Nothing was charged.
Request
curl -X POST https://verisec.dev/v1/screen/sanctions \
  -H "Authorization: Bearer $VERISEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Jane Doe",
    "schema": "Person",
    "limit": 10
  }'
Response · 200
{
  "ok": true,
  "request_id": "req_7c1e2a9b40d35f6e8a12",
  "latency_ms": 410,
  "data": {
    "query": {
      "name": "Jane Example",
      "type": "Person",
      "birth_date": "1980-04-12",
      "countries": [
        "xx"
      ],
      "id_numbers": []
    },
    "summary": {
      "results": 2,
      "matches": 1,
      "top_score": 0.93
    },
    "results": [
      {
        "id": "ent_2cea995ec08e7dbbb4e4",
        "name": "Jane EXAMPLE",
        "type": "Person",
        "score": 0.93,
        "match": true,
        "topics": [
          "Sanction"
        ],
        "lists": [
          "Example Sanctions List"
        ],
        "countries": [
          "xx"
        ],
        "birth_dates": [
          "1980-04-12"
        ],
        "nationalities": [
          "xx"
        ],
        "identifiers": {
          "passportNumber": [
            "X0000000"
          ]
        },
        "why": {
          "name": {
            "score": 0.97,
            "effect": "raises",
            "exact": [
              "jane",
              "example"
            ],
            "close": [],
            "equivalent": [],
            "only_in_listed": [],
            "only_in_yours": []
          },
          "birth_date": {
            "score": 0,
            "effect": "none",
            "note": "Same birth date"
          }
        },
        "details": {
          "aliases": [
            "Jane Q. Example",
            "Jane Exampleova"
          ],
          "addresses": [
            "1 Example Street, Example City, 00000"
          ],
          "sanctions": [
            {
              "authority": "Example Sanctions Office",
              "program": "EXAMPLE-2024",
              "reason": "Listed for supporting a sanctioned regime (fictional).",
              "country": "xx",
              "start_date": "2024-02-01",
              "end_date": null
            }
          ],
          "sanctions_total": 1,
          "positions": [
            "Director, Example Holdings"
          ],
          "birth_places": [
            "Example City"
          ],
          "gender": "female",
          "first_seen": "2024-02-02T09:00:00",
          "last_seen": "2026-10-01T06:00:00",
          "last_change": "2025-06-11T14:20:00"
        }
      },
      {
        "id": "ent_be5253d97f8da094418c",
        "name": "Janet EXAMPLE",
        "type": "Person",
        "score": 0.61,
        "match": false,
        "topics": [
          "PEP"
        ],
        "lists": [
          "Example Politically Exposed Persons List"
        ],
        "countries": [
          "xx"
        ],
        "birth_dates": [
          "1975"
        ],
        "nationalities": [],
        "identifiers": {},
        "why": {
          "name": {
            "score": 0.82,
            "effect": "raises",
            "exact": [
              "example"
            ],
            "close": [
              {
                "yours": "jane",
                "listed": "janet",
                "similarity": 0.8
              }
            ],
            "equivalent": [],
            "only_in_listed": [],
            "only_in_yours": []
          },
          "birth_year": {
            "score": 0.2,
            "effect": "lowers",
            "note": "Birth years differ: 1980 / 1975"
          }
        }
      }
    ]
  },
  "warnings": [],
  "error": null
}

Adverse Media

POST/v1/osint/webosint.web

Web pages that name a person or company, filtered to adverse news by default and tagged with risk topics.

**Returns**

- results[]: title, site, url, date, topics and a snippet - complete: false when some sources did not answer - left_out: how many were dropped as off-name, not adverse, or a screening-list entry page (those facts come from Screening)

**Limits**

- Results depend on outside search engines; complete=false means retry later for more.

Price: 0.1 credits per successful call.

Body parameters

querystringrequired

Name.

modestring

Show.

amlall

Returns

The check ran.

Show the OsintWebResponse fields
okbooleanrequired

true: the result is in data.

request_idstring
latency_msnumber

How long the check took, in milliseconds.

dataobjectrequired

The answer of Adverse Media.

Show 6 fields
querystring
modestring
completeboolean
countnumber
resultsarray of objects
Show 6 fields
titlestring
sitestring
urlstring
datestring
topicsarray of strings
snippetstring
left_outobject
Show 3 fields
not_about_this_namenumber
not_adversenumber
list_entriesnumber
warningsarray of strings
errorany

Empty on success.

Errors

  • 400A field is missing or not valid.
  • 401No API key, or the key is not valid, expired or revoked.
  • 402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.
  • 403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.
  • 413The image or the request is too large.
  • 429Too many requests for this key: wait Retry-After seconds. Nothing was charged.
  • 5XXThe check could not run. Nothing was charged.
Request
curl -X POST https://verisec.dev/v1/osint/web \
  -H "Authorization: Bearer $VERISEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "Jane Doe",
    "mode": "aml"
  }'
Response · 200
{
  "ok": true,
  "request_id": "req_7c1e2a9b40d35f6e8a12",
  "latency_ms": 6800,
  "data": {
    "query": "Example Holdings",
    "mode": "adverse",
    "complete": true,
    "count": 1,
    "results": [
      {
        "title": "Regulator fines Example Holdings over reporting failures",
        "site": "news.example.com",
        "url": "https://news.example.com/2026/03/example-holdings-fine",
        "date": "2026-03-14",
        "topics": [
          "reg.action"
        ],
        "snippet": "The regulator said Example Holdings failed to file required reports on time."
      }
    ],
    "left_out": {
      "not_about_this_name": 3,
      "not_adverse": 5,
      "list_entries": 0
    }
  },
  "warnings": [],
  "error": null
}

Wallet Screening

POST/v1/screen/cryptoscreening.crypto

A verdict and a risk level for up to 100 wallet addresses, on any supported network, from sanctions and illicit-activity data.

**Returns**

- checked / counts: how many, grouped by verdict - results[].verdict: sanctioned, illicit, formerly_sanctioned, scheme_participant, named_in_risk_list, risk_attribution, service, mentioned, disputed_listing or no_record; and for input that is not an address: invalid_address, unreadable or unrecognised - results[].risk: high, medium, low or unknown - results[].summary: the verdict in one sentence - results[].listings / disputed_by / labels: for an address on record: each listing and its category, who vouches for it, and what it is known as

**Limits**

- 1 to 100 addresses. Invalid addresses are returned with an invalid_address verdict, not an error.

Price: 0.1 credits per successful call.

Body parameters

addressesarray of stringsrequired

Wallet addresses. One per line, up to 100.

Returns

The check ran.

Show the ScreeningCryptoResponse fields
okbooleanrequired

true: the result is in data.

request_idstring
latency_msnumber

How long the check took, in milliseconds.

dataobjectrequired

The answer of Wallet Screening.

Show 3 fields
checkednumber
countsobject
Show 8 fields
highnumber
mediumnumber
lownumber
no_recordnumber
unreadablenumber
invalid_addressnumber
unrecognisednumber
disputed_listingnumber
resultsarray of objects
Show 13 fields
addressstring
networkany
valid_formatany
checksum_okany
format_notestring
verdictstring
riskstring
summaryany
flagsarray of anys
listingsarray of objects
Show 5 fields
networkstring
categoriesarray of strings
risk_classstring
subcategoryany
victim_contractboolean
disputed_byarray of anys
schemesarray of anys
labelsarray of objects
Show 2 fields
networkstring
labelstring
warningsarray of strings
errorany

Empty on success.

Errors

  • 400A field is missing or not valid.
  • 401No API key, or the key is not valid, expired or revoked.
  • 402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.
  • 403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.
  • 413The image or the request is too large.
  • 429Too many requests for this key: wait Retry-After seconds. Nothing was charged.
  • 5XXThe check could not run. Nothing was charged.
Request
curl -X POST https://verisec.dev/v1/screen/crypto \
  -H "Authorization: Bearer $VERISEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "addresses": [
      "1BoatSLRHtKNngkdXEeobR76b53LETtpyT"
    ]
  }'
Response · 200
{
  "ok": true,
  "request_id": "req_7c1e2a9b40d35f6e8a12",
  "latency_ms": 95,
  "data": {
    "checked": 3,
    "counts": {
      "high": 1,
      "medium": 0,
      "low": 0,
      "no_record": 1,
      "unreadable": 0,
      "invalid_address": 0,
      "unrecognised": 1,
      "disputed_listing": 0
    },
    "results": [
      {
        "address": "0x1111111111111111111111111111111111111111",
        "network": "Ethereum-compatible",
        "valid_format": true,
        "checksum_ok": false,
        "format_note": "format correct; this spelling has no mixed-case checksum",
        "verdict": "illicit",
        "risk": "high",
        "summary": "Listed for heist.",
        "flags": [
          "illicit",
          "service_attribution"
        ],
        "listings": [
          {
            "network": "Ethereum",
            "categories": [
              "heist"
            ],
            "risk_class": "illicit",
            "subcategory": null,
            "victim_contract": false
          }
        ],
        "disputed_by": [],
        "schemes": [],
        "labels": [
          {
            "network": "BNB Chain",
            "label": "Null: 0x111...111"
          },
          {
            "network": "Ethereum",
            "label": "Null: 0x111...111"
          },
          {
            "network": "Polygon",
            "label": "Null: 0x111...111"
          }
        ]
      },
      {
        "address": "0x9d8f1c2a6b7e4d3c5a0f8e1b2c3d4e5f6a7b8c9d",
        "network": "Ethereum-compatible",
        "valid_format": true,
        "checksum_ok": false,
        "format_note": "format correct; this spelling has no mixed-case checksum",
        "verdict": "no_record",
        "risk": "unknown",
        "summary": null,
        "flags": []
      },
      {
        "address": "not-a-wallet",
        "network": null,
        "valid_format": null,
        "checksum_ok": null,
        "format_note": "address format is not supported for checksum validation",
        "verdict": "unrecognised",
        "risk": "unknown",
        "summary": null,
        "flags": []
      }
    ]
  },
  "warnings": [],
  "error": null
}

Contact Dossier

POST/v1/verify/contactcontact.dossier

Everything in one call: email, phone, IP, sanctions screening and wallet, each part in exactly the same shape as its own API. The slower checks (accounts, username, adverse media) are opt-in.

**Returns**

- email / phone / ip / screening / wallet: each source's own result, or an error note for that part - (opt-in) accounts / username / web: only when you tick them

**Limits**

- At least one input. A failing part is reported in place; the rest still returns. - The opt-in checks each add up to a few minutes.

Price: 1.39 credits per successful call.

Body parameters

emailstring

Email.

phonestring

Phone. With its country code.

namestring

Name.

dobstring

Date of birth. YYYY-MM-DD.

countrystring

Country. ISO alpha-2.

ipstring

IP address.

walletstring

Wallet address.

includearray of strings

Slower checks. Each adds up to a few minutes.

Returns

The check ran.

Show the ContactDossierResponse fields
okbooleanrequired

true: the result is in data.

request_idstring
latency_msnumber

How long the check took, in milliseconds.

dataobjectrequired

The full result of Contact Dossier: everything the check found. See the fields listed in the operation.

warningsarray of strings
errorany

Empty on success.

Errors

  • 400A field is missing or not valid.
  • 401No API key, or the key is not valid, expired or revoked.
  • 402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.
  • 403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.
  • 413The image or the request is too large.
  • 429Too many requests for this key: wait Retry-After seconds. Nothing was charged.
  • 5XXThe check could not run. Nothing was charged.
Request
curl -X POST https://verisec.dev/v1/verify/contact \
  -H "Authorization: Bearer $VERISEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "include": []
  }'
Response · 200
{
  "ok": true,
  "request_id": "req_7c1e2a9b40d35f6e8a12",
  "latency_ms": 4100,
  "data": {
    "email": {
      "email": "jane.doe@example.com",
      "domain": "example.com",
      "syntax_ok": true,
      "suggestion": null,
      "disposable": false,
      "free_provider": false,
      "mail_server": {
        "found": true,
        "hosts": [
          "mx1.example.com",
          "mx2.example.com"
        ]
      },
      "mailbox": "exists",
      "deliverable": "yes",
      "risk": {
        "level": "low",
        "reasons": []
      }
    },
    "phone": {
      "phone": "+250788000000",
      "valid": true,
      "format": {
        "e164": "+250788000000",
        "national": "0788 000 000",
        "international": "+250 788 000 000"
      },
      "country": {
        "code": "RW",
        "name": "Rwanda",
        "calling_code": "+250"
      },
      "location": null,
      "line": {
        "type": "mobile",
        "carrier": "Example Mobile",
        "mcc": "635",
        "mnc": "10"
      },
      "status": "active",
      "sms_pumping": {
        "score": 12,
        "carrier_risk": "low",
        "blocked": false,
        "blocked_on": null,
        "blocked_last_3_months": false
      },
      "sim_swap": {
        "available": false,
        "reason": "Not offered for numbers in this country."
      },
      "call_forwarding": {
        "available": false,
        "reason": "Not offered for numbers in this country."
      },
      "caller": {
        "available": false,
        "reason": "No data for this number."
      },
      "risk": {
        "level": "low",
        "reasons": []
      }
    },
    "ip": {
      "ip": "203.0.113.42",
      "version": 4,
      "location": {
        "continent": "EU",
        "country_code": "NL",
        "country": "Netherlands",
        "region": "North Holland",
        "city": "Amsterdam",
        "coordinates": {
          "lat": 52.374,
          "lon": 4.8897
        },
        "timezones": [
          "Europe/Amsterdam"
        ]
      },
      "network": {
        "asn": 64500,
        "organization": "Example Hosting B.V.",
        "connection_type": "datacenter",
        "isp": "Example Hosting B.V.",
        "operator": "Example VPN Ltd",
        "domain": "example-hosting.example",
        "hostnames": [
          "vpn-42.example-hosting.example"
        ],
        "mobile": false
      },
      "anonymity": {
        "tor": false,
        "vpn": true,
        "datacenter": true,
        "cloud_provider": null,
        "private_relay": false,
        "relay_region": null,
        "blocklisted": false,
        "proxy": false
      },
      "reputation": {
        "abuse_score": 0,
        "reports": 0,
        "distinct_reporters": 0,
        "last_reported": null,
        "usage": "Data Center/Web Hosting/Transit",
        "allowlisted": false
      },
      "risk": {
        "level": "medium",
        "reasons": [
          "A VPN address.",
          "A data centre or hosting address, not a home or mobile connection."
        ]
      }
    },
    "screening": {
      "query": {
        "name": "Jane Example",
        "type": "Person",
        "birth_date": "1980-04-12",
        "countries": [
          "xx"
        ],
        "id_numbers": []
      },
      "summary": {
        "results": 2,
        "matches": 1,
        "top_score": 0.93
      },
      "results": [
        {
          "id": "ent_2cea995ec08e7dbbb4e4",
          "name": "Jane EXAMPLE",
          "type": "Person",
          "score": 0.93,
          "match": true,
          "topics": [
            "Sanction"
          ],
          "lists": [
            "Example Sanctions List"
          ],
          "countries": [
            "xx"
          ],
          "birth_dates": [
            "1980-04-12"
          ],
          "nationalities": [
            "xx"
          ],
          "identifiers": {
            "passportNumber": [
              "X0000000"
            ]
          },
          "why": {
            "name": {
              "score": 0.97,
              "effect": "raises",
              "exact": [
                "jane",
                "example"
              ],
              "close": [],
              "equivalent": [],
              "only_in_listed": [],
              "only_in_yours": []
            },
            "birth_date": {
              "score": 0,
              "effect": "none",
              "note": "Same birth date"
            }
          },
          "details": {
            "aliases": [
              "Jane Q. Example",
              "Jane Exampleova"
            ],
            "addresses": [
              "1 Example Street, Example City, 00000"
            ],
            "sanctions": [
              {
                "authority": "Example Sanctions Office",
                "program": "EXAMPLE-2024",
                "reason": "Listed for supporting a sanctioned regime (fictional).",
                "country": "xx",
                "start_date": "2024-02-01",
                "end_date": null
              }
            ],
            "sanctions_total": 1,
            "positions": [
              "Director, Example Holdings"
            ],
            "birth_places": [
              "Example City"
            ],
            "gender": "female",
            "first_seen": "2024-02-02T09:00:00",
            "last_seen": "2026-10-01T06:00:00",
            "last_change": "2025-06-11T14:20:00"
          }
        },
        {
          "id": "ent_be5253d97f8da094418c",
          "name": "Janet EXAMPLE",
          "type": "Person",
          "score": 0.61,
          "match": false,
          "topics": [
            "PEP"
          ],
          "lists": [
            "Example Politically Exposed Persons List"
          ],
          "countries": [
            "xx"
          ],
          "birth_dates": [
            "1975"
          ],
          "nationalities": [],
          "identifiers": {},
          "why": {
            "name": {
              "score": 0.82,
              "effect": "raises",
              "exact": [
                "example"
              ],
              "close": [
                {
                  "yours": "jane",
                  "listed": "janet",
                  "similarity": 0.8
                }
              ],
              "equivalent": [],
              "only_in_listed": [],
              "only_in_yours": []
            },
            "birth_year": {
              "score": 0.2,
              "effect": "lowers",
              "note": "Birth years differ: 1980 / 1975"
            }
          }
        }
      ]
    },
    "wallet": {
      "checked": 1,
      "counts": {
        "high": 0,
        "medium": 0,
        "low": 0,
        "no_record": 1,
        "unreadable": 0,
        "invalid_address": 0,
        "unrecognised": 0,
        "disputed_listing": 0
      },
      "results": [
        {
          "address": "0x9d8f1c2a6b7e4d3c5a0f8e1b2c3d4e5f6a7b8c9d",
          "network": "Ethereum-compatible",
          "valid_format": true,
          "checksum_ok": false,
          "format_note": "format correct; this spelling has no mixed-case checksum",
          "verdict": "no_record",
          "risk": "unknown",
          "summary": null,
          "flags": []
        }
      ]
    }
  },
  "warnings": [],
  "error": null
}