> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Batch Delete Sessions

> Bulk soft-delete User Verification (KYC) sessions by their numeric `session_number`, or wipe every KYC session in your application with `delete_all: true`.

`session_number` is the human-friendly incrementing counter shown in the Console session list and returned as `session_number` by the create-session and decision endpoints — it is **not** the `session_id` UUID. To delete a session by UUID — or to delete a Business Verification (KYB) session, which this endpoint never touches — use `DELETE /v3/session/{sessionId}/delete/` instead.

Each deleted session gets exactly the same treatment as the single-session delete endpoint: stamped with a deletion timestamp, removed from all read endpoints, related face/liveness/face-match records soft-deleted, and all stored media moved to a quarantined storage prefix by a background job so previously issued media URLs stop resolving. Database records are retained internally but become unreachable through the API; blocklist entries are **not** removed; no webhook is emitted; there is no undo.

**Selection semantics:**
- Entries in `session_numbers` that do not match a live KYC session in your application — unknown numbers, already-deleted sessions, or sessions owned by another application — are **silently skipped**. There is no per-item failure report: the endpoint returns `204` whether it deleted all, some, or none of the listed sessions.
- Validation failures (a non-numeric entry, an empty list, or neither `session_numbers` nor `delete_all` provided) reject the **whole request** with `400` and delete nothing.
- All deletions run inside a single database transaction.
- There is no documented cap on the list length; the shared write rate limit (below) is the practical bound.

**Idempotency:** fully idempotent — repeating the same request returns `204` again (already-deleted numbers are skipped).

**`delete_all: true` — destructive:** soft-deletes **every** non-deleted KYC session in the application; `session_numbers` is ignored when set. There is no confirmation step and no undo.

**Authentication:** API key in the `x-api-key` header. Missing or invalid credentials return `403` (`{"detail": "You do not have permission to perform this action."}`) — this API never returns `401`.

**Rate limit:** shared write budget of 300 requests/min per API key across all POST/PATCH/DELETE endpoints; exceeding it returns `429`.

This endpoint accepts API keys only — Business Console user Bearer tokens are rejected with `403` (unlike the single-session delete, which accepts both).

export const AgentPromptAccordion = ({prompt, title = "AI Agent Integration Prompt"}) => {
  const [copied, setCopied] = React.useState(false);
  const handleCopy = e => {
    e.stopPropagation();
    if (!prompt) return;
    navigator.clipboard.writeText(prompt.trim()).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    });
  };
  const agents = ["Claude Code", "Codex", "Cursor", "Devin", "Windsurf", "GitHub Copilot"];
  return <div className="didit-agent-card">
      {}
      <div className="didit-agent-titlebar">
        <div className="didit-agent-dots" aria-hidden="true">
          <span className="didit-agent-dot didit-agent-dot-red"></span>
          <span className="didit-agent-dot didit-agent-dot-yellow"></span>
          <span className="didit-agent-dot didit-agent-dot-green"></span>
        </div>
        <span className="didit-agent-filename">{title}</span>
        <button type="button" className={`didit-agent-copy ${copied ? "didit-agent-copy-copied" : ""}`} onClick={handleCopy} title="Copy prompt to clipboard" aria-label={copied ? "Copied!" : "Copy prompt to clipboard"}>
          {copied ? <>
              <svg width="13" height="13" viewBox="0 0 16 16" fill="none">
                <path d="M3 8.5l3.5 3.5L13 4" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
              <span>Copied</span>
            </> : <>
              <svg width="13" height="13" viewBox="0 0 16 16" fill="none">
                <rect x="5" y="5" width="9" height="9" rx="1.5" stroke="currentColor" strokeWidth="1.5" />
                <path d="M11 5V3.5A1.5 1.5 0 0 0 9.5 2h-6A1.5 1.5 0 0 0 2 3.5v6A1.5 1.5 0 0 0 3.5 11H5" stroke="currentColor" strokeWidth="1.5" />
              </svg>
              <span>Copy</span>
            </>}
        </button>
      </div>

      {}
      <pre className="didit-agent-body"><code>{prompt.trim()}</code></pre>

      {}
      <div className="didit-agent-footer">
        <span className="didit-agent-footer-label">Paste into</span>
        <div className="didit-agent-chips">
          {agents.map(name => <span key={name} className="didit-agent-chip">{name}</span>)}
        </div>
      </div>
    </div>;
};

