API Documentation
The RiskUnified API screens emails, phone numbers and IP addresses for fraud risk. All endpoints accept POST requests with a JSON body and return JSON.
Base URL
https://api.riskunified.comYour first request
curl -X POST https://api.riskunified.com/email_risk \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'Authentication
Create an API key in the dashboard and send it with every request, either as a bearer token or an x-api-key header.
Authorization: Bearer YOUR_API_KEY
# or
x-api-key: YOUR_API_KEYKeys are shown once at creation and stored hashed. Revoke a key instantly from the dashboard if it leaks.
Email Risk
POST/email_risk
Analyzes deliverability, alias trickery, gibberish prefixes, catch-all configuration, address history and domain intelligence (age, registrar, web/mail infrastructure, domain risk).
curl -X POST https://api.riskunified.com/email_risk \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "john@gmail.com"}'| Field | Type | Description |
|---|---|---|
| string | Required. The email address to screen. |
{
"status": "complete",
"errors": null,
"email": "john@gmail.com",
"email_features": {
"prefix": "john",
"group_control": false,
"gibberish_prefix": false,
"email_deliverable": false,
"catch_all": false,
"email_history_count": 446,
"email_age": "2008-07-01"
},
"domain_features": {
"domain": "gmail.com",
"tld": ".com",
"subdomains": "none",
"domain_risk": "low",
"registrar": "MarkMonitor Inc.",
"registration_date": "1995-08-13T04:00:00+00:00",
"domain_age_days": 11299,
"has_website": true,
"has_mailserver": true
},
"risk": {
"level": "medium",
"signals": ["email_not_deliverable"]
}
}| Field | Type | Description |
|---|---|---|
| email_features.group_control | boolean | Local part uses alias trickery, Gmail +suffix and dot-variant tricks combined into one flag. |
| email_features.gibberish_prefix | boolean | Local part looks randomly generated. |
| email_features.email_deliverable | boolean | Mailbox accepts mail (SMTP-verified). |
| email_features.catch_all | boolean | Domain accepts mail for any address. |
| email_features.email_history_count | number | How many times this address has been seen in historical data, established addresses are lower risk. |
| email_features.email_age | string | null | Date the address was first seen (YYYY-MM-DD). |
| domain_features.domain_risk | string | low | medium | high, reputation of the email domain. |
| domain_features.domain_age_days | number | Days since domain registration. Young domains are risky. |
| domain_features.has_website | boolean | Domain serves a website. |
| domain_features.has_mailserver | boolean | Domain has MX records configured. |
| risk.level | string | low | medium | high. |
| risk.signals | string[] | Named signals that contributed to the verdict. |
Phone Risk
POST/phone_risk
Resolves carrier, line type, VoIP and prepaid status, and spam rating for US and international numbers.
curl -X POST https://api.riskunified.com/phone_risk \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"phone": "2025550142"}'| Field | Type | Description |
|---|---|---|
| phone | string | Required. The phone number to screen (digits, E.164 accepted). |
{
"phone": "2025550142"
}{
"status": "complete",
"errors": null,
"phone": "2025550142",
"phone_features": {
"country_code": "+1",
"number": "2025550142",
"carrier": "BANDWIDTH.COM CLEC, LLC - MD",
"state": "MD",
"prefix_type": "CLEC",
"line_type": "voip",
"voip": true,
"prepaid": false
},
"risk": {
"score": 50,
"level": "medium",
"signals": ["voip"]
}
}| Field | Type | Description |
|---|---|---|
| phone_features.carrier | string | Operating carrier for the number. |
| phone_features.line_type | string | mobile | landline | voip. |
| phone_features.voip | boolean | Number is VoIP, common in fraud and burner setups. |
| phone_features.prepaid | boolean | Number is on a prepaid plan. |
| phone_features.prefix_type | string | Numbering-plan prefix classification (e.g. CLEC). |
| risk.score / level / signals | , | Composite verdict, same shape as Email Risk. |
IP Risk
POST/ip_risk
Resolves network, ISP, ASN and geolocation, then classifies the address (residential, datacenter, proxy) with a confidence score, flags known VPN ranges, and detects search-engine crawlers, for any IPv4 or IPv6 address.
curl -X POST https://api.riskunified.com/ip_risk \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"ip": "185.48.52.69"}'| Field | Type | Description |
|---|---|---|
| ip | string | Required. The IP address to screen. |
{
"ip": "185.48.52.69"
}{
"status": "complete",
"errors": null,
"ip": "185.48.52.69",
"ip_features": {
"network": "185.48.52.0/22",
"isp": "Latitude.sh",
"asn": 396356,
"geolocation": {
"country": "LT",
"state": null,
"city": null,
"latitude": 55.4167,
"longitude": 24
},
"classification": "datacenter",
"classification_confidence": 0.7,
"known_vpn": true,
"crawler": {
"is_crawler": false,
"tag": null,
"source": null
}
},
"risk": {
"level": "high"
}
}| Field | Type | Description |
|---|---|---|
| ip_features.network | string | CIDR block the address belongs to. |
| ip_features.isp | string | Internet service provider or hosting company operating the network. |
| ip_features.asn | number | Autonomous system number. |
| ip_features.geolocation | object | country, state, city, latitude, longitude. State and city may be null when only country-level data is available. |
| ip_features.classification | string | residential | datacenter | proxy, datacenter and proxy traffic carries elevated risk. |
| ip_features.classification_confidence | number | 0–1 confidence in the classification above. |
| ip_features.known_vpn | boolean | Address belongs to a known commercial VPN range. |
| ip_features.crawler | object | Search-engine / bot detection: is_crawler (boolean), tag and source (string | null, e.g. the crawler's name and how it was verified). |
| risk.level | string | low | medium | high composite verdict. |
Errors
Errors use conventional HTTP status codes and a consistent body:
{
"status": "error",
"errors": [
{
"code": "credits_exhausted",
"message": "Monthly credit balance exhausted (500/500 used on the Free plan)."
}
]
}| Field | Type | Description |
|---|---|---|
| 400 invalid_json | , | Body is not valid JSON. |
| 401 missing_api_key | , | No API key supplied. |
| 401 invalid_api_key | , | Key is unknown or revoked. |
| 422 validation_error | , | A field failed validation (e.g. malformed email). |
| 429 credits_exhausted | , | Monthly credit balance used up, upgrade or wait for the reset. |
Credits & billing
Every plan includes a monthly pool of lookup credits shared across all endpoints: each lookup (email, phone or IP) costs 1 credit. Only successful requests (HTTP 2xx) consume credits, failures are free. The Free plan includes 500 credits/month; paid plans from 20,000 to 1,000,000. When your balance runs out the API returns 429 credits_exhausted until the monthly reset. See pricing for plans.
const res = await fetch(
"https://api.riskunified.com/email_risk",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RISKUNIFIED_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ email }),
}
);
const report = await res.json();
if (report.risk.level === "high") {
// block or step-up verification
}import os, requests
res = requests.post(
"https://api.riskunified.com/email_risk",
headers={
"Authorization": f"Bearer {os.environ['RISKUNIFIED_KEY']}"
},
json={"email": email},
timeout=30,
)
report = res.json()
if report["risk"]["level"] == "high":
... # block or step-up verification