Skip to content

Latest commit

 

History

History
249 lines (192 loc) · 8.63 KB

File metadata and controls

249 lines (192 loc) · 8.63 KB

API Reference

Back to README · See also: Architecture · Compliance

Base URL: http://localhost:8000 (dev) / https://fraud.yourdomain.example (prod)
Auth: Bearer token in Authorization header
Protocol: HTTPS TLS 1.2+ in production
Timeout: Hard 200ms server-side cutoff


Authentication

All endpoints (except /health/*) require a Bearer token:

Authorization: Bearer <api_key>

Keys configured via API_KEYS environment variable (comma-separated). Invalid key → 401 Unauthorized immediately, before any business logic runs.


Endpoints

POST /v1/transaction/score

Score a transaction for fraud risk. Returns decision, risk score, and SHAP explanations.

Note on verb-in-path: /score follows ML inference API convention. SageMaker uses /invocations, Azure ML uses /score, Vertex AI uses /predict. The action is the resource for inference APIs — a noun path (/transactions/{id}) would imply a persisted entity that doesn't exist until after scoring.

Latency SLA: P50 < 40ms · P95 < 100ms · Hard timeout 200ms

Request Body

{
  "transaction_id": "txn_2026_001",
  "timestamp_utc": "2026-07-30T10:00:00Z",
  "rail": "upi",
  "channel": "upi_push",
  "amount_inr": "5000.00",
  "currency_code": "INR",
  "customer_id_hash": "sha256_hash_64_chars",
  "client_id": "tenant_fintech_001",
  "merchant_id": "merch_001",
  "merchant_country": "IN",

  "vpa_sender_hash": "sha256_of_sender_vpa",
  "vpa_receiver_hash": "sha256_of_receiver_vpa",
  "upi_app": "gpay",

  "ip_address_hash": "sha256_of_ip",
  "device_id_hash": "sha256_of_device_fingerprint",
  "txn_lat": 19.0760,
  "txn_lon": 72.8777
}

Request Fields

Field Type Required Description
transaction_id string Yes Unique ID (UUIDv4 recommended)
timestamp_utc ISO 8601 datetime Yes Transaction time in UTC
rail enum Yes upi · aeps · dmt · cards · loans
channel enum Yes See channel list below
amount_inr decimal string Yes Amount in Indian Rupees
currency_code string Yes ISO 4217, usually INR
customer_id_hash hex string (64 chars) Yes SHA-256 of customer ID
client_id string (≤ 64 chars) No BaaS downstream tenant ID; stored in audit trail for per-client reporting
merchant_id string Yes Merchant identifier
merchant_country string Yes ISO 3166-1 alpha-2
card_token string Cards Tokenized card (no raw PAN)
bin_8 string (8 chars) Cards First 8 digits of card
pan_last4 string (4 chars) Cards Last 4 digits only
card_type enum Cards debit · credit · prepaid · corporate
cvv_result enum Cards match · no_match · not_provided
three_ds_result enum Cards authenticated · not_authenticated · not_attempted
vpa_sender_hash hex string UPI Required for UPI
vpa_receiver_hash hex string UPI Required for UPI
upi_app string UPI App identifier
aadhaar_last4 string (4 chars) AEPS Last 4 of Aadhaar — no more
agent_id string AEPS Required for AEPS
biometric_quality_score float 0–100 AEPS UIDAI quality score (NOT raw biometric)
biometric_attempt_count int AEPS Auth attempt count
session_duration_seconds float AEPS Session wall-clock time
beneficiary_account_hash hex string DMT SHA-256 of beneficiary account
beneficiary_is_new bool DMT First transfer to this beneficiary
ip_address_hash hex string Optional SHA-256 of IP (for MaxMind lookup)
device_id_hash hex string Optional SHA-256 of device fingerprint
txn_lat float Optional Transaction latitude
txn_lon float Optional Transaction longitude

Channel values: upi_collect · upi_push · aeps_withdrawal · aeps_balance · dmt_transfer · card_present · card_not_present · ecommerce · atm · recurring · loan_disbursement · loan_repayment · utility_payment

Response Body

{
  "transaction_id": "txn_2026_001",
  "rail": "upi",
  "decision": "ALLOW",
  "risk_score": 0.042153,
  "risk_score_int": 42,
  "model_scores": {
    "lightgbm": 0.038,
    "xgboost": 0.041,
    "catboost": 0.035,
    "lstm": 0.051,
    "autoencoder": 0.029,
    "isoforest": 0.061
  },
  "rules_triggered": [],
  "top_reasons": [
    {
      "feature": "card_txn_count_1h",
      "shap_value": 0.12,
      "direction": "increases_risk"
    },
    {
      "feature": "user_amount_z_score",
      "shap_value": -0.08,
      "direction": "decreases_risk"
    }
  ],
  "latency_ms": 34.7,
  "model_version": "1.4.2",
  "confidence": "HIGH"
}

Response Fields

Field Type Description
decision enum ALLOW · REVIEW · BLOCK
risk_score float 0–1 Calibrated fraud probability
risk_score_int int 0–1000 round(risk_score × 1000)
model_scores object Raw L2 model probabilities; xgboost/catboost/isoforest are null when those optional models are not loaded
rules_triggered array Rules that fired (with reason codes)
top_reasons array Top-5 TreeSHAP feature contributions
latency_ms float Server-side processing time
model_version string Semantic version of scoring model
confidence enum HIGH (all features available) · LOW (Redis miss)

Decision Mapping

risk_score_int decision Recommended action
0 – 299 ALLOW Process transaction
300 – 699 REVIEW Queue for manual review; process with extra auth
700 – 1000 BLOCK Decline; return reason to customer

Error Responses

Status Code Cause
401 unauthorized Missing or invalid Bearer token
422 validation_error Invalid request body (Pydantic V2 errors)
429 rate_limited Too many requests for this API key
503 service_unavailable Models not yet loaded (startup)
504 gateway_timeout Processing exceeded 200ms hard timeout

GET /health/live

Liveness probe. Returns 200 if the process is alive (even if models are still loading).

{"status": "ok"}

GET /health/ready

Readiness probe. Returns 200 only when all models are loaded and Redis is reachable.

{
  "status": "ready",
  "checks": {
    "models_loaded": true,
    "rules_loaded": true,
    "redis": true
  }
}

Returns 503 with "status": "not_ready" if any check fails.


GET /metrics

Prometheus metrics scrape endpoint. Returns text/plain in Prometheus exposition format.

Key metrics exposed:

Metric Type Description
fraud_request_latency_seconds Histogram End-to-end request latency
fraud_decision_total Counter Decisions by {rail, decision}
fraud_redis_miss_total Counter Redis timeout / fail-open events
fraud_feature_psi Gauge PSI drift per feature
fraud_score_psi Gauge Output score PSI drift
fraud_rules_triggered_total Counter Rule fires by {rule_id, action}

Rate Limiting

Fixed-window counter per API key via Redis Lua script (atomic INCR + EXPIRE). Default: 1000 req/min per key (override with RATE_LIMIT_PER_MINUTE env var).

Rate-limited response:

HTTP/1.1 429 Too Many Requests
Retry-After: 60
Content-Type: application/json

{"detail": "Rate limit exceeded"}

Request IDs

Every response includes X-Request-ID header (UUID4 injected by middleware). Use this for log correlation and support tickets.

X-Request-ID: 550e8400-e29b-41d4-a716-446655440000

Compliance Notes

  • PCI-DSS: Never send raw PAN in transaction_id, logs, or any field. Use card_token (tokenized). bin_8 and pan_last4 only.
  • Aadhaar Act §29: aadhaar_last4 only. Never send full Aadhaar number.
  • SHAP explanations: Stored for 3 years (RBI customer dispute window). Retrievable by support teams within 1 business day.
  • Audit trail: Every scoring decision logged to model_decisions with all 6 model scores (lgbm, lstm, ae, xgb, catboost, isoforest), client_id tenant field, rules, latency, and record_hash SHA-256 tamper seal. Run migration 002_add_xgb_catboost_client_id.sql before deploying v0.6.0+.

See Compliance for full regulatory requirements.


Next: Operations · Compliance