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

# Set Up a Webhook Sync

> Configure a Destination, filter events, authenticate outbound requests, and shape the payload with a Liquid template.

> [!NOTE]
>
> Real-Time Event Streams are in private beta. Contact your Mixpanel account team to enable the feature for your project.

This page walks through creating a webhook Sync end to end: configuring the Destination, selecting which events stream, adding property-level filters, authenticating outbound requests, and shaping the payload with a Liquid template.

## Prerequisites

* Your project has access to the Real-Time Event Streams feature.
* You have Project Admin permissions.
* You have an HTTPS endpoint that can accept POST requests and return a 2xx response.

## Create a Sync

**1. Open Real-Time Event Streams**

**2. Add a Destination**

Create a new webhook Destination with the endpoint URL and authentication method. See [Webhook authentication](#webhook-authentication).

**3. Select events to stream**

Choose one or more event types. See [Event-type filtering](#event-type-filtering).

> [!WARNING]
>
> There is no "All events" default. You must explicitly select event types to prevent accidentally streaming a firehose of data.

**4. Add property conditions (optional)**

Narrow the stream further using [property-level filters](#property-level-filters).

**5. Write the payload template**

Define the outbound request body using [Liquid template syntax](#liquid-payload-template).

**6. Save and enable**

Mixpanel validates the template on save. Once enabled, matching events will begin streaming within seconds.

## Event-type filtering

Users select one or more event types to stream. Only matching events are forwarded; all others are discarded before entering the streaming pipeline. Filtering happens before delivery, so unmatched events do not consume retry budget or queue capacity.

* You must explicitly select at least one event type. There is no "All events" option.
* You can update the selected event types at any time without recreating the Sync.

## Property-level filters

Add one or more property conditions that must all be true for an event to stream. Conditions are combined with logical AND.

**Example:** Stream `Purchase Completed` events only when `plan = "premium"` AND `country = "US"`.

* Filters apply to event properties.
* All conditions must evaluate to true for the event to be forwarded.
* Events that fail filter evaluation are discarded and never counted against retry or delivery metrics.

## Webhook authentication

Configure how Mixpanel authenticates outbound requests. The current authentication method is always visible on the Destination card.

**API key header**

Set a custom header name and value. Mixpanel adds this header to every outbound request.

```http theme={"system"}
X-API-Key: abc123
```

**Bearer token**

Standard `Authorization: Bearer <token>` header.

```http theme={"system"}
Authorization: Bearer eyJhbGciOi...
```

**No auth**

No authentication header is added. Use this only for internal endpoints that are otherwise protected (for example, IP-allowlisted or on a private network).

> [!WARNING]
>
> If the destination returns an authentication failure, the Destination immediately moves to the `auth_error` state. Authentication failures are never silently swallowed. Re-authenticating updates the existing Destination in place — you do not need to delete and recreate it.

## Liquid payload template

The full outbound request body is customer-controlled via a [Liquid](https://shopify.github.io/liquid/) template. This is the primary mechanism for shaping payloads, naming fields, and including identity information. There is no separate field-mapping UI.

### Available template variables

| Variable | Description |
| - | - |
| `{{ event_name }}` | Event name |
| `{{ event_time }}` | Event timestamp (ISO 8601) |
| `{{ distinct_id }}` | Mixpanel user identifier |
| `{{ insert_id }}` | Mixpanel deduplication ID |
| `{{ project_id }}` | Mixpanel project ID |
| `{{ properties['key'] }}` | Any event property |

> [!NOTE]
>
> User properties are **not** currently available in the payload template. Only event properties and the top-level variables above are supported. If you need user attributes on the destination side, include them as event properties at tracking time or enrich after delivery.

### Example template

```liquid Payload template theme={"system"}
{
  "user_id": "{{ distinct_id }}",
  "event": "{{ event_name }}",
  "timestamp": "{{ event_time }}",
  "insert_id": "{{ insert_id }}",
  "properties": {
    "plan": "{{ properties['plan'] }}",
    "country": "{{ properties['country'] }}",
    "revenue": "{{ properties['revenue'] }}"
  }
}
```

### Validation

Template syntax is validated on save. Invalid syntax surfaces a clear error and blocks the Sync from enabling, so you cannot ship a broken template into production.

> [!TIP]
>
> Include `{{ insert_id }}` in your payload if you plan to deduplicate on the destination side

## Next steps

> **[Delivery and reliability](https://docs.mixpanel.com/docs/real-time-event-streams/delivery-and-reliability.md)**
>
> Retries, failed events log, and at-least-once delivery.

> **[States and monitoring](https://docs.mixpanel.com/docs/real-time-event-streams/states-and-monitoring.md)**
>
> Destination and Sync states, plus how to monitor health.
