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

# Webhooks

> Deliver raw event payloads to any HTTP endpoint for custom integrations, data warehouses, and internal systems.

<Note>
  **Data direction:** This is a **destination** — Upstack sends event and conversion data **out** to this platform via server-side APIs.
</Note>

## What it does

The webhook destination delivers Upstack events as JSON payloads to any HTTPS endpoint you control. Use it to feed data warehouses, trigger internal workflows, connect platforms Upstack does not support natively, or build custom integrations on top of Upstack's enriched event stream.

Every event Upstack captures — including identity-resolved customer data and attribution context — can be delivered to your endpoint in near real-time. Webhooks give you the same enriched event payload that powers Upstack's native destinations, with full schema control on your side.

## How it works

Webhook deliveries are HTTP POST requests with a JSON body. Upstack signs each request with HMAC-SHA256 using a per-destination signing secret, so your endpoint can verify the payload originated from Upstack and was not tampered with. Each delivery includes standard headers (`X-Upstack-Event-Id`, `X-Upstack-Event-Type`, `X-Upstack-Signature`, `X-Upstack-Timestamp`) for routing, deduplication, and signature verification.

Delivery is at-least-once with a 10-second timeout per attempt and up to 5 retries with exponential backoff (1s, 5s, 30s, 2m, 10m). Events are delivered in approximate chronological order, but strict ordering is not guaranteed — your endpoint should be idempotent and use the `event_id` to deduplicate.

## Setup guides

Webhook setup is configured directly in Upstack's destination settings — endpoint URL, event filter, headers, and signing secret. There are no platform-side credentials to provision.

<CardGroup cols={2}>
  <Card title="Standard events reference" icon="bolt" href="/data-dictionary/standard-events">
    Full reference for all event types and properties included in webhook payloads.
  </Card>

  <Card title="Properties and context" icon="list" href="/data-dictionary/properties-and-context">
    Complete list of event properties and context fields available in every payload.
  </Card>
</CardGroup>

## Payload format

Every webhook delivery is an HTTP POST with a JSON body that follows Upstack's standard event schema:

```json theme={null}
{
  "event_id": "evt_abc123def456",
  "event_type": "Purchase",
  "timestamp": "2026-02-18T14:32:01.000Z",
  "pixel_id": "px_your_pixel_id",
  "session_id": "sess_789xyz",
  "user": {
    "anonymous_id": "anon_456def",
    "customer_id": "cust_123abc",
    "email_hash": "sha256:a1b2c3...",
    "phone_hash": "sha256:d4e5f6..."
  },
  "properties": {
    "order_id": "1234",
    "value": 89.99,
    "currency": "USD",
    "items": [
      {
        "product_id": "prod_001",
        "title": "Classic T-Shirt",
        "variant_id": "var_001",
        "price": 29.99,
        "quantity": 3
      }
    ]
  },
  "context": {
    "page_url": "https://your-store.myshopify.com/checkout",
    "referrer": "https://www.google.com",
    "user_agent": "Mozilla/5.0...",
    "ip": "203.0.113.42",
    "utm_source": "google",
    "utm_medium": "cpc",
    "utm_campaign": "summer-sale"
  },
  "attribution": {
    "source": "google",
    "medium": "cpc",
    "campaign": "summer-sale",
    "click_ids": {
      "gclid": "abc123",
      "fbclid": null,
      "ttclid": null
    }
  }
}
```

PII fields (`email_hash`, `phone_hash`) are delivered as SHA-256 hashes by default. Raw (unhashed) PII delivery is available for endpoints you own and is subject to your data processing agreement.

### Delivery headers

| Header                 | Value              | Description                             |
| ---------------------- | ------------------ | --------------------------------------- |
| `Content-Type`         | `application/json` | Payload format                          |
| `X-Upstack-Event-Id`   | `evt_abc123...`    | Unique event ID for deduplication       |
| `X-Upstack-Event-Type` | `Purchase`         | Event type                              |
| `X-Upstack-Signature`  | `sha256=...`       | HMAC signature for payload verification |
| `X-Upstack-Timestamp`  | `1708266721`       | Unix timestamp of delivery attempt      |

## FAQ

<AccordionGroup>
  <Accordion title="What does Upstack guarantee about delivery?">
    Webhooks use **at-least-once** delivery. Each request has a 10-second timeout and up to 5 retries with exponential backoff (1s, 5s, 30s, 2m, 10m). After all retries fail, the event is logged as a failed delivery in your dashboard's delivery log. In rare cases (network timeouts, retries) your endpoint may receive the same event more than once — deduplicate using the `event_id` field or the `X-Upstack-Event-Id` header.
  </Accordion>

  <Accordion title="How do I verify a webhook payload actually came from Upstack?">
    Every delivery includes an `X-Upstack-Signature` header containing an HMAC-SHA256 signature of the raw request body, computed with your destination's signing secret. Recompute the signature on your end over the **raw** (un-parsed, un-reformatted) request body and compare using a constant-time comparison. If the signatures match, the payload is authentic. The signing secret is shown once when you create the destination — store it securely; it can only be regenerated, not retrieved.
  </Accordion>

  <Accordion title="Can I receive only certain event types?">
    Yes. Each webhook destination supports event filtering — choose all events, standard events only, or any custom subset. Excluded events are dropped at the Upstack level and are not retried.
  </Accordion>

  <Accordion title="My endpoint is timing out. What should I do?">
    Accept the request immediately (return `200`) and process the payload asynchronously. The 10-second timeout is end-to-end — including any work your endpoint does before responding. The standard pattern is: validate signature, enqueue the payload to your own queue, return `200`, then process the payload separately.
  </Accordion>

  <Accordion title="Does the endpoint URL need to be HTTPS?">
    Yes. HTTP endpoints are not supported. Your endpoint must be publicly reachable (Upstack delivers from its cloud infrastructure) and serve a valid TLS certificate.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Standard events reference" icon="bolt" href="/data-dictionary/standard-events">
    Full reference for all event types and properties included in webhook payloads.
  </Card>

  <Card title="Properties and context" icon="list" href="/data-dictionary/properties-and-context">
    Complete list of event properties and context fields available in every payload.
  </Card>

  <Card title="Destinations overview" icon="arrow-right-from-bracket" href="/destinations/overview">
    How Upstack delivers events to all destination types.
  </Card>

  <Card title="Events not reaching destination" icon="wrench" href="/troubleshooting/events-not-reaching-destination">
    End-to-end diagnostic guide when events aren't arriving at any destination.
  </Card>
</CardGroup>