<AgentPromptAccordion
  title="Batch Delete Sessions Prompt"
  prompt={`Goal: Soft-delete a list of User Verification (KYC) sessions, or every session, for the calling application. KYC only (Session table) — KYB sessions are not covered here; use DELETE /v3/session/{sessionId}/delete/ for a single KYB or KYC session.

Endpoint: POST https://verification.didit.me/v3/sessions/delete/
Auth header: x-api-key: YOUR_API_KEY
Content-Type: application/json

Request body — provide EXACTLY ONE selector:
- session_numbers: string[] — UI-visible decimal session numbers ("#1234" style), NOT UUIDs. Each entry must be digits only (regex ^[0-9]+$). minItems: 1.
- delete_all: true — soft-delete every non-deleted KYC session for the application. When delete_all is true, session_numbers is ignored.

curl:
curl -X POST 'https://verification.didit.me/v3/sessions/delete/' \\
-H "x-api-key: YOUR_API_KEY" \\
-H 'Content-Type: application/json' \\
-d '{"session_numbers": ["1001", "1002", "1003"]}'

Response 204: empty body. Sessions soft-deleted.

Side effects:
- Each matched row flagged with deleted_at (SOFT delete — not hard).
- The session and its KYC / Face / AML / Location / POA / Phone / Email child rows and activity logs stop appearing in GET /v3/sessions/ and GET /v3/session/{sessionId}/decision/.
- Hosted-flow share tokens and webhook deliveries already in flight are NOT revoked.
- NO deletion webhook is emitted.
- Wrapped in @transaction.atomic — if any row fails, none persist.

Idempotency: re-running with the same session_numbers produces the same outcome (already-deleted rows are filtered out of the queryset). There is no undo.

Failure modes:
- 400 — validation:
{ "session_numbers": "This field is required unless delete_all is true." }
{ "session_numbers": "All session_numbers must be numeric." }
- 401 — missing/invalid \`x-api-key\` header. { "detail": "Authentication credentials were not provided." }
- 403 — API key valid but application not allowed. { "detail": "You do not have permission to perform this action." }

For end-to-end Didit integration, paste in the full prompt at /integration/integration-prompt.`}
/>


## OpenAPI

