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

# Event Sources

> Named inbound event channels that route external events to jobs and workflows.

An `EventSource` is a named inbound event channel. External systems dispatch events to a source by name, and the source routes them to one or more jobs or workflows via **subscriptions**. Each subscription can optionally filter on the event payload, so a single source can fan out to multiple targets selectively.

## Event Sources vs Event Triggers

Event Sources and [Event Triggers](/concepts/event-triggers) serve different purposes:

* **Event Sources** are inbound channels for receiving external events and routing them to jobs or workflows. They are always-on endpoints that evaluate subscriptions on every dispatch.
* **Event Triggers** are durable waits used by workflow steps and runs to pause execution until a matching event arrives. They are created by in-flight runs and consumed once.

<Note>
  Event Sources push events into the system. Event Triggers wait for events from within the system.
</Note>

## EventSource Model

The `EventSource` struct (defined in `apps/strait/internal/domain/types.go`) contains the following fields:

| Field         | Type        | Description                                                                       |
| :------------ | :---------- | :-------------------------------------------------------------------------------- |
| `id`          | `string`    | Unique identifier.                                                                |
| `project_id`  | `string`    | The project this event source belongs to.                                         |
| `name`        | `string`    | Human-readable name, used to address the source during dispatch.                  |
| `description` | `string`    | Optional description of the source's purpose.                                     |
| `schema`      | `json`      | Optional JSON Schema for validating inbound event payloads.                       |
| `enabled`     | `bool`      | Whether the source accepts and routes events. Disabled sources reject dispatches. |
| `created_at`  | `time.Time` | Timestamp when the source was created.                                            |
| `updated_at`  | `time.Time` | Timestamp of the last update.                                                     |

## EventSubscription Model

An `EventSubscription` binds an event source to a target (a job or workflow). When an event is dispatched to the source, each enabled subscription is evaluated and, if matched, triggers its target.

| Field         | Type        | Description                                                     |
| :------------ | :---------- | :-------------------------------------------------------------- |
| `id`          | `string`    | Unique identifier.                                              |
| `source_id`   | `string`    | Reference to the parent `EventSource`.                          |
| `target_type` | `string`    | The kind of target: `job` or `workflow`.                        |
| `target_id`   | `string`    | The ID of the target job or workflow.                           |
| `filter_expr` | `json`      | Optional filter expression evaluated against the event payload. |
| `enabled`     | `bool`      | Whether this subscription is active.                            |
| `created_at`  | `time.Time` | Timestamp when the subscription was created.                    |

## Subscriptions

A subscription connects a source to a target. Two target types are supported:

* **`job`** -- When matched, a new job run is enqueued with `triggered_by: "event"` and the dispatched payload.
* **`workflow`** -- When matched, a new workflow run is triggered with the dispatched payload.

A single event source can have multiple subscriptions, each pointing to a different target and each with its own filter expression. This allows one inbound event to fan out to several jobs and workflows simultaneously.

## Filter Expressions

The optional `filter_expr` field on a subscription controls whether a dispatched event triggers that subscription. When present, the expression is evaluated against the event payload using `eventfilter.Eval`:

* If the expression evaluates to `true`, the subscription fires.
* If it evaluates to `false`, the subscription is skipped for that event.
* If `filter_expr` is omitted, the subscription fires on every dispatch.

<Tip>
  Use filter expressions to route different event shapes through a single source. For example, a `webhooks` source could route `"action": "created"` events to one job and `"action": "deleted"` events to another.
</Tip>

## Event Dispatch

The `POST /v1/events/dispatch` endpoint is the primary entry point for sending events into the system. The dispatch flow works as follows:

1. The source is looked up by `name` from the request body.
2. If the source is disabled, the dispatch is rejected.
3. Each subscription on the source is evaluated:
   * The `filter_expr` (if present) is evaluated against the event payload.
   * Matching subscriptions trigger their target (enqueue a job run or start a workflow run).
4. The response includes the number of subscriptions that fired:

```json theme={null}
{
  "dispatched": 2,
  "source": "webhook-events"
}
```

<Warning>
  A disabled event source rejects all dispatches. Subscriptions with `enabled: false` are also skipped during evaluation, even if their filter expression would match.
</Warning>

## Schema Validation

The optional `schema` field on an event source accepts a JSON Schema definition. When set, inbound event payloads can be validated against this schema before subscriptions are evaluated. This provides a contract between event producers and the source, catching malformed payloads early.

## CRUD Lifecycle

Event sources and their subscriptions are managed through the following API operations:

| Operation           | Method   | Path                                                          |
| :------------------ | :------- | :------------------------------------------------------------ |
| Create source       | `POST`   | `/v1/event-sources`                                           |
| List sources        | `GET`    | `/v1/event-sources`                                           |
| Get source          | `GET`    | `/v1/event-sources/{sourceID}`                                |
| Update source       | `PATCH`  | `/v1/event-sources/{sourceID}`                                |
| Delete source       | `DELETE` | `/v1/event-sources/{sourceID}`                                |
| Create subscription | `POST`   | `/v1/event-sources/{sourceID}/subscriptions`                  |
| List subscriptions  | `GET`    | `/v1/event-sources/{sourceID}/subscriptions`                  |
| Delete subscription | `DELETE` | `/v1/event-sources/{sourceID}/subscriptions/{subscriptionID}` |

## Related Concepts

* [Event Triggers](/concepts/event-triggers) -- Durable waits for events within workflow steps and runs.
* [Jobs](/concepts/jobs) -- The unit of work that event subscriptions can target.
* [Workflows](/concepts/workflows) -- Multi-step orchestrations that event subscriptions can target.
