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

# Triggering

> Start and list workflow runs from the corsair.workflows client, plus webhook and schedule triggers.

Once you've defined a workflow, your app reaches it through the `corsair.workflows` namespace. It's available on every client that has [Hub configured](/workflows/execution#turn-on-execution), and it's tenant-scoped like the rest of the SDK.

## Run a workflow

Call `run()` with the workflow id:

```ts theme={null}
const { status, runId } = await corsair.workflows.run('wf_123', {
    payload: { channel: 'C0123', message: 'Ship it' },
});
```

`run()` accepts:

| Option           | Type      | Purpose                                                          |
| ---------------- | --------- | ---------------------------------------------------------------- |
| `payload`        | `unknown` | Data handed to the workflow as its `payload` argument. Optional. |
| `idempotencyKey` | `string`  | Collapses retried triggers into a single run. Optional.          |

It resolves to `{ status, runId? }`, where `status` is `'ok'` when the run was accepted, and `runId` identifies it.

<Tip>
  Pass an `idempotencyKey` whenever a trigger might fire more than once (a retried request, an at-least-once queue). Two `run()` calls with the same key produce one run, not two.
</Tip>

## Scope to a tenant

In a multi-tenant app, resolve the tenant first. The run executes against that tenant's connected accounts:

```ts theme={null}
await corsair.withTenant('acme').workflows.run('wf_123', { payload });
```

In a single-tenant app, `corsair.workflows.run(...)` runs against the default tenant.

## List workflows

```ts theme={null}
const workflows = await corsair.workflows.list();
// [{ id, name, status, triggerType, createdAt, updatedAt }, ...]
```

Each entry is a `WorkflowSummary`, enough to render a list, show a status, and pick an id to `run()`.

## Trigger types

Manual `run()` is one of three ways a workflow starts. The other two are configured in Hub and need no call from you:

<CardGroup cols={2}>
  <Card title="Manual">
    Your app calls `corsair.workflows.run(id, { payload })`. The payload is yours to shape.
  </Card>

  <Card title="Webhook">
    An incoming [trigger](/concepts/webhooks) fires the workflow; the webhook body arrives as its `payload`.
  </Card>

  <Card title="Schedule">
    A cron or cadence configured in Hub runs the workflow on a timer; `payload` is empty.
  </Card>
</CardGroup>

However a run starts, it executes the same way. See [Execution & steps](/workflows/execution).
