Overview
The WGD Signal Intelligence API evaluates a session event against a trained scoring model and returns a structured risk assessment. It processes signals across five categories — network, device, identity, velocity, and behavior — and applies both individual rules and compound logic to produce a final score.
The API is designed for integration at login, account creation, transaction initiation, or any event where session-level fraud signals are available.
How it works
Your system collects session signals and sends them in a POST request. The API runs the scoring model synchronously and returns a risk score (0–100), a risk level, a decision, and the list of rules that were triggered — all in a single response.
Authentication
All requests must include your API key in the request header. Keys are issued on request — contact us to get yours.
X-WGD-API-Key: your_api_key_here
Security
Never expose your API key in client-side code. All API calls should be made server-side.
Quick Start
Get a risk score in under 5 minutes. Send a POST request with your session signals and receive a structured response.
curl -X POST https://api.wgd.ai/v1/score \
-H "Content-Type: application/json" \
-H "X-WGD-API-Key: your_api_key_here" \
-d '{
"user_id": "usr_123",
"session_id": "sess_456",
"event_type": "login",
"signals": {
"vpn_detected": true,
"new_device": true,
"failed_logins_24h": 4,
"login_attempts_1h": 7
}
}'
Response
{
"risk_score": 80,
"risk_level": "critical",
"decision": "block_or_step_up",
"reasons": [
"vpn_detected",
"new_device",
"failed_logins_spike",
"high_login_velocity",
"new_device_plus_vpn"
],
"model_version": "wgd_v1"
}
POST /v1/score
Evaluate a single session event and return a risk assessment.
POST
https://api.wgd.ai/v1/score
Request Body
| Field |
Type |
Required |
Description |
| user_id | string | required | Your internal user identifier |
| session_id | string | required | Unique session identifier |
| event_type | string | required | Event type: login, signup, transaction |
| signals | object | required | Session signals object. See Signal Fields below. |
Response Fields
| Field | Type | Description |
| risk_score | integer | Score from 0–100. Higher = greater risk. |
| risk_level | string | low, moderate, high, or critical |
| decision | string | Recommended action. See Decision Types. |
| reasons | array | List of rule IDs that were triggered |
| model_version | string | Scoring model version used |
POST /v1/score/batch
Evaluate up to 100 session events in a single request. Useful for backfilling historical sessions or processing event queues.
POST
https://api.wgd.ai/v1/score/batch
{
"events": [
{
"user_id": "usr_123",
"session_id": "sess_001",
"event_type": "login",
"signals": { "vpn_detected": true, "new_device": true }
},
{
"user_id": "usr_456",
"session_id": "sess_002",
"event_type": "login",
"signals": { "tor_detected": false, "failed_logins_24h": 1 }
}
]
}
Signal Fields
All fields in the signals object are optional. Omitted fields are treated as their default (false / 0). The more signals you provide, the more accurate the score.
Network
| Field | Type | Default | Description |
| vpn_detected | boolean | false | Session originated from a known VPN exit node |
| tor_detected | boolean | false | Session originated from a TOR exit node |
| impossible_travel | boolean | false | Geo-velocity inconsistent with prior session location |
Device
| Field | Type | Default | Description |
| new_device | boolean | false | Device fingerprint not seen before for this user |
| device_linked_to_multiple_accounts | boolean | false | Device fingerprint associated with 2+ accounts |
Identity
| Field | Type | Default | Description |
| disposable_email | boolean | false | Email domain is a known disposable / temporary provider |
Velocity
| Field | Type | Default | Description |
| failed_logins_24h | integer | 0 | Number of failed login attempts in the past 24 hours |
| login_attempts_1h | integer | 0 | Total login attempts in the past 1 hour |
| accounts_created_ip_24h | integer | 0 | Accounts created from this IP in the past 24 hours |
Behavior
| Field | Type | Default | Description |
| high_value_first_session | boolean | false | High-value action attempted in the user's first session |
| linked_to_confirmed_fraud | boolean | false | User, device, or IP previously linked to confirmed fraud |
Risk Bands
Scores are mapped to four risk levels, each with a recommended decision.
0 – 24
LOW
allow
Clean signal profile. Proceed normally.
25 – 49
MODERATE
allow_with_logging
Some signals present. Allow but log for review.
50 – 74
HIGH
review
Multiple signals active. Flag for manual review or friction.
75 – 100
CRITICAL
block_or_step_up
High-confidence fraud pattern. Block or require step-up auth.
Decision Types
| Decision | Description | Suggested Action |
| allow | Low risk session | Proceed normally |
| allow_with_logging | Moderate risk, no blocking required | Log event, monitor session |
| review | Elevated risk, human or automated review warranted | Add friction, queue for review |
| block_or_step_up | High-confidence fraud indicators | Block action or require MFA / identity verification |
Rule Catalogue
These are the rules active in wgd_v1. Each triggered rule contributes its score to the total.
| Rule ID | Category | Score | Trigger |
| vpn_detected | network | +20 | vpn_detected == true |
| tor_detected | network | +35 | tor_detected == true |
| impossible_travel | network | +35 | impossible_travel == true |
| new_device | device | +15 | new_device == true |
| device_linked_to_multiple_accounts | device | +30 | device_linked_to_multiple_accounts == true |
| disposable_email | identity | +25 | disposable_email == true |
| failed_logins_spike | velocity | +25 | failed_logins_24h > 2 |
| high_login_velocity | velocity | +20 | login_attempts_1h > 5 |
| high_value_first_session | behavior | +20 | high_value_first_session == true |
| linked_to_confirmed_fraud | history | +40 | linked_to_confirmed_fraud == true |
| new_device_plus_vpn | compound | +15 | new_device + vpn_detected |
| disposable_email_plus_creation_velocity | compound | +20 | disposable_email + accounts_created_ip_24h > 3 |
Python Example
import requests
API_KEY = "your_api_key_here"
BASE_URL = "https://api.wgd.ai/v1"
def score_session(user_id, session_id, event_type, signals):
response = requests.post(
f"{BASE_URL}/score",
headers={
"X-WGD-API-Key": API_KEY,
"Content-Type": "application/json"
},
json={
"user_id": user_id,
"session_id": session_id,
"event_type": event_type,
"signals": signals
}
)
return response.json()
result = score_session(
user_id="usr_123",
session_id="sess_456",
event_type="login",
signals={
"vpn_detected": True,
"new_device": True,
"failed_logins_24h": 4,
"login_attempts_1h": 7
}
)
print(result["risk_score"])
print(result["decision"])
print(result["reasons"])
JavaScript Example
const scoreSession = async (userId, sessionId, eventType, signals) => {
const response = await fetch('https://api.wgd.ai/v1/score', {
method: 'POST',
headers: {
'X-WGD-API-Key': 'your_api_key_here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
user_id: userId,
session_id: sessionId,
event_type: eventType,
signals
})
});
return response.json();
};
const result = await scoreSession(
'usr_123',
'sess_456',
'login',
{
vpn_detected: true,
new_device: true,
failed_logins_24h: 4,
login_attempts_1h: 7
}
);
console.log(result.risk_score);
console.log(result.decision);
cURL Example
curl -X POST https://api.wgd.ai/v1/score \
-H "Content-Type: application/json" \
-H "X-WGD-API-Key: your_api_key_here" \
-d '{
"user_id": "usr_123",
"session_id": "sess_456",
"event_type": "login",
"signals": {
"vpn_detected": true,
"tor_detected": false,
"new_device": true,
"impossible_travel": false,
"failed_logins_24h": 4,
"login_attempts_1h": 7,
"disposable_email": false,
"device_linked_to_multiple_accounts": false,
"high_value_first_session": false,
"linked_to_confirmed_fraud": false,
"accounts_created_ip_24h": 1
}
}'
Error Codes
| Code | Error | Description |
| 400 | Bad Request | Missing required fields or malformed payload |
| 401 | Unauthorized | Missing or invalid API key |
| 422 | Unprocessable Entity | Payload structure is valid but signal values are out of range |
| 429 | Rate Limited | Request volume exceeded for your plan |
| 500 | Server Error | Internal error — contact support |
Changelog
| Version | Date | Changes |
| wgd_v1 | 2025 | Initial release. 10 rules, 2 compound rules, 4 risk bands. |