Triggers and webhooks
Get signed events on your server when something happens in a user's app or your project.
A webhook endpoint is a URL on your server. Dexby posts project events to it, signed with the Standard Webhooks scheme. A trigger listens for one event, such as a new Slack message, on one user's connection and forwards it to your webhooks.
Add a webhook endpoint
In the dashboard, open Configure → Webhooks, click Add endpoint, enter a public
https URL, and pick events. Copy the signing secret (whsec_...). It is shown once.
Verify each delivery
import { Webhook } from 'standardwebhooks'
const webhook = new Webhook(process.env.DEXBY_WEBHOOK_SECRET ?? '')
export async function POST(request: Request) {
const body = await request.text()
const event = webhook.verify(body, Object.fromEntries(request.headers)) // throws if forged
console.log(event)
return new Response(null, { status: 204 })
}Answer 2xx within 10 seconds. Anything else is retried for about two days. webhook-id stays the
same on every retry, so use it to drop duplicates.
To change the secret, choose Rotate signing secret in the endpoint's menu. Until the old secret
stops, webhook-signature carries one signature for each secret, so a receiver holding either one
verifies the delivery.
Create a trigger
Connect a WooCommerce account for the user before creating this order.created trigger.
import { Dexby } from '@dexby.ai/sdk'
const dexby = new Dexby()
const trigger = await dexby.createTrigger({
connectionId: '<connection-id>',
event: 'order.created'
})
if (trigger.isErr()) throw new Error(trigger.error.message)<connection-id>: the user's connected WooCommerce account, from Operate → Connections → open the account → Connection ID, orGET /v1/connections?userId=user_123.event: an event the app supports (table below). Or create the trigger in Operate → Triggers → New trigger, which lists them.
Events then arrive as trigger.fired, with data.userId set to your user. Pass that id when
creating the agent's session so it uses that user's connected accounts.
Apps with triggers
| App | Events | Setup |
|---|---|---|
| GitHub | push, pull_request_opened, pull_request_merged, pull_request_closed, issue_opened, issue_comment_created, release_published, workflow_run_completed | GitHub App |
| Linear | issue_created, issue_updated, issue_removed, comment_created, project_updated | OAuth app |
| Gmail | email_received | OAuth app |
| Google Calendar | event_changed, event_cancelled | Automatic |
| Google Drive | file_changed, file_trashed, file_removed | Automatic |
| HubSpot | contact_created, contact_deleted, company_created, deal_created, deal_stage_changed, ticket_created | OAuth app |
| Microsoft Teams | chat_message, channel_message (needs teamId and channelId) | Automatic |
| OneDrive | file_changed, file_deleted | Automatic |
| Outlook | email_received, event_created, event_updated, event_deleted | Automatic |
| Notion | page_created, page_content_updated, page_properties_updated, page_deleted, comment_created | OAuth app |
| ShipStation | track, fulfillment_shipped_v2, fulfillment_rejected_v2, batch | Automatic |
| Slack | message, app_mention, reaction_added | Manual |
| Telegram | message, edited_message, channel_post, callback_query | Automatic |
| Zoom | meeting_created, meeting_updated, meeting_deleted, meeting_started, meeting_ended, participant_joined, participant_left, recording_completed, transcript_completed | OAuth app |
| WooCommerce | order.created, order.updated, product.created, product.updated, customer.created | Automatic |
Manual (Slack): pass secret (your Slack app's Signing secret). The response has a url,
shown once. Paste it as the Request URL under Event Subscriptions in your Slack app, and subscribe
to the bot event.
GitHub App: GitHub sends events from every repository the GitHub App is installed on. If the
user has not installed it anywhere, creating the trigger fails with APP_NOT_INSTALLED and an
installUrl to install it. New installations are picked up automatically.
Notion: an event reaches only the accounts whose Notion connection can see its page. With your own Notion connection, create its webhook subscription with the auth config's Event URL. Notion sends a verification token there once: in the auth config, choose Show token, paste it into Notion's Verify box, then choose Save as webhook secret.
Google: Google only says that something changed, so Dexby reads what changed and sends one
event per new email, changed calendar event or changed file. Dexby renews Google's watch before it
expires. email_received carries the message's headers, snippet and labels; read the body with the
Gmail actions. With your own Google OAuth app, Gmail needs a Pub/Sub topic: enter it and its push
service account in the auth config, and point the topic's push subscription at the auth config's
event URL.
Google Super: an account connected through Google Super has every Gmail, Google Calendar and
Google Drive trigger, named after the app as its actions are: gmail_email_received,
google_calendar_event_changed, google_drive_file_changed. The trigger and its events report the
app they come from (connectorId: "gmail", event: "email_received"). With your own Google OAuth
app, Gmail's push subscription points at https://api.harryy.ai/triggers/gmail/<auth config id>.
Microsoft: Microsoft Graph names the changed item, so Dexby reads it and sends it: the email's sender, recipients, subject and preview (read the body with the Outlook actions), the calendar event, the Teams message, or the OneDrive file. Dexby renews Microsoft's subscription before it expires.
A Teams channel trigger needs the channel: pass options: { teamId, channelId }, from the list
joined teams and list channels actions. Teams works with work or school accounts, and channel
messages need an admin to consent to ChannelMessage.Read.All. An account connected through
Microsoft Super has every Outlook, OneDrive and Teams trigger, named after the app:
outlook_email_received, microsoft_teams_channel_message.
Zoom: an event reaches the account of the meeting's host. With your own Zoom app, set its event
notification endpoint URL to the auth config's Event URL and enter the app's Secret token in
the auth config before Zoom validates the URL. When a user removes the app in Zoom, Dexby deletes
their Zoom connection and its triggers, and sends connection.deleted.
Events
| Event | When | data |
|---|---|---|
trigger.fired | A trigger received an event. | triggerId, connectorId, event, userId, connectionId, eventId, receivedAt, payload |
connection.created | A user connected an account. | connectionId, connectorId, userId, name |
connection.deleted | An account was removed and its credential erased. | connectionId, connectorId, userId |
connection.reauth_required | An account needs reconnecting. | connectionId, connectorId, userId |
execution.failed | A tool run failed. | toolId, connectorId, userId, errorCode |
mcp_server.tools_changed | An MCP server's tools changed. | server, toolCount |
For a global account, the connection.* events carry
"userId": null and "global": true.
Every delivery has the shape { "type", "timestamp", "data" }. Payloads never include tool input or
output, except the app's own payload in trigger.fired.