Reviews & Case Management

Create, manage, and resolve fraud review cases linked to specific risk assessments.

Overview

When a risk assessment returns a review action, or when your team wants to manually inspect a flagged transaction, you can create a review case tied to the stored assessment.

This guide covers the client-facing review APIs. Reviews are usually available only on plans that include the reviews feature.

Creating a review

POST /reviews

Auth: bearer token with admin or analyst role.

Request body:

json
{
  "assessmentId": "e7d3c2b1-a0f9-4e8d-b7c6-5a4f3e2d1c0b",
  "analystNote": "Customer flagged by velocity spike. Checking device history."
}
  1. assessmentId Required. The risk evaluation linked to this review.
  2. analystNote Optional. Initial investigation notes.

Response:

json
{
  "id": "r1a2b3c4-d5e6-7890-abcd-ef1234567890",
  "assessmentId": "e7d3c2b1-a0f9-4e8d-b7c6-5a4f3e2d1c0b",
  "status": "open",
  "analystId": "f1e2d3c4-...",
  "analystEmail": "alice@acme.com",
  "analystNote": "Customer flagged by velocity spike. Checking device history.",
  "createdAt": "2026-04-02T10:00:00.000Z",
  "closedAt": null
}
ℹ️

analystId and analystEmail are populated from the authenticated user. Clients do not send them in the request body.

Review status lifecycle

plaintext
open → in_review → escalated ─────┐
                       confirmed_fraud │ false_positive │ closed │ resolved
  1. open Newly created and not yet picked up. Not terminal.
  2. in_review An analyst has opened the case. Not terminal.
  3. escalated Passed to a senior analyst or manager. Not terminal.
  4. confirmed_fraud Investigation confirmed fraud. Terminal.
  5. false_positive Investigation confirmed the activity was legitimate. Terminal.
  6. closed Manually closed without a more specific verdict. Terminal.
  7. resolved Resolved with no further action required. Terminal.

Terminal statuses set closedAt automatically.

Updating status

PATCH /reviews/status

Auth: bearer token with admin or analyst role.

Request body:

json
{
  "reviewId": "r1a2b3c4-d5e6-7890-abcd-ef1234567890",
  "status": "confirmed_fraud"
}

Listing reviews

GET /reviews?page=1&limit=20&status=open

Auth: bearer token with admin or analyst role.

Query parameters:

  1. page Integer. Default is 1.
  2. limit Integer. Default is 20 and maximum is 100.
  3. status Optional status filter.

Response:

json
{
  "data": [ /* ReviewEntity[] */ ],
  "meta": {
    "total": 42,
    "page": 1,
    "limit": 20,
    "totalPages": 3
  }
}

Fetching a single review

GET /reviews/:id

The response includes a nested assessment summary with the score, action, risk level, and reason codes — so analysts can see the risk context without leaving the review.

json
{
  "id": "r1a2b3c4-...",
  "status": "in_review",
  "analystNote": "Customer flagged by velocity spike.",
  "assessment": {
    "id": "e7d3c2b1-...",
    "finalScore": 78,
    "action": "review",
    "riskLevel": "high",
    "reasonCodes": ["VELOCITY_ZSCORE_SPIKE"],
    "createdAt": "2026-04-02T09:55:00.000Z"
  }
}

Closing the loop with feedback

After resolving a review, submit the outcome back to the risk engine so it can recalibrate indicator confidence:

POST /risk-engine/feedback

json
{
  "assessmentId": "e7d3c2b1-a0f9-4e8d-b7c6-5a4f3e2d1c0b",
  "outcome": "confirmed_fraud"
}