Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ComposioHQ/composio/llms.txt

Use this file to discover all available pages before exploring further.

Triggers let your agent react to real-world events from connected apps in real time. When a trigger fires — a new email arrives, a GitHub PR is opened, a Slack message is sent — Composio delivers the event payload to your webhook endpoint or SDK subscription. Your code then decides what to do: run an agent, send a notification, update a database, or anything else.
Triggers require an active connected account for the user whose events you want to monitor. Make sure the user has authenticated with the relevant toolkit before creating a trigger.

Creating a trigger

First, inspect the trigger type to see what configuration it requires. Then create a trigger instance for a user’s connected account.
import { Composio } from '@composio/core';

const composio = new Composio({ apiKey: process.env.COMPOSIO_API_KEY });

// Inspect the trigger to see required config fields
const triggerType = await composio.triggers.getType("GITHUB_COMMIT_EVENT");
console.log(triggerType.config);
// { properties: { owner: {...}, repo: {...} }, required: ["owner", "repo"] }

// Create the trigger for a user
const trigger = await composio.triggers.create(
  "user_123",
  "GITHUB_COMMIT_EVENT",
  {
    triggerConfig: {
      owner: "my-org",
      repo: "my-repo",
    },
  }
);

console.log(trigger.triggerId); // "ti_abc123"
When you pass a userId, Composio automatically finds the user’s connected account for the relevant toolkit. If the user has multiple connected accounts for the same toolkit, the most recently created one is used. You can also pass a connectedAccountId directly for explicit control.

Subscribing to triggers

Composio delivers trigger events in two ways: webhooks (recommended for production) and SDK subscriptions (useful for local development and testing).

Webhooks

Register a publicly accessible webhook endpoint to receive events in production:
curl -X POST https://backend.composio.dev/api/v3.1/webhook_subscriptions \
  -H "X-API-KEY: your-composio-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "webhook_url": "https://myapp.com/webhook",
    "enabled_events": ["composio.trigger.message"]
  }'
Then handle the incoming events in your server:
// Example: Express.js webhook handler
import express from 'express';

const app = express();
app.use(express.json());

app.post('/webhook', async (req, res) => {
  const payload = req.body;

  if (payload.type === 'composio.trigger.message') {
    const triggerSlug = payload.metadata.trigger_slug;
    const eventData = payload.data;

    if (triggerSlug === 'GITHUB_COMMIT_EVENT') {
      console.log(`New commit by ${eventData.author}: ${eventData.message}`);
      // Run your agent, update your database, etc.
    }

    if (triggerSlug === 'GMAIL_NEW_EMAIL') {
      console.log(`New email from: ${eventData.from}`);
    }
  }

  res.status(200).json({ status: 'ok' });
});

SDK subscriptions (development)

Use SDK subscriptions to receive events without a public webhook URL — useful for local development and testing. Events are delivered over a WebSocket connection.
import { Composio } from '@composio/core';

const composio = new Composio({ apiKey: process.env.COMPOSIO_API_KEY });

// Subscribe to all triggers
await composio.triggers.subscribe(
  (data) => {
    console.log('Trigger received:', data.triggerSlug);
    console.log('User:', data.userId);
    console.log('Payload:', data.payload);
  }
);

// Subscribe with filters
await composio.triggers.subscribe(
  (data) => {
    console.log('New email received for:', data.userId);
    // Process the email event...
  },
  {
    triggerSlug: ["GMAIL_NEW_EMAIL"],
    userId: "user_123",
  }
);

Trigger event payload

Every trigger event carries a normalized payload. For webhook deliveries, the V3 format separates event metadata from the app-specific data:
{
  "id": "msg_abc123",
  "type": "composio.trigger.message",
  "timestamp": "2026-01-15T10:30:00Z",
  "metadata": {
    "log_id": "log_abc123",
    "trigger_slug": "GITHUB_COMMIT_EVENT",
    "trigger_id": "ti_xyz789",
    "connected_account_id": "ca_def456",
    "auth_config_id": "ac_xyz789",
    "user_id": "user_123"
  },
  "data": {
    "commit_sha": "a1b2c3d",
    "message": "fix: resolve null pointer",
    "author": "jane"
  }
}
For SDK subscriptions, the event is delivered as an IncomingTriggerPayload:
FieldTypeDescription
idstringUnique trigger instance ID
triggerSlugstringThe trigger type (e.g., GITHUB_COMMIT_EVENT)
toolkitSlugstringThe toolkit the event came from (e.g., GITHUB)
userIdstringYour user ID associated with this event
payloadRecord<string, unknown>App-specific event data
metadata.connectedAccount.idstringThe connected account that fired the event
metadata.authConfigIdstringThe auth config used for this connection
To know exactly what fields will be in payload / data for a trigger type, inspect its schema:
const triggerType = await composio.triggers.getType("GITHUB_COMMIT_EVENT");
console.log(triggerType.payload);
// { properties: { author: {...}, message: {...}, commit_sha: {...} } }

Available triggers

Triggers are available for all toolkits that support webhooks or polling. Some common examples:
Trigger slugAppDescription
GMAIL_NEW_EMAILGmailFires when a new email is received
GITHUB_COMMIT_EVENTGitHubFires on every new commit to a repository
GITHUB_PULL_REQUEST_EVENTGitHubFires when a PR is opened, updated, or merged
SLACK_NEW_MESSAGESlackFires when a new message is posted in a channel
SLACK_NEW_DIRECT_MESSAGESlackFires when a direct message is received
NOTION_PAGE_UPDATEDNotionFires when a Notion page is modified
LINEAR_ISSUE_CREATEDLinearFires when a new issue is created
List all available trigger types for a toolkit:
const triggerTypes = await composio.triggers.listTypes({
  toolkits: ["github"],
});

triggerTypes.items.forEach((t) => {
  console.log(t.slug, '-', t.description);
});

Managing triggers

Listing active triggers

const active = await composio.triggers.listActive({
  connectedAccountIds: ["ca_def456"],
});

for (const trigger of active.items) {
  console.log(`${trigger.id} (${trigger.triggerName})`);
}

// Paginate
if (active.nextCursor) {
  const nextPage = await composio.triggers.listActive({
    cursor: active.nextCursor,
  });
}

Enabling and disabling triggers

Pause a trigger without deleting it — useful for temporarily stopping event delivery:
// Disable a trigger
await composio.triggers.disable("ti_abc123");

// Re-enable when needed
await composio.triggers.enable("ti_abc123");

Deleting a trigger

Permanently remove a trigger instance. Use disable() instead if you may need it again.
await composio.triggers.delete("ti_abc123");

Unsubscribing (SDK subscriptions)

Stop receiving events from an SDK subscription:
// Unsubscribes the WebSocket connection for all active subscriptions
await composio.triggers.unsubscribe();

Connected Accounts

Set up the connections that trigger events come from

Authentication

Auth configs and Connect Links for user onboarding

Sessions

Running agents in response to trigger events

Observability

Inspect trigger event logs and debug delivery issues

Build docs developers (and LLMs) love