Events
POST /v1/events scores one event. Required: event_id and event_type. Everything else is optional, but rules can only use what you send.
| Field | Notes |
|---|---|
event_id | UUID you generate. The idempotency key. |
event_type | payment, payout, login, registration, deposit or withdrawal. |
async | true to ingest and score in the background. Default false. |
external_account_id | Your id for the user (string, up to 64 chars; a number is accepted). Links events into one account. To use it in /v1/accounts/{id} URLs it may contain only letters, digits and . _ : @ -; otherwise use the acc_... id. |
brand_id | Your brand tag, up to 64 chars. |
context | ip, user_agent, fp_id, session_id, country, affiliate_id, session_anon. |
user | email, phone (E.164 or national with user.country; an unparseable number is accepted and reported in enrichment_status.phone), name, country, registered_at, plus email_hash / phone_hash for callers that cannot send raw values, and the declared marks trusted, vip, is_known_fraud, chargeback_flag, name_blocked, sanctions_match. |
payment | amount_cents (integer), currency, method, bin, last4, billing_country, card_token (used for velocity counts only; card links and reputation use bin + last4). |
extras | Free-form object for project-specific signals. |
Unknown top-level properties are rejected with 400; the context, user and payment objects accept extra fields. The full schema, with limits, is in the API reference.
user.trusted, user.vip and the declared marks (is_known_fraud, chargeback_flag, name_blocked, sanctions_match) act through the rules of the project's preset: in the shipped presets trusted and vip allow with score 0 and the others hard-block, but an archived or shadow rule stops that. Set them only from data you trust.
Idempotency
event_id is the idempotency key. Resending the same sync request does not score twice and returns the stored result (without degraded, latency_ms and account_public_id when it is rebuilt from storage). Sending the same event_id with a different body returns 409 EVENT_ID_CONFLICT; the async flag is not part of the compared body. A repeated async request returns a new 202 receipt. After a 500 or 503, retry the same event_id and body.
Sync and async
Sync is the default and returns 200 with the decision. With "async": true you get 202 and an accepted_at receipt; read the result with GET /v1/scores/{event_id} (pending until scored) or through the decision webhook. See How it works.
Reading the result
| Field | Meaning |
|---|---|
decision | allow, review or block. |
risk_score, max_possible | The score (floored at 0; equal to max_possible on a hard block) and the sum of all positive deltas of active scoring rules. It is a scale for display, not always an attainable score. |
breakdown | Per active rule: rule_id, rule_version, score_delta, band, matched, reason (the rule id), and action when matched. Shadow rules are omitted; on a trust or hard-block verdict only the winning rule is listed. |
flags | rule_ids of matched monitoring rules. |
actions | Present only when non-empty: actions requested by matched active rules. The only supported form is require_kyc:<phone|document|liveness|sanctions|pep>. |
trust_override, hard_block_hit | Evaluation ended early on a trust or hard-block rule. |
degraded | Present when an active rule could not read a signal as written. See fail-closed behaviour. |
enrichment_status | Per-provider outcome: ok, unconfigured, error, unparseable. |
account_public_id | The resolved account id (acc_...), usually present when you sent external_account_id. Not returned by GET /v1/scores. |
latency_ms | Rule evaluation time only. Not returned by GET /v1/scores. |
Linked accounts and erasure
GET /v1/accounts/{id}/linksreturns a flatlinksarray of accounts sharing anemail,phone,fp,ip_24horcardsignal with this one; each entry has asignal_type. There is no time filter, so older IP links are included.{id}is theacc_...id or your ownexternal_account_id. Signals are shown masked.DELETE /v1/accounts/{id}erases an account (GDPR). It needs a live key and theaccounts:erasescope.