> For the complete documentation index, see [llms.txt](https://docs.harmony.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.harmony.io/workflows-and-automation/workflow-events-and-webhooks.md).

# Workflow Events and Webhooks

Harmony can notify your external systems in real time whenever important things happen inside a workflow - requests being created or updated, messages being sent, and more. These notifications are delivered as **workflow events** and can be forwarded to any endpoint you control via **webhooks**.

This article explains the event types available, the data each event carries, and how to use that data to build reliable, precise integrations.

***

### How Workflow Events and Webhooks Work

When activity occurs in Harmony - such as a new request being opened or a message being sent - Harmony emits a structured event. If you have a webhook configured, Harmony sends an HTTP POST request containing the event payload to your specified endpoint.

This lets your downstream systems react immediately without polling the API, making it straightforward to:

* Sync request data to your CRM or helpdesk
* Trigger automations in third-party tools
* Build audit logs and reporting pipelines
* Filter and route activity based on context

***

### Configuring Webhooks

To receive events, you need to register a webhook endpoint in your Harmony workspace settings.

1. Go to **Settings** and open the **Integrations** section.
2. Select **Webhooks** and click **Add Webhook**.
3. Enter the destination URL for your endpoint.
4. Choose the event types you want to subscribe to.
5. Save your configuration.

Harmony will begin delivering events to your endpoint immediately. Each delivery is an HTTP POST request with a JSON body and a `Content-Type: application/json` header.

***

### Event Types

#### Request Lifecycle Events

Request lifecycle events fire when a request is created or updated. These are the primary events for tracking the state of work moving through your workflows.

**`RequestCreated`**

Emitted when a new request is opened. The payload includes full request metadata so your systems can immediately index or act on the new request.

**`RequestUpdated`**

Emitted whenever a request is modified - for example when its status changes, it is assigned to an agent, or it is resolved.

**Resolution Details on Request Events**

Both `RequestCreated` and `RequestUpdated` events now include two additional fields that tell your downstream systems how a request was resolved, without requiring any follow-up API calls:

| Field           | Type              | Description                                                                                    |
| --------------- | ----------------- | ---------------------------------------------------------------------------------------------- |
| `resolution`    | string or null    | How the request was resolved - for example `escalated`, `handled_by_ai`, or `closed_by_agent`. |
| `resolution_at` | timestamp or null | The date and time at which the resolution was determined.                                      |

Both fields are **optional** and default to `null` when no resolution has been recorded yet. This means the change is fully backward-compatible - your existing integrations will continue to work without any modification.

**Example payload fragment:**

```json
{
  "event": "RequestUpdated",
  "request_id": "req_01abc123",
  "status": "resolved",
  "resolution": "handled_by_ai",
  "resolution_at": "2024-06-10T14:32:00Z"
}
```

When a request has not yet been resolved, these fields appear as:

```json
{
  "resolution": null,
  "resolution_at": null
}
```

***

#### Message Events

**`MessageCreated`**

Emitted whenever a new message is added to a request conversation. This event is useful for building notification systems, logging conversation history, or triggering follow-up automations based on message content.

**Source Attribution with `event_source`**

The `MessageCreated` event includes an `event_source` field that tells you exactly where the message originated. This gives you the context you need to build more precise filtering and automation logic.

| Value      | Description                                         |
| ---------- | --------------------------------------------------- |
| `customer` | The message was sent by the end user or customer.   |
| `agent`    | The message was sent by a human agent.              |
| `workflow` | The message was generated by an automated workflow. |

**Example payload fragment:**

```json
{
  "event": "MessageCreated",
  "request_id": "req_01abc123",
  "message_id": "msg_09xyz789",
  "body": "Thanks for reaching out, I'll look into this now.",
  "event_source": "agent",
  "created_at": "2024-06-10T14:33:00Z"
}
```

You can use `event_source` to, for example:

* Only forward customer messages to your CRM
* Trigger a satisfaction survey only after an agent closes a conversation
* Skip logging automated workflow messages in your audit trail

***

### Payload Structure

Every event payload shares a common envelope, regardless of event type:

| Field        | Type      | Description                                   |
| ------------ | --------- | --------------------------------------------- |
| `event`      | string    | The name of the event, e.g. `RequestCreated`. |
| `created_at` | timestamp | When the event was emitted.                   |
| `request_id` | string    | The unique identifier of the related request. |

Event-specific fields are included alongside these common fields in the same flat JSON object.

***

### Reliability and Retries

Harmony expects your endpoint to respond with an HTTP `2xx` status code to acknowledge successful receipt. If your endpoint returns a non-`2xx` response or does not respond within the timeout window, Harmony will retry delivery using an exponential back-off strategy.

To avoid processing duplicate events during retries, design your endpoint to be idempotent - that is, handling the same event more than once should produce the same result as handling it once.

***

### Backward Compatibility

Harmony follows an additive-only policy for event payloads. This means:

* New fields may be added to any event at any time.
* Existing fields will not be removed or renamed without advance notice.
* Optional fields default to `null` when not applicable, so your integration is never broken by their absence.

You should write your event consumers to **ignore unknown fields** rather than treating them as errors. This keeps your integrations resilient as new capabilities are introduced.


---

# 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.harmony.io/workflows-and-automation/workflow-events-and-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.
