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

# Events

> Send events, trigger workflows with them and wait on them inside a run.

An event is a name and some data. Every workflow whose trigger names the event
starts a run, and every run waiting on it wakes.

## Send one

```ts theme={null}
import { createClient } from "@duraton/sdk/client";

const client = createClient({ url, apiKey: "dtn_sk_..." });

await client.events.send({ name: "order/paid", data: { orderId: "o_1" } });
await client.events.sendMany([
  { name: "order/paid", data: { orderId: "o_2" } },
  { name: "order/paid", data: { orderId: "o_3" } },
]);
```

Over HTTP, `POST /events` takes one event or an array and answers `202`.

## See what arrived

```ts theme={null}
const { data } = await client.events.list({ name: "order/paid", source: "api" });
const event = await client.events.get(data[0].id);
```

`GET /events` lists the events the project received, newest first, and
`GET /events/{id}` reads one. Each is `{ id, name, app?, source, data?,
receivedAt, woke, triggered }`: `source` is how it arrived (`api` for a send,
`emit` for a step's emit, `webhook` for an inbound webhook), `woke` how many
waiting runs it woke, and `triggered` one entry per workflow it matched, with
the `runId` it started, or `skipped`, `dropped`, `debounced`, `batched` or
`deduped` when it started none. Filter by `name`, `app`, `source`, `since`
(included) and `until` (excluded), both RFC 3339.

## Trigger a workflow

```ts theme={null}
defineWorkflow({
  name: "fulfil-order",
  triggers: [{ event: "order/paid", if: 'event.data.currency == "EUR"' }],
  handler: async ({ event, step }) => {
    // ...
  },
});
```

`if` is an optional condition on the event, written as in a wait below; a
workflow may list several triggers.

## Wait for one inside a run

```ts theme={null}
const shipped = await step.waitForEvent("wait-for-shipping", {
  event: "order/shipped",
  timeout: "7d",
  if: `event.data.orderId == "${event.data.orderId}"`,
});
```

It answers the event, or `null` once the timeout passes.

## Reserved names

An event name under a reserved prefix is refused with `422
event_name_reserved`: the name of any module followed by `/` (for example
`database/`, `workflows/`), `project/` and `duraton/`. Those events come from
the platform itself, and a workflow can be triggered by them:

| Event | Data |
| - | - |
| `database/database.created`, `.deleted`, `.resumed` | `{ databaseId }` |
| `database/database.paused` | `{ databaseId, reason }`: `owner`, `idle`, `storage_cap` or `operator` |
| `database/database.read_only_entered`, `.read_only_exited` | `{ sizeBytes, limitBytes }` |
| `database/export.completed`, `database/restore.completed` | `{ databaseId, jobId, status }`: `succeeded`, `failed` or `canceled` |
| `project/key.created`, `project/key.revoked` | `{ keyId, keyKind }` |

Each platform event starts at most one run of each workflow it triggers,
however often it is delivered.

## While Workflows is off

A project whose workflows are switched off still accepts events and answers
`{ "woke": 0, "suspended": true }`; nothing starts.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.