Fidro API Documentation

Welcome to Fidro, your comprehensive fraud detection and risk analysis API. Protect your business from fraudulent users, disposable emails, suspicious IP addresses, and high-risk transactions with our powerful, easy-to-integrate API. Prefer to see it before reading about it? Send a live request in the playground, no key needed.

What is Fidro?

Fidro is a real-time fraud detection API that helps businesses identify and prevent fraudulent activities before they cause damage. Our API provides instant validation of emails, IP addresses, and user behavior patterns, giving you the tools to make informed decisions about user trust and risk.

Whether you're running an e-commerce platform, SaaS application, or financial service, Fidro integrates seamlessly to provide real-time risk assessments and fraud signals that protect your business and legitimate users.

Key Features

Email Validation

Detect disposable emails, syntax errors, and invalid domains in real-time

IP Intelligence

Identify VPNs, proxies, hosting providers, and suspicious IP addresses

Custom Blocklists

Manage your own blocklist of emails, IPs, and domains to block

Real-Time Analysis

Get instant risk scores and fraud signals with millisecond response times

Common Use Cases

User Registration & Sign-ups

Validate email addresses and IP addresses during registration to prevent fake accounts, bots, and abuse

E-commerce Transactions

Screen orders for suspicious patterns before processing payments to reduce chargebacks

Account Security

Monitor login attempts from suspicious IPs and flag potential account takeover attempts

Content Moderation

Identify and block spam, abuse, and malicious users before they can cause harm

Getting Started

Get up and running with Fidro's fraud detection API in minutes.

1. Create an Account

Sign up for an account and get started. No credit card required. Free forever!

Once you register or log in, your test API key will be automatically populated in all code examples throughout this documentation.

2. Make Your First Request

Use the API playground below or make a request with curl:

curl -X POST https://fidro.io/api/validate \
  -H "Authorization: Bearer sk_test_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com"
  }'

Authentication

All API requests require authentication using your API key.

Bearer Token Authentication

Include your API key in the Authorization header using the Bearer scheme:

Authorization: Bearer sk_test_YOUR_API_KEY

Test vs Live Keys

Test Keys (sk_test_...)

Use test keys for development and testing. They work identically to live keys but don't count against your usage limits.

View test data scenarios

Live Keys (sk_live_...)

Use live keys for production. All requests count toward your plan's validation limits.

Cross-Origin Requests (CORS)

The API sends Access-Control-Allow-Origin: * and answers preflight OPTIONS requests, allowing Authorization and Content-Type. Browsers will therefore not block a cross-origin call.

Call the API from your server, not the browser. Your API key is a secret credential. Any key used in client-side JavaScript is readable by anyone who opens developer tools, and can be extracted and used against your quota. CORS being permitted is not a recommendation to put your key in a web page.

If you need to check a visitor from the browser, call your own backend and have it call Fidro, so the key never leaves your server.

Validate

Validates email addresses and IP addresses with comprehensive risk analysis.

POST /api/validate

Request Parameters

Parameter Type Required Description
email string Optional* Email address to validate
ip string Optional* IP address to analyze
country_code string Optional ISO 3166-1 alpha-2 country code (requires ip)
include_public_data boolean Optional Include public blocklist data (default: true)
event string Optional What is happening: signup, login, checkout, password_reset, check or custom:<name>. Sending it records the call and turns on velocity and anomalies
user_id string Optional Your identifier for the person (max 191 chars). Sending it builds a per-user history; with no event the call is recorded as a check
session_id string Optional Your session identifier, stored with the event for your own correlation

* Either email or ip is required. Calls without event or user_id are stateless: nothing is recorded and the response has no velocity or anomalies blocks.

Response Parameters

Parameter Type Description
test_mode boolean Indicates if the request was processed in test mode
risk_score integer Overall risk score from 0 (no risk) to 100 (high risk)
recommendation string Action recommendation: "allow" (score 0 to 49), "challenge" (50 to 79) or "block" (80 and up). An anomaly can raise the floor, so a low score may still come back as "challenge"
message string Human-readable explanation of the validation result
data.checks object Detailed fraud checks (disposable_email, valid_email, vpn, proxy, tor, bad_isp, bad_ip, location_match, user_blocked_email, user_blocked_ip, user_blocked_domain). On stateful calls each anomaly code that fired is added here as true
data.velocity object Stateful calls only. Counts over your account's own history, including this call: ip_events_1h, ip_events_24h, ip_signups_1h, ip_signups_24h, subnet_signups_1h, ip_distinct_users_24h, email_pattern_matches_24h, user_distinct_ips_24h, user_countries_30d
data.anomalies array Stateful calls only. Each entry has code, severity (high or medium) and a one-sentence detail. Empty when nothing fired. See Velocity and anomalies
data.location object Geolocation data for the IP address (country, city, timezone, ISP, etc.)
request_id string Unique identifier for this request (starts with "req_")
timestamp string ISO 8601 timestamp of when the response was generated

