Skip to main content

Documentation Index

Fetch the complete documentation index at: https://ratel-docs.bevars.com/llms.txt

Use this file to discover all available pages before exploring further.

Introduction

Ratel Security is an enterprise-grade Anti-Money Laundering (AML) and Combating the Financing of Terrorism (CFT) platform built for African financial institutions. Our API enables you to screen every transaction through a 6-layer compliance pipeline in under 200ms. This guide covers everything you need to integrate Ratel Security into your backend systems:
  1. Authentication — How to authenticate your API requests
  2. Quick Start — Screen your first transaction in under 5 minutes
  3. API Reference — Full endpoint documentation
  4. How Screening Works — Understand the pipeline behind the verdict
  5. Webhooks — Receive real-time case resolution notifications
  6. Error Handling — Status codes and troubleshooting

Authentication

All API requests require an X-API-Key header. Generate your API key from the Admin → API Keys page of your Ratel Dashboard.
X-API-Key: rk_live_a1b2c3d4e5f6g7h8i9j0
Keep your API key secret. Your key carries full screening privileges for your workspace. Never expose it in client-side code (mobile apps, browser JavaScript). All API calls must originate from your backend servers.

Quick Start

Screen your first transaction in 3 steps: Step 1: Generate an API key from your Dashboard. Step 2: Send a screening request:
curl -X POST https://api.ratelsecurity.com/v1/transactions/screen \
  -H "X-API-Key: rk_live_a1b2c3d4e5f6g7h8i9j0" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "TXN-2026-001",
    "type": "TRANSFER",
    "channel": "MOBILE_APP",
    "amount": 5000000,
    "currency": "NGN",
    "senderAccountNumber": "0123456789",
    "senderBvn": "22012345678",
    "senderName": "John Doe",
    "receiverAccountNumber": "9876543210",
    "receiverName": "Jane Smith",
    "receiverCountry": "NG",
    "narration": "Payment for goods",
    "timestamp": "2026-05-08T12:00:00Z"
  }'
Step 3: Handle the response. Route your transaction based on the outcome field:
OutcomeRisk LevelScore RangeYour Action
APPROVELOW0–29✅ Process the transaction immediately.
REVIEWMEDIUM30–59⚠️ Process it, but flag for compliance review.
ESCALATEHIGH60–79🔶 Hold the transaction pending manual approval.
BLOCKCRITICAL80–100🚫 Reject the transaction and freeze the account.

Screen Transaction

Request

POST /api/v1/transactions/screen
FieldTypeRequiredDescription
externalIdstringYour unique transaction reference. Used for idempotency — sending the same ID twice returns the cached verdict.
typestringTRANSFER, CASH_DEPOSIT, CASH_WITHDRAWAL, INTERNATIONAL_TRANSFER, BILL_PAYMENT
channelstringMOBILE_APP, INTERNET_BANKING, USSD, ATM, POS, BRANCH
amountnumberAmount in base currency unit (e.g. 5000000 = ₦5M).
currencystringISO 4217 code. Defaults to NGN.
senderAccountNumberstringSender’s bank account number (NUBAN, 10 digits).
senderBvnstringSender’s BVN. Strongly recommended — enables Identity Risk scoring.
senderNamestringSender’s full name. Screened against global sanctions & PEP lists.
receiverAccountNumberstringReceiver’s bank account number.
receiverNamestringReceiver’s full name. Also screened if provided.
receiverBankCodestringReceiver’s bank CBN code (e.g. "058" for GTBank).
receiverCountrystringISO 3166-1 alpha-2 code (e.g. "NG", "US"). Triggers FTR if ≠ NG.
narrationstringTransaction description. Scanned for high-risk keywords.
deviceIdstringDevice fingerprint. Enables behavioral anomaly detection.
ipAddressstringClient IP address. Enables geo-anomaly detection.
timestampstringISO 8601 (e.g. "2026-05-08T12:00:00Z").

Response

