API Reference

Complete API documentation for the Keverd fraud detection platform. All endpoints, request/response formats, error handling, and integration examples.

API Overview

Base URL

https://api.keverd.com

Authentication

All API requests require authentication using an API key. Include your API key in one of the following headers:

  • x-keverd-key (recommended)
  • X-API-KEY
  • Authorization: Bearer YOUR_API_KEY

Content Type

All requests must use Content-Type: application/json

SDK Source Identification

SDKs automatically include the X-SDK-Source header to identify the SDK type:

  • javascript - Vanilla JavaScript SDK
  • react - React SDK
  • vue - Vue.js SDK
  • angular - Angular SDK
  • android - Android SDK
POST

/fingerprint/score

Score a fingerprint submission and return risk assessment. This is the primary endpoint for fraud detection. Accepts both SDK format (nested structure) and direct format (flat structure). Target latency: <100ms p99.

Request Format

SDK Format (Recommended)

This is the format used by all Keverd SDKs. It provides a structured, nested format that's easier to work with.

http
POST https://api.keverd.com/fingerprint/score
Content-Type: application/json
x-keverd-key: your-api-key-here
X-SDK-Source: javascript

{
  "userId": "user123",
  "device": {
    "deviceId": "abc123...",
    "fingerprint": "sha256_hash_64_chars...",
    "manufacturer": "Apple",
    "model": "iPhone 13",
    "brand": "Apple",
    "device": "mobile",
    "product": "iPhone",
    "hardware": "iPhone13,2",
    "sdkVersion": "1.0.0",
    "osVersion": "15.0",
    "screenWidth": "390",
    "screenHeight": "844",
    "screenDensity": "3.0",
    "locale": "en-US",
    "timezone": "America/New_York"
  },
  "session": {
    "sessionId": "session_123",
    "timestamp": "2025-01-15T10:30:00Z"
  },
  "behavioral": {
    "typing_dwell_ms": [120.5, 135.2, 110.8, 125.3, 130.1],
    "typing_flight_ms": [45.2, 50.1, 42.3, 48.7, 46.5],
    "swipe_velocity": 2.5,
    "session_entropy": 3.8
  }
}

Android SDK Format (with SIM data)

Android SDK includes SIM card information for enhanced fraud detection:

json
{
  "userId": "user123",
  "device": {
    "deviceId": "abc123...",
    "fingerprint": "sha256_hash...",
    "manufacturer": "Samsung",
    "model": "SM-G991B",
    "osVersion": "13",
    "timezone": "Africa/Nairobi",
    ...
  },
  "sim": {
    "simOperator": "63902",
    "simOperatorName": "Safaricom",
    "simSerialNumber": "hashed_sim_serial",
    "networkOperator": "63902",
    "networkType": "LTE"
  },
  "session": {
    "sessionId": "session_123",
    "sessionCount": "5",
    "firstSession": "2025-01-01T00:00:00Z"
  },
  "behavioral": {
    "typing_dwell_ms": [120.5, 135.2],
    "typing_flight_ms": [45.2, 50.1],
    "swipe_velocity": 2.5,
    "session_entropy": 3.8
  }
}

Request Parameters

ParameterTypeRequiredDescription
userIdstringNoUser identifier. If not provided, backend auto-generates from device fingerprint
deviceobjectYesDevice information object (see DeviceInfo below)
sessionobjectNoSession information object (see SessionInfo below)
behavioralobjectNoBehavioral data object (see BehavioralData below)
simobjectNoSIM card information (Android/iOS only, see SimInfo below)

DeviceInfo Object

FieldTypeRequiredDescription
deviceIdstringYesUnique device identifier (first 32 chars of fingerprint)
fingerprintstringYesSHA-256 hash of device characteristics (64 hex characters)
manufacturerstringNoDevice manufacturer (e.g., "Apple", "Samsung")
modelstringNoDevice model name
osVersionstringNoOperating system version
screenWidthstringNoScreen width in pixels
screenHeightstringNoScreen height in pixels
timezonestringYesIANA timezone identifier (e.g., "America/New_York", "Africa/Nairobi")
localestringNoDevice locale (e.g., "en-US", "sw-KE")

SessionInfo Object

FieldTypeDescription
sessionIdstringUnique session identifier
timestampstring (ISO 8601)Session timestamp in ISO 8601 format
sessionCountstringNumber of sessions for this device (Android SDK)
firstSessionstring (ISO 8601)Timestamp of first session (Android SDK)

BehavioralData Object