Try It Out

/api/
Response

Error:


            

Velocity and Anomalies

A single check answers "is this email and IP risky right now?". Tell Fidro what is happening and it also answers "is this the third signup from that IP this hour?". Send event or user_id on /api/validate and the call is recorded, counted against your account's own history, and checked against a fixed set of rules.

How it works

  1. The usual checks run first (email, IP, VPN, blocklists) and produce the base risk_score.
  2. The call is stored as an event: type, email pattern, IP, /24 subnet, country and your user_id. Test keys write test-mode events that never mix with live history.
  3. Velocity counts are taken over your account's events, including this one, so ip_signups_1h: 3 means this call is the third.
  4. Each rule below is checked. A rule that fires adds its weight to the score (capped at 100), may raise the recommendation floor, and adds its code to data.checks and to the end of message.

Events

signup, login, checkout, password_reset, check, or your own custom:<name> (lowercase letters, digits and underscores, up to 24 characters). The burst rules only count signup events; the shared-IP rule only looks at non-signup events; the travel rules need a user_id.

Anomaly codes

Code Fires when Severity Score Floor
ip_signup_burst 3 or more signups from one IP in an hour, or 5 in 24 hours high +40 challenge
subnet_signup_burst 5 or more signups from one /24 (IPv4) or /64 (IPv6) in an hour medium +20 none
email_pattern_burst 3 or more signups in 24 hours whose addresses reduce to the same pattern: sam+1@, s.a.m@ and sam42@ on the same domain are one pattern high +40 challenge
ip_many_users 5 or more different user_ids seen from one IP in 24 hours, on a non-signup event medium +20 none
new_country_for_user A user with at least 3 prior events, all from one country, appears from another medium +15 none
impossible_travel The same user_id seen from two countries within 60 minutes high +30 challenge

Example

The third signup from the same IP inside an hour:

curl -X POST https://fidro.io/api/validate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "c@example.com", "ip": "1.1.1.1", "event": "signup", "user_id": "usr_3"}'

{
  "test_mode": true,
  "risk_score": 40,
  "recommendation": "challenge",
  "message": "No risk factors detected. Velocity: ip signup burst.",
  "data": {
    "checks": { "disposable_email": false, "vpn": false, "ip_signup_burst": true },
    "location": { "country_code": "US" },
    "velocity": {
      "ip_events_1h": 3, "ip_events_24h": 3,
      "ip_signups_1h": 3, "ip_signups_24h": 3,
      "subnet_signups_1h": 3, "ip_distinct_users_24h": 1,
      "email_pattern_matches_24h": 1,
      "user_distinct_ips_24h": 1, "user_countries_30d": 1
    },
    "anomalies": [
      {
        "code": "ip_signup_burst",
        "severity": "high",
        "detail": "3 signups from 1.1.1.1 in the last hour."
      }
    ]
  },
  "request_id": "req_...",
  "timestamp": "2026-10-02T10:00:00.000000Z"
}

Good to know

  • Velocity is counted on every stateful call, even when the email and IP result came from the 24-hour response cache. A second signup from the same address still moves the counts.
  • Test keys have their own history. Three signup calls from the same IP with a test key reproduce ip_signup_burst on demand. In test mode the country_code you send stands in for the IP's country, so changing it between two calls for the same user_id reproduces impossible_travel.
  • Events are kept for 7 days on Free, 90 days on Starter and 365 days on Pro and Enterprise. Older events are deleted nightly.
  • Each event is one request against your monthly quota, the same as a stateless check.
  • Events and anomalies appear in the dashboard audit log alongside the request.

IP Lookup

Lookup geolocation data for an IP address without full validation.

GET /api/ip/{ipAddress}

Path Parameters

Parameter Description
ipAddress Valid IPv4 or IPv6 address

