Verify API
Assess the risk of a user registration or sign-in attempt by analyzing their email, IP address, phone number, and device fingerprint.
Overview#
The /verifyendpoint is the core of AlliedPass. Send it a user's registration or sign-in data and receive a risk score, risk level, and a detailed breakdown of each signal analyzed. You can then use the riskLevel to decide whether to allow, challenge, or block the request.
Base URL
https://api.alliedpass.com
Protocol
HTTPS only
Format
JSON
Authentication#
All requests must include your API key in the Authorization header. API keys are scoped to a project — create and manage them from the API Keys page.
Authorization: Bearer ap_live_<identifier>_<secret>Never expose your API key in client-side code. Always call the Verify API from your server.
Rate Limits#
Rate limits are enforced per API key, per minute. When exceeded, the API returns 429 Too Many Requests. Rate limit headers (RateLimit-*) are included in every response.
| Plan | Requests / minute |
|---|---|
| Starter | 60 |
| Pro | 300 |
| Enterprise | 1,000 |
Endpoint & Request#
/verifyRequest Headers
| Field | Type | Required | Description |
|---|---|---|---|
Authorization | string | Yes | Bearer ap_live_<your_key> |
Content-Type | string | Yes | Must be application/json |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | The user's email address (max 254 chars) |
ip | string | Yes | The user's IP address (IPv4 or IPv6) |
phone | string | No | Phone number in E.164 format (e.g. +2348012345678) |
userAgent | string | No | Raw User-Agent header string from the user's browser (max 512 chars). Improves device fingerprinting — pass when possible. |
Response#
serviceErrors and "partial": trueExample Response
{
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"riskScore": 82,
"riskLevel": "low",
"isVpn": false,
"isProxy": false,
"isTor": false,
"isDisposableEmail": false,
"secureGateway": false,
"email": {
"address": "user@example.com",
"domain": "example.com",
"disposable": false,
"freeProvider": false,
"roleAddress": false,
"tagged": false,
"noReply": false
},
"phone": {
"number": "+2348012345678",
"valid": true,
"voip": false,
"lineType": "mobile",
"carrier": "MTN Nigeria",
"countryCode": "NG"
},
"flaggedReasons": [],
"geo": {
"country": "NG",
"city": "Lagos",
"isp": "MTN Nigeria"
},
"device": {
"browser": "Chrome",
"os": "Windows",
"fingerprintId": "3f9a1c72b4e8d05a2f6c"
}
}Top-level Fields
| Field | Type | Description |
|---|---|---|
requestId | string | Unique UUID for this verification request |
riskScore | number | Trust score from 0 (high risk) to 100 (low risk) |
riskLevel | string | "low", "medium", or "high" |
isVpn | boolean | IP is a known VPN exit node |
isProxy | boolean | IP is a known proxy |
isTor | boolean | IP is a Tor exit node |
isDisposableEmail | boolean | Email domain is a disposable/temporary provider |
isVoip | boolean | Phone number is a VoIP line |
secureGateway | boolean | Email is behind a secure email gateway (e.g. Proofpoint, Mimecast) |
secureGatewayProvider | string | Name of the gateway provider (only present when secureGateway is true) |
flaggedReasons | string[] | List of risk flag codes |
email | object | Detailed email analysis |
phone | object | Detailed phone analysis (only present if phone was provided) |
geo | object | Geolocation derived from IP |
device | object | Browser, OS, and fingerprint data |
partial | boolean | true if one or more services failed (only present on 207) |
serviceErrors | array | Details of failed services (only present on 207) |
email object
| Field | Type | Description |
|---|---|---|
address | string | Normalized input email |
domain | string | Domain portion of the email |
disposable | boolean | Domain is a disposable provider |
freeProvider | boolean | Domain is a free provider (e.g. Gmail, Yahoo) |
roleAddress | boolean | Address is role-based (e.g. admin@, support@) |
tagged | boolean | Email uses address tagging (e.g. user+tag@) |
tagValue | string | The tag value if tagged is true |
noReply | boolean | Address appears to be a no-reply address |
irregularChars | boolean | Address contains irregular characters |
unicodeSymbols | boolean | Address contains unicode/non-ASCII symbols |
phone object (only present if phone was provided)
| Field | Type | Description |
|---|---|---|
number | string | The input phone number |
valid | boolean | Number is a valid, dialable number |
voip | boolean | Number is a VoIP line |
lineType | string | "mobile", "landline", "voip", etc. |
carrier | string | Carrier/network name |
countryCode | string | ISO 3166-1 alpha-2 country code |
geo object
| Field | Type | Description |
|---|---|---|
country | string | null | ISO country code derived from IP |
city | string | null | City derived from IP |
isp | string | null | Internet Service Provider |
device object
| Field | Type | Description |
|---|---|---|
browser | string | Detected browser: "Chrome", "Firefox", "Safari", "Edge", or "unknown" |
os | string | Detected OS: "Windows", "macOS", "Android", "iOS", "Linux", or "unknown" |
fingerprintId | string | 24-char hex fingerprint derived from email + IP + user agent |
Risk Score#
The riskScore is a value from 0 to 100, where higher means safer.
71 – 100
low risk
41 – 70
medium risk
0 – 40
high risk
Tor exit nodes and proxy IPs always force riskLevel to "high" regardless of score.
Flagged Reasons#
The flaggedReasons array contains zero or more of the following codes. An empty array means no risk signals were detected.
| Code | Meaning |
|---|---|
TOR_EXIT_NODE_DETECTED | IP is a Tor exit node |
PROXY_IP_DETECTED | IP is a known proxy |
VPN_IP_DETECTED | IP is a known VPN |
DISPOSABLE_EMAIL_DETECTED | Email domain is disposable |
NO_REPLY_ADDRESS_DETECTED | Email is a no-reply address |
ROLE_BASED_ADDRESS_DETECTED | Email is a role address (e.g. admin@) |
FREE_PROVIDER_DETECTED | Email uses a free provider |
VOIP_NUMBER_DETECTED | Phone is a VoIP number |
HIGH_RISK_SCORE | Overall risk score is high |
Errors#
All errors follow a consistent format:
{
"error": {
"code": "SNAKE_CASE_CODE",
"message": "Human-readable description"
}
}| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Missing required fields or invalid values |
| 401 | UNAUTHORIZED | Missing or invalid API key |
| 429 | — | Rate limit exceeded |
| 500 | INTERNAL_SERVER_ERROR | Unexpected server error |
Whitelisting#
Emails and domains can be whitelisted per-project from the AlliedPass dashboard. Whitelisted entries bypass the disposable email signal — a known internal or partner email will not be flagged even if its domain appears on a disposable list. Manage your whitelist from the Logs page.
Code Examples#
A full end-to-end verification call. Replace ap_live_your_key_here with an API key from the API Keys page.
const response = await fetch("https://api.alliedpass.com/verify", {
method: "POST",
headers: {
"Authorization": "Bearer ap_live_your_key_here",
"Content-Type": "application/json",
},
body: JSON.stringify({
email: "user@example.com",
ip: "203.0.113.42",
phone: "+2348012345678",
userAgent: navigator.userAgent,
}),
});
const result = await response.json();
if (result.riskLevel === "high") {
// Block or challenge the user
}Check riskLevel first for a quick allow/block decision. Use flaggedReasons and the detailed sub-objects for fine-grained logic (e.g. only allow VPN users if they verified a non-VoIP phone).