Cases
A case is an investigation. It groups one or more alerts, holds analyst notes and attachments, and is the unit at which a SAR (Suspicious Activity Report) is filed.
Lifecycle
open → in_review → ┐
├→ closed_no_action (resolved benignly)
├→ closed_other (e.g. customer offboarded)
├→ escalated (sent to a higher tier — usually MLRO)
└→ sar_filed (terminal — SAR has been submitted)Terminal states (closed_*, sar_filed) cannot be transitioned out of via the API. Use the dashboard's "reopen" admin action if you need to revisit a case.
Read a case
/api/cases/{id}{
"ok": true,
"data": {
"id": "cas_01HXY...",
"orgId": "org_01HXY...",
"customerId": "cus_01HXY...",
"title": "Case · sanctions_match",
"status": "in_review",
"priority": "high",
"assignedToId": "usr_01HXY...",
"alertIds": ["alt_01HXY...", "alt_01HXZ..."],
"notes": [
{
"id": "csn_01HXY...",
"actorUserId": "usr_01HXY...",
"body": "Counterparty PT Foo also under separate watchlist hit. Possible structuring.",
"createdAt": "..."
}
],
"sarFilings": [],
"createdAt": "...",
"updatedAt": "..."
}
}Update a case
/api/cases/{id}{
"status": "in_review",
"priority": "low | medium | high | critical",
"assignedToId": "usr_01HXY..."
}All fields optional. Pass assignedToId: null to unassign. Terminal-state transitions are rejected with HTTP 409 — close via /close instead.
Add a note
/api/cases/{id}/notes{
"body": "Reviewed source-of-funds documents; customer is a private trader with legitimate IDR 50M+ monthly inflow from confirmed counterparties."
}Notes are append-only and immutable. The author and timestamp are recorded automatically.
Close a case
/api/cases/{id}/close{
"disposition": "no_action | other",
"reason": "All linked alerts dismissed as false positives — counterparty verified legitimate."
}Closing a case auto-resolves all linked alerts that are still in open state. SAR filings on a closed case can still be amended for up to 30 days.
Closing ≠ deleting
Closed cases stay queryable forever. We never delete cases — that would break audit. To "remove" a case from active queues, close it; to fully purge it (data retention compliance), use the dashboard's GDPR/UU-PDP export-and-erase tool, which is per-customer not per-case.
Four-eyes on case actions
By default, the user who creates an alert cannot also close it. Configurable per-org from the decision policy:
PATCH /api/decision-policy
{
"fourEyesOnCaseClose": true
}When enabled, attempting to close a case where the closer is also a note author (or the original alert dismissor) returns HTTP 409 four-eyes violation: actor must differ from prior approver.
Promoting an alert directly to a case
You can also create a case independent of an alert via the dashboard. Programmatic creation is via POST /api/alerts/{id}/escalate — see Alerts → Escalate.
Querying cases
The full GET /api/cases list endpoint isn't documented in this MVP because most automation works at the alert level. If you need it, use the dashboard's filterable case queue or the SQL-grade BigQuery export (request via support@quantumelixir.tech).