Response Parameters

Parameter Type Description
ip string The IP address that was looked up
location.country_code string ISO 3166-1 alpha-2 country code (e.g., "US", "GB")
location.country_name string Full country name
location.city string City name (if available)
location.timezone string IANA timezone identifier (e.g., "America/New_York")
location.latitude float Geographic latitude coordinate
location.longitude float Geographic longitude coordinate
location.isp string Internet Service Provider name
location.asn integer Autonomous System Number
location.connection_type string Type of connection (e.g., "Corporate", "Residential", "Cellular")

Additional location fields may include: postal_code, subdivision, continent_code, continent_name, organization, user_type, and asn_organization

Try It Out

/api/
ip/
No request body required for GET requests
Response

Error:


            

Blocklist Management

Manage your custom blocklists for emails, IPs, and domains.

GET /api/blocklist

List all blocklist entries with optional filters.

Query Parameters

  • type - Filter by type (email, ip, domain)
  • value - Filter by value
  • severity - Filter by severity (1-10)
  • is_public - Filter by public status

Response

Returns an array of blocklist entries, each containing:

Parameter Type Description
id string Unique identifier (UUID)
type string Type of entry: "email", "ip", or "domain"
value string The blocked value (email address, IP, or domain)
reason string Reason for blocking
severity integer Severity level from 1 (low) to 10 (high)
is_public boolean Whether this entry is shared publicly
created_at string ISO 8601 timestamp of when the entry was created

Try It Out

/api/
No request body required for GET requests
Response

Error:


            
POST /api/blocklist

Create a new blocklist entry.

Request Parameters

Parameter Type Required Description
type string Required Type of entry: "email", "ip", or "domain"
value string Required The value to block (email address, IP, or domain)
reason string Optional Reason for blocking this entry
severity integer Optional Severity level from 1 (low) to 10 (high). Default: 5
is_public boolean Optional Share this entry publicly. Default: false

Response

Returns the created blocklist entry object (same structure as GET /api/blocklist response).

Try It Out

/api/
Response

Error:


            
DELETE /api/blocklist/{id}

Delete a blocklist entry. You can only delete entries you created.

Path Parameters

Parameter Description
id UUID of the blocklist entry to delete

Response

Returns a success message with HTTP 200 status code, or an error if the entry is not found or doesn't belong to your account.

Status

Check API status and verify your API key is working.

GET /api/status

Response Parameters

Parameter Type Description
message string A friendly status message
api_key string Type of API key being used ("test" or "live")
timestamp string ISO 8601 timestamp of when the response was generated

Try It Out

/api/
No request body required for GET requests
Response

Error:


            

Error Handling

Fidro uses conventional HTTP response codes to indicate success or failure.

HTTP Status Codes

200 OK Request succeeded
400 Bad Request Invalid request parameters
401 Unauthorized Invalid or missing API key
422 Unprocessable Entity Validation errors
429 Too Many Requests Rate limit exceeded
500 Internal Server Error Server error

Error Response Format

{
  "error": {
    "type": "invalid_request_error",
    "message": "No API key provided. You can get your API key from the dashboard."
  }
}

Rate Limiting

The Fidro API implements rate limiting to ensure fair usage and maintain service quality for all users.

Current Limits

60 requests per minute

Per API key. Limits can be increased in Enterprise plans.

How it works: Rate limits are tracked per API key. Each request decrements your available requests for that minute.

Reset time: Your rate limit counter resets every minute. For example, if you make 60 requests at 2:00:00 PM, your limit will reset at 2:01:00 PM.

Test vs Live keys: Test and live API keys share the same rate limit pool. However, test keys do not count against your usage quotas.

Response Headers

Every API response includes rate limit information in the response headers. Use these headers to track your usage and implement appropriate backoff strategies.

X-RateLimit-Limit

The maximum number of requests allowed in the current time window (60)

X-RateLimit-Remaining

The number of requests remaining in the current time window

X-RateLimit-Reset

Unix timestamp indicating when the rate limit will reset (only included when limit is exceeded)

Retry-After

Number of seconds until the rate limit resets (only included when limit is exceeded)

Example Response Headers:

HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1762784176

Rate Limit Exceeded

When you exceed the rate limit, the API will return a 429 Too Many Requests status code with details about when you can retry.

Response Example:

{
  "message": "Too Many Requests",
  "retry_after": 42
}

Best Practice: Implement Exponential Backoff

When you receive a 429 response, wait for the duration specified in the Retry-After header before making another request. Implement exponential backoff for repeated failures.

Best Practices

Monitor Headers

Check X-RateLimit-Remaining to know when you're approaching the limit

Implement Caching

Cache API responses on your end to reduce the number of requests needed

Batch Requests When Possible

If you need to validate multiple items, consider queuing them and processing in batches

Respect Retry-After

Always wait for the duration specified in the Retry-After header before retrying

Test Mode & Test Data

Use test API keys with predefined test data to simulate various fraud scenarios without affecting your production data or usage quotas.

How Test Mode Works

Test API Keys (sk_test_*): When using a test API key, you must use specific test email addresses and IP addresses from our predefined test scenarios. These return consistent, predictable results for testing different fraud patterns.

Live API Keys (sk_live_*): Live keys work with any real email addresses and IP addresses, performing actual validation and risk analysis.

Important: Test keys only work with the predefined test data below. Using random data with test keys will return validation errors.

Test IP Addresses

Use these IP addresses to test different risk scenarios:

Clean IPs (No Risk)

1.1.1.1 Clean IP - No risk factors

VPN Detection

2.2.2.2 VPN only - Low risk
2.2.2.3 VPN only - High severity

Proxy Detection

3.3.3.3 Proxy only - Low risk
3.3.3.4 Proxy only - Maximum severity

Tor Network Detection

4.4.4.4 Tor only - High risk
4.4.4.5 Tor only - Maximum severity

Multiple Risk Factors

6.6.6.6 VPN + Proxy - Medium risk
7.7.7.7 VPN + Proxy + Tor - High risk
9.9.9.9 All risk factors - Maximum severity

Bad ISP & IP Reputation

5.5.5.5 Bad ISP - Low severity
8.8.8.8 Bad ISP - Medium severity
12.12.12.12 Bad IP reputation - Low risk
13.13.13.13 Bad IP reputation - High severity

Test Email Addresses

Use these email addresses to test email validation scenarios:

Valid Emails (No Risk)

valid@example.com Valid email - No risk factors
clean@example.com Clean email - No risk factors

Disposable Email Detection

disposable@example.com Disposable email - Medium risk
temp@example.com Temporary email - High risk

Invalid Email Detection

fake@example.com Fake email - Medium risk
invalid@example.com Invalid email - No MX record
malformed@example.com Malformed email - Maximum risk

Multiple Issues

disposable-invalid@example.com Disposable + Invalid - High risk
temp-fake@example.com Temporary + Fake - Very high risk

Example Usage

Here's how to test different scenarios with your test API key:

Testing a Clean User

curl -X POST https://fidro.io/api/validate \
  -H "Authorization: Bearer sk_test_YOUR_TEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "valid@example.com",
    "ip": "1.1.1.1"
  }'

✓ Returns a clean validation with no risk factors detected

Testing High-Risk User

curl -X POST https://fidro.io/api/validate \
  -H "Authorization: Bearer sk_test_YOUR_TEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "disposable@example.com",
    "ip": "7.7.7.7"
  }'

⚠ Returns high risk score with VPN, Proxy, Tor, and disposable email flags

Testing Maximum Risk Scenario

curl -X POST https://fidro.io/api/validate \
  -H "Authorization: Bearer sk_test_YOUR_TEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "temp-fake@example.com",
    "ip": "9.9.9.9"
  }'

🚨 Returns maximum risk score with all fraud signals detected

Pro Tip: Building Test Suites

Use these test scenarios to build comprehensive automated tests for your integration. Each scenario returns predictable results, making it easy to test your fraud handling logic.

Webhooks

Receive real-time notifications about Stripe transaction analysis.

Stripe Integration

Fidro automatically analyzes Stripe payment intents via webhooks. Configure your webhook endpoint in the Stripe Dashboard.

Webhook Endpoint

POST https://fidro.io/api/webhooks/stripe/{account}

Required Event

Subscribe to payment_intent.succeeded in your Stripe webhook configuration.

PaymentIntent Metadata

Include the following metadata in your PaymentIntent:

{
  "metadata": {
    "user_id": "uuid",
    "customer_email": "user@example.com",
    "customer_ip": "1.2.3.4",
    "customer_country": "US"
  }
}