{
  "success": true,
  "data": {
    "verdict": {
      "outcome": "ESCALATE",
      "riskLevel": "HIGH",
      "score": 75,
      "triggeredRules": [
        {
          "ruleId": "AML-003",
          "name": "Structuring Detection",
          "severity": "HIGH",
          "category": "REGULATORY"
        }
      ]
    },
    "caseId": "case_12345abcde",
    "status": "PROCESSED"
  }
}
Idempotency: If you send the same externalId twice, the API returns the previously cached verdict without re-screening. Use this to safely retry failed requests.

How Screening Works

Every transaction passes through 6 screening layers in sequence. The entire pipeline completes in 80–200ms (p95).

The Pipeline

StageEngineLatencyWhat It Does
1Validation~5msSchema validation, idempotency check, persist transaction
2Context Enrichment~15msFetch sender’s recent history, account dormancy, KYC status
3Sanctions & PEP~25msScreen names against 1.8M global watchlist entities
4Regulatory Compliance~2msExecute 7 mandatory AML rules
5Identity Risk~1msEvaluate sender’s KYC verification status
6Behavioral Analysis~50msML scoring for device, velocity, and geographic anomalies

Mandatory Regulatory Rules

These 7 rules are always active and cannot be disabled. They implement national AML/CFT Act requirements.
RuleTriggerAuto-Actions
AML-001 Cash ThresholdCash ≥ ₦5,000,000Generate CTR, Notify Officer
AML-002 Transfer ThresholdTransfer ≥ ₦10,000,000Generate CTR, Notify Officer
AML-003 StructuringSingle txn ≥ 80% of threshold, OR 3+ txns in 24h exceeding thresholdGenerate SAR, Create Case
AML-004 PEP ScreeningSender is a Politically Exposed PersonEnhanced Due Diligence
AML-005 Foreign TransferInternational transfer or receiver country ≠ NGGenerate FTR
AML-006 Dormant AccountNo activity for ≥ 180 daysCreate Case
AML-007 Rapid Succession≥ 5 txns within 60 minutes from same accountCreate Case

Sanctions & PEP Matching

Sender and receiver names are cross-referenced against 1.8 million entities from:
  • UN Security Council Consolidated List
  • US OFAC SDN + Consolidated Lists
  • EU Consolidated Financial Sanctions
  • UK HMT Sanctions List
  • Interpol Red Notices
  • FATF Blacklist / Greylist entities
The engine uses multi-algorithm entity resolution to catch typos, transliterations, and aliases:
AlgorithmPurpose
Exact MatchCase-normalized literal comparison
Jaro-WinklerFuzzy string similarity (handles typos)
Phonetic MatchSound-alike matching (handles transliterations)
Fingerprint LevenshteinEdit distance on normalized name tokens
Only matches with ≥ 70% composite confidence are flagged.

Identity Risk Scoring

Sender KYC StatusRisk ScoreOutcome
VERIFIED0APPROVE
NONE (no application)40REVIEW
EXPIRED50REVIEW
REJECTED70ESCALATE

Behavioral Analysis

SignalTriggerDetects
Multiple Devices> 3 devices on one accountAccount takeover, credential sharing
Multiple IPs> 5 IPs on one accountProxy/VPN usage, bot activity
Multi-Country> 2 countries on one accountImpossible travel, geographic anomalies

Scoring Algorithm

Each engine produces a risk score (0–100). Scores are aggregated using weighted severity:
CategoryWeightRationale
Regulatory Compliance1.5×Core compliance — highest authority
Identity Verification1.3×KYC integrity is compliance-critical
Custom Rules1.2×Bank-specific logic elevated above generic engines
Sanctions & PEP1.0×Standard weight — severity via outcome escalation
Behavioral Analysis0.8×Supplementary evidence
Score Floor Guarantee: Final Score = MAX(weighted_average, max_engine_score × 0.8) This prevents a critical match (e.g., Sanctions hit scoring 95) from being diluted by clean engines. The highest-severity outcome from any engine becomes the final decision.

