---
updatedAt: 2026-08-31T03:40:46.000Z
agentTools:
  projectIndex: https://readme.cipherowl.ai/llms.txt
---

# List and search Cases

Returns one page of your organization's Cases with the total row count for the filter set. Filter by lifecycle status or work-queue stage, investigator, network and address, client reference, priority, mute state, and creation or last-modified time windows. Every filter is optional and a valid combination of set filters applies them together (AND); the parameters say which combinations are rejected. Timestamps are RFC 3339 (e.g. 2026-08-01T00:00:00Z), every time window is inclusive at both ends, and bounds are applied at microsecond precision (finer fractions of a second are dropped). Pagination is 1-based page/pageSize. To poll for changes, filter on updatedFrom/updatedTo — see updatedFrom for the overlap rule and for the changes it cannot see.

# OpenAPI definition

```json
{
  "openapi": "3.0.3",
  "info": {
    "title": "API ENDPOINTS",
    "description": "CipherOwl blockchain compliance and risk assessment APIs.",
    "version": "1.0"
  },
  "servers": [
    {
      "url": "https://svc.cipherowl.ai"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Case Management",
      "description": "Read the organization's compliance cases. Search and page the case queue, read one case with the screening route currently in force for its address, its append-only screening history, and its audit trail. Read-only: cases are opened by screening (or by hand in the CipherOwl console), worked and closed there, and no write route is published here. A Case identifies its address by `network`; Cases opened today store the chain there (e.g. `evm`)."
    }
  ],
  "paths": {
    "/api/case-management/v1/cases": {
      "get": {
        "summary": "List and search Cases",
        "description": "Returns one page of your organization's Cases with the total row count for the filter set. Filter by lifecycle status or work-queue stage, investigator, network and address, client reference, priority, mute state, and creation or last-modified time windows. Every filter is optional and a valid combination of set filters applies them together (AND); the parameters say which combinations are rejected. Timestamps are RFC 3339 (e.g. 2026-08-01T00:00:00Z), every time window is inclusive at both ends, and bounds are applied at microsecond precision (finer fractions of a second are dropped). Pagination is 1-based page/pageSize. To poll for changes, filter on updatedFrom/updatedTo — see updatedFrom for the overlap rule and for the changes it cannot see.",
        "operationId": "CaseManagementService_ListCases",
        "responses": {
          "200": {
            "description": "A successful response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/case_managementv1ListCasesResponse"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "investigatorId",
            "description": "Only Cases assigned to this investigator, matched exactly on the user's\nsubject id (the value Case.investigatorId returns). Cannot be combined\nwith queueStage=QUEUE_STAGE_UNASSIGNED.",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "clientReference",
            "description": "Only Cases whose clientReference currently equals this value exactly\n(the reference is editable in the console after the Case is opened).",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "network",
            "description": "Only Cases whose address is on this network. Accepts a network key\n(\"ethereum_mainnet\") or a common alias (\"eth\"). Cases are stored by\nchain, so every network in the same chain returns the same Cases. An\nunknown name is rejected (INVALID_ARGUMENT). May be used on its own;\nrequired whenever address is set.",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "address",
            "description": "Only the Case(s) for this address; requires network, and address without\nnetwork is rejected (INVALID_ARGUMENT). The address is normalized before\nmatching, so any accepted spelling of it matches (EVM addresses, for\nexample, match regardless of letter case). An address that is not valid\non the requested network returns an empty page rather than an error.",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "description": "Only Cases in this lifecycle status; see CaseStatus for the values.\nOmitted or CASE_STATUS_UNSPECIFIED applies no status filter. Use either\nstatus or queueStage, not both — queueStage is the finer-grained view of\nthe same lifecycle (CASE_STATUS_OPEN covers UNASSIGNED and ASSIGNED,\nCASE_STATUS_CLOSED covers CLOSED and ARCHIVED). CASE_STATUS_CLOSED cannot\nbe combined with excludeClosed.\n\n - CASE_STATUS_UNSPECIFIED: No status; as a List Cases filter, any status.\n - CASE_STATUS_OPEN: Being worked, whether or not an investigator is assigned.\n - CASE_STATUS_PENDING_APPROVAL: A close request awaits Manager approval.\n - CASE_STATUS_CLOSED: Closed; archived Cases are Closed too.",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "CASE_STATUS_UNSPECIFIED",
                "CASE_STATUS_OPEN",
                "CASE_STATUS_PENDING_APPROVAL",
                "CASE_STATUS_CLOSED"
              ],
              "default": "CASE_STATUS_UNSPECIFIED"
            }
          },
          {
            "name": "createdFrom",
            "description": "Only Cases created at or after this instant.",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "createdTo",
            "description": "Only Cases created at or before this instant; createdFrom must not be\nafter createdTo.",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "pageSize",
            "description": "Cases per page, 1 to 100. Omitted or 0 means 50.",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "queueStage",
            "description": "Only Cases in this work-queue stage; see QueueStage for the values.\nOmitted or QUEUE_STAGE_UNSPECIFIED applies no stage filter. Cannot be\ncombined with status (use one or the other) or with deletedOnly, and\nQUEUE_STAGE_UNASSIGNED cannot be combined with investigatorId.\n\n - QUEUE_STAGE_UNSPECIFIED: No stage; as a List Cases filter, any stage.\n - QUEUE_STAGE_UNASSIGNED: No investigator holds the Case.\n - QUEUE_STAGE_ASSIGNED: Assigned to an investigator and being worked.\n - QUEUE_STAGE_WAITING_FOR_APPROVAL: A close request awaits Manager approval.\n - QUEUE_STAGE_CLOSED: Closed and not archived.\n - QUEUE_STAGE_ARCHIVED: Closed and archived: the separate Archive view, retained indefinitely\nwith complete evidence and audit history.",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "QUEUE_STAGE_UNSPECIFIED",
                "QUEUE_STAGE_UNASSIGNED",
                "QUEUE_STAGE_ASSIGNED",
                "QUEUE_STAGE_WAITING_FOR_APPROVAL",
                "QUEUE_STAGE_CLOSED",
                "QUEUE_STAGE_ARCHIVED"
              ],
              "default": "QUEUE_STAGE_UNSPECIFIED"
            }
          },
          {
            "name": "page",
            "description": "Page to return, starting at 1; omitted or 0 returns page 1. Pages beyond\n10000 are rejected.",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "muted",
            "description": "How muted Cases are treated; see MutedFilter for the values. Omitted or\nMUTED_FILTER_UNSPECIFIED includes them.\n\n - MUTED_FILTER_UNSPECIFIED: Include muted Cases (the default; hides nothing).\n - MUTED_FILTER_EXCLUDE: Leave muted Cases out.\n - MUTED_FILTER_INCLUDE: Include muted Cases; the same result as the default.\n - MUTED_FILTER_ONLY: Only muted Cases.",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "MUTED_FILTER_UNSPECIFIED",
                "MUTED_FILTER_EXCLUDE",
                "MUTED_FILTER_INCLUDE",
                "MUTED_FILTER_ONLY"
              ],
              "default": "MUTED_FILTER_UNSPECIFIED"
            }
          },
          {
            "name": "priority",
            "description": "Only Cases with exactly this priority. Omitted or CASE_PRIORITY_UNSPECIFIED\napplies no priority filter (it does not select Cases without a priority).",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "CASE_PRIORITY_UNSPECIFIED",
                "CASE_PRIORITY_CRITICAL",
                "CASE_PRIORITY_HIGH",
                "CASE_PRIORITY_MEDIUM",
                "CASE_PRIORITY_LOW"
              ],
              "default": "CASE_PRIORITY_UNSPECIFIED"
            }
          },
          {
            "name": "deletedOnly",
            "description": "Return only Cases in the Trash (soft-deleted) instead of active ones.\nRequires the Case Management Manager role, which API clients\nauthenticating with client credentials do not hold: they are denied when\nthey set it, so leave it unset. Cannot be combined with queueStage.",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "excludeClosed",
            "description": "Leave out closed Cases — archived ones included, since a Case is only ever\narchived after it is closed. This is the way to ask for every Case still\nbeing worked, whatever its stage; a single status or queueStage value\ncannot express that. Cannot be combined with status=CASE_STATUS_CLOSED or\nwith queueStage QUEUE_STAGE_CLOSED / QUEUE_STAGE_ARCHIVED, which would\ndescribe an empty set.",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "updatedFrom",
            "description": "Only Cases last changed at or after this instant (Case.updatedAt). This\nis the filter to poll for changes with: request the window since your\nprevious poll and overlap successive windows slightly, because updatedAt\nis stamped when a change starts rather than when it is committed, so a\nchange that commits after your read is not in that read. Expect to see\nthe same Case in more than one poll. Combined with\nstatus=CASE_STATUS_CLOSED (or a queueStage) it finds Cases closed, or\nchanged while closed, since the previous poll, whenever they were\ncreated. It cannot see the\nchanges that leave updatedAt untouched — a MONITOR_ONLY screening hit, an\nintake suppress/resume, a Closure Report status change, and the\nasynchronous evidence and artifact progress of the Screening history\n(see Case.updatedAt; poll List Screenings for that). updatedFrom must\nnot be after updatedTo.",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "updatedTo",
            "description": "Only Cases last changed at or before this instant.",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "tags": [
          "Case Management"
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "OAuth 2.0 access token obtained from /oauth/token using client credentials."
      }
    },
    "schemas": {
      "case_managementv1Case": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique Case identifier; the caseId path parameter of the per-Case routes."
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/case_managementv1CaseStatus"
              }
            ],
            "description": "Current lifecycle status; see CaseStatus for the values and the moves\nbetween them. Together with investigatorId (assigned or not) and\narchivedAt (archived or not) it places the Case in exactly one\nwork-queue stage — the QueueStage the List Cases queueStage filter\nselects on."
          },
          "investigatorId": {
            "type": "string",
            "description": "Subject id of the investigator the Case is assigned to; absent while the\nCase is unassigned."
          },
          "clientReference": {
            "type": "string",
            "description": "Your own system's reference for the Case, for correlating it with your\nrecords: supplied when the Case was opened and editable in the console\nafterwards; absent when none is set. Filterable in List Cases."
          },
          "network": {
            "type": "string",
            "description": "Network of the Case's address. Cases opened today store the chain here\n(\"evm\", \"solana\", \"bitcoin\", \"tron\", …); older Cases may carry a network\nkey such as \"ethereum_mainnet\". The network a screening hit named is on\nthe Case's screening history (trigger.network)."
          },
          "address": {
            "type": "string",
            "description": "The Case's address, in the canonical form for its chain; the\nservice normalizes it on intake."
          },
          "createdBy": {
            "type": "string",
            "description": "Who created the Case: the subject id of the user who opened it by hand, or\nthe service identity \"system:screening\" when a screening hit opened it\nautomatically. Never an email address."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the Case was created."
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the Case last changed: moves on every status change, assignment,\nmetadata edit, workflow action and accepted screening hit — the instant\nupdatedFrom/updatedTo filter on in List Cases. Three Case-level changes\nleave it untouched: a screening hit recorded under MONITOR_ONLY\nsuppression (adds a Screening history entry), suppressing or resuming\nscreening intake (changes screeningRoute) — both increment version only —\nand closureReportStatus, which is read live from the report. It tracks\nthe Case itself, not its Screening history: evidence and artifacts on\nthat history settle asynchronously without moving updatedAt or version,\nso re-read the Screening history for their progress."
          },
          "version": {
            "type": "string",
            "format": "int64",
            "description": "Change counter, incremented on every accepted change to the Case,\nMONITOR_ONLY screening hits and intake suppress/resume included.\nclosureReportStatus is read live from the report and changes without\nmoving version or updatedAt."
          },
          "closedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the Case was closed. Present only while the Case is Closed; reopening\nclears it. Earlier closures remain in the audit trail as CASE_CLOSED\nevents, each with its own closure under payload.closure."
          },
          "latestClosureNumber": {
            "type": "string",
            "format": "int64",
            "description": "Ordinal of the Case's latest closure: 1 for the first close, one more for\nevery close after a reopen. Absent while the Case is not Closed."
          },
          "latestDisposition": {
            "allOf": [
              {
                "$ref": "#/components/schemas/v1ClosureDisposition"
              }
            ],
            "description": "Outcome recorded by the latest closure; see ClosureDisposition. Absent\nwhile the Case is not Closed."
          },
          "closureReportStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/v1ClosureReportStatus"
              }
            ],
            "description": "Render state of the latest Closure Report; see ClosureReportStatus. Read\nlive from the report, so it changes without moving updatedAt or version.\nAbsent while the Case is not Closed."
          },
          "archivedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the Case was archived; absent while not archived. Only a Closed Case\nis archived, and reopening it clears this."
          },
          "mutedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the Case was muted; absent while not muted. Muting is a flag beside\nthe lifecycle, not a status of its own: a muted Case keeps its status and\nqueue stage. Set when a Manager mutes the Case in the console and cleared\non unmute, close or reopen, so a Closed or Archived Case is never muted."
          },
          "mutedBy": {
            "type": "string",
            "description": "Subject id of the Manager who muted the Case; absent when not muted."
          },
          "muteReason": {
            "type": "string",
            "description": "Reason given for the current mute; absent when not muted. Reasons for\nearlier mutes live in the CASE_MUTED / CASE_UNMUTED audit events."
          },
          "title": {
            "type": "string",
            "description": "Human-readable title; never empty. Supplied by the creator of a Case opened\nby hand; generated for a Case opened by a screening hit as\n\"CASE_{yyMMdd}_{4 random uppercase alphanumerics}\" (e.g. CASE_260728_7Q2F)\nfrom the UTC creation date. Editable in the console."
          },
          "priority": {
            "allOf": [
              {
                "$ref": "#/components/schemas/v1CasePriority"
              }
            ],
            "description": "Triage priority; see CasePriority. Absent when no priority is set.\nEditable in the console."
          },
          "deletedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the Case was moved to the Trash (soft-deleted); absent while the Case\nis active. A deleted Case keeps every other field but is left out of List\nCases and Get Case unless the Manager-only deletedOnly / includeDeleted\noption asks for it — API clients authenticating with client credentials\ncannot, so they never see a deleted Case. Managers restore Cases from the\nTrash in the console."
          },
          "deletedBy": {
            "type": "string",
            "description": "Subject id of the Manager who deleted the Case; absent while not deleted\nand cleared on restore. Who/when/why of earlier deletions lives in the\nCASE_DELETED / CASE_RESTORED audit events."
          },
          "deleteReason": {
            "type": "string",
            "description": "Reason given for the current deletion; absent while not deleted and\ncleared on restore."
          }
        },
        "description": "Case is one compliance Case: a single blockchain address on a single chain\nclass, opened by a screening hit or by hand, and worked through the Open /\nPending Approval / Closed lifecycle (status; see CaseStatus). Fields\ndescribed as absent are omitted from the JSON response rather than sent\nempty."
      },
      "case_managementv1CaseStatus": {
        "type": "string",
        "enum": [
          "CASE_STATUS_UNSPECIFIED",
          "CASE_STATUS_OPEN",
          "CASE_STATUS_PENDING_APPROVAL",
          "CASE_STATUS_CLOSED"
        ],
        "default": "CASE_STATUS_UNSPECIFIED",
        "description": "CaseStatus is the Case's lifecycle status. A Case is Open while it is being\nworked (assigned to an investigator or not), Pending Approval while a close\nrequest awaits a Manager's decision, and Closed once it has been closed —\neither directly from Open, or by a Manager approving the close request\n(a rejected request returns the Case to Open). Reopening a Closed Case\nreturns it to Open, unassigned. Archiving, muting and the Trash are flags\nbeside the status, not statuses: an archived Case is still Closed.\nQueueStage is the finer-grained work-queue view of the same lifecycle.\n\n - CASE_STATUS_UNSPECIFIED: No status; as a List Cases filter, any status.\n - CASE_STATUS_OPEN: Being worked, whether or not an investigator is assigned.\n - CASE_STATUS_PENDING_APPROVAL: A close request awaits Manager approval.\n - CASE_STATUS_CLOSED: Closed; archived Cases are Closed too."
      },
      "case_managementv1ListCasesResponse": {
        "type": "object",
        "properties": {
          "cases": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/case_managementv1Case"
            },
            "description": "The Cases on this page. Always present in REST JSON; zero matches are\nencoded as `[]`."
          },
          "totalCount": {
            "type": "string",
            "format": "int64",
            "description": "Total Cases matching the filter set across all pages."
          },
          "page": {
            "type": "integer",
            "format": "int32",
            "description": "Echo of the served 1-based page number."
          },
          "pageSize": {
            "type": "integer",
            "format": "int32",
            "description": "Echo of the served page size."
          }
        },
        "description": "ListCasesResponse is one page of Cases plus the total for the filter set."
      },
      "v1CasePriority": {
        "type": "string",
        "enum": [
          "CASE_PRIORITY_UNSPECIFIED",
          "CASE_PRIORITY_CRITICAL",
          "CASE_PRIORITY_HIGH",
          "CASE_PRIORITY_MEDIUM",
          "CASE_PRIORITY_LOW"
        ],
        "default": "CASE_PRIORITY_UNSPECIFIED",
        "description": "CasePriority is the optional triage priority of a Case, from CRITICAL down\nto LOW. A Case with no priority set carries no priority field at all, so\nCASE_PRIORITY_UNSPECIFIED is never a value a response returns; as a List\nCases filter it means any priority."
      },
      "v1ClosureDisposition": {
        "type": "string",
        "enum": [
          "CLOSURE_DISPOSITION_UNSPECIFIED",
          "CLOSURE_DISPOSITION_FALSE_POSITIVE",
          "CLOSURE_DISPOSITION_NO_ACTION",
          "CLOSURE_DISPOSITION_ENHANCED_MONITORING",
          "CLOSURE_DISPOSITION_SAR_FILED"
        ],
        "default": "CLOSURE_DISPOSITION_UNSPECIFIED",
        "description": "ClosureDisposition is the outcome recorded when a Case is closed, alongside\nthe free-text disposition note the closing user writes.\n\n - CLOSURE_DISPOSITION_FALSE_POSITIVE: The screening risk did not hold up under investigation.\n - CLOSURE_DISPOSITION_NO_ACTION: The risk is real or plausible but requires no further action.\n - CLOSURE_DISPOSITION_ENHANCED_MONITORING: The Subject warrants continued heightened attention.\n - CLOSURE_DISPOSITION_SAR_FILED: A suspicious activity report was filed for this Case."
      },
      "v1ClosureReportStatus": {
        "type": "string",
        "enum": [
          "CLOSURE_REPORT_STATUS_UNSPECIFIED",
          "CLOSURE_REPORT_STATUS_PENDING",
          "CLOSURE_REPORT_STATUS_AVAILABLE",
          "CLOSURE_REPORT_STATUS_FAILED"
        ],
        "default": "CLOSURE_REPORT_STATUS_UNSPECIFIED",
        "description": "ClosureReportStatus is the render state of the Closure Report, the document\ngenerated in the background when a Case is closed. Rendering never affects\nthe Case itself: a Pending or Failed report leaves the Case Closed, and a\nFailed report can be rendered again.\n\n - CLOSURE_REPORT_STATUS_PENDING: The report is still being rendered.\n - CLOSURE_REPORT_STATUS_AVAILABLE: The report is ready.\n - CLOSURE_REPORT_STATUS_FAILED: Rendering failed; the Case stays Closed and the report can be retried."
      }
    }
  }
}
```