FieldTypeDescription
typing_dwell_msnumber[]Array of typing dwell times (time key is held down) in milliseconds. Typically 5-20 samples.
typing_flight_msnumber[]Array of typing flight times (time between key releases) in milliseconds. Typically 5-20 samples.
swipe_velocitynumberAverage swipe velocity in pixels per millisecond. 0.0 if no swipe data available.
session_entropynumberSession entropy value (Shannon entropy) based on event diversity. Higher values indicate more diverse user interactions. 0.0 if no events collected.

Response Format

json
{
  "risk_score": 25,
  "score": 0.25,
  "action": "allow",
  "reason": [],
  "session_id": "123e4567-e89b-12d3-a456-426614174000",
  "requestId": "123e4567-e89b-12d3-a456-426614174000",
  "sim_swap_engine": {
    "risk": 0.0,
    "flags": {
      "sim_changed": false,
      "device_changed": false,
      "behavior_anomaly": false,
      "time_anomaly": false,
      "velocity_anomaly": false
    },
    "updatedProfile": {}
  }
}

Response Fields

FieldTypeDescription
risk_scorenumber (0-100)Risk score from 0 (lowest risk) to 100 (highest risk). Integer value for easy comparison.
scorenumber (0.0-1.0)Normalized risk score as float. Equal to risk_score / 100. Provided for SDK compatibility.
actionstringRecommended action: "allow", "soft_challenge", "hard_challenge", or "block"
reasonstring[]Array of risk reasons explaining why the risk score was assigned. Examples: ["new_user_profile", "geo_jump", "device_changed", "behavior_anomaly"]
session_idstring (UUID)Unique session identifier for this request. Use this to track and correlate events.
requestIdstring (UUID)Unique request identifier. Same as session_id, provided for SDK compatibility.
sim_swap_engineobjectSIM swap detection results (only present for Android/iOS SDKs with SIM data). Contains risk score and flags indicating detected anomalies.

Risk Score Interpretation

Understanding Risk Scores: Risk scores are calculated based on multiple factors including device history, behavioral patterns, geographic anomalies, and SIM swap detection (for mobile devices).

Score RangeActionMeaningRecommended Response
0-29allowLow risk. User appears to be legitimate based on device history and behavior patterns.Proceed with login/transaction. No additional verification required.
30-49soft_challengeModerate risk. Some anomalies detected but may be legitimate (e.g., new device, location change).Require additional verification such as email/SMS verification or security questions.
50-69hard_challengeHigh risk. Significant anomalies detected (e.g., device change, behavioral mismatch, geographic jump).Require strong MFA (multi-factor authentication) such as TOTP, hardware key, or biometric verification.
70-100blockVery high risk. Strong indicators of fraud or account takeover (e.g., SIM swap, multiple device changes, suspicious behavior).Block the request and flag for manual review. Consider account lockout and user notification.

Risk Reasons

The reason array contains strings explaining why a particular risk score was assigned. Common reasons include:

Profile Reasons

  • new_user_profile - First time seeing this user
  • device_changed - Different device than usual
  • multiple_devices - User has multiple devices

Geographic Reasons

  • geo_jump - Unusual location change
  • vpn_detected - VPN or proxy detected
  • unusual_location - Location not in user history

Behavioral Reasons

  • behavior_anomaly - Typing patterns don't match
  • typing_speed_mismatch - Typing speed differs significantly
  • session_entropy_low - Unusual interaction patterns

SIM Swap Reasons

  • sim_changed - SIM card changed (Android only)
  • time_anomaly - Unusual timing patterns
  • velocity_anomaly - Rapid successive requests

Use-Case Verification Endpoints

These endpoints are optimized for specific use cases and automatically set the use_case parameter. They accept the same request format as /fingerprint/score and return the same response format.

POST

/fingerprint/verify/login

Verify user identity during login attempts. Optimized for detecting account takeover and credential stuffing.

Use Case: Automatically set to "login"

POST

/fingerprint/verify/checkout

Verify user during checkout/payment flows. Detects payment fraud and stolen card usage.

Use Case: Automatically set to "checkout"

POST

/fingerprint/verify/registration

Verify new account registrations. Detects bot signups and fake accounts.

Use Case: Automatically set to "registration"

POST

/fingerprint/verify/password-reset

Verify password reset requests. High-risk use case requiring enhanced security checks.

Use Case: Automatically set to "password_reset"

POST

/fingerprint/verify/account-change

Verify account modification requests (email change, phone change, etc.).

Use Case: Automatically set to "account_change"

Error Handling

HTTP Status Codes

Status CodeMeaningResponse Body
200SuccessFingerprintScoreResponse object
400Bad RequestError message describing invalid request format or missing required fields
401UnauthorizedInvalid or missing API key
403ForbiddenAPI key inactive or insufficient permissions
429Too Many RequestsRate limit exceeded. Check Retry-After header
500Internal Server ErrorServer error. Retry request after a delay

Error Response Format

