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

# Event Waiting + Correlation

> Pause a workflow until the right external event arrives, then resume the correct run.

<Tip>
  **Live.** This area is documented as current, user-reliable behavior.
</Tip>

## Goal

Use event waiting and correlation keys for user actions, payments, webhooks, and external approvals.

## Prerequisites

* A workflow that needs to wait for something outside the process

## Workflow

<Steps>
  <Step>
    Wait for an event by name.
  </Step>

  <Step>
    Use a correlation key that identifies the specific user, order, invoice, or resource.
  </Step>

  <Step>
    Send the external event with the same event name and correlation key.
  </Step>

  <Step>
    Decide what should happen if the event never arrives.
  </Step>
</Steps>

## Wait for an event

Backend flows often need to pause for something external: an email click, payment confirmation, manual approval, or webhook from another system.

<CodeGroup>
  ```ts Pause the workflow theme={null}
  await step.waitForEvent('email.verified', {
    correlationKey: `user:${userId}`,
    timeout: '24h',
    onTimeout: 'fail',
  })
  ```

  ```go Go theme={null}
  event, err := job.Step.WaitForEvent(ctx, "email.verified", stackshift.WaitForEventOptions{
    CorrelationKey: "user:" + userID,
    Timeout: "24h",
    OnTimeout: "fail",
  })
  ```
</CodeGroup>

## What happens while waiting

* The workflow pauses.
* State and completed steps are saved.
* No compute runs while the workflow is waiting.
* The workflow resumes when a matching event arrives.

## Correlation

Multiple workflows may wait for the same event name. Correlation tells StackShift which waiting run should resume.

Matching uses the event name plus correlationKey.

<CodeGroup>
  ```ts Send the matching event theme={null}
  await stackshift.events.send(
    'email.verified',
    { userId: '123' },
    {
      correlationKey: 'user:123',
      idempotencyKey: 'email.verified:user:123',
    }
  )
  ```

  ```go Go theme={null}
  event, err := client.Events.Send(ctx, "email.verified", map[string]any{
    "userId": "123",
  }, stackshift.SendEventOptions{
    CorrelationKey: "user:123",
    IdempotencyKey: "email.verified:user:123",
  })
  ```
</CodeGroup>

## Timeout behavior

* fail: mark the run failed when the timeout expires.
* continue: resume the workflow with a timeout result so your code can choose the next step.
* cancel: cancel the run when waiting is no longer useful.

## Durable events

* Events are stored durably.
* An event can arrive before or after the workflow reaches the wait.
* StackShift matches stored events and waiting runs by event name and correlation key.

## Expected result

<Check>
  The right workflow resumes even when many workflows are waiting for the same event name.
</Check>

## Related guides

<CardGroup cols={2}>
  <Card title="Durable Jobs workflows" href="/durable-jobs/workflows">
    Use steps and events to build multi-step jobs that can retry, pause, and resume.
  </Card>

  <Card title="Idempotency" href="/durable-jobs/idempotency">
    Use idempotency keys so duplicate requests do not create duplicate work.
  </Card>
</CardGroup>
