API Reference

Complete endpoint documentation for AccessGate fraud detection and continuous authentication.

Production URL: https://ag.runloci.com
Staging URL: https://ag-staging.runloci.com

---

Authentication

All API requests require authentication via headers:

bash
x-org-id: your_organization_id
x-api-key: your_api_key

Keep your API key secure. Never expose it in client-side code or public repositories.

---

Core Endpoints

Risk Check

POST/v1/check

Verify User

Analyzes behavioral signals and returns a fraud decision. This is the primary endpoint for all verification requests.

Request Headers:

  • x-org-id (required) — Your organization ID
  • x-api-key (required) — Your API key
  • Content-Type: application/json

Request Body:

json
{
  "email": "[email protected]",
  "ip": "102.88.34.45",
  "phone": "+2348012345678",
  "device": {
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...",
    "fingerprint": {
      "screen": { "width": 1920, "height": 1080, "colorDepth": 24 },
      "timezone": "Africa/Lagos",
      "language": "en-US",
      "canvas": "a1b2c3d4",
      "hardware": { "cores": 8, "memory": 16 }
    }
  },
  "behavior": {
    "mouseMovements": 245,
    "clickPattern": "human",
    "keystrokeTimings": [120, 150, 200],
    "scrollBehavior": "natural",
    "timeOnPage": 45000,
    "formFillSpeed": 2.5
  },
  "behavioral": {
    "mouse": [
      { "type": "move", "x": 100, "y": 200, "timestamp": 1700000001000 },
      { "type": "click", "x": 102, "y": 202, "timestamp": 1700000001500 }
    ],
    "keystrokes": [
      { "key": "Shift", "type": "keydown", "timestamp": 1700000002000 },
      { "key": "A", "type": "keydown", "timestamp": 1700000002100 }
    ]
  },
  "context": {
    "action": "login",
    "user_id": "user_123",
    "session_id": "sess_abc123",
    "timestamp": "2026-01-22T10:00:00Z"
  },
  "expand": true
}

Parameters:

Field Type Required Description
email string One of email/ip/phone required User's email address
ip string One of email/ip/phone required Client IP address (IPv4 or IPv6)
phone string One of email/ip/phone required Phone number (E.164 format recommended)
device object Recommended Device fingerprint data from SDK
behavior object Recommended Aggregated behavioral signals
behavioral object Recommended Raw behavioral events (mouse, keystrokes)
context.action string Required Action type: signup, login, payment, password_reset, profile_update, default
context.user_id string Recommended Your unique user identifier
context.session_id string Optional Your session identifier
expand boolean Optional Return expanded response details

Response: 200 OK

json
{
  "request_id": "req_550e8400-e29b-41d4-a716-446655440000",
  "decision": {
    "outcome": "allow",
    "score": 23,
    "confidence": 0.88,
    "reasons": []
  },
  "metadata": {
    "processing_time_ms": 45,
    "baseline_sessions": 15
  }
}

Decision Outcomes:

Outcome Score Range Description
allow 0-39 Low risk, proceed normally
review 40-79 Medium risk, request additional verification
block 80-100 High risk, deny access

Evaluation Mode (Debug)

:::api POST /v1/eval/check Glass Box Evaluation Returns detailed signal breakdown for debugging and POCs. Same payload as /v1/check. :::

Request: Same as /v1/check

Response: 200 OK

json
{
  "eval_mode": true,
  "decision": "ALLOW",
  "risk_score": 23,
  "signals": {
    "biometrics": "APPROVED",
    "stability_score": 0.85,
    "entropy_score": 0.72,
    "reasoning": []
  },
  "context": {
    "ip_reputation": "Clean",
    "network": "MTN Nigeria",
    "baseline_sessions": 15
  },
  "original_response": { }
}

The eval endpoint reveals internal signal details. Use only in development and staging environments.

---

Reason Codes

When a request is flagged, the reasons array contains specific indicators:

IP & Network Signals

Reason Description
Tor exit node detected Traffic from Tor network
VPN detected VPN service detected
Proxy detected Proxy server detected
Datacenter IP IP belongs to a datacenter/hosting provider
Known fraud IP IP associated with previous fraud
High-risk country: {name} Traffic from high-risk jurisdiction

Email Signals

Reason Description
Disposable email domain Temporary/disposable email service
Suspicious email pattern Pattern matching fraud indicators
Disposable keyword in email Email contains disposable service keywords
Random character pattern detected Randomly generated email address
Long numeric sequence in email Unusual numeric pattern
Suspicious TLD: .{tld} High-risk top-level domain

Phone Signals