Asynchronous Side-Effects

While the API responds in under 200ms, the following actions are queued in the background:
  • Case Management — Auto-creates compliance cases for REVIEW, ESCALATE, or BLOCK outcomes
  • Regulatory Reporting — Auto-generates XML drafts for SAR, CTR, and FTR reports
  • Audit Logging — Immutable audit trail for regulatory inspection
  • Alert Dispatch — Email and dashboard notifications to Compliance Officers

Webhooks

Ratel Security sends real-time notifications to your backend when a compliance officer resolves a case linked to one of your transactions.
Setup: Configure your Webhook URL and Webhook Secret in the Developer Webhooks section of the API Keys page in your Dashboard.

Events

EventTrigger
case.resolvedA compliance officer marks a case as RESOLVED_TRUE_POSITIVE, RESOLVED_FALSE_POSITIVE, or CLOSED

Payload

{
  "event": "case.resolved",
  "timestamp": "2026-05-08T15:00:00Z",
  "data": {
    "caseId": "case_12345abcde",
    "status": "RESOLVED_FALSE_POSITIVE",
    "resolutionNote": "Customer provided valid source of funds documentation.",
    "relatedTransactionId": "TXN-2026-001",
    "updatedAt": "2026-05-08T15:00:00Z"
  }
}
Handling the resolution in your system:
status ValueMeaningYour Action
RESOLVED_FALSE_POSITIVEOfficer confirmed the transaction is legitimateUnfreeze the transaction and process it
RESOLVED_TRUE_POSITIVEOfficer confirmed suspicious activityPermanently block and escalate internally
CLOSEDCase closed after investigationTake no further action

Delivery Guarantees

Webhook delivery is backed by a persistent message queue with automatic retries:
PropertyValue
Max Attempts5
Backoff StrategyExponential (5s → 10s → 20s → 40s → 80s)
Request Timeout10 seconds per attempt
Completed Job Retention24 hours
Failed Job Retention7 days
Your endpoint must return a 2xx status code. Any non-2xx response will trigger automatic retries. If all 5 attempts fail, the event is retained in the dead-letter queue for 7 days.

Signature Verification

Every webhook includes an X-Ratel-Signature header — an HMAC-SHA256 hash of the raw JSON body, signed with your Webhook Secret. Always verify this server-side.
const crypto = require('crypto');

app.post('/ratel/webhooks', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-ratel-signature'];
  const hash = crypto
    .createHmac('sha256', process.env.RATEL_WEBHOOK_SECRET)
    .update(req.body)
    .digest('hex');

  if (`sha256=${hash}` !== signature) {
    return res.status(401).send('Invalid signature');
  }

  const event = JSON.parse(req.body);

  if (event.event === 'case.resolved') {
    if (event.data.status === 'RESOLVED_FALSE_POSITIVE') {
      // Unfreeze the transaction in your system
    } else if (event.data.status === 'RESOLVED_TRUE_POSITIVE') {
      // Permanently block and escalate
    }
  }

  res.status(200).send('OK');
});

Error Handling

Standard HTTP status codes indicate success or failure:
CodeMeaningSolution
200SuccessRequest processed successfully.
400Bad RequestCheck validation errors in the response body. Ensure all required fields are present.
401UnauthorizedYour X-API-Key is missing, invalid, or revoked. Check the API Keys page in your Dashboard.
409ConflictThe externalId was already processed. The cached verdict is returned.
429Too Many RequestsYou exceeded your workspace’s rate limit. Implement exponential backoff.
500Internal Server ErrorUnexpected server error. Retry with backoff.
Fail-Open Policy: If the Sanctions or Behavioral engines experience upstream downtime, Ratel Security implements a fail-open policy — your legitimate transactions continue processing without interruption, while partial screenings are logged for retroactive review.

Ratel Security — Enterprise-grade AML/CFT compliance for African financial institutions. For support, contact support@ratelsecurity.com.