````yaml POST /v3/sessions/delete/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: Identity verification API. Authenticate with x-api-key header.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/sessions/delete/:
    post:
      tags:
        - Sessions
      summary: Bulk soft-delete KYC sessions by session_number
      description: >-
        Bulk soft-delete User Verification (KYC) sessions by their numeric
        `session_number`, or wipe every KYC session in your application with
        `delete_all: true`.


        `session_number` is the human-friendly incrementing counter shown in the
        Console session list and returned as `session_number` by the
        create-session and decision endpoints — it is **not** the `session_id`
        UUID. To delete a session by UUID — or to delete a Business Verification
        (KYB) session, which this endpoint never touches — use `DELETE
        /v3/session/{sessionId}/delete/` instead.


        Each deleted session gets exactly the same treatment as the
        single-session delete endpoint: stamped with a deletion timestamp,
        removed from all read endpoints, related face/liveness/face-match
        records soft-deleted, and all stored media moved to a quarantined
        storage prefix by a background job so previously issued media URLs stop
        resolving. Database records are retained internally but become
        unreachable through the API; blocklist entries are **not** removed; no
        webhook is emitted; there is no undo.


        **Selection semantics:**

        - Entries in `session_numbers` that do not match a live KYC session in
        your application — unknown numbers, already-deleted sessions, or
        sessions owned by another application — are **silently skipped**. There
        is no per-item failure report: the endpoint returns `204` whether it
        deleted all, some, or none of the listed sessions.

        - Validation failures (a non-numeric entry, an empty list, or neither
        `session_numbers` nor `delete_all` provided) reject the **whole
        request** with `400` and delete nothing.

        - All deletions run inside a single database transaction.

        - There is no documented cap on the list length; the shared write rate
        limit (below) is the practical bound.


        **Idempotency:** fully idempotent — repeating the same request returns
        `204` again (already-deleted numbers are skipped).


        **`delete_all: true` — destructive:** soft-deletes **every** non-deleted
        KYC session in the application; `session_numbers` is ignored when set.
        There is no confirmation step and no undo.


        **Authentication:** API key in the `x-api-key` header. Missing or
        invalid credentials return `403` (`{"detail": "You do not have
        permission to perform this action."}`) — this API never returns `401`.


        **Rate limit:** shared write budget of 300 requests/min per API key
        across all POST/PATCH/DELETE endpoints; exceeding it returns `429`.


        This endpoint accepts API keys only — Business Console user Bearer
        tokens are rejected with `403` (unlike the single-session delete, which
        accepts both).
      operationId: batch_delete_sessions
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                session_numbers:
                  type: array
                  description: >-
                    Numeric `session_number` values of the KYC sessions to
                    soft-delete, as digit-only strings (JSON numbers are also
                    accepted and coerced). Required unless `delete_all` is
                    `true`; an empty list returns `400`. Any non-digit entry
                    rejects the whole request with `400` (unless `delete_all` is
                    `true`, in which case validation is skipped and the entries
                    are ignored). Numbers that do not match a live session in
                    your application are silently skipped.
                  items:
                    type: string
                    pattern: ^[0-9]+$
                    example: '1001'
                  minItems: 1
                  example:
                    - '1001'
                    - '1002'
                    - '1003'
                delete_all:
                  type: boolean
                  description: >-
                    When `true`, every non-deleted KYC session in the calling
                    application is soft-deleted and `session_numbers` is
                    ignored. Defaults to `false`. Irreversible — there is no
                    confirmation step.
                  default: false
                  example: false
            examples:
              Specific sessions:
                summary: Delete specific sessions by number
                value:
                  session_numbers:
                    - '1001'
                    - '1002'
                    - '1003'
              All sessions:
                summary: Delete every KYC session in the application
                value:
                  delete_all: true
      responses:
        '204':
          description: >-
            Request accepted and all matching sessions soft-deleted. Empty body.
            Returned even when some or all `session_numbers` matched nothing
            (unknown or already deleted) — there is no per-item report.
        '400':
          description: >-
            Validation error — nothing was deleted. Error values are arrays of
            message strings keyed by field name.
          content:
            application/json:
              schema:
                type: object
                properties:
                  session_numbers:
                    type: array
                    items:
                      type: string
              examples:
                Missing selector:
                  summary: Neither session_numbers nor delete_all provided
                  value:
                    session_numbers:
                      - This field is required unless delete_all is true.
                Empty list:
                  summary: session_numbers is an empty array
                  value:
                    session_numbers:
                      - This list may not be empty.
                Non-numeric entry:
                  summary: session_numbers contains a non-digit string
                  value:
                    session_numbers:
                      - All session_numbers must be numeric.
        '403':
          description: >-
            Missing or invalid API key. This API returns `403` for
            authentication failures — never `401`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
              examples:
                Missing or invalid API key:
                  summary: No x-api-key header, or the key is invalid
                  value:
                    detail: You do not have permission to perform this action.
        '429':
          description: >-
            Shared write rate limit exceeded (300 POST/PATCH/DELETE requests per
            minute per API key). Inspect `Retry-After` and the `X-RateLimit-*`
            response headers before retrying.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
              examples:
                Rate limited:
                  summary: Write budget exhausted
                  value:
                    detail: >-
                      Write request rate limit exceeded. You can make up to 300
                      requests per minute.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl -X POST \
              https://verification.didit.me/v3/sessions/delete/ \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "session_numbers": ["1001", "1002", "1003"]
              }'
        - lang: python
          label: Python
          source: >-
            import requests


            response = requests.post(
                "https://verification.didit.me/v3/sessions/delete/",
                headers={
                    "x-api-key": "YOUR_API_KEY",
                    "Content-Type": "application/json",
                },
                json={"session_numbers": ["1001", "1002", "1003"]},
            )

            response.raise_for_status()  # 204 on success, even if some numbers
            matched nothing


            # Destructive: delete every KYC session in the application

            # requests.post(

            #     "https://verification.didit.me/v3/sessions/delete/",

            #     headers={"x-api-key": "YOUR_API_KEY"},

            #     json={"delete_all": True},

            # )
        - lang: javascript
          label: JavaScript
          source: >-
            const response = await fetch(
              'https://verification.didit.me/v3/sessions/delete/',
              {
                method: 'POST',
                headers: {
                  'x-api-key': 'YOUR_API_KEY',
                  'Content-Type': 'application/json',
                },
                body: JSON.stringify({ session_numbers: ['1001', '1002', '1003'] }),
              },
            );

            if (response.status !== 204) throw new Error(`HTTP
            ${response.status}`);
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````