> ## 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.

# List Session Webhook Deliveries

> List every webhook Didit sent for a verification session, with the URL, your endpoint's answer, and the exact headers and payload.



List Session Webhook Deliveries API Prompt
        Copy prompt to clipboard



      
      

\<pre>

\`List every webhook delivery Didit recorded for one verification session through the API.

Endpoint:
GET https://verification.didit.me/v3/session/{session_id}/webhooks/

Authentication:
Send my Didit API key in the x-api-key header. A scoped key needs sessions: read and decisions: read.

Goal:
\- See which webhooks Didit sent for a session, to which URL, and what my endpoint answered. Use it to debug a missing or rejected webhook, or to reconcile my records with Didit's.

Behavior:
\- Works for user (KYC) and business (KYB) session IDs.
\- Returns a JSON array, newest first. It is not paginated. An empty array means no webhook was sent for the session yet.
\- Each entry is one delivery attempt to one destination. The first delivery, each automatic retry and each manual resend are separate entries with their own uuid; retries and resends keep the payload's event_id.
\- request_header and request_body are JSON-encoded strings. Parse them with a JSON parser to read the headers and the payload.
\- A scoped key without media: read receives media URLs inside request_body as null; without sessions: write it receives session links and tokens as null. A redacted body no longer matches the recorded signatures.

Example call:
curl -X GET "https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/webhooks/" \
-H "x-api-key: YOUR_API_KEY"

What to read from the response:
\- uuid: the delivery id. Use it as {webhook_uuid} to get or resend one delivery.
\- webhook_type: status.updated or data.updated for session deliveries.
\- status: the session status when the event was generated.
\- response_status: the HTTP status my endpoint returned. null while the delivery is queued; 504 means a timeout (5 seconds), 503 a connection failure, 400 a URL refused as unsafe.
\- request_url and created_at: where and when it was sent.

Failure modes:
\- 401: the API key has expired.
\- 403: missing or invalid key ({ "detail": "Authentication credentials were not provided or are invalid." }), a key of another application, a scoped key without the permissions above, or a request from outside the key's IP allowlist.
\- 404: the session does not exist or was deleted ({ "detail": "Not found." }), or is outside a scoped key's workflow or status limits ({ "detail": "Session not found." }).
\- 429: more than 600 reads per minute for this API key; honor Retry-After.

Side effects: none. This is a pure read.

For the full integration shape, see /integration/integration-prompt.`

\</pre>



      
      

Paste into

