# `step.waitForEvent`

`step.waitForEvent()` pauses a run until a matching event arrives or the wait times out. Inngest resumes the run with the event without keeping your function process running while it waits.

They are useful when:

- You need a response from another service before continuing.
- A person must approve or reject work.
- One event should be able to resume multiple matching runs.

## Why choose an event?

- **Resume several runs.** One event can resume multiple matching waits and trigger other functions.
- **Keep systems independent.** The sender publishes an event; it does not need to know which runs are waiting.
- **Keep an audit trail.** Inngest stores events for audit and Insights.

Use `step.waitForEvent` for most waits. If you must address one run directly and need lower resume latency, use [step.waitForSignal](/docs-markdown/durable-execution/primitives/step-waitforsignal). A signal resumes one run through a transactional API.

## Wait for invoice review

This function waits up to seven days for an invoice review. It matches the review to the invoice that started the run.

```typescript
import { eventType, Inngest, staticSchema } from "inngest";

type ApprovalRequested = { invoiceId: string };
type ApprovalRecorded = { invoiceId: string; approved: boolean };

const approvalRequested = eventType("invoice/approval.requested", {
  schema: staticSchema<ApprovalRequested>(),
});
const approvalRecorded = eventType("invoice/approval.recorded", {
  schema: staticSchema<ApprovalRecorded>(),
});

const inngest = new Inngest({ id: "billing" });

export const awaitInvoiceReview = inngest.createFunction(
  { id: "await-invoice-review", triggers: [approvalRequested] },
  async ({ event, step }) => {
    const review = await step.waitForEvent("wait-for-review", {
      event: approvalRecorded,
      match: "data.invoiceId",
      timeout: "7d",
    });

    if (review === null) {
      return { invoiceId: event.data.invoiceId, status: "timed-out" };
    }

    return {
      invoiceId: event.data.invoiceId,
      status: review.data.approved ? "approved" : "rejected",
    };
  }
);
```

Send `invoice/approval.recorded` with the same `invoiceId` after the wait starts. The returned event provides `review.data.approved`; a timeout returns `null`.

## API

```ts
const event = await step.waitForEvent(id, { event, timeout, match });
```

- **`id`**: a stable step ID.
- **`event`**: the name of the event to wait for.
- **`timeout`**: how long to wait, such as `"7d"`.
- **`match`**: a field both events share, such as `"data.invoiceId"`. For more specific matches, use an `if` expression instead.
- **Returns** the matching event, or `null` if the timeout expires.

Always handle the timeout, for example by recording an expired request or sending a reminder. See the [`step.waitForEvent` reference](/docs-markdown/reference/typescript/v4/functions/step-wait-for-event) for every option, including `if` expressions.

## Match the right event

Use a stable request or entity ID in both events. An event name alone can match unrelated runs. Sessions do not filter `step.waitForEvent()`; the event name and `match` or `if` determine the match.

The wait only sees events sent after it starts listening. If an external system can send a response before the wait begins, arrange the sequence so the wait is registered first or check the external state before waiting. A matching event sent earlier will not resume this wait.

Use `step.waitForEvent()` for events that can fan out to multiple functions or runs. For direct, latency-sensitive resumption of one run, see [step.waitForSignal](/docs-markdown/durable-execution/primitives/step-waitforsignal).

## Limits and related pages

- Check the current platform limits when choosing a timeout and shaping event or run data. The limit for a running step is a separate setting from a durable wait.
- In a `group.parallel()` race, a losing `step.waitForEvent()` remains active until its timeout. Use a short timeout when that pattern applies.
- For a delay with no external event, use [step.sleep](/docs-markdown/durable-execution/primitives/step-sleep).