PlatformXeDocs
Get API Key

Cases

Manual reviewer workflow for flagged decisions — open, triage, escalate, resolve.

Cases give your fraud team a structured workspace to follow up on flagged decisions. Each case ties to one fraud decision (or none, for manual investigations), tracks who's working it, captures notes, runs a 24h default SLA, and ends with one of three resolutions.

Lifecycle

open  →  triaging  →  escalated  →  resolved (terminal)
   \         \                          ↑
    \         → resolved                |
     → resolved                         |
                                          ↓
                  { confirmed_fraud | false_positive | inconclusive }
FromToNotes
opentriaging, escalated, resolvedNew cases start here.
triagingopen, escalated, resolvedA reviewer is actively working it. Reverting to open re-queues.
escalatedtriaging, resolvedSLA breach OR explicit escalation.
resolvedTerminal. To re-investigate, open a new case.

Auto-open from decide

When /api/v1/fraud/decide returns block, a case is automatically opened with:

  • decisionId — the originating decision
  • severity — equal to the decision score (75–100)
  • An opening note carrying the triggered reason codes
  • 24h default SLA window

This is fire-and-forget: a failure to auto-open never affects the verdict. review and step_up verdicts do not auto-open — subscribe to FRAUD_DECISION_REVIEW (etc.) and call POST /v1/fraud/cases yourself if you want them.

SLA escalation

Cases past their slaBreachAt are bulk-escalated by the fraud-case-sla cron (recommended schedule: every 5 minutes). Each escalation emits FRAUD_CASE_ESCALATED with reason: "sla_breach" so you can wire pager / email / Slack from the workflow engine.

Endpoints

MethodPathDescription
GET/api/v1/fraud/casesList cases (filter by status, decisionId, overdueOnly)
POST/api/v1/fraud/casesOpen a new case
GET/api/v1/fraud/cases/:idFetch one case
PATCH/api/v1/fraud/cases/:idUpdate severity / assignee / append note
POST/api/v1/fraud/cases/:id/transitionState-machine transition
PropertyValue
Scopefraud:cases
Plan gateDetection Pack addon
Rate limit500 requests / hour per API key
IdempotentPOST endpoints honour Idempotency-Key

Open a case

curl -X POST https://api.platformxe.com/api/v1/fraud/cases \
  -H "Content-Type: application/json" \
  -H "x-api-key: pxk_live_..." \
  -d '{
    "decisionId": "dec_2j7yhq8wcs9",
    "severity": 80,
    "assignedTo": "reviewer_jane",
    "note": { "by": "reviewer_jane", "text": "Cross-border transfer flagged by velocity rule." }
  }'
FieldTypeRequiredDescription
decisionIdstring | nullNoBind to a fraud decision. null = manual case.
severitynumber (0–100)NoDefaults to 50. Auto-opened cases carry the decision score.
assignedTostring | nullNoReviewer id / email.
note{ by, text }NoOpening note. ≤ 4,000 chars.
slaWindowMsnumberNoOverride the 24h default SLA.

Returns 201 with the full case record.

Update a case

curl -X PATCH https://api.platformxe.com/api/v1/fraud/cases/fcs_2j7yhq8 \
  -H "Content-Type: application/json" \
  -H "x-api-key: pxk_live_..." \
  -d '{
    "severity": 90,
    "appendNote": { "by": "reviewer_jane", "text": "Confirmed pattern across 3 accounts." }
  }'

PATCH allows updating severity, assignedTo, and appending notes. Existing notes are immutable. Resolved cases are terminal — PATCH returns 409.

Transitions

curl -X POST https://api.platformxe.com/api/v1/fraud/cases/fcs_2j7yhq8/transition \
  -H "Content-Type: application/json" \
  -H "x-api-key: pxk_live_..." \
  -d '{
    "target": "resolved",
    "resolution": "confirmed_fraud",
    "note": { "by": "reviewer_jane", "text": "Account frozen, refund processed." }
  }'

Transitioning to resolved requires a resolution:

ResolutionUse when
confirmed_fraudThe flagged behaviour was indeed fraud.
false_positiveVerdict was wrong; no action needed.
inconclusiveCouldn't determine; closing for triage capacity.

Tracking the resolution mix is essential for tuning rule thresholds — a false_positive rate trending upward signals a rule is too tight.

List filters

GET /api/v1/fraud/cases accepts:

QueryDescription
statusopen | triaging | escalated | resolved
decisionIdCases bound to a specific decision.
overdueOnly=trueCases past slaBreachAt.
limit (≤ 100, default 50) / offsetPagination.

Cases come back ordered by openedAt descending so the freshest queue items are at the top.

Events

EventWhen
FRAUD_CASE_OPENEDNew case created (manual or auto-open).
FRAUD_CASE_ESCALATEDStatus moved to escalated. SLA-breach escalations carry reason: "sla_breach".
FRAUD_CASE_CLOSEDStatus moved to resolved. Payload includes the chosen resolution.

Subscribe to wire your reviewer queue, alert your SOC, or trigger Workflow-engine actions on resolution.

Errors

HTTPCodeCause
400BAD_REQUESTValidation failure — invalid severity, missing resolution for resolved, oversized note.
401UNAUTHORIZEDMissing or invalid API key.
402DETECTION_PACK_REQUIREDDetection Pack addon not enabled.
403FORBIDDENAPI key has no organisation context, or wrong scope.
404NOT_FOUNDCase unknown or belongs to a different org.
409CONFLICTPATCH on a resolved case, or invalid state transition.
429RATE_LIMITED500/hr ceiling exceeded.
500INTERNAL_ERRORUnexpected service failure.