Radar API β€” Integration Guide

Practical guidance for integrating Radar into your system: real-world examples, validation rules, error handling, and best practices.

Back to: Radar Event API Overview Β· API Reference


Use Cases & Examples

Common integration scenarios across all three event categories, showing the full request payload and the expected response. Use these as a starting point for your own integration.

1. User Login Event

Track a successful user login.

Request:

{
  "event": "login_succeeded",
  "event_timestamp": 1734523200000,
  "ip": "192.168.1.100",
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "[email protected]",
    "mobile": "+966501234567"
  },
  "device": {
    "id": "660e8400-e29b-41d4-a716-446655440001",
    "os": "Android",
    "brand": "Samsung",
    "model": "Galaxy S21",
    "os_version": "13",
    "rooted": false,
    "emulator": false
  },
  "session": {
    "id": "770e8400-e29b-41d4-a716-446655440002"
  },
  "location": {
    "latitude": 24.7136,
    "longitude": 46.6753,
    "mocked": false
  }
}

Response:

{
  "action_id": "unknown",
  "action": "allow",
  "state": "unknown"
}

2. Failed Login Attempt

Track a failed login attempt for potential brute-force detection.

Request:

{
  "event": "login_failed",
  "event_timestamp": 1734523200000,
  "ip": "45.33.32.156",
  "user": {
    "email": "[email protected]"
  },
  "device": {
    "id": "660e8400-e29b-41d4-a716-446655440001",
    "os": "Android",
    "rooted": true,
    "emulator": true
  },
  "browser": {
    "user_agent": "Mozilla/5.0 (Linux; Android 11) AppleWebKit/537.36"
  }
}

Response (High Risk):

{
  "action_id": "unknown",
  "action": "block",
  "state": "unknown"
}

3. Business Registration

Track a new business registration.

Request:

{
  "event": "business_registered",
  "event_timestamp": 1734523200000,
  "ip": "192.168.1.100",
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "[email protected]"
  },
  "business": {
    "id": "880e8400-e29b-41d4-a716-446655440003",
    "registration_number": "1010123456",
    "registration_date": "2024-01-15T00:00:00.000Z",
    "registration_country": "SA",
    "name": "Example Trading Est.",
    "type": "LLC",
    "category": "Retail",
    "tax_id": "300012345600003",
    "status": "active",
    "owners": [
      {
        "id": "990e8400-e29b-41d4-a716-446655440004",
        "name": "John Doe",
        "national_id": "1234567890",
        "nationality": "SA"
      }
    ]
  }
}

Response:

{
  "action_id": "unknown",
  "action": "allow",
  "state": "unknown"
}

4. Payment Transaction (POS)

Track a point-of-sale purchase transaction.

Request:

{
  "event": "payment_completed",
  "event_timestamp": 1734523200000,
  "ip": "10.0.0.50",
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000"
  },
  "merchant": {
    "id": "MID123456789",
    "mcc": "5411",
    "name": "Grocery Store"
  },
  "terminal": {
    "id": "TID987654321",
    "merchant_id": "MID123456789",
    "card_acceptor_terminal_id": "12345678",
    "lat": 24.7136,
    "lon": 46.6753
  },
  "request": {
    "id": "aa0e8400-e29b-41d4-a716-446655440005",
    "card_present": true,
    "channel": "pos",
    "type": "PURCHASE",
    "entry_mode": "tapped",
    "amount": 150.5,
    "currency": "SAR",
    "is_3ds": false,
    "card": {
      "pan": "489537******1234",
      "brand": "mada",
      "last4": "1234",
      "verification": "pin",
      "cardholder_verification": "pin"
    }
  },
  "response": {
    "auth_code": "123456",
    "response_code": "00",
    "response_message": "Approved",
    "is_approved": true
  },
  "location": {
    "latitude": 24.7136,
    "longitude": 46.6753,
    "mocked": false
  }
}

Response:

{
  "action_id": "unknown",
  "action": "allow",
  "state": "unknown"
}

5. E-Commerce Payment

Track an online card-not-present transaction.

Request:

{
  "event": "payment_requested",
  "event_timestamp": 1734523200000,
  "ip": "203.0.113.50",
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "[email protected]"
  },
  "merchant": {
    "id": "MID123456789",
    "mcc": "5399",
    "name": "Online Store"
  },
  "browser": {
    "name": "Chrome",
    "version": "120.0.0",
    "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
    "timezone": "Asia/Riyadh",
    "fingerprint": "abc123fingerprint",
    "screen_resolution": "1920x1080"
  },
  "domain": {
    "name": "onlinestore.com",
    "age_days": 365,
    "is_new": false,
    "is_suspicious": false
  },
  "request": {
    "id": "bb0e8400-e29b-41d4-a716-446655440006",
    "card_present": false,
    "channel": "e-commerce",
    "type": "PURCHASE",
    "entry_mode": "entered",
    "amount": 299.99,
    "currency": "SAR",
    "is_3ds": true,
    "card": {
      "pan": "411111******1111",
      "brand": "Visa",
      "last4": "1111",
      "exp_month": "12",
      "exp_year": "2025",
      "verification": "3ds",
      "cardholder_ip": "203.0.113.50"
    }
  },
  "response": {
    "response_code": "00",
    "is_approved": true
  }
}

Response:

{
  "action_id": "unknown",
  "action": "allow",
  "state": "unknown"
}

6. Payment Refund

Track a refund transaction (requires original transaction reference).

Request:

{
  "event": "payment_refunded",
  "event_timestamp": 1734609600000,
  "ip": "10.0.0.50",
  "merchant": {
    "id": "MID123456789"
  },
  "terminal": {
    "id": "TID987654321"
  },
  "request": {
    "id": "cc0e8400-e29b-41d4-a716-446655440007",
    "type": "REFUND",
    "original_transaction_id": "aa0e8400-e29b-41d4-a716-446655440005",
    "amount": 150.5,
    "currency": "SAR",
    "channel": "pos",
    "card": {
      "pan": "489537******1234"
    }
  },
  "response": {
    "auth_code": "654321",
    "response_code": "00",
    "is_approved": true
  }
}

Response:

{
  "action_id": "unknown",
  "action": "allow",
  "state": "unknown"
}

7. High-Risk Transaction (Blocked)

Example of a transaction that triggers a block action.

Request:

{
  "event": "payment_requested",
  "event_timestamp": 1734523200000,
  "ip": "45.33.32.156",
  "device": {
    "id": "dd0e8400-e29b-41d4-a716-446655440008",
    "rooted": true,
    "emulator": true,
    "hooked": true,
    "malware": true
  },
  "location": {
    "latitude": 0,
    "longitude": 0,
    "mocked": true
  },
  "request": {
    "amount": 50000.0,
    "currency": "SAR",
    "channel": "e-commerce",
    "card": {
      "pan": "411111******9999"
    }
  },
  "response": {
    "is_approved": false,
    "response_code": "51"
  }
}

Response:

{
  "action_id": "unknown",
  "action": "block",
  "state": "unknown"
}


Validation Rules

All events are validated before processing. Requests that fail validation return a 400 Bad Request with a message describing the issue.

Global Rules

RuleDescription
event_timestampRequired. Must be a valid number (Unix timestamp in milliseconds).
event_idIf provided, must be a valid UUID v4. Auto-generated if omitted.
eventMust be one of the defined event types.

Financial Event Rules

For all financial events (payment_*), these additional validations apply:

RuleDescription
requestRequired. Must contain payment request details.
responseRequired. Must contain financial response details.
request.amountRequired. Must be a number greater than 0.01.
request.card.panRequired within card object. Must be a string.
request.currencyIf provided, must match pattern ^[A-Z]{3}$ (ISO 4217).

UUID Validation

All fields marked as UUID must conform to UUID v4 format:

  • xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx

Enum Constraints

FieldAllowed Values
user.statusactive, inactive
business.statusactive, inactive
device.install_sourcegoogle_play, apple_store, unknown
request.channele-commerce, pos, softpos
request.typePURCHASE, REFUND, REVERSAL
request.entry_modeswiped, dipped, tapped, entered, apple_pay, google_pay, samsung_pay, mada_pay, tokenized, contactless
card.verificationcvv, cvc, none, 3ds, cryptogram
card.cardholder_verificationsignature, otp, pin, none, 3ds, cryptogram

Transform Rules

FieldTransformation
Boolean fieldsAccepts: true, false, 1, 0, "true", "false"
Date fieldsConverted to JavaScript Date objects

