Docs

Events

The event bus, event types, and how modules communicate.

The Event Bus

While uses an in-process event bus for inter-module communication. When a module performs an action (deploy, error ingestion, etc.), it emits a typed event. Other modules can listen to specific event types or subscribe to all events using the wildcard * pattern.

The webhooks module listens on * and dispatches matching events to registered webhook URLs. This is how external systems (like your AI agent) receive real-time notifications without polling.

Event Structure

Every event in While follows the WhileEvent interface:

interface WhileEvent {
  type: string;            // e.g. "deployment.triggered"
  tenantId: string;        // tenant that owns the resource
  projectId?: string;      // project context (if applicable)
  environmentId?: string;  // environment context (if applicable)
  payload: Record<string, unknown>;  // event-specific data
  timestamp: Date;         // when the event occurred
}

Events are scoped to a tenant. The projectId and environmentId fields provide hierarchical context for filtering and routing.

How Modules Use Events

Emitting events (from an action handler)

// Inside triggerDeploy action:
ctx.eventBus?.emit({
  type: "deployment.triggered",
  tenantId: ctx.tenantId,
  projectId: env.project.id,
  environmentId,
  payload: { deploymentId: deployment.id, gitUrl, commitSha },
  timestamp: new Date(),
});

Listening to events (in module definition)

// In webhooks module:
events: {
  emits: ["webhook.delivered", "webhook.failed"],
  listens: {
    "*": handleEvent,  // wildcard — receives ALL events
  },
}

Event Flow

Action (e.g. triggerDeploy)
  │
  ├─ emit("deployment.triggered")
  │
  ▼
EventBus
  │
  ├─ webhooks module (*) ─── POST to registered URLs
  ├─ other listeners...
  │
  ▼
Events stored in DB (audit trail)
  │
  ▼
Visible in Activity feed (/activity)

All Event Types

15 event types

Deployment Events

Emitted by the deploy module during the build and release lifecycle.

deployment.triggered

Deployment queued for building

payload: deploymentId, gitUrl, appId, commitSha
deployment.building

Container image build started

payload: deploymentId, status
deployment.running

Deployment live and serving traffic

payload: deploymentId, status, image
deployment.failed

Build or rollout failed

payload: deploymentId, status, error
deployment.cancelled

Deployment cancelled by user/agent

payload: deploymentId

Project Events

Emitted when projects and environments are created or removed.

project.created

New project created with environments

payload: projectId, name, slug
project.deleted

Project and all resources deleted

payload: projectId, name

Error Events

Emitted when application errors are ingested or resolved.

error.detected

New error ingested from application

payload: errorId, message, file, line, deploymentId
error.resolved

Error marked as resolved

payload: errorId, message

Uptime Events

Emitted by uptime checks when health status changes.

uptime.down

Health check returned non-200 or timed out

payload: checkId, url, statusCode
uptime.recovered

Previously failing check is healthy

payload: checkId, url, statusCode

Scale Events

Emitted when replica counts change or pods restart.

scale.changed

Replica count adjusted

payload: environmentId, from, to
scale.restarted

Rolling restart initiated

payload: environmentId, appId

Webhook Events

Emitted by the webhook dispatch system itself.

webhook.delivered

Payload delivered successfully

payload: webhookId, url, statusCode
webhook.failed

Delivery failed (non-2xx or timeout)

payload: webhookId, url, error

Events + Webhooks

The webhooks module listens to all events and dispatches matching ones to your registered webhook URLs. When you create a webhook with events: ["deployment.failed"], the webhooks module filters the event stream and only forwards matching events.

See the Webhooks guide for setup, payload format, and signature verification.