> For the complete documentation index, see [llms.txt](https://docs.eesel.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.eesel.ai/automations-and-schedules/webhooks.md).

# Webhooks

Trigger your AI agent with a webhook. Zapier, Make, your own backend or any service that can send a web request can wake it with data and instructions.

Most automations run when something happens in a connected app, or on a schedule. A **webhook automation** covers the other cases. It gives you a unique URL, and any service that can send a web request (Zapier, Make, your own backend, a warehouse system) can POST data to it. Your agent wakes up with that data and follows the automation's instructions.

Use it when the thing that should wake your agent lives in an app eesel does not connect to directly, or when you want your own systems to hand work to your agent.

## Setting one up

{% stepper %}
{% step %}

### Ask for it in chat

Tell your agent what will be sending and what to do with each delivery. It creates the automation and hands you the URL to paste into the other app, along with the two optional headers below.

<figure><img src="https://3732419023-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2xXO0947TYoPIhGoBgSE%2Fuploads%2Fgit-blob-2357bc72f0990949dbec248ba3906ff3dd907b9d%2Fwebhook-setup-chat.png?alt=media" alt="The dashboard chat where the user asks for a webhook URL for shipment delay alerts, and the agent posts the URL, lists what it will do with each payload and names the two optional headers"><figcaption><p>The agent hands out the URL and says what it will do with each payload.</p></figcaption></figure>

You can also build one yourself on your agent's **Automations** page: choose **When a webhook is received**.
{% endstep %}

{% step %}

### Check it on your Automations page

The automation is listed with **Webhook received** under its name, switched on.

<figure><img src="https://3732419023-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2xXO0947TYoPIhGoBgSE%2Fuploads%2Fgit-blob-faa5bab9b2b732e341e11aca390f80a14b6e9df4%2Fwebhook-automations-list.png?alt=media" alt="The Automations page listing a Warehouse Shipment Delay Alert automation marked Webhook received, switched on, beside the chat that created it"><figcaption><p>The webhook automation, switched on.</p></figcaption></figure>

**Check it worked.** From a terminal, `eesel automations` lists the automation as on.
{% endstep %}

{% step %}

### Copy the URL

Open the automation. **When it runs** shows the URL with a **Copy** button, and the instructions sit below it.

Keep the URL private: anyone who has it can wake your agent, so share it only with the service that should call it. If it ever leaks, delete the automation and create a new one for a fresh URL.

<figure><img src="https://3732419023-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2xXO0947TYoPIhGoBgSE%2Fuploads%2Fgit-blob-6f1e0b2126ec939d8c0fe024f410997e17a82d4b%2Fwebhook-automation-page.png?alt=media" alt="A webhook automation&#x27;s page with its URL and a Copy button under When it runs, and instructions describing how to handle a shipment delay payload"><figcaption><p>The automation's page, with the URL and the instructions.</p></figcaption></figure>
{% endstep %}

{% step %}

### Point the other app at it

In Zapier that is a "Webhooks by Zapier" POST action. In your own code it is a plain HTTP POST. Send any JSON you like, and your agent reads all of it.

```
curl -X POST https://your-webhook-url \
  -H 'Content-Type: application/json' \
  -H 'X-Eesel-Event-Id: evt-88213' \
  -H 'X-Eesel-Reference: order-4711' \
  -H 'X-Eesel-Reference-Url: https://shop.example.com/admin/orders/4711' \
  -d '{"customer": "Sam", "message": "Order arrived damaged"}'
```

Send the headers whenever your app can. They are optional, but without them every row on your Activity page looks the same.
{% endstep %}

{% step %}

### Check the result

Each delivery is a run on your **Activity** page: what arrived, what your agent did, and what it cost. When the instructions tell it to act in another app, the result is there too. In this example a shipment delay came in, the order could not be found in the store, and the agent opened a tagged ticket in Gorgias for the team.

<figure><img src="https://3732419023-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2xXO0947TYoPIhGoBgSE%2Fuploads%2Fgit-blob-bfbf47f5fbe2782b37d4f38f008ccbb8440e85c6%2Fwebhook-gorgias-ticket.png?alt=media" alt="A Gorgias ticket the webhook run created, titled Shipment Delay Alert, with the delay details in the body and the tags shipment-delay, urgent and warehouse-alert"><figcaption><p>The ticket the webhook run created in Gorgias.</p></figcaption></figure>
{% endstep %}
{% endstepper %}

## Tell eesel what each delivery is

The three headers do different jobs.

| Header                  | What it is                                                                      | What it buys you                                                                        |
| ----------------------- | ------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| `X-Eesel-Event-Id`      | Unique for **this delivery**, and the same value if you retry it                | eesel processes the event exactly once, however many times your app sends it            |
| `X-Eesel-Reference`     | Stable for the **thing** the delivery is about: a conversation, ticket or order | Activity rows say which one they were about, instead of repeating the automation's name |
| `X-Eesel-Reference-Url` | Optional link to that thing in your own app                                     | Turns the Activity row into a link straight back to it                                  |

The distinction matters when a single conversation sends several events. Each one needs its **own** event id, while they all share the **same** reference. Reusing one event id across them would look like a retry, and eesel would process only the first.

If you cannot set headers, a JSON body with an `event_id` or `idempotency_key` field still stops duplicate runs. Headers are the better option because they work for every kind of body. If you send form data or plain text rather than JSON, eesel keeps the body as it is for your agent to read, and a field inside it cannot be used as an event id.

Without any of this, eesel falls back to comparing whole payloads within the same day, which catches most retries but treats two identical events as one.

## Only wake on the deliveries you want

By default every delivery wakes your agent. If only some deliveries matter, tell your agent in the dashboard chat which ones, for example "only act on deliveries where the delay is over 48 hours". It adds that to the automation. A delivery that does not match creates no run, is listed in the automation's activity as skipped, and is not billed.

## Limits

* A body can be up to 1,000,000 bytes. Larger deliveries are rejected.
* A workspace can send 60 deliveries a minute. Above that the URL answers 429, and the sender should retry after a moment.
* eesel processes eight deliveries at a time. A burst beyond that also gets a 429, and the sender should retry.
* A paused automation answers deliveries with "skipped" and wakes nothing.

## Good to know

* **Pause instead of delete.** The switch on the automation stops deliveries from waking your agent but keeps the URL. Deleting the automation retires its URL for good.
* **Edits are safe.** Changing the name or instructions never changes the URL, and the next delivery uses the new instructions.
* **Billing** works like other automation runs: each processed delivery is one run against your plan. A filtered-out delivery is not a run.

## FAQ

<details>

<summary>Can Zapier or Make trigger my eesel agent?</summary>

Yes. Any service that can send a web request can POST to a webhook automation's URL. In Zapier that is a "Webhooks by Zapier" POST action. In your own code it is a plain HTTP POST.

</details>

<details>

<summary>What data can I send to the webhook?</summary>

Any JSON you like, and your agent reads all of it. Form data and plain text work too: eesel keeps the body as it is for your agent to read. A body can be up to 1,000,000 bytes.

</details>

<details>

<summary>How do I stop duplicate runs when my app retries?</summary>

Send an `X-Eesel-Event-Id` header that is unique for each delivery and the same on a retry. eesel then processes each event exactly once. If you cannot set headers, an `event_id` or `idempotency_key` field in a JSON body does the same.

</details>

<details>

<summary>Can I have the agent ignore some deliveries?</summary>

Yes. Tell your agent in the dashboard chat which deliveries to act on, and it adds that to the automation. A delivery that does not match creates no run, is listed as skipped, and is not billed.

</details>

<details>

<summary>What happens if my webhook URL leaks?</summary>

Anyone who has the URL can wake your agent. Delete the automation and create a new one for a fresh URL. Pausing keeps the URL, and deleting retires it for good.

</details>

<details>

<summary>How many webhook deliveries can eesel take?</summary>

A workspace can send 60 deliveries a minute, and eesel processes eight at a time. Above either limit the URL answers 429, and the sender should retry after a moment.

</details>

## Related

* [Automations and Schedules](/automations-and-schedules/automations-and-schedules.md) for event and scheduled automations
* [Actions and Approvals](/instructions-and-memory/actions-and-approvals.md) for what happens when the run's action asks first
* [The eesel CLI](/apis-and-developer-resources/cli.md) for `eesel automations` and `eesel activity`
* [Network Access](/apis-and-developer-resources/network-access.md) for the other direction: your agent calling your API
* [Use eesel from Claude and other AI assistants](/apis-and-developer-resources/use-eesel-from-claude-and-other-assistants.md) and [Use eesel from ChatGPT](/apis-and-developer-resources/use-eesel-from-chatgpt.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.eesel.ai/automations-and-schedules/webhooks.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
