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

# Resend Webhook Destination Delivery

> Send a past webhook delivery to your endpoint again, freshly signed, and get the new attempt with the HTTP status your endpoint returned.



Resend Webhook Destination Delivery API Prompt
        Copy prompt to clipboard



      
      

\<pre>

\`Resend a past Didit webhook delivery to my endpoint through the Management API.

Endpoint:
POST https://verification.didit.me/v3/webhook/destinations/{destination_uuid}/deliveries/{delivery_uuid}/resend/

Authentication:
Use the x-api-key header with my Didit API key. A scoped API key needs webhooks: write and decisions: read. A key limited to some workflows or to approved sessions cannot use this endpoint.

Goal:
\- Recover webhooks my endpoint missed (for example during an outage) by sending them again once the endpoint is fixed.

Path parameters:
\- destination_uuid: the destination uuid from GET /v3/webhook/destinations/.
\- delivery_uuid: the uuid of the delivery to resend, from GET /v3/webhook/destinations/{destination_uuid}/deliveries/.

Behavior:
\- No request body.
\- Didit takes the stored payload, sets a fresh timestamp, signs it again with the destination's current secret_shared_key (X-Signature, X-Signature-V2, X-Signature-Simple and X-Timestamp) and POSTs it to the URL the original delivery went to (request_url), even if the destination URL changed since or the destination is disabled.
\- event_id and the rest of the payload are unchanged, so deduplicate on event_id in my endpoint.
\- The call waits for my endpoint (up to 5 seconds) and returns 200 with the new delivery whatever my endpoint answered. Check response_status in the response: 2xx means accepted, 504 a timeout, 503 a connection failure.
\- One attempt only: a resend is not retried automatically. Every call sends again and creates a new delivery with its own uuid; the original delivery is unchanged.
\- The response is redacted like GET delivery for scoped keys (media URLs, session tokens and hosted links as null); my endpoint still receives the full payload.

Example call:
curl -X POST "https://verification.didit.me/v3/webhook/destinations/{destination_uuid}/deliveries/{delivery_uuid}/resend/" \
-H "x-api-key: YOUR_API_KEY"

Failure modes:
\- 400: { "detail": "Invalid webhook data format", "code": "invalid_webhook_payload" } when the stored delivery cannot be signed again. Nothing is sent.
\- 401: { "detail": "This API key has expired." }
\- 403: { "detail": "You do not have permission to perform this action." }, { "detail": "This API key has no write access to webhooks." }, { "detail": "This API key has no read access to decisions." }, or the limited-key message.
\- 404: { "detail": "Webhook destination not found." } or { "detail": "Webhook delivery not found." }
\- 429: more than 300 write requests per minute with this key; wait for Retry-After.

Side effects:
\- My endpoint receives the webhook again, and a new delivery appears in the destination's deliveries and analytics.

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

\</pre>



      
      

Paste into

> [!WARNING]
>
> Each call delivers the webhook again. Make your endpoint idempotent on `event_id` before you resend in bulk, and resend only deliveries whose `response_status` is `null`, `400` or above.A resend goes to the URL the original delivery used. If you moved the destination to a new URL, the old deliveries still point at the old one. Find the deliveries to resend with [List Webhook Destination Deliveries](/management-api/webhook/list-deliveries.md), and see the [webhooks guide](/integration/webhooks.md) for signature verification.


## OpenAPI

````yaml POST /v3/webhook/destinations/{destination_uuid}/deliveries/{delivery_uuid}/resend/
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/webhook/destinations/{destination_uuid}/deliveries/{delivery_uuid}/resend/:
    post:
      tags:
        - Webhook
      summary: Resend webhook destination delivery
      description: >-
        Send a past delivery again, for example after your endpoint was down.
        Didit takes the stored payload, sets a fresh `timestamp`, signs it again
        with the destination's current `secret_shared_key` (`X-Signature`,
        `X-Signature-V2`, `X-Signature-Simple` and `X-Timestamp`) and posts it
        to the delivery's `request_url`, even if the destination's URL has
        changed since or the destination is disabled. `event_id` and the rest of
        the payload are unchanged, so deduplicate on `event_id`. The call waits
        up to 5 seconds for your endpoint and returns the new delivery with
        `200` whatever your endpoint answered: read `response_status`. A resend
        is not retried automatically, every call sends again and creates a new
        delivery, and the request has no body. A scoped API key needs `webhooks:
        write` and `decisions: read`; a key limited to some workflows or to
        approved sessions cannot use this endpoint.
      operationId: resend_webhook_destination_delivery
      parameters:
        - name: destination_uuid
          in: path
          required: true
          description: UUID of the destination the delivery was sent to.
          schema:
            type: string
            format: uuid
          example: 11111111-2222-3333-4444-555555555555
        - name: delivery_uuid
          in: path
          required: true
          description: >-
            UUID of the delivery to resend: the `uuid` of an entry returned by
            `GET /v3/webhook/destinations/{destination_uuid}/deliveries/`.
          schema:
            type: string
            format: uuid
          example: 66666666-7777-8888-9999-000000000001
      responses:
        '200':
          description: >-
            The new delivery, already attempted. `response_status` is what your
            endpoint answered this time (`504` timeout, `503` connection
            failure). The original delivery is unchanged.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookDestinationDeliveryDetail'
              examples:
                Accepted on resend:
                  value:
                    uuid: 66666666-7777-8888-9999-000000000004
                    session_id: 22222222-3333-4444-5555-666666666666
                    request_url: https://yourapp.com/webhooks/didit
                    response_status: 200
                    response_time_ms: 151
                    status: In Progress
                    webhook_type: status.updated
                    created_at: '2026-10-16T14:05:42.330981Z'
                    request_header: >-
                      {"Content-Type": "application/json", "X-Signature":
                      "b8eb1e376517ee0cad8ba98ff7f8fd35fc72eca231000963a96a335f82328835",
                      "X-Signature-V2":
                      "9efd2ce9ed1303e1d05273ef9608a59363ed9789a05253db4748b3e8e50cb109",
                      "X-Signature-Simple":
                      "bf3a9dc04b2c20ab539203b0cd5cca2a10f630bf62d8feb6d68d82af80f64774",
                      "X-Timestamp": "1792159542", "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":1792159542,"vendor_data":"user-123","webhook_type":"status.updated","workflow_id":"44444444-5555-6666-7777-888888888888","workflow_version":3}
        '400':
          description: The stored delivery could not be signed again. Nothing is sent.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: Human-readable error message.
                  code:
                    type: string
                    description: >-
                      Stable machine-readable error code. Branch on this, not on
                      `detail`.
              examples:
                Unsignable delivery:
                  value:
                    detail: Invalid webhook data format
                    code: invalid_webhook_payload
        '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. A missing, invalid or revoked
            `x-api-key` 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.`
            A key limited to some workflows or to approved sessions gets `This
            API key only reaches sessions inside its workflow or status limits,
            so it can't use this endpoint.`
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: Human-readable error message.
              examples:
                Missing or invalid key:
                  value:
                    detail: You do not have permission to perform this action.
                Scoped key without webhooks write:
                  value:
                    detail: This API key has no write access to webhooks.
                Scoped key without decisions read:
                  value:
                    detail: This API key has no read access to decisions.
                Key limited to workflows or approved sessions:
                  value:
                    detail: >-
                      This API key only reaches sessions inside its workflow or
                      status limits, so it can't use this endpoint.
                Outside the IP allowlist:
                  value:
                    detail: This API key can't be used from this IP address.
        '404':
          description: >-
            The destination does not exist for the application or has been
            deleted, or the delivery does not exist, belongs to another
            destination, or is no longer available.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: Human-readable error message.
              examples:
                Destination not found:
                  value:
                    detail: Webhook destination not found.
                Delivery not found:
                  value:
                    detail: Webhook delivery not found.
        '429':
          description: >-
            Rate limit exceeded: more than 300 write requests (POST, PATCH, PUT,
            DELETE) 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 (300).
              schema:
                type: integer
                example: 300
            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-write
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    description: Human-readable error message.
              examples:
                Throttled:
                  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/webhook/destinations/11111111-2222-3333-4444-555555555555/deliveries/66666666-7777-8888-9999-000000000001/resend/'
            \
              -H 'x-api-key: YOUR_API_KEY'
        - lang: python
          label: Python
          source: >-
            import os


            import requests


            destination_uuid = '11111111-2222-3333-4444-555555555555'

            delivery_uuid = '66666666-7777-8888-9999-000000000001'

            resp = requests.post(
                f'https://verification.didit.me/v3/webhook/destinations/{destination_uuid}/deliveries/{delivery_uuid}/resend/',
                headers={'x-api-key': os.environ['DIDIT_API_KEY']},
                timeout=10,
            )

            resp.raise_for_status()

            resent = resp.json()

            if resent['response_status'] is None or resent['response_status'] >=
            400:
                print('Your endpoint still rejects it:', resent['response_status'])
            else:
                print('Delivered as', resent['uuid'])
        - lang: javascript
          label: JavaScript
          source: |-
            const destinationUuid = '11111111-2222-3333-4444-555555555555';
            const deliveryUuid = '66666666-7777-8888-9999-000000000001';
            const resp = await fetch(
              `https://verification.didit.me/v3/webhook/destinations/${destinationUuid}/deliveries/${deliveryUuid}/resend/`,
              { method: 'POST', headers: { 'x-api-key': process.env.DIDIT_API_KEY } },
            );
            if (!resp.ok) throw new Error(await resp.text());
            const resent = await resp.json();
            console.log(resent.uuid, resent.response_status);
