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:
{
"assessmentId": "e7d3c2b1-a0f9-4e8d-b7c6-5a4f3e2d1c0b",
"analystNote": "Customer flagged by velocity spike. Checking device history."
}assessmentIdRequired. The risk evaluation linked to this review.analystNoteOptional. Initial investigation notes.
Response:
{
"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
open → in_review → escalated ─────┐
↓
confirmed_fraud │ false_positive │ closed │ resolvedopenNewly created and not yet picked up. Not terminal.in_reviewAn analyst has opened the case. Not terminal.escalatedPassed to a senior analyst or manager. Not terminal.confirmed_fraudInvestigation confirmed fraud. Terminal.false_positiveInvestigation confirmed the activity was legitimate. Terminal.closedManually closed without a more specific verdict. Terminal.resolvedResolved 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:
{
"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:
pageInteger. Default is 1.limitInteger. Default is 20 and maximum is 100.statusOptional status filter.
Response:
{
"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.
{
"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
{
"assessmentId": "e7d3c2b1-a0f9-4e8d-b7c6-5a4f3e2d1c0b",
"outcome": "confirmed_fraud"
}