Reason Description
Invalid phone number format Phone number failed validation
Phone number validation failed (HLR) HLR lookup returned invalid
VoIP number detected Virtual phone number
Recently ported number (SIM swap risk) Number recently changed carriers
SIM swap detected ({risk} risk, {days} days ago) Recent SIM swap activity

Behavioral Signals

Reason Description
Bot detected ({confidence}% confidence) Automated behavior patterns
Non-human mouse patterns Mouse movement indicates automation
Automated keystrokes Keystroke timing indicates bot
Unnatural session behavior Session patterns don't match human behavior
Emulator detected (Perfect Stability) Device emulator identified
Biometric deviation (score: {score}) Behavior differs significantly from baseline

Velocity & Travel

Reason Description
Velocity exceeded ({count} requests) Too many requests in time window
Impossible travel detected Location change too fast to be legitimate
Physically impossible: {speed} km/h Travel speed exceeds physical possibility

Session & Device

Reason Description
New device detected Device not seen before for this user
New country: {country} Login from unusual country
Unusual time: {hour}:00 Activity at unusual hour for user
Account less than 1 day old Very new account
Session anomalies: {patterns} Suspicious session patterns

Behavioral Deviation (Continuous Auth)

Reason Description
High mouse deviation: {pct}% from baseline Mouse patterns differ from baseline
High keystroke deviation: {pct}% from baseline Typing patterns differ from baseline
High session deviation: {pct}% from baseline Session behavior differs from baseline
Rapid device addition detected Multiple new devices added quickly
Behavioral divergence across devices Inconsistent behavior across devices
Low behavioral consistency: {pct}% Overall behavior inconsistency

Fraud Ring Indicators

Reason Description
High fraud ring score: {score}/100 Strong fraud ring indicators
Moderate fraud ring indicators detected Some fraud ring patterns
Device added within 24h of another (fraud ring pattern) Rapid device addition pattern
Suspicious device sharing pattern Devices shared across accounts

Whitelist Management

Add to Whitelist

POST/v1/whitelist

Add Whitelist Entry

Add a user, IP, email, phone, or device to the whitelist.

Request Body:

json
{
  "entity_type": "ip",
  "identifier": "203.0.113.50",
  "reason": "Corporate VPN Exit Node",
  "duration_hours": 168,
  "verified_by": "[email protected]",
  "verification_method": "manual_review"
}

Parameters:

Field Type Required Description
entity_type string Yes One of: user, email, ip, phone, device_fingerprint
identifier string Yes The value to whitelist (max 255 chars)
reason string Yes Audit trail reason (10-500 chars)
duration_hours integer No How long to whitelist (1-720 hours, default: 168/7 days)
verified_by string Yes Who verified this entry
verification_method string Yes One of: phone_callback, document_review, manual_review, challenge_flow

Response: 201 Created

json
{
  "id": "wl_abc123",
  "entity_type": "ip",
  "identifier": "203.0.113.50",
  "created_at": "2026-01-25T10:30:00Z",
  "expires_at": "2026-02-01T10:30:00Z"
}

Remove from Whitelist

DELETE/v1/whitelist/{id}

Remove Whitelist Entry

Remove an entity from the whitelist.

Parameters:

  • id (path, required) — Whitelist entry ID

Response: 204 No Content


Feedback System

Report Feedback

POST/v1/feedback

Submit Feedback

Report whether a decision was correct or incorrect. Used to improve accuracy.

Request Body:

json
{
  "request_id": "req_550e8400-e29b-41d4-a716-446655440000",
  "feedback_type": "false_positive",
  "actual_outcome": "allow",
  "reported_by": "support_agent_01",
  "notes": "User was traveling, confirmed via phone call."
}

Parameters:

Field Type Required Description
request_id string Yes Original request ID
feedback_type string Yes One of: false_positive, false_negative, correct
actual_outcome string Yes What should have happened: allow, review, block
reported_by string Yes Who reported this feedback
notes string No Additional context (max 1000 chars)

Response: 201 Created

json
{
  "feedback_id": "fb_ghi789",
  "received_at": "2026-01-25T10:30:00Z"
}

Challenge Flow (Step-Up Auth)

Issue Challenge

POST/v1/challenge/issue

Issue Challenge

Send an OTP or verification challenge to the user.

Request Body:

json
{
  "challenge_type": "email_otp",
  "email": "[email protected]",
  "request_id": "req_8888",
  "metadata": {
    "source": "login_screen"
  }
}

Parameters:

Field Type Required Description
challenge_type string Yes One of: email_otp, phone_otp
email string Required if email_otp User's email address
phone string Required if phone_otp User's phone number
request_id string Yes Original request ID that triggered challenge