Every attempt is logged, including the [automatic retries](/integration/webhooks.md#retry-policy) Didit makes after a `5xx` or `404` answer, so a failed delivery followed by a successful retry shows up as two entries with the same `event_id` inside `request_body`.To inspect one delivery, use [Get session webhook delivery](/management-api/sessions/get-webhook.md). To send one again after fixing your endpoint, use [Resend session webhook delivery](/management-api/sessions/resend-webhook.md).


## OpenAPI

````yaml GET /v3/session/{sessionId}/webhooks/
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/session/{sessionId}/webhooks/:
    get:
      tags:
        - Sessions
      summary: List session webhook deliveries
      description: >-
        List every webhook delivery Didit recorded for one verification session,
        user (KYC) or business (KYB), newest first, as a plain JSON array (not
        paginated). Each entry is one attempt to one destination: the first
        send, each automatic
        [retry](https://docs.didit.me/integration/webhooks#retry-policy) and
        each resend are separate entries with their own `uuid`, and retries and
        resends keep the payload's `event_id`. `request_header` and
        `request_body` are JSON text; parse them to read the signatures and the
        payload. Delivery records are available for about 30 days, so an empty
        array means no webhook has been sent for the session yet or every
        delivery is older than that. A scoped API key needs `sessions: read` and
        `decisions: read`.
      operationId: get_v3_session_webhooks
      parameters:
        - name: sessionId
          in: path
          required: true
          description: >-
            UUID of the verification session, user (KYC) or business (KYB): the
            `session_id` returned by `POST /v3/session/`. The server resolves it
            against both session types.


            **Must be a valid UUID.** The route only matches well-formed UUIDs,
            so a malformed value is rejected by the URL router before any
            application code runs and the response is a `404` **HTML** page
            rather than the JSON `{"detail": ...}` envelope shown below.
          schema:
            type: string
            format: uuid
          example: 22222222-3333-4444-5555-666666666666
      responses:
        '200':
          description: Every delivery recorded for the session, newest first.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SessionWebhookDelivery'
              examples:
                Failed delivery and its successful retry:
                  value:
                    - uuid: 66666666-7777-8888-9999-000000000002
                      session_id: 22222222-3333-4444-5555-666666666666
                      request_url: https://yourapp.com/webhooks/didit
                      response_status: 200
                      status: In Progress
                      webhook_type: status.updated
                      request_header: >-
                        {"Content-Type": "application/json", "X-Signature":
                        "9188851d160b5b3aacfc946e4dde1f061b7e568662518942c927ddaf507f533d",
                        "X-Signature-V2":
                        "381236af514d3fb538579365ac5a24f2464ce1b8224c6e770c60d8201c43ecc5",
                        "X-Signature-Simple":
                        "4740131dc38f29e78a8508371979be74967d5307464494bd3148a03b4d6c8716",
                        "X-Timestamp": "1792056139", "User-Agent":
                        "DiditWebhook/2.0 +https://didit.me"}
                      request_body: >-
                        {"application_id":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee","created_at":1792056057,"environment":"live","event_id":"33333333-4444-5555-6666-777777777777","sandbox_scenario":null,"session_id":"22222222-3333-4444-5555-666666666666","status":"In
                        Progress","timestamp":1792056139,"vendor_data":"user-123","webhook_type":"status.updated","workflow_id":"44444444-5555-6666-7777-888888888888","workflow_version":3}
                      created_at: '2026-10-15T09:22:19.104233Z'
                    - uuid: 66666666-7777-8888-9999-000000000001
                      session_id: 22222222-3333-4444-5555-666666666666
                      request_url: https://yourapp.com/webhooks/didit
                      response_status: 503
                      status: In Progress
                      webhook_type: status.updated
                      request_header: >-
                        {"Content-Type": "application/json", "X-Signature":
                        "a5e02a03404e1337a0198e6be15d34abbd053c658a0e51e5d0e78554213ef29b",
                        "X-Signature-V2":
                        "927e7cb770c94ce745939bff73f04aa200015f3bc64795ba46c2aaf78a6cedc5",
                        "X-Signature-Simple":
                        "e37b0d4c716c72bb5ae7127b9cc455d28ab4686e9e22312b4ec2327409a73302",
                        "X-Timestamp": "1792056078", "User-Agent":
                        "DiditWebhook/2.0 +https://didit.me"}
                      request_body: >-
                        {"application_id":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee","created_at":1792056057,"environment":"live","event_id":"33333333-4444-5555-6666-777777777777","sandbox_scenario":null,"session_id":"22222222-3333-4444-5555-666666666666","status":"In
                        Progress","timestamp":1792056078,"vendor_data":"user-123","webhook_type":"status.updated","workflow_id":"44444444-5555-6666-7777-888888888888","workflow_version":3}
                      created_at: '2026-10-15T09:21:18.412345Z'
                No webhook sent yet:
                  value: []
        '401':
          description: >-
            The API key has expired: it was created with an expiry date that has
            passed. A missing, invalid or revoked key gets `403`, not `401`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: Human-readable error message.
              examples:
                Expired key:
                  value:
                    detail: This API key has expired.
        '403':
          description: >-
            The request is not allowed. No `x-api-key`, or an invalid or revoked
            key, gets `Authentication credentials were not provided or are
            invalid.` A key of another application gets `You do not have
            permission to perform this action.` A scoped key without the access
            this endpoint needs gets a message naming the missing access, and a
            key used from outside its IP allowlist gets `This API key can't be
            used from this IP address.` An unknown `sessionId` returns `404`
            before the credential is checked.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: Human-readable error message.
              examples:
                Missing or invalid key:
                  value:
                    detail: >-
                      Authentication credentials were not provided or are
                      invalid.
                Key of another application:
                  value:
                    detail: You do not have permission to perform this action.
                Scoped key without sessions read:
                  value:
                    detail: This API key has no read access to sessions.
                Scoped key without decisions read:
                  value:
                    detail: This API key has no read access to decisions.
                Outside the IP allowlist:
                  value:
                    detail: This API key can't be used from this IP address.
        '404':
          description: >-
            The session does not exist or has been deleted (`Not found.`,
            returned before the credential is checked), or it is outside the
            workflow or status limits of a scoped key (`Session not found.`).
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: Human-readable error message.
              examples:
                Unknown session:
                  value:
                    detail: Not found.
                Outside the key's limits:
                  value:
                    detail: Session not found.
        '429':
          description: >-
            Rate limit exceeded: more than 600 GET requests in the current
            one-minute window for this API key. Wait `Retry-After` seconds
            before retrying.
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
                minimum: 1
                example: 30
            X-RateLimit-Limit:
              description: Requests allowed in the one-minute window (600).
              schema:
                type: integer
                example: 600
            X-RateLimit-Remaining:
              description: Requests left in the current window.
              schema:
                type: integer
                example: 0
            X-RateLimit-Reset:
              description: Unix time (seconds) when the current window resets.
              schema:
                type: integer
                example: 1792056120
            X-RateLimit-Scope:
              description: Name of the budget that was exceeded.
              schema:
                type: string
                example: generic-get
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: Human-readable error message.
              examples:
                Throttled:
                  value:
                    detail: >-
                      GET request rate limit exceeded. You can make up to 600
                      requests per minute.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: >-
            curl -X GET
            'https://verification.didit.me/v3/session/22222222-3333-4444-5555-666666666666/webhooks/'
            \
              -H 'x-api-key: YOUR_API_KEY'
        - lang: python
          label: Python
          source: |-
            import json
            import os

            import requests

            session_id = '22222222-3333-4444-5555-666666666666'
            resp = requests.get(
                f'https://verification.didit.me/v3/session/{session_id}/webhooks/',
                headers={'x-api-key': os.environ['DIDIT_API_KEY']},
                timeout=10,
            )
            resp.raise_for_status()
            for delivery in resp.json():
                payload = json.loads(delivery['request_body'])
                print(delivery['created_at'], delivery['webhook_type'], delivery['response_status'], payload['event_id'])
        - lang: javascript
          label: JavaScript
          source: >-
            const sessionId = '22222222-3333-4444-5555-666666666666';

            const resp = await
            fetch(`https://verification.didit.me/v3/session/${sessionId}/webhooks/`,
            {
              headers: { 'x-api-key': process.env.DIDIT_API_KEY },
            });

            if (!resp.ok) throw new Error(`Request failed: ${resp.status}`);

            const deliveries = await resp.json();

            for (const delivery of deliveries) {
              const payload = JSON.parse(delivery.request_body);
              console.log(delivery.created_at, delivery.webhook_type, delivery.response_status, payload.event_id);
            }
components:
  schemas:
    SessionWebhookDelivery:
      type: object
      description: >-
        One webhook delivery attempt recorded for a verification session, with
        the exact request headers and body Didit sent.
      required:
        - uuid
        - session_id
        - request_url
        - response_status
        - status
        - webhook_type
        - request_header
        - request_body
        - created_at
      properties:
        uuid:
          type: string
          format: uuid
          description: >-
            Delivery ID. Use it as `{webhook_uuid}` to get or resend this
            delivery.
        session_id:
          type: string
          format: uuid
          description: The session the delivery belongs to (the session in the path).
        request_url:
          type: string
          format: uri
          nullable: true
          description: URL the delivery was sent to.
        response_status:
          type: integer
          nullable: true
          description: >-
            HTTP status your endpoint returned. `null` while the delivery is
            queued and not yet attempted. When no HTTP answer was received Didit
            records a status of its own: `504` when your endpoint did not answer
            within 5 seconds, `503` for a connection failure, `400` when the URL
            was refused as unsafe (for example a private or internal address),
            and `404` for any other request error. `400` or above counts as a
            failed delivery.
        status:
          type: string
          nullable: true
          description: >-
            Session status when the event was generated, for example `In
            Progress`, `Approved` or `Declined`.
        webhook_type:
          $ref: '#/components/schemas/WebhookEvent'
        request_header:
          type: string
          description: >-
            JSON text (a string) of the request headers Didit sent:
            `Content-Type`, `X-Signature`, `X-Signature-V2`,
            `X-Signature-Simple`, `X-Timestamp` and `User-Agent`. Parse it with
            a JSON parser. It holds signatures, never the signing secret.
        request_body:
          type: string
          description: >-
            JSON text (a string) of the exact payload Didit sent, keys sorted,
            including `event_id` and `timestamp`. Parse it with a JSON parser;
            see [Payload
            shape](https://docs.didit.me/integration/webhooks#payload-shape).
            For a scoped key without `media: read`, media URLs inside it are
            `null`; without `sessions: write`, session tokens and hosted
            verification links are `null`. A body changed that way no longer
            matches its signatures. Didit does not record the response body your
            endpoint returned.
        created_at:
          type: string
          format: date-time
          description: When the delivery was created.
    WebhookEvent:
      type: string
      description: >-
        Supported webhook event name. Use these exact strings in
        `subscribed_events`; unsupported values are rejected.
      enum:
        - status.updated
        - data.updated
        - user.status.updated
        - user.data.updated
        - business.status.updated
        - business.data.updated
        - activity.created
        - transaction.created
        - transaction.status.updated
        - travel_rule.status.updated
        - workflow.compliance_changed
        - auth.signup
        - auth.login
        - auth.login_failed
        - auth.password_reset_requested
        - auth.password_reset_completed
        - auth.mfa_changed
        - auth.new_device
        - auth.account_locked
        - investigator.report.ready
        - investigator.decision.automated
        - investigator.decision.overridden
        - investigator.decision.contested
        - investigator.question.raised
        - investigator.automation.paused
        - investigator.rfi.answered
        - investigator.rfi.overdue
        - investigator.drift.detected
        - investigator.sla.breached
        - investigator.qa.failed
        - investigator.external.report.ready
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Your application's API key, from Developers -> API keys in the Business
        Console. The primary key has full access. A named key can be scoped:
        none, read or write per resource, limited to some workflows or to
        approved sessions, to a list of IP addresses, and to an expiry date. 401
        means the key is missing, wrong, revoked or expired; 403 means the key
        has no access to this resource or action, or the request came from an
        address outside its IP list; 404 on a session route means the session is
        outside the key's workflows or statuses. A key without media access
        receives image, video and PDF URLs as null, and a key without sessions
        write receives session links and tokens as null. See
        https://docs.didit.me/console/api-keys.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.