json
{
  "detail": "Error message describing what went wrong",
  "error_code": "ERROR_CODE",
  "status_code": 400
}

Common Error Codes

INVALID_API_KEY

The provided API key is invalid or has been revoked.

MISSING_DEVICE_INFO

Required device information is missing from the request.

RATE_LIMIT_EXCEEDED

Too many requests. Rate limit is 100 requests per second per API key.

INVALID_FINGERPRINT

Device fingerprint format is invalid. Must be SHA-256 hash (64 hex characters).

Authentication

All API requests require authentication using an API key. You can obtain your API key from the API Keys page in the dashboard.

Header Format

Include your API key in the request headers. The API accepts multiple header formats for compatibility:

http
# Recommended format
x-keverd-key: your-api-key-here

# Alternative formats (also supported)
X-API-KEY: your-api-key-here
Authorization: Bearer your-api-key-here

Security Note: Never expose your API key in client-side code or commit it to version control. Always use environment variables or secure configuration management.

Rate Limiting

Rate Limits

  • Per API Key: 100 requests per second
  • Per User ID: 100 requests per second (additional limit)
  • Sandbox Environment: 10 requests per second

Rate Limit Headers

When rate limits are approached or exceeded, the API includes the following headers:

HeaderDescription
X-RateLimit-LimitMaximum number of requests allowed per window
X-RateLimit-RemainingNumber of requests remaining in current window
X-RateLimit-ResetUnix timestamp when rate limit resets
Retry-AfterSeconds to wait before retrying (only on 429 responses)

Best Practice: Implement exponential backoff when receiving 429 responses. Start with a 1-second delay and double it for each subsequent retry, up to a maximum of 60 seconds.

Code Examples

cURL Example

bash
curl -X POST https://api.keverd.com/fingerprint/score \
  -H "Content-Type: application/json" \
  -H "x-keverd-key: your-api-key-here" \
  -d '{
    "userId": "user123",
    "device": {
      "deviceId": "abc123",
      "fingerprint": "sha256_hash_64_chars...",
      "timezone": "America/New_York"
    },
    "behavioral": {
      "typing_dwell_ms": [120.5, 135.2, 110.8],
      "typing_flight_ms": [45.2, 50.1, 42.3],
      "swipe_velocity": 2.5,
      "session_entropy": 3.8
    }
  }'

JavaScript/Fetch Example

javascript
const response = await fetch('https://api.keverd.com/fingerprint/score', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-keverd-key': 'your-api-key-here'
  },
  body: JSON.stringify({
    userId: 'user123',
    device: {
      deviceId: 'abc123',
      fingerprint: 'sha256_hash...',
      timezone: 'America/New_York'
    },
    behavioral: {
      typing_dwell_ms: [120.5, 135.2, 110.8],
      typing_flight_ms: [45.2, 50.1, 42.3],
      swipe_velocity: 2.5,
      session_entropy: 3.8
    }
  })
});

const data = await response.json();
console.log('Risk Score:', data.risk_score);
console.log('Action:', data.action);

Python Example

python
import requests

url = "https://api.keverd.com/fingerprint/score"
headers = {
    "Content-Type": "application/json",
    "x-keverd-key": "your-api-key-here"
}
payload = {
    "userId": "user123",
    "device": {
        "deviceId": "abc123",
        "fingerprint": "sha256_hash...",
        "timezone": "America/New_York"
    },
    "behavioral": {
        "typing_dwell_ms": [120.5, 135.2, 110.8],
        "typing_flight_ms": [45.2, 50.1, 42.3],
        "swipe_velocity": 2.5,
        "session_entropy": 3.8
    }
}

response = requests.post(url, json=payload, headers=headers)
data = response.json()

print(f"Risk Score: {data['risk_score']}")
print(f"Action: {data['action']}")

Performance & Latency

Target Performance

  • p50 Latency: < 50ms (median response time)
  • p95 Latency: < 80ms (95th percentile)
  • p99 Latency: < 100ms (99th percentile)

Optimization Tips

  • • Use connection pooling for multiple requests
  • • Implement request batching when possible
  • • Cache risk scores for short periods (5-10 seconds) for repeated requests
  • • Use async/await or non-blocking I/O for better concurrency

Data Privacy & Compliance

Privacy-First Design

  • All device identifiers are SHA-256 hashed client-side before transmission
  • No raw PII (Personally Identifiable Information) is stored or transmitted
  • HTTPS-only communication enforced
  • GDPR and Kenya Data Protection Act compliant

Data Retention

Fingerprint data is retained according to your subscription plan and regional compliance requirements. You can request data deletion through the dashboard or API.

SDK Integration Guides

For easier integration, use one of our official SDKs which handle all the API details for you: