---
title: "Open an evidence case on a user"
method: POST
path: "/stats/evidence/cases"
tags: ["Stats"]
---

# Open an evidence case on a user

`POST /stats/evidence/cases`

## Request

- Base URL: `https://api.nippy.host`
- URL: `https://api.nippy.host/stats/evidence/cases`
- Auth: `bearer` (a scheme the document does not define)

Admin-only (ADR 0061). Freezes a snapshot of everything Nippy holds about the user, their accounts, sites and previews, and hashes every stored file. Changes nothing about the user: ban them afterwards to take the content offline.

## Request body

- CreateEvidenceCaseDto
  - `userId` string, uuid, required: The user the case is about.
  - `category` 'csam' | 'terrorism' | 'fraud' | 'other', required
  - `note` string: Why the case is opened. Goes into the snapshot and the report, so write it for the authorities.

## Response `200`

- APIEvidenceCase
  - `id` string, required
  - `reference` string, required: e.g. `EV-2026-0001`.
  - `category` 'csam' | 'terrorism' | 'fraud' | 'other', required
  - `subjectUserId` string, required
  - `subjectEmail` string, required: The subject’s address when the case opened.
  - `fileCount` number, required
  - `totalBytes` number, required: Sum of the file sizes, in bytes.
  - `activeLinks` number, required: Links that work right now.
  - `createdByName` string, nullable, required
  - `createdAt` string, required
  - `note` string, nullable, required
  - `externalReferences` string, nullable, required
  - `takenAt` string, required: When the snapshot was taken.
  - `snapshotSha256` string, required: SHA-256 of the snapshot JSON file.
  - `files` APIEvidenceFile[], required
    - `index` number, required: Position in the snapshot; links use it.
    - `ownerKind` 'site' | 'preview', required
    - `ownerName` string, required: Subdomain or preview slug.
    - `path` string, required: Path inside the site.
    - `size` number, required
    - `contentType` string, nullable, required
    - `sha256` string, nullable, required
    - `md5` string, nullable, required
    - `note` string, nullable, required: Why a hash is missing, when it is.
  - `sections` APIEvidenceSectionCount[], required
    - `key` string, required: Section key in the snapshot JSON.
    - `title` string, required
    - `count` number, required
  - `links` APIEvidenceLink[], required
    - `id` string, required
    - `label` string, required
    - `state` 'active' | 'expired' | 'revoked', required
    - `expiresAt` string, required
    - `revokedAt` string, nullable, required
    - `createdByName` string, nullable, required
    - `createdAt` string, required
    - `accessCount` number, required: Requests made with the link.
    - `lastAccessAt` string, nullable, required
  - `accesses` APIEvidenceAccess[], required: Newest first, at most 500.
    - `id` string, required
    - `linkId` string, required
    - `linkLabel` string, required
    - `outcome` 'served' | 'refused' | 'missing', required
    - `path` string, required: Path with the token removed.
    - `filePath` string, nullable, required: The file asked for, or null for the file list.
    - `ip` string, nullable, required
    - `userAgent` string, nullable, required
    - `createdAt` string, required

## Other responses

- `403`: Admin access required
- `404`: User not found

---

[API](https://skmtc.dev/nippy/apis/nippy-backend-api.md) · [All operations](https://skmtc.dev/nippy/apis/nippy-backend-api/llms.txt) · [OpenAPI document](https://skmtc.dev/nippy/apis/nippy-backend-api/revisions/7ab23f040a55?raw)
