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

base url
https://api.riskunified.com

Your first request

curl
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.

headers
Authorization: Bearer YOUR_API_KEY
# or
x-api-key: YOUR_API_KEY

Keys 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
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"}'
FieldTypeDescription
emailstringRequired. The email address to screen.
response · 200 OK
{
  "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"]
  }
}
FieldTypeDescription
email_features.group_controlbooleanLocal part uses alias trickery, Gmail +suffix and dot-variant tricks combined into one flag.
email_features.gibberish_prefixbooleanLocal part looks randomly generated.
email_features.email_deliverablebooleanMailbox accepts mail (SMTP-verified).
email_features.catch_allbooleanDomain accepts mail for any address.
email_features.email_history_countnumberHow many times this address has been seen in historical data, established addresses are lower risk.
email_features.email_agestring | nullDate the address was first seen (YYYY-MM-DD).
domain_features.domain_riskstringlow | medium | high, reputation of the email domain.
domain_features.domain_age_daysnumberDays since domain registration. Young domains are risky.
domain_features.has_websitebooleanDomain serves a website.
domain_features.has_mailserverbooleanDomain has MX records configured.
risk.levelstringlow | medium | high.
risk.signalsstring[]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
curl -X POST https://api.riskunified.com/phone_risk \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone": "2025550142"}'
FieldTypeDescription
phonestringRequired. The phone number to screen (digits, E.164 accepted).
request
{
  "phone": "2025550142"
}
response · 200 OK
{
  "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"]
  }
}
FieldTypeDescription
phone_features.carrierstringOperating carrier for the number.
phone_features.line_typestringmobile | landline | voip.
phone_features.voipbooleanNumber is VoIP, common in fraud and burner setups.
phone_features.prepaidbooleanNumber is on a prepaid plan.
phone_features.prefix_typestringNumbering-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
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"}'
FieldTypeDescription
ipstringRequired. The IP address to screen.
request
{
  "ip": "185.48.52.69"
}
response · 200 OK
{
  "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"
  }
}
FieldTypeDescription
ip_features.networkstringCIDR block the address belongs to.
ip_features.ispstringInternet service provider or hosting company operating the network.
ip_features.asnnumberAutonomous system number.
ip_features.geolocationobjectcountry, state, city, latitude, longitude. State and city may be null when only country-level data is available.
ip_features.classificationstringresidential | datacenter | proxy, datacenter and proxy traffic carries elevated risk.
ip_features.classification_confidencenumber0–1 confidence in the classification above.
ip_features.known_vpnbooleanAddress belongs to a known commercial VPN range.
ip_features.crawlerobjectSearch-engine / bot detection: is_crawler (boolean), tag and source (string | null, e.g. the crawler's name and how it was verified).
risk.levelstringlow | medium | high composite verdict.

Errors

Errors use conventional HTTP status codes and a consistent body:

error response
{
  "status": "error",
  "errors": [
    {
      "code": "credits_exhausted",
      "message": "Monthly credit balance exhausted (500/500 used on the Free plan)."
    }
  ]
}
FieldTypeDescription
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.

node.js
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
}
python
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