## Retry a pending webhook delivery now

**post** `/v1/webhook_deliveries/{delivery}/retry`

Pulls a pending delivery's next attempt forward to now, so a receiver
that was down — or not yet deployed — gets its retry immediately
instead of at the end of the backoff. The delivery is otherwise
untouched: the same event, the same payload, the same position in its
endpoint-and-chat order. Later deliveries to the same endpoint and chat
wait behind it, so pulling the delivery at the head of the line forward
and having it succeed releases the rest. A message that is waiting for
its attachments has no delivery yet, so there is nothing to pull forward
until it is recorded.

**The attempt this triggers is an ordinary one, and it is not free.**
Every delivery gets at most nine attempts; the one you pull forward
spends one of them, and a failure schedules the next attempt on the
same backoff as before, from the same attempt number. Pulling forward
against a receiver that is still down therefore only spends the bounded
attempts faster. Once the last attempt fails the delivery leaves live
delivery as `retry_exhausted`, later deliveries in its line proceed, and
only a replay (`POST /v1/webhook_endpoints/{endpoint}/replays`) can send
its event.

Answers `200` with the delivery as `GET /v1/webhook_deliveries` renders
it. A `pending` delivery whose `next_attempt_at` is already at or
before now is answered `200` unchanged — pulling forward what is
already due is a no-op, not an error — so read `next_attempt_at` to tell
the two apart. A `delivering` delivery answers
`409 webhook_delivery_in_progress`: an attempt is on the wire and its
result decides the next timer. A `delivered`, `permanent_refusal` or
`retry_exhausted` delivery answers `409 webhook_delivery_terminal` with
the state in the message. An unknown delivery, or one belonging to
another account or partition, answers `404 webhook_delivery_not_found`.

### Path Parameters

- `delivery: string`

### Returns

- `Delivery object { id, attempt_history_complete, attempts, 11 more }`

  One webhook delivery and every retained applied attempt belonging to it.

  - `id: string`

  - `attempt_history_complete: boolean`

    True only when every spent attempt has a retained applied verdict and collection covered this delivery from creation.

  - `attempts: array of DeliveryAttempt`

    - `attempt: number`

      The spent attempt number. Gaps mean a lease expired without an applied verdict.

    - `attempt_completed_at: string`

    - `attempt_started_at: string`

    - `destination: string`

      Scheme, host and effective port only. Path, query, fragment and credentials are never returned.

    - `http_status: number`

      Response status, or `null` when no response was received.

    - `phase: string`

      `pre_dial` when no request began, or `wire` after the HTTP round trip began.

    - `reason_code: string`

      A bounded machine reason. Treat unknown values as `unknown`.

    - `verdict: string`

      `delivered`, `retryable`, or `permanent`. Treat unknown values as an unavailable verdict.

    - `wire_completed_at: string`

    - `wire_duration_ms: number`

    - `wire_started_at: string`

    - `trace_id: optional string`

      W3C trace id when one was recorded. Correlation only; never authorization.

  - `created_at: string`

  - `endpoint_id: string`

  - `event_id: string`

  - `event_kind: string`

  - `observed_attempt_count: number`

    Applied attempt verdicts retained below.

  - `seq_from: number`

  - `seq_to: number`

  - `spent_attempt_count: number`

    Attempts spent by the delivery machine, including leases that expired without an applied verdict.

  - `state: string`

    `pending`, `delivering`, `delivered`, `permanent_refusal`, or `retry_exhausted`.

  - `chat_id: optional string`

  - `next_attempt_at: optional string`

    Present only while `state` is `pending`: the instant the next attempt
    becomes due. A value in the future is a delivery backing off after a
    failed attempt; a value at or before now is a delivery that is due and
    waiting — usually behind an earlier delivery to the same endpoint and
    chat. Deliveries to one endpoint and chat are sent in the order their
    events were recorded. A `message.received` for a message carrying
    attachments can be recorded once every attachment has been captured or has
    failed, or ten minutes after the message arrived. It can therefore
    follow deliveries for later messages of the same chat, and carry a lower
    `data.seq_from` than an event you already received: `seq_from` can
    decrease relative to arrival. Never discard such an event as stale:
    deduplicate by the event `id`, order a conversation by `data.seq_from`,
    and for live processing buffer briefly or reconcile with
    `GET /v1/chats/{chat}/events`. `POST /v1/webhook_deliveries/{delivery}/retry`
    moves a future value to now.

### Example

```http
curl https://whatsapp.messages.api.linqapp.com/v1/webhook_deliveries/$DELIVERY/retry \
    -X POST \
    -H "Authorization: Bearer $LINQ_WHATSAPP_API_KEY"
```

#### Response

```json
{
  "id": "id",
  "attempt_history_complete": true,
  "attempts": [
    {
      "attempt": 0,
      "attempt_completed_at": "2019-12-27T18:11:19.117Z",
      "attempt_started_at": "2019-12-27T18:11:19.117Z",
      "destination": "destination",
      "http_status": 0,
      "phase": "phase",
      "reason_code": "reason_code",
      "verdict": "verdict",
      "wire_completed_at": "2019-12-27T18:11:19.117Z",
      "wire_duration_ms": 0,
      "wire_started_at": "2019-12-27T18:11:19.117Z",
      "trace_id": "trace_id"
    }
  ],
  "created_at": "2019-12-27T18:11:19.117Z",
  "endpoint_id": "endpoint_id",
  "event_id": "event_id",
  "event_kind": "event_kind",
  "observed_attempt_count": 0,
  "seq_from": 0,
  "seq_to": 0,
  "spent_attempt_count": 0,
  "state": "state",
  "chat_id": "chat_id",
  "next_attempt_at": "2019-12-27T18:11:19.117Z"
}
```