Response: 201 Created

json
{
  "challenge_id": "ch_7777",
  "type": "email_otp",
  "expires_at": "2026-01-25T10:35:00Z"
}

Verify Challenge

POST/v1/challenge/verify

Verify Challenge Response

Validate the user's OTP code.

Request Body:

json
{
  "challenge_id": "ch_7777",
  "code": "123456"
}

Response: 200 OK

json
{
  "verified": true,
  "decision": {
    "outcome": "allow",
    "reasons": ["Step-up authentication completed"]
  }
}

Error Response: 400 Bad Request

json
{
  "verified": false,
  "error": "invalid_code"
}

Configuration

Update Risk Weights

POST/v1/weights

Update Risk Configuration

Configure scoring weights and thresholds for your organization.

Request Body:

json
{
  "config_name": "Strict Login Policy",
  "is_active": true,
  "thresholds": {
    "block": 80,
    "review": 40,
    "challenge": 60
  },
  "ip": {
    "tor": 50,
    "vpn": 20
  },
  "velocity": {
    "abuse": 100
  },
  "features": {
    "behavioral_entropy": true,
    "continuous_auth": true
  }
}

Response: 200 OK


Get Current Weights

GET/v1/weights

Get Risk Configuration

Retrieve current scoring configuration.

Response: 200 OK

json
{
  "config_name": "Strict Login Policy",
  "is_active": true,
  "thresholds": {
    "block": 80,
    "review": 40,
    "challenge": 60
  },
  "features": {
    "behavioral_entropy": true,
    "continuous_auth": true
  }
}

GDPR & Sessions

Get Active Sessions

GET/sessions/{entity_id}

Get User Sessions

Retrieve all active sessions for a user.

Response: 200 OK


Export User Data

GET/gdpr/export/{entity_id}

Export User Data

Export all data stored for a user (GDPR Article 15).

Response: 200 OK


Delete User Data

POST/gdpr/delete/{entity_id}

Delete User Data

Permanently delete all data for a user (GDPR Article 17).

Response: 200 OK

json
{
  "entity_id": "user_123",
  "deleted_at": "2026-01-25T10:30:00Z"
}

This action is irreversible. The user's behavioral baseline will need to be re-established.

---

Webhooks

Configure Webhook

POST/v1/webhooks/config

Configure Webhook

Set up webhook notifications for risk events.

Request Body:

json
{
  "url": "https://your-backend.com/webhooks/accessgate",
  "secret": "whsec_...",
  "events": ["risk.high", "risk.low"],
  "enabled": true
}

Response: 200 OK


System

Health Check

GET/health

Health Check

Check API availability.

Response: 200 OK

json
{
  "status": "healthy",
  "timestamp": "2026-01-25T10:30:00Z"
}

Error Handling

Error Response Format

json
{
  "error": "error_code",
  "message": "Human-readable description",
  "details": {}
}

HTTP Status Codes

Status Description
200 Success
201 Created
204 No Content (successful deletion)
400 Bad Request — Invalid parameters
401 Unauthorized — Invalid or missing API key
403 Forbidden — Insufficient permissions
404 Not Found — Resource doesn't exist
429 Too Many Requests — Rate limit exceeded
500 Internal Server Error — Contact support

Code Examples

Python

python
import requests

response = requests.post(
    'https://ag.runloci.com/v1/check',
    headers={
        'x-org-id': 'your_org_id',
        'x-api-key': 'your_api_key',
        'Content-Type': 'application/json'
    },
    json={
        'email': '[email protected]',
        'ip': '102.88.34.45',
        'context': {
            'action': 'login',
            'user_id': 'user_123'
        }
    }
)

result = response.json()
print(f"Decision: {result['decision']['outcome']}")

Node.js

javascript
const response = await fetch('https://ag.runloci.com/v1/check', {
  method: 'POST',
  headers: {
    'x-org-id': process.env.ACCESSGATE_ORG_ID,
    'x-api-key': process.env.ACCESSGATE_API_KEY,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    email: '[email protected]',
    ip: '102.88.34.45',
    context: {
      action: 'login',
      user_id: 'user_123'
    }
  })
});

const result = await response.json();
console.log(`Decision: ${result.decision.outcome}`);

cURL

bash
curl -X POST "https://ag.runloci.com/v1/check" \
  -H "x-org-id: your_org_id" \
  -H "x-api-key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "ip": "102.88.34.45",
    "context": {
      "action": "login",
      "user_id": "user_123"
    }
  }'

All code examples are ready to use. Replace credentials with your own.

---

Support