|
| 1 | +--- |
| 2 | +title: "Webhook Subscriptions API & Connection Expiry Events" |
| 3 | +description: "New API for managing webhook configurations with event filtering, plus a new event to notify when connected accounts expire" |
| 4 | +date: "2026-02-06" |
| 5 | +--- |
| 6 | + |
| 7 | +A new API for managing webhook configurations with event filtering, HMAC signature verification, and support for platform lifecycle events. This replaces the legacy project-level webhook settings with a more flexible, subscription-based model. |
| 8 | + |
| 9 | +## Summary |
| 10 | + |
| 11 | +| Change | Type | Action Required | |
| 12 | +|--------|------|-----------------| |
| 13 | +| New Webhook Subscriptions API | New Feature | No | |
| 14 | +| `composio.connected_account.expired` event | New Feature | Opt-in | |
| 15 | +| Legacy webhook endpoints | Deprecated | Migration recommended | |
| 16 | +| `webhook_url`, `webhook_secret` in Project | Deprecated | Use new API | |
| 17 | + |
| 18 | +--- |
| 19 | + |
| 20 | +## API Overview |
| 21 | + |
| 22 | +See the [API Reference](/reference/api-reference/webhooks) for complete details. |
| 23 | + |
| 24 | +### Endpoints |
| 25 | + |
| 26 | +| Method | Endpoint | Description | |
| 27 | +|--------|----------|-------------| |
| 28 | +| `POST` | `/api/v3/webhook_subscriptions` | Create a subscription | |
| 29 | +| `GET` | `/api/v3/webhook_subscriptions` | List all subscriptions | |
| 30 | +| `GET` | `/api/v3/webhook_subscriptions/{id}` | Get subscription details | |
| 31 | +| `PATCH` | `/api/v3/webhook_subscriptions/{id}` | Update subscription | |
| 32 | +| `DELETE` | `/api/v3/webhook_subscriptions/{id}` | Delete subscription | |
| 33 | +| `POST` | `/api/v3/webhook_subscriptions/{id}/rotate_secret` | Rotate signing secret | |
| 34 | +| `GET` | `/api/v3/webhook_subscriptions/event_types` | List available event types | |
| 35 | + |
| 36 | +### Key Capabilities |
| 37 | + |
| 38 | +- **Event filtering**: Subscribe only to events you need |
| 39 | +- **HMAC-SHA256 signatures**: Every webhook includes a cryptographic signature for verification |
| 40 | +- **Secret rotation**: Rotate signing secrets on demand |
| 41 | + |
| 42 | +### Creating a Subscription |
| 43 | + |
| 44 | +```bash |
| 45 | +curl -X POST "https://backend.composio.dev/api/v3/webhook_subscriptions" \ |
| 46 | + -H "x-api-key: YOUR_API_KEY" \ |
| 47 | + -H "Content-Type: application/json" \ |
| 48 | + -d '{ |
| 49 | + "webhook_url": "https://your-server.com/webhooks/composio", |
| 50 | + "enabled_events": ["composio.trigger.message"], |
| 51 | + "version": "V3" |
| 52 | + }' |
| 53 | +``` |
| 54 | + |
| 55 | +**Response:** |
| 56 | + |
| 57 | +```json |
| 58 | +{ |
| 59 | + "id": "ws_your-subscription-id", |
| 60 | + "webhook_url": "https://your-server.com/webhooks/composio", |
| 61 | + "version": "V3", |
| 62 | + "enabled_events": ["composio.trigger.message"], |
| 63 | + "secret": "<your-webhook-secret>", |
| 64 | + "created_at": "2026-02-06T12:00:00.000Z", |
| 65 | + "updated_at": "2026-02-06T12:00:00.000Z" |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +<Callout type="warn"> |
| 70 | +The `secret` is only returned once at creation time or when rotated. Store it securely for signature verification. |
| 71 | +</Callout> |
| 72 | + |
| 73 | +### Notes |
| 74 | + |
| 75 | +- **1 subscription per project**: Currently limited to one webhook subscription per project. This will be expanded in future releases. |
| 76 | +- **HTTPS required**: Webhook URLs must use HTTPS in production environments. |
| 77 | + |
| 78 | +--- |
| 79 | + |
| 80 | +## New Event: `composio.connected_account.expired` |
| 81 | + |
| 82 | +A new platform event that notifies you when an **OAuth2** connected account's authentication expires and cannot be automatically refreshed. |
| 83 | + |
| 84 | +<Callout type="info"> |
| 85 | +This event is **only available in V3 format**. We strongly recommend using V3 for all new integrations to access the latest features and follow standard webhook practices. |
| 86 | +</Callout> |
| 87 | + |
| 88 | +### Use Cases |
| 89 | + |
| 90 | +- Prompt users to re-authenticate before workflows fail |
| 91 | +- Track connection health across your user base |
| 92 | +- Automate re-connection flows |
| 93 | +- Build proactive notification systems |
| 94 | + |
| 95 | +### Subscribing to Connection Expiry Events |
| 96 | + |
| 97 | +```bash |
| 98 | +curl -X POST "https://backend.composio.dev/api/v3/webhook_subscriptions" \ |
| 99 | + -H "x-api-key: YOUR_API_KEY" \ |
| 100 | + -H "Content-Type: application/json" \ |
| 101 | + -d '{ |
| 102 | + "webhook_url": "https://your-server.com/webhooks/composio", |
| 103 | + "enabled_events": [ |
| 104 | + "composio.trigger.message", |
| 105 | + "composio.connected_account.expired" |
| 106 | + ], |
| 107 | + "version": "V3" |
| 108 | + }' |
| 109 | +``` |
| 110 | + |
| 111 | +### Payload Structure |
| 112 | + |
| 113 | +The `composio.connected_account.expired` event follows the V3 envelope format: |
| 114 | + |
| 115 | +```json |
| 116 | +{ |
| 117 | + "id": "evt_847cdfcd-d219-4f18-a6dd-91acd42ca94a", |
| 118 | + "timestamp": "2026-02-06T12:00:00.000Z", |
| 119 | + "type": "composio.connected_account.expired", |
| 120 | + "metadata": { |
| 121 | + "project_id": "pr_your-project-id", |
| 122 | + "org_id": "ok_your-org-id" |
| 123 | + }, |
| 124 | + "data": { |
| 125 | + "toolkit": { |
| 126 | + "slug": "gmail" |
| 127 | + }, |
| 128 | + "auth_config": { |
| 129 | + "id": "ac_your-auth-config-id", |
| 130 | + "auth_scheme": "OAUTH2", |
| 131 | + "is_composio_managed": true, |
| 132 | + "is_disabled": false |
| 133 | + }, |
| 134 | + "id": "ca_your-connected-account-id", |
| 135 | + "status": "EXPIRED", |
| 136 | + "created_at": "2025-12-01T10:00:00.000Z", |
| 137 | + "updated_at": "2026-02-06T12:00:00.000Z", |
| 138 | + "status_reason": "OAuth refresh token expired", |
| 139 | + "is_disabled": false |
| 140 | + } |
| 141 | +} |
| 142 | +``` |
| 143 | + |
| 144 | +<Callout type="info"> |
| 145 | +The `data` object matches the response from [`GET /api/v3/connected_accounts/{id}`](/reference/api-reference/connected-accounts/getConnectedAccountsByNanoid), making it easy to process with existing code and SDK types. |
| 146 | +</Callout> |
| 147 | + |
| 148 | +--- |
| 149 | + |
| 150 | +## Verifying Webhook Signatures |
| 151 | + |
| 152 | +All webhooks include an HMAC signature in the `webhook-signature` header. Use the SDK's built-in verification functions or see the [Triggers documentation](/docs/triggers) for implementation details. |
| 153 | + |
| 154 | +--- |
| 155 | + |
| 156 | +## Available Event Types |
| 157 | + |
| 158 | +Query available events and their version compatibility: |
| 159 | + |
| 160 | +```bash |
| 161 | +curl "https://backend.composio.dev/api/v3/webhook_subscriptions/event_types" \ |
| 162 | + -H "x-api-key: YOUR_API_KEY" |
| 163 | +``` |
| 164 | + |
| 165 | +| Event Type | Description | Supported Versions | |
| 166 | +|------------|-------------|-------------------| |
| 167 | +| `composio.trigger.message` | Trigger events from integrations | V1, V2, V3 | |
| 168 | +| `composio.connected_account.expired` | Connection authentication expired | **V3 only** | |
| 169 | + |
| 170 | +--- |
| 171 | + |
| 172 | +## Deprecations |
| 173 | + |
| 174 | +### Deprecated Endpoints |
| 175 | + |
| 176 | +The following legacy endpoints are deprecated and will be removed in a future release: |
| 177 | + |
| 178 | +| Deprecated Endpoint | Replacement | |
| 179 | +|---------------------|-------------| |
| 180 | +| `GET /api/v3/org/project/webhook` | `GET /api/v3/webhook_subscriptions` | |
| 181 | +| `POST /api/v3/org/project/webhook/update` | `POST /api/v3/webhook_subscriptions` | |
| 182 | +| `DELETE /api/v3/org/project/webhook` | `DELETE /api/v3/webhook_subscriptions/{id}` | |
| 183 | +| `POST /api/v3/org/project/webhook/refresh` | `POST /api/v3/webhook_subscriptions/{id}/rotate_secret` | |
| 184 | + |
| 185 | +### Deprecated Fields in Project Response |
| 186 | + |
| 187 | +| Field | Status | Notes | |
| 188 | +|-------|--------|-------| |
| 189 | +| `webhook_url` | Deprecated | Use Webhook Subscriptions API | |
| 190 | +| `webhook_secret` | Deprecated | Use Webhook Subscriptions API | |
| 191 | +| `event_webhook_url` | Deprecated | Never implemented | |
| 192 | +| `is_new_webhook` | Deprecated | Use Webhook Subscriptions API | |
| 193 | + |
| 194 | +--- |
| 195 | + |
| 196 | +## Backward Compatibility |
| 197 | + |
| 198 | +<Callout type="warn"> |
| 199 | +**No immediate action required.** Your existing webhook configurations will continue to work. |
| 200 | +</Callout> |
| 201 | + |
| 202 | +### What We've Done For You |
| 203 | + |
| 204 | +- **Automatic migration**: We've created a webhook subscription for all existing projects that had webhook URLs configured, with `composio.trigger.message` enabled by default |
| 205 | +- **Same payload format**: If you were using V1, V2, or V3 triggers, they continue with the same format |
| 206 | + |
| 207 | +### What Continues to Work |
| 208 | + |
| 209 | +- Legacy webhook endpoints (deprecated but functional) |
| 210 | +- Existing project webhook configurations |
| 211 | +- All existing trigger payload formats (V1, V2, V3) |
| 212 | +- Signature verification with your existing secret |
| 213 | + |
| 214 | +--- |
| 215 | + |
| 216 | +## Payload Version Comparison |
| 217 | + |
| 218 | +| Version | Format | Recommendation | |
| 219 | +|---------|--------|----------------| |
| 220 | +| V1 | Legacy flat structure | For backward compatibility only | |
| 221 | +| V2 | Nested with metadata | For existing integrations | |
| 222 | +| **V3** | Structured envelope with `id`, `timestamp`, `type`, `metadata`, `data` | **Recommended for all new integrations** | |
0 commit comments