---
title: Create Triggers for Real-Time Events
impact: HIGH
description: Set up trigger instances to receive real-time events from connected accounts
tags: [triggers, events, webhooks, real-time, notifications]
---

# Create Triggers for Real-Time Events

Triggers receive real-time events from connected accounts (Gmail, GitHub, Slack, etc.). Create trigger instances to subscribe to specific events.

> **⚠️ IMPORTANT:** Do NOT make up or guess trigger names. Always verify trigger slugs before using them:
> - Use `composio manage triggers list` to discover and `composio manage triggers info "TRIGGER_NAME"` to see configuration schema (CLI)
> - Use `composio.triggers.list()` to discover available triggers programmatically (SDK)
>
> See [Composio CLI Reference](./composio-cli.md) for discovery commands.

## Basic Usage

```typescript
import { Composio } from '@composio/core';

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

// Create trigger for specific connected account
const trigger = await composio.triggers.create(
  'user_123',
  'GMAIL_NEW_GMAIL_MESSAGE',
  {
    connectedAccountId: 'conn_abc123',
    triggerConfig: {
      labelIds: 'INBOX',
      userId: 'me',
      interval: 60
    }
  }
);

console.log('Trigger ID:', trigger.triggerId);
```

## SDK Auto-Discovery

Omit `connectedAccountId` to let SDK find the account automatically:

```typescript
// SDK finds user's Gmail connection
const trigger = await composio.triggers.create(
  'user_123',
  'GMAIL_NEW_GMAIL_MESSAGE',
  {
    triggerConfig: { labelIds: 'INBOX', interval: 60 }
  }
);
```

## Automatic Reuse

Triggers with identical configuration are automatically reused:

```typescript
// First call creates trigger
const trigger1 = await composio.triggers.create(
  'user_123',
  'GMAIL_NEW_GMAIL_MESSAGE',
  { triggerConfig: { labelIds: 'INBOX' } }
);

// Second call returns same trigger (no duplicate)
const trigger2 = await composio.triggers.create(
  'user_123',
  'GMAIL_NEW_GMAIL_MESSAGE',
  { triggerConfig: { labelIds: 'INBOX' } }
);

console.log(trigger1.triggerId === trigger2.triggerId); // true
```

## Version Pinning

Pin trigger versions in production to prevent breaking changes:

```typescript
const composio = new Composio({
  apiKey: process.env.COMPOSIO_API_KEY,
  triggerVersions: {
    'GMAIL_NEW_GMAIL_MESSAGE': '12082025_00',
    'GITHUB_COMMIT_EVENT': '12082025_00'
  }
});

// Uses pinned version
const trigger = await composio.triggers.create(
  'user_123',
  'GMAIL_NEW_GMAIL_MESSAGE',
  { triggerConfig: { labelIds: 'INBOX' } }
);
```

**Why pin versions:**
- Prevents config schema changes
- Ensures production stability
- Updates on your schedule

## Trigger Configuration Examples

```typescript
// Gmail - New messages in specific label
await composio.triggers.create('user_123', 'GMAIL_NEW_GMAIL_MESSAGE', {
  triggerConfig: {
    labelIds: 'INBOX',
    userId: 'me',
    interval: 60
  }
});

// GitHub - New commits
await composio.triggers.create('user_123', 'GITHUB_COMMIT_EVENT', {
  triggerConfig: {
    owner: 'composio',
    repo: 'sdk',
    branch: 'main'
  }
});

// Slack - New messages in channel
await composio.triggers.create('user_123', 'SLACK_NEW_MESSAGE', {
  triggerConfig: {
    channelId: 'C123456',
    botUserId: 'U123456'
  }
});
```

## Error Handling

```typescript
try {
  const trigger = await composio.triggers.create(
    'user_123',
    'GMAIL_NEW_GMAIL_MESSAGE',
    { triggerConfig: { labelIds: 'INBOX' } }
  );
} catch (error) {
  if (error.name === 'ComposioConnectedAccountNotFoundError') {
    // User hasn't connected Gmail yet
    console.log('Please connect your Gmail account');
  } else if (error.name === 'ValidationError') {
    // Invalid trigger config
    console.error('Invalid configuration:', error.message);
  } else {
    throw error;
  }
}
```

## Discover Available Triggers

```typescript
// Get all triggers
const triggers = await composio.triggers.list();

// Search by keyword
const emailTriggers = await composio.triggers.list({ search: 'email' });

// Filter by toolkit
const slackTriggers = await composio.triggers.list({ toolkit: 'slack' });

// Get trigger details
const trigger = await composio.triggers.getTrigger('GMAIL_NEW_GMAIL_MESSAGE');
console.log(trigger.config); // Shows required config fields
```

## List Active Triggers

```typescript
// All active triggers
const active = await composio.triggers.getActiveTriggers();

// By trigger slug
const gmailTriggers = await composio.triggers.getActiveTriggers({
  triggerSlugs: ['GMAIL_NEW_GMAIL_MESSAGE']
});

// By connected account
const accountTriggers = await composio.triggers.getActiveTriggers({
  connectedAccountIds: ['conn_abc123']
});

// Combine filters
const userSlackTriggers = await composio.triggers.getActiveTriggers({
  triggerSlugs: ['SLACK_NEW_MESSAGE'],
  connectedAccountIds: ['conn_def456']
});
```

## Common Patterns

### Check Before Creating

```typescript
async function ensureTrigger(userId: string, triggerSlug: string, config: any) {
  // Check if trigger exists
  const existing = await composio.triggers.getActiveTriggers({
    triggerSlugs: [triggerSlug]
  });

  if (existing.items.length > 0) {
    return existing.items[0];
  }

  // Create if doesn't exist
  return await composio.triggers.create(userId, triggerSlug, {
    triggerConfig: config
  });
}
```

### Onboarding Flow

```typescript
async function setupUserTriggers(userId: string) {
  // Check connected accounts
  const accounts = await composio.connectedAccounts.list({
    userIds: [userId]
  });

  // Create triggers for each service
  for (const account of accounts.items) {
    if (account.toolkit.slug === 'gmail') {
      await composio.triggers.create(userId, 'GMAIL_NEW_GMAIL_MESSAGE', {
        connectedAccountId: account.id,
        triggerConfig: { labelIds: 'INBOX' }
      });
    }
  }
}
```

## Key Points

- **Use proper user IDs** - Never use 'default' in production
- **Requires connected account** - User must authenticate first
- **Automatic reuse** - Identical configs share same trigger instance
- **Pin versions** - Prevents breaking changes in production
- **Error handling** - Handle missing connections gracefully
