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

# Flow webhooks

> Trigger Omneo actions from a Klaviyo Flow using webhook actions, with the headers and body Omneo expects.

Klaviyo Flows can call into Omneo using Klaviyo's [webhook action](https://developers.klaviyo.com/en/docs/how_to_add_a_webhook_action_to_a_flow). This lets you fire Omneo-side logic (issuing a reward, recording an interaction, granting a benefit) at exactly the right point in a customer journey.

This page covers how to add and configure a webhook action against Omneo. For event-by-event behaviour of Klaviyo's built-in system webhooks (bounces, subscribes, unsubscribes), see [System webhooks](/extensions/klaviyo/system-webhooks).

## Add a webhook action to your Flow

<Steps>
  <Step title="Open or create a Flow">
    In Klaviyo, navigate to **Flows**, then open the Flow you want to extend or create a new one.
  </Step>

  <Step title="Drag in a Webhook action">
    From the action sidebar, drag a **Webhook** action onto the canvas after your trigger or filter steps.
  </Step>

  <Step title="Configure the destination URL">
    Set the **Destination URL** to the relevant Omneo extension endpoint (see [Available endpoints](#available-endpoints) below).
  </Step>

  <Step title="Add headers and body">
    Add the headers and JSON body shown below for the action you want Omneo to perform.
  </Step>

  <Step title="Preview, save, and activate">
    Use Klaviyo's **Preview** feature to render the JSON for a real profile and confirm the values look right, then save the Flow and switch it live.
  </Step>
</Steps>

## Required headers

Every webhook call into Omneo must include the shared secret configured against the extension. This is the same secret used by Klaviyo system webhooks.

| Header           | Value                                                   |
| ---------------- | ------------------------------------------------------- |
| `Content-Type`   | `application/json`                                      |
| `x-omneo-secret` | The Webhook Secret configured in the extension settings |

<Warning>
  Requests without a matching `x-omneo-secret` are rejected. Treat this secret like an API key: store it only in Klaviyo's secured webhook configuration.
</Warning>

## Available endpoints

The extension exposes a small set of Flow webhook endpoints. Each is mounted under your tenant on the extension URL provided by Omneo:

```text theme={null}
https://{your-extension-url}/{tenant}/api/v1/webhooks/klaviyo/{action}
```

### Rewards

`POST /{tenant}/api/v1/webhooks/klaviyo/rewards`

Issues a reward against the Omneo profile that triggered the Flow.

**Required fields**

| Field                       | Description                                                          |
| --------------------------- | -------------------------------------------------------------------- |
| `person_id`                 | The Klaviyo profile ID (`{{ person.id }}`)                           |
| `email`                     | The profile email, used as fallback if `person_id` cannot be matched |
| `data.reward_definition_id` | The Omneo reward definition to issue                                 |
| `data.amount`               | The reward value (integer or float)                                  |

**Optional fields**

| Field       | Description                                                                                                                                    |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`        | Unique identifier used for deduplication. If supplied, Omneo will not create the reward again on retry. Stored as `external_id` on the reward. |
| `data.meta` | Free-form metadata object stored against the reward                                                                                            |
| `data.*`    | Any additional fields pass straight through to the Omneo rewards API                                                                           |

**Example body**

```json theme={null}
{
  "id": "{{ event.reward_id }}",
  "person_id": "{{ person.id }}",
  "email": "{{ person.email }}",
  "data": {
    "reward_definition_id": 123,
    "amount": "{{ event.reward_amount }}",
    "meta": {
      "campaign": "{{ event.campaign_name }}"
    }
  }
}
```

**Response codes**

| Code  | Meaning                                          |
| ----- | ------------------------------------------------ |
| `200` | Reward created, or already existed (idempotent)  |
| `400` | Missing required fields                          |
| `404` | No Omneo profile found by `person_id` or `email` |
| `500` | Internal error                                   |

## Templating tips

Klaviyo exposes a limited set of variables inside Flow webhook bodies:

* `{{ person.id }}`, `{{ person.email }}`, `{{ person.first_name }}`, `{{ person.last_name }}`: profile fields
* `{{ event.* }}`: **only** the custom event properties you have defined in your Flow. Internal Klaviyo metadata like `unique_id` and `timestamp` is **not** available here.

If you need a deduplication key but do not have a natural one, define a custom event property on your Flow (for example `event.reward_id`) and reference it as `id` in the JSON body.
