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

# Subscribing to Events

> Subscribe to workflow events and validation alerts

### Flow Control

Control how many notifications can be pending at once:

<CodeGroup>
  ```javascript JavaScript theme={null}
  const threadify = await Threadify.connect('your-api-key', 'my-service', {
    maxInFlight: 50  // Default: 10, Max: 100
  });
  ```

  ```go Go theme={null}
  conn, err := threadify.Connect(ctx, "your-api-key", 
      threadify.WithServiceName("my-service"),
      threadify.WithMaxInFlight(50), // Default: 10, Max: 100
  )
  if err != nil {
      log.Fatal(err)
  }
  ```

  ```python Python theme={null}
  from threadify import Threadify

  connection = await Threadify.connect(
      "your-api-key",
      service_name="my-service",
      max_in_flight=50,  # Default: 10, Max: 100
  )
  ```
</CodeGroup>

Notifications are **HPA-safe** - each delivered to exactly one pod in your cluster.

### Event Patterns

| Pattern            | Triggers On                |
| ------------------ | -------------------------- |
| `thread.cancelled` | Thread cancelled           |
| `thread.completed` | Thread completed           |
| `step.success`     | Step succeeded             |
| `step.failed`      | Step failed                |
| `rule.violated`    | Contract violation         |
| `rule.passed`      | Contract validation passed |
| `step.*`           | Any step event (wildcard)  |
| `rule.*`           | Any validation (wildcard)  |

### Subscribing

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Thread events (2 parameters)
  threadify.on('thread.completed', (notification) => {
    console.log('Thread completed');
    notification.ack();
  });

  // Step events (3 parameters: event, stepName, handler)
  threadify.on('step.failed', 'payment_processed', (notification) => {
    console.error('Payment failed:', notification.message);
    notification.ack();
  });

  // Contract-specific (use @ syntax)
  threadify.on('rule.violated', 'product_delivery@order_placed', (notification) => {
    console.error('Contract violation:', notification.message);
    notification.ack();
  });
  ```

  ```go Go theme={null}
  // Thread events
  err := conn.Subscribe(ctx, "thread.completed", "", func(n *threadify.Notification) {
      fmt.Println("Thread completed")
      n.Ack()
  })
  if err != nil {
      log.Fatal(err)
  }

  // Step events (specify step name)
  err = conn.Subscribe(ctx, "step.failed", "payment_processed", func(n *threadify.Notification) {
      fmt.Printf("Payment failed: %s\n", n.Message)
      n.Ack()
  })
  if err != nil {
      log.Fatal(err)
  }

  // Contract-specific (use @ syntax)
  err = conn.Subscribe(ctx, "rule.violated", "product_delivery@order_placed", func(n *threadify.Notification) {
      fmt.Printf("Contract violation: %s\n", n.Message)
      n.Ack()
  })
  if err != nil {
      log.Fatal(err)
  }
  ```

  ```python Python theme={null}
  # Thread events
  def on_thread_completed(notification):
      print("Thread completed")
      notification.ack()

  connection.subscribe("thread.completed", on_thread_completed)

  # Step events (specify step name)
  def on_payment_failed(notification):
      print(f"Payment failed: {notification.message}")
      notification.ack()

  connection.subscribe("step.failed", "payment_processed", on_payment_failed)

  # Contract-specific (use @ syntax)
  def on_contract_violation(notification):
      print(f"Contract violation: {notification.message}")
      notification.ack()

  connection.subscribe("rule.violated", "product_delivery@order_placed", on_contract_violation)
  ```
</CodeGroup>

### Notification Properties

| Property         | Type   | Description                   |
| ---------------- | ------ | ----------------------------- |
| `notificationId` | string | Unique notification ID        |
| `threadId`       | string | Thread ID                     |
| `stepName`       | string | Step name                     |
| `stepStatus`     | string | `success` or `failed`         |
| `status`         | string | `passed` or `violated`        |
| `severity`       | string | `info`, `warning`, `critical` |
| `message`        | string | Human-readable message        |
| `timestamp`      | string | ISO timestamp                 |
| `ack()`          | method | Acknowledge notification      |

### Next Steps

<CardGroup cols={2}>
  <Card title="Handling Notifications" icon="code" href="/core-concepts/notifications/handling">
    Learn how to process and acknowledge notifications
  </Card>

  <Card title="Working with Contracts" icon="file-contract" href="/core-concepts/working-with-contracts">
    Understand contract validation
  </Card>
</CardGroup>
