# Triggers and Webhook Handlers for Event-Driven Workflows in simstudioai/sim

> Explore simstudioai/sim's event-driven workflows. Discover standardized webhook handlers and a modular trigger system for seamless integration and rapid execution of your automated tasks.

- Repository: [Sim/sim](https://github.com/simstudioai/sim)
- Tags: how-to-guide
- Published: 2026-05-02

---

**The simstudioai/sim repository implements event-driven workflows through a modular trigger system where each integration lives in `apps/sim/triggers/<service>/` and exposes a standardized webhook handler that validates external payloads, maps them to normalized `TriggerEvent` objects, and enqueues workflow executions via the `runTrigger()` function.**

The simstudioai/sim platform provides a comprehensive event-driven workflow architecture that converts external SaaS events into automated workflow executions. This system organizes triggers and webhook handlers within a predictable directory structure under `apps/sim/triggers/`, enabling integrations with services ranging from GitHub to Stripe. Understanding the trigger lifecycle—from incoming webhook validation to execution enqueueing—is essential for developers extending or debugging the platform's event handling capabilities.

## Trigger Architecture and Directory Structure

Each trigger integration follows a consistent four-file pattern within `apps/sim/triggers/<service>/`:

- **[`index.ts`](https://github.com/simstudioai/sim/blob/main/index.ts)**: Registers the trigger with the platform, exposing the trigger ID, display name, UI configuration schema, and supported event types.
- **[`webhook.ts`](https://github.com/simstudioai/sim/blob/main/webhook.ts)**: Implements the HTTP POST handler that receives third-party webhooks, validates request signatures, and initiates workflow executions.
- **`event-*.ts`**: Service-specific event converters that map raw webhook payloads to the normalized `TriggerEvent` interface consumed by the executor.
- **[`utils.ts`](https://github.com/simstudioai/sim/blob/main/utils.ts)**: Helper functions for signature verification, payload normalization, and generating UI instructions for webhook URL configuration.

All webhook handlers are registered as Next.js API routes in `apps/sim/app/api/v1/triggers/<service>/route.ts`, which simply forwards incoming requests to the respective service's [`webhook.ts`](https://github.com/simstudioai/sim/blob/main/webhook.ts) handler.

## Catalog of Built-in Triggers

The platform supports **webhook-based** triggers for real-time events and **polling-based** triggers for services without native webhook support.

### Webhook-Based Triggers

These services push events to the platform via HTTP POST requests:

- **GitHub**: [`apps/sim/triggers/github/webhook.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/github/webhook.ts) — Handles push events, pull request lifecycle (opened/closed/merged), issues, comments, releases, and workflow runs.
- **Stripe**: [`apps/sim/triggers/stripe/webhook.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/stripe/webhook.ts) — Processes payment succeeded, invoice created, and subscription updated events.
- **Zoom**: [`apps/sim/triggers/zoom/webhook.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/zoom/webhook.ts) — Captures meeting start/end, participant join/leave, and recording completion.
- **Slack**: [`apps/sim/triggers/slack/webhook.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/slack/webhook.ts) — Responds to message posted and reaction added events.
- **Airtable**: [`apps/sim/triggers/airtable/webhook.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/airtable/webhook.ts) — Triggers on record creation, updates, and deletion.
- **Calendly**: [`apps/sim/triggers/calendly/webhook.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/calendly/webhook.ts) — Handles invitee creation, cancellation, and rescheduling.
- **Jira**: [`apps/sim/triggers/jira/webhook.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/jira/webhook.ts) — Monitors issue creation, updates, comments, and sprint events.
- **Salesforce**: [`apps/sim/triggers/salesforce/webhook.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/salesforce/webhook.ts) — Processes record change events.
- **Webflow**: [`apps/sim/triggers/webflow/webhook.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/webflow/webhook.ts) — Captures form submissions and collection item changes.

Additional webhook integrations include Asana, Ashby, Attio, Cal.com, CircleBack, Fathom, Fireflies, Google Forms, Gong, JSM (Jira Service Management), Intercom, Lemlist, Notion, Pipedrive, RingCentral, Telegram, Twilio Voice, Vercel, and WhatsApp.

### Polling-Based Triggers

For services lacking webhook capabilities, the platform uses polling handlers located in [`poller.ts`](https://github.com/simstudioai/sim/blob/main/poller.ts) files:

- **Google Calendar**: [`apps/sim/triggers/google-calendar/poller.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/google-calendar/poller.ts) — Polls for event creation, updates, and deletion.
- **Google Drive**: [`apps/sim/triggers/google-drive/poller.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/google-drive/poller.ts) — Detects file additions and modifications.
- **Google Sheets**: [`apps/sim/triggers/google-sheets/poller.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/google-sheets/poller.ts) — Monitors for row additions and updates.
- **Outlook**: [`apps/sim/triggers/outlook/poller.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/outlook/poller.ts) — Polls for incoming mail and calendar changes.
- **RSS**: [`apps/sim/triggers/rss/poller.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/rss/poller.ts) — Checks for new feed items.

## How Webhook Handlers Process Events

Every webhook handler in simstudioai/sim follows a standardized execution flow. The GitHub integration provides a canonical example of this pattern.

### 1. Route Registration and Entry Point

Incoming requests hit [`apps/sim/app/api/v1/triggers/github/route.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/app/api/v1/triggers/github/route.ts), which forwards the POST request to [`apps/sim/triggers/github/webhook.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/github/webhook.ts). This thin routing layer allows the platform to leverage Next.js API route conventions while keeping business logic organized in the triggers directory.

### 2. Signature Verification

The handler first validates the request authenticity using service-specific logic in [`apps/sim/triggers/github/utils.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/github/utils.ts). The `verifySignature(payload, signatureHeader)` function verifies the HMAC signature provided in the `x-hub-signature-256` header against the configured webhook secret.

### 3. Event Routing and Normalization

After validation, the handler extracts the event type from the `x-github-event` header and routes to the appropriate event converter file:

```typescript
// Example from apps/sim/triggers/github/webhook.ts
const eventName = request.headers.get('x-github-event');
const { toTriggerEvent } = await import(`./event-${eventName}.ts`);
const triggerEvent = toTriggerEvent(payload);

```

Individual event files like [`apps/sim/triggers/github/push.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/github/push.ts) and [`apps/sim/triggers/github/issue_opened.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/github/issue_opened.ts) implement `toTriggerEvent(payload): TriggerEvent`, normalizing disparate payload structures into the platform's standard event schema.

### 4. Execution Enqueueing

Finally, the normalized event passes to `runTrigger(event)`, defined in [`apps/sim/lib/triggers/runner.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/lib/triggers/runner.ts). This function creates a workflow execution record in the database and enqueues the job for processing by the executor service. The webhook handler returns the job ID to the caller:

```typescript
const job = await runTrigger(triggerEvent);
return NextResponse.json({ ok: true, jobId: job.id });

```

## Implementing a Custom Trigger

To add a new service integration, create the standard four-file structure. Below is a complete skeleton for a hypothetical `myservice` integration:

```typescript
// apps/sim/triggers/myservice/index.ts
import type { TriggerConfig } from '@/triggers/types';
import { webhook } from './webhook';
import { MyServiceIcon } from '@/components/icons';

export const myserviceTrigger: TriggerConfig = {
  id: 'myservice',
  name: 'My Service',
  description: 'Handles events from My Service',
  icon: MyServiceIcon,
  webhook,
  events: ['event_a', 'event_b'],
};

```

```typescript
// apps/sim/triggers/myservice/webhook.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { verifySignature } from './utils';
import { toEventA } from './event_a';
import { toEventB } from './event_b';
import { runTrigger } from '@/lib/triggers/runner';

export async function POST(request: NextRequest) {
  const raw = await request.text();
  
  if (!verifySignature(raw, request.headers.get('x-myservice-signature'))) {
    return NextResponse.json({ error: 'Invalid signature' }, { status: 400 });
  }
  
  const payload = JSON.parse(raw);
  const eventName = request.headers.get('x-myservice-event')!;

  const triggerEvent =
    eventName === 'event_a' ? toEventA(payload) :
    eventName === 'event_b' ? toEventB(payload) :
    null;

  if (!triggerEvent) {
    return NextResponse.json({ error: 'Unsupported event' }, { status: 400 });
  }

  const job = await runTrigger(triggerEvent);
  return NextResponse.json({ ok: true, jobId: job.id });
}

```

## Key Files Reference

Understanding the following files is critical for working with triggers and webhook handlers in simstudioai/sim:

- **`apps/sim/triggers/<service>/index.ts`**: Declares trigger metadata and UI configuration.
- **`apps/sim/triggers/<service>/webhook.ts`**: Core HTTP handler implementing validation and event processing.
- **`apps/sim/triggers/<service>/utils.ts`**: Signature verification and payload helpers.
- **`apps/sim/triggers/<service>/event-*.ts`**: Normalization functions converting service payloads to `TriggerEvent`.
- **[`apps/sim/lib/triggers/runner.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/lib/triggers/runner.ts)**: Central execution routine that persists and enqueues workflow jobs.
- **`apps/sim/app/api/v1/triggers/<service>/route.ts`**: Next.js API route forwarding layer.

## Summary

- **Triggers** in simstudioai/sim reside in `apps/sim/triggers/<service>/` and follow a standardized four-file architecture: [`index.ts`](https://github.com/simstudioai/sim/blob/main/index.ts), [`webhook.ts`](https://github.com/simstudioai/sim/blob/main/webhook.ts), `event-*.ts`, and [`utils.ts`](https://github.com/simstudioai/sim/blob/main/utils.ts).
- **Webhook handlers** validate incoming requests using service-specific signature verification, normalize payloads into `TriggerEvent` objects, and invoke `runTrigger()` from [`apps/sim/lib/triggers/runner.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/lib/triggers/runner.ts) to enqueue workflow executions.
- **Polling triggers** like Google Calendar and RSS use [`poller.ts`](https://github.com/simstudioai/sim/blob/main/poller.ts) implementations instead of webhooks to detect changes.
- **Route registration** occurs in `apps/sim/app/api/v1/triggers/<service>/route.ts`, which forwards requests to the respective service's webhook handler.
- All **event converters** implement a `toTriggerEvent()` function that ensures external payloads conform to the platform's internal event schema.

## Frequently Asked Questions

### How do I add a new webhook trigger to simstudioai/sim?

Create a directory under `apps/sim/triggers/<service>/` containing [`index.ts`](https://github.com/simstudioai/sim/blob/main/index.ts) for configuration, [`webhook.ts`](https://github.com/simstudioai/sim/blob/main/webhook.ts) for the HTTP handler, and individual `event-*.ts` files for each event type you support. Implement signature verification in [`utils.ts`](https://github.com/simstudioai/sim/blob/main/utils.ts) using the service's documented method, then register the route in `apps/sim/app/api/v1/triggers/<service>/route.ts` that imports your webhook handler.

### What is the difference between webhook and polling triggers in this repository?

**Webhook triggers** receive real-time HTTP POST requests from external services to endpoints like `/api/v1/triggers/github`, requiring immediate validation and response. **Polling triggers**, such as those for Google Calendar in [`apps/sim/triggers/google-calendar/poller.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/triggers/google-calendar/poller.ts), periodically query external APIs to detect changes and do not require public webhook endpoints.

### How does the platform validate webhook signatures?

Each service implements a `verifySignature()` function in its [`utils.ts`](https://github.com/simstudioai/sim/blob/main/utils.ts) file. For example, the GitHub trigger uses HMAC-SHA256 verification against the `x-hub-signature-256` header, while Stripe uses timestamped signatures to prevent replay attacks. The webhook handler rejects requests with invalid signatures before processing the payload.

### Where are workflow executions queued after a trigger fires?

After validation and normalization, the `runTrigger()` function in [`apps/sim/lib/triggers/runner.ts`](https://github.com/simstudioai/sim/blob/main/apps/sim/lib/triggers/runner.ts) creates a workflow execution record in the database and enqueues the job for the executor service. This function returns a job ID that the webhook handler includes in its HTTP response to the calling service.