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

# Delivery & Signing

> HTTP headers, signature verification, retries, ordering, and dashboard test requests.

| Property | Actions 1–7 | Actions 8–9 |
| - | - | - |
| HTTP method / content type | POST / `application/json` | POST / `application/json` |
| Body | Bare object; no outer `data` wrapper | `{event, id, occurred_at, data}` |
| Timing | Inline synchronous delivery | Queued after database commit |
| Attempts | Single attempt; no automatic retry in this path | Up to 3 attempts; backoff 10 seconds, then 60 seconds |
| Request time limits | Uses client defaults; no per-call override in live legacy path | 5-second request timeout; 3-second connection timeout |
| Event header | Absent | `X-WeGive-Event` |
| Delivery identifier | No generic delivery ID | `X-WeGive-Delivery`; equals body `id`, stable across retries |
| Signature | `X-WeGive-Signature` when subscription has a secret | Same |

Session retries retain byte-identical JSON and the same delivery ID; each attempt receives a fresh signature timestamp. Non-2xx responses and connection failures enter the retry path. Delivery ordering is not guaranteed. A removed subscription is skipped by a queued job. Failures are reported without failing the originating model operation; retries are bounded rather than durable indefinite delivery.

The session delivery ID identifies **one delivery for one subscription**. Two subscriptions receiving the same underlying session event get separate IDs. Use the session UUID plus event type for business-level deduplication, and delivery ID for retry deduplication. Legacy payload `id` is a record ID, not an event ID: dropping every repeated transaction ID would also drop legitimate updates.

## Signature contract

```text theme={null}
X-WeGive-Signature: t=<unix_seconds>,v1=<hex_digest>
hex_digest = HMAC-SHA256(signing_secret, "<unix_seconds>.<exact_raw_request_body>")
```

Verify the exact raw request bytes before reformatting/parsing them; compare digests in constant time. The reference verifier accepts timestamps within 300 seconds of the receiver’s clock (past or future). Each subscription has its own secret, revealed on creation/rotation. Rotation replaces the old secret immediately. Legacy subscriptions with no secret send no signature until a secret is generated. The signing secret is not part of the delivered JSON body.

## Dashboard test requests

The released **Test** action sends an actual HTTP request with `X-WeGive-Test: true`; receivers should separate these from business counts. Actions 1–7 use a recent renderable record from the organization, so test requests can contain real contact data. Actions 8–9 use a synthetic session sample, a fresh delivery UUID, and current `occurred_at`, with the same event/delivery headers as live requests. Tests use a 5-second timeout and 3-second connection timeout and are a single immediate attempt. A static View sample/API sample response is distinct from a real delivery.

The subscription-management API’s `id`, `event_type`, `target_url`, `has_signing_secret`, and reveal-once `signing_secret` describe the **subscription**, not fields automatically added to webhook bodies.


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