---
updatedAt: 2026-06-12T07:54:29.000Z
agentTools:
  projectIndex: https://api-docs.omnisend.com/llms.txt
---

# How to send webhooks from automation workflows

## Intro

Use the `sendWebhook` action block in automation workflows to send real-time HTTP POST requests to external systems when contacts reach a specific point in a workflow. This enables integrations with CRMs, messaging platforms (Slack, WhatsApp), order management systems, or any custom API endpoint — without building a native integration.

See API reference: [Automations](https://api-docs.omnisend.com/v2026-03-15/reference/automations)

## Prerequisites

* An API key with `automations.write` scope (or an OAuth token with the same scope)
* A paid Omnisend plan — webhooks in automations are not available on the free plan
* An HTTPS endpoint to receive the webhook (for testing, [webhook.site](https://webhook.site) provides a temporary URL)

## Step 1: Create an automation with a webhook action

Create a disabled automation workflow that triggers on an event and sends an HTTP POST to your endpoint. The example below triggers when a contact subscribes to marketing, waits 5 minutes, then sends contact data to an external URL.

See endpoint: [Create automation workflow](https://api-docs.omnisend.com/v2026-03-15/reference/post_automations)

```sh
curl -X POST 'https://api.omnisend.com/api/automations' \
  -H 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
  -H 'Omnisend-Version: 2026-03-15' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "New Subscriber Webhook",
    "trigger": {
      "condition": {
        "event": "subscribed to marketing"
      }
    },
    "blocks": [
      {
        "temporaryID": "wait-5m",
        "type": "delay",
        "delay": {
          "mode": "duration",
          "duration": {
            "amount": 5,
            "units": "m"
          }
        }
      },
      {
        "temporaryID": "webhook-notify",
        "type": "action",
        "action": {
          "type": "sendWebhook",
          "sendWebhook": {
            "callbackUrl": "https://example.com/webhooks/omnisend",
            "headers": [
              {"key": "X-Webhook-Secret", "value": "my-shared-secret"}
            ],
            "body": "{\"contactEmail\": \"[[contact.email]]\", \"contactName\": \"[[contact.first_name]]\", \"event\": \"subscribed\"}"
          }
        }
      }
    ]
  }'
```

The response returns the automation in disabled state with an `id` and the resolved `blocks` array (each block now has a server-assigned `id` replacing `temporaryID`).

> **Note**: The `callbackUrl` must be HTTPS. IP literals, non-443 ports, non-FQDN hosts, and internal/private IP addresses are rejected. The `body` must be valid JSON and supports personalization tags like `[[contact.email]]`, `[[contact.first_name]]`, and `[[event.raw.<property>]]`. The `trigger.condition.event` value must be a valid event for your brand — some events (e.g., `"placed order"`) require an `origin` field specifying the source platform.

## Step 2: Verify the webhook configuration

Retrieve the automation to confirm the webhook block was created correctly.

See endpoint: [Get automation workflow](https://api-docs.omnisend.com/v2026-03-15/reference/get_automations-id)

```sh
curl -X GET 'https://api.omnisend.com/api/automations/AUTOMATION_ID' \
  -H 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
  -H 'Omnisend-Version: 2026-03-15'
```

In the response, look for the `blocks` array. The webhook block will contain:

```json
{
  "type": "action",
  "action": {
    "type": "sendWebhook",
    "sendWebhook": {
      "callbackUrl": "https://example.com/webhooks/omnisend",
      "headers": [
        {"key": "X-Webhook-Secret", "value": "my-shared-secret"}
      ],
      "body": "{\"contactEmail\": \"[[contact.email]]\", ...}"
    }
  }
}
```

## Step 3: Update the webhook (optional)

To change the webhook URL, body, or headers on an existing automation, use PATCH. Only provided fields are updated.

See endpoint: [Patch automation workflow](https://api-docs.omnisend.com/v2026-03-15/reference/patch_automations-id)

```sh
curl -X PATCH 'https://api.omnisend.com/api/automations/AUTOMATION_ID' \
  -H 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
  -H 'Omnisend-Version: 2026-03-15' \
  -H 'Content-Type: application/json' \
  -d '{
    "blocks": [
      {
        "id": "WEBHOOK_BLOCK_ID",
        "type": "action",
        "action": {
          "type": "sendWebhook",
          "sendWebhook": {
            "callbackUrl": "https://example.com/webhooks/omnisend/v2",
            "body": "{\"contactEmail\": \"[[contact.email]]\", \"contactPhone\": \"[[contact.phone_number]]\", \"event\": \"subscribed\"}"
          }
        }
      }
    ]
  }'
```

> **Note**: The automation must be disabled before replacing blocks. If it is currently enabled, disable it first via `POST /automations/{id}/disable`, replace blocks, then re-enable.

## Webhook configuration reference

| Field         | Required | Description                                                              |
| ------------- | -------- | ------------------------------------------------------------------------ |
| `callbackUrl` | Yes      | HTTPS URL that receives the POST request (max 2,000 characters)          |
| `body`        | Yes      | JSON body template with optional personalization tags (max 64 KB)        |
| `headers`     | No       | Up to 15 custom HTTP headers (key max 256 chars, value max 10,000 chars) |

### URL restrictions

* Must use `https://` scheme
* Must be a fully-qualified domain name (no IP literals)
* Only port 443 is allowed (or omit port entirely)
* Internal/private IP addresses are blocked (DNS is resolved externally)
* TLS certificate must be valid

### Forbidden header keys

The following headers cannot be set as custom headers (they are managed by the system): `Host`, `Content-Length`, `Transfer-Encoding`, `Connection`, `Keep-Alive`, `Upgrade`, `TE`, `Trailer`, `Proxy-Authorization`, `Proxy-Authenticate`, `Expect`, `User-Agent`, `Content-Type`.

### Personalization tags

The webhook body supports the same personalization variables available in automation messages:

* `[[contact.email]]`, `[[contact.first_name]]`, `[[contact.last_name]]`, `[[contact.phone_number]]`
* `[[event.raw.<property>]]` — access properties from the triggering event

For a full list of available personalization tags, see [Use personalization in Omnisend](https://support.omnisend.com/en/articles/1061845-use-personalization-in-omnisend).

## Receiving and verifying webhooks

When the automation fires, Omnisend sends an HTTP POST to your `callbackUrl` with:

* **Content-Type**: `application/json`
* Your custom headers (as configured)
* The JSON body with personalization tags resolved to actual contact/event values

To verify the request comes from Omnisend:

1. **Shared secret header** — include a secret value in a custom header (e.g., `X-Webhook-Secret`) and validate it on your server.
2. **IP whitelisting** — Omnisend sends webhook requests from these static IPs: `34.170.162.11`, `34.56.62.59`, `34.56.108.215`, `34.133.59.36`, `34.58.66.146`, `35.184.130.5`, `35.232.14.89`.

### Testing with webhook.site

For quick testing without setting up your own server:

1. Go to [webhook.site](https://webhook.site) and copy your unique URL
2. Use that URL as the `callbackUrl` when creating the automation
3. Enable the automation and trigger the event — the request will appear on webhook.site

## Troubleshooting

* **400 on create/patch with `callbackUrl` error**: The URL is not HTTPS, uses an IP literal, or resolves to an internal address. Use a public HTTPS domain.
* **400 with body validation error**: The `body` field must contain valid JSON. Validate your JSON before submitting.
* **409 Conflict on PATCH**: The automation is currently enabled. Disable it first via `POST /automations/{id}/disable`, make changes, then re-enable.
* **Webhook not reaching your endpoint**: Ensure your server accepts POST requests, has a valid TLS certificate, and is not blocking Omnisend's IP addresses.
* **Duplicate headers rejected**: Header keys are case-insensitive and must be unique.

## Related resources

* [Automations API reference](https://api-docs.omnisend.com/v2026-03-15/reference/automations)
* [Automations overview](https://api-docs.omnisend.com/v2026-03-15/docs/automations)
* [Use Webhooks in Automation (Help Center)](https://support.omnisend.com/en/articles/9924457-use-webhooks-in-automation)
* [Use personalization in Omnisend (Help Center)](https://support.omnisend.com/en/articles/1061845-use-personalization-in-omnisend)