components:
  schemas:
    WebhookDestinationDeliveryDetail:
      type: object
      description: >-
        One delivery attempt to a webhook destination, with the exact request
        headers and body Didit sent.
      required:
        - uuid
        - session_id
        - request_url
        - response_status
        - response_time_ms
        - status
        - webhook_type
        - created_at
        - request_header
        - request_body
      properties:
        uuid:
          type: string
          format: uuid
          description: Delivery ID, for the detail and resend calls.
        session_id:
          type: string
          format: uuid
          nullable: true
          description: >-
            User verification session the event is about. `null` for business
            session, user, business, transaction, Travel Rule and workflow
            events.
        request_url:
          type: string
          format: uri
          nullable: true
          description: >-
            URL the delivery was sent to: the destination's URL when the event
            was generated.
        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.
        response_time_ms:
          type: integer
          nullable: true
          minimum: 0
          description: >-
            Time the attempt took, in milliseconds. `null` while the delivery is
            queued.
        status:
          type: string
          nullable: true
          description: >-
            Status the event reported when it was generated: the session status
            for session events (for example `Approved` or `In Review`), the
            person's or company's status for user and business events, and the
            transaction status for transaction events. `null` for events that
            carry no status.
        webhook_type:
          $ref: '#/components/schemas/WebhookEvent'
        created_at:
          type: string
          format: date-time
          description: When the delivery was created.
        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.
    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.