# Connect your application to an automation

Send an application event when something happens in your system, such as an order being created or a payment arriving. An event can start a run, continue a run that is waiting for it, or cancel a run with a matching cancellation rule. Each automation has one event URL for all three uses.

> Automations is in Early access. Your workspace permissions determine which actions you can perform.

If you cannot open Automations or create a draft, see [workspace access and editing controls](/docs/guides/automations/troubleshooting#automations-is-missing-from-the-dashboard).

## Configure the event that starts a run

1. Create an automation with **Event from your application** as its trigger.
2. Set **Event name**, for example `order.created`. Names are case-sensitive and can contain letters, numbers, dots, underscores, or hyphens.
3. Define **Event fields** for the data your application sends. For an order, add a string field named `order_id`. Later steps can use these fields.
4. Publish the automation. The success screen shows **How to start a run**, including the event URL and a request example.

To find the connection details again, select the trigger and click **How to connect your application** in quick edit. The expanded editor shows the connection controls.

## Simulate a draft or execute the published version

Use **Preview workflow** with sample data to simulate your draft without sending messages or changing data. Running the cURL command, clicking **Send event…**, or using **Start run** executes the published automation and can perform real actions. Saved and unsaved draft changes do not apply to those runs.

Publish the automation before sending events. If it has no published version, the request is rejected immediately; the event is not queued or saved for later. Editor examples can reflect draft changes, so publish those changes before sending data that relies on them.

## Copy the URL and send an event

Use **Copy request** to get a cURL command containing the URL, headers, and example body. Replace the example values with your application's data.

The URL includes the workspace and automation IDs:

```text
POST https://<your-regional-api-host>/v1/hooks/automations/<workspace-id>/<automation-id>
```

Use the full URL copied from the dashboard. You do not need an `X-Workspace-Id` header. The current authentication option is **No authentication**: anyone with this URL can send events. Keep it in your server configuration.

For an automation configured for `order.created`, set `AUTOMATION_EVENT_URL` to the copied URL and send:

```bash
curl --request POST "$AUTOMATION_EVENT_URL" \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: order-created-123' \
  --data '{
    "type": "order.created",
    "data": { "order_id": "order_123" }
  }'
```

Set `type` to the configured event name and `data` to an object matching the event fields. You can also provide `occurred_at` as an RFC 3339 timestamp; it defaults to the time the event arrives.

A `202 Accepted` response with `status: "queued"` confirms that the event is queued. Bird generates the event identifier and returns it as `event_id`. Open the automation's **Runs** tab to inspect execution. Queue acceptance does not confirm that the event matched a trigger or that a run started.

You can also use **Send event…** in the dashboard to submit the example without a terminal. This sends a real event.

## Continue a run that is waiting for an event

A waiting step uses the same automation URL as the trigger. Its event name and `subject_key` identify what happened and which run should receive it.

1. In **Automation settings**, enable **Skip overlapping runs** and **Use a business key**. Set **Business key** to a value that identifies the order, invoice, or other object. For the order example, use the expression `trigger.data.data.order_id`.
2. Add **Wait for application event** and configure its event name, event fields, and timeout. For example, wait for `order.paid` with a string `payment_id` field.
3. Publish, send the starting event, and wait until its run appears in **Runs**.
4. Send the follow-up event to the same URL, with `subject_key` equal to the run's business key:

```json
{
  "type": "order.paid",
  "subject_key": "order_123",
  "data": { "payment_id": "payment_456" }
}
```

Use a new `Idempotency-Key` for this follow-up request. `subject_key` is the business key value, such as `order_123`; it is not the event ID or the run ID. The waiting step's expanded connection view shows guidance for your configured key.

A matching event can be captured after the run starts, even before it reaches the waiting step. Events processed before a matching run exists are not saved for a future run. A wait with a filter continues only when both its event fields and filter match. The run takes its timeout path if no eligible event is processed before the deadline.

Cancellation rules in **Automation settings** use this URL too. A rule can target all active runs of the automation, or the run matching `subject_key`. Configure a filter to narrow which runs it cancels. Cancellation cannot undo an action that has already happened.

## Published versions and paused automations

New runs use the version active when the event is processed. Existing runs keep their original version, including their event fields and wait conditions. Publishing a changed event format does not update runs that already started.

Pausing a published automation stops new runs. Events can still continue or cancel existing runs while it is paused.

## Handle delivery and retries

Events are processed asynchronously and may be retried or processed out of order. Wait for the starting run to exist before sending a follow-up event. An event's `occurred_at` does not control processing order, extend a wait, or prevent a timeout.

Retry protection is bounded. If retry records expire or are lost, an event can be processed again, potentially against a newer version or a different active run. Design your application to tolerate duplicate events.

For an HTTP retry, reuse the same `Idempotency-Key`, URL, and unchanged body. Use a new key for each new request. A replay returns the same `event_id`. The [idempotency guide](/docs/guides/idempotency) explains the bounded replay window and conflict responses.

## Troubleshoot an event

- **The request returns 4xx:** Check the response's error details, the URL, and the required `type` and object `data` fields. Send `Content-Type: application/json`. The whole request body must fit within 25 KB (25,000 bytes); larger bodies return `413`.
- **The automation has not been published:** Publish it before sending an event. The rejected event is not retained; send a new request after publishing.
- **The request returns 202 but no run starts:** Check that the automation is active, the event name matches its trigger, and the data matches the published event fields. Overlap protection can skip a new run while another is active.
- **The run stays at a waiting step:** Check the event name, exact business key, data fields, filter, and timeout. Use the event format from the run's original published version.
- **A retry returns a conflict:** Retry with the original key and unchanged request. If you intend to send a different event, use a new key.

The request's envelope is checked before queueing. Event data is checked against the trigger, wait, and cancellation rules during processing, so a queued event can fail to match any of them.

## Next steps

- [Open **Automations**](https://bird.com/dashboard/w/automations) to configure and publish your workflow.
- [Handle idempotent retries](/docs/guides/idempotency) in your application.
- [Wait for an event](/docs/guides/automations/waits) in a running workflow.
- [Browse the Automations guides](/docs/guides/automations).

## Related resources

- [Preview your first automation](/docs/get-started/automations) (docs)