Error Responses

Errors follow a consistent JSON structure with statusCode, message, and error fields. Use the statusCode to distinguish between:

  • 401 / 404 β€” Authentication and account errors
  • 400 β€” Validation errors (missing fields, invalid formats, unknown properties)
  • 500 β€” Unexpected server errors β€” contact NearPay support

Authentication Errors

401 Unauthorized - Missing or Invalid API Key

{
  "statusCode": 401,
  "message": "invalid_api_key",
  "error": "Unauthorized"
}

Cause: The api-key header is missing or does not match any registered key.

404 Not Found - Client Not Found

{
  "statusCode": 404,
  "message": "client_not_found",
  "error": "Not Found"
}

Cause: No customer account associated with the provided API key.


Validation Errors

400 Bad Request - Missing Required Field

{
  "statusCode": 400,
  "message": ["event_timestamp must be a number"],
  "error": "Bad Request"
}

400 Bad Request - Invalid Event Type

{
  "statusCode": 400,
  "message": ["Event type must be a valid activity event"],
  "error": "Bad Request"
}

400 Bad Request - Invalid UUID

{
  "statusCode": 400,
  "message": ["User ID must be a valid UUID"],
  "error": "Bad Request"
}

400 Bad Request - Invalid Currency Format

{
  "statusCode": 400,
  "message": ["Currency must be a valid ISO 4217 code"],
  "error": "Bad Request"
}

400 Bad Request - Missing Financial Event Fields

{
  "statusCode": 400,
  "message": [
    "Request is required for financial events",
    "Response is required for financial events"
  ],
  "error": "Bad Request"
}

400 Bad Request - Invalid Amount

{
  "statusCode": 400,
  "message": [
    "Payment amount must be a number",
    "Payment amount must be greater than 0"
  ],
  "error": "Bad Request"
}

400 Bad Request - Non-Whitelisted Properties

{
  "statusCode": 400,
  "message": ["property unknownField should not exist"],
  "error": "Bad Request"
}

Server Errors

500 Internal Server Error

{
  "risk": "error",
  "score": 0
}

Cause: An unexpected error occurred during event processing. Contact NearPay support.


Best Practices

Follow these guidelines to get the most accurate risk scoring and maintain a reliable integration.

1. Include Complete Context

Provide as much context as possible for accurate risk scoring:

{
  "event": "payment_requested",
  "event_timestamp": 1734523200000,
  "ip": "192.168.1.100",
  "device": { ... },
  "browser": { ... },
  "location": { ... },
  "user": { ... },
  "merchant": { ... },
  "terminal": { ... },
  "request": { ... },
  "response": { ... }
}

2. Use Consistent Identifiers

  • Use the same user.id for all events from the same user
  • Use the same device.id for events from the same device
  • Use the same session.id within a user session

3. Send Events in Real-Time

Send events as they occur for accurate time-based analysis:

  • payment_requested β†’ When payment is initiated
  • payment_responsed β†’ When processor responds
  • payment_completed β†’ When transaction finalizes

4. Handle Responses Appropriately

const response = await radarApi.sendEvent(event);

if (response.action === 'block') {
  // Block the transaction/action
  throw new Error('Transaction blocked by fraud detection');
} else if (response.action === 'allow') {
  // Proceed with the transaction
  processTransaction();
}

5. Provide Device Trust Signals

For mobile applications, include device attestation:

{
  "device": {
    "rooted": false,
    "emulator": false,
    "hooked": false,
    "debuggable": false,
    "malware": false,
    "attestation_passed": true,
    "app_verified": true,
    "install_source": "google_play"
  }
}

6. Track Location Accurately

{
  "location": {
    "latitude": 24.7136,
    "longitude": 46.6753,
    "mocked": false
  }
}

7. Use Proper Date Formats

All date fields should use ISO 8601 format:

{
  "signup_date": "2024-01-15T10:30:00.000Z",
  "date_of_birth": "1990-05-20T00:00:00.000Z"
}

8. Reference Original Transactions

For refunds, reversals, and chargebacks:

{
  "event": "payment_refunded",
  "request": {
    "type": "REFUND",
    "original_transaction_id": "uuid-of-original-transaction",
    "original_event_id": "uuid-of-original-event",
    "original_rrn": "123456789012"
  }
}