Webhook triggers reference
A webhook trigger starts a workflow the moment something happens in another system: an invitee books a Calendly event, a payment lands, an issue opens. The other system POSTs an event to a URL Cotera mints for the trigger, Cotera verifies and filters it, and your workflow runs with the event payload as its input.
For the click-through setup, see Kick off from a webhook. This page is the technical reference for how deliveries are handled, and links to the per-provider pages.
The delivery URL and secret
Each webhook trigger gets its own delivery URL, of the form:
https://app.cotera.co/api/triggers/webhooks/<trigger-id>
Cotera also generates a signing secret for that trigger. Treat the URL like a secret — anyone who can POST to it can start a run.
Depending on the provider, the URL is registered for you or you paste it in yourself:
| Setup | What Cotera does | Providers |
|---|---|---|
| Auto-registered | Cotera calls the provider's API to create the webhook subscription (and removes it when you delete the trigger). Requires a connected account for that provider. | Calendly, GitHub, Grain, Lemlist, Linear, Shopify, Stripe, Telegram, Typeform, WorkOS, Zendesk, and others that expose a subscription API |
| Paste the URL | Cotera shows you the URL; you add it in the other system's webhook settings. | Custom webhook, Gong, HubSpot, Sentry, Slack, and providers with no subscription API |
Verifying deliveries
Cotera authenticates every delivery before it runs anything, using the trigger's secret — you don't write any verification code. A delivery that fails is rejected and never reaches your workflow. Providers fall into two camps, and each provider page documents which:
- Signature — the provider signs the request body with the secret and sends the signature in a header (for example GitHub's
X-Hub-Signature-256, Calendly'sCalendly-Webhook-Signature). Cotera recomputes and compares it. - URL token — the provider can't sign, so the secret is carried as a token — inside the delivery URL (Gong, Grain), in a header the provider echoes back (Telegram's secret token), or in the delivery body (Lemlist). Cotera timing-safe compares it. Treat these URLs and tokens like a secret.
Event filtering and deduplication
- Event filtering. A trigger is bound to one event type (for example
invitee.created). Deliveries for other event types on the same endpoint are ignored — only matching events start a run. - Deduplication. A delivery identical to one already seen for that trigger in the last hour is skipped, so a provider that retries a delivery won't double-run your workflow.
What your workflow receives
The raw JSON body of the delivery becomes the workflow's input. Downstream nodes and your agent read its fields directly — no unwrapping. Each provider page below shows the exact payload shape for its events.
Testing
While building, use the Test webhook button on the trigger to send a signed sample delivery for the selected event through the full pipeline — verification, filtering, and your workflow — without waiting for the real system to fire.
Provider catalog
| Provider | Events |
|---|---|
| Calendly | invitee.created, invitee.canceled |
| Custom webhook | Any HTTP POST |
email.received | |
| GitHub | push, pull_request.*, issues.opened |
| Gong | call.processed |
| Grain | recording_*, highlight_*, story_*, upload_status |
| HubSpot | contact.created, company.created, contact.property_changed, company.property_changed |
| Lemlist | Email, LinkedIn, call, SMS, WhatsApp, enrichment & campaign activity |
| Linear | issue.*, comment.create, project.* |
| Sentry | issue.created, issue.resolved, issue.assigned, issue.archived, issue.unresolved |
| Shopify | orders/*, products/*, customers/*, checkouts/create, fulfillments/create |
| Slack | Any subscribed Slack Events API event |
| Stripe | payment_intent.succeeded, charge.*, customer.created, invoice.paid, checkout.session.completed |
| Telegram | message, callback_query, message_reaction, message_reaction_count |
| Typeform | form_response |
| WorkOS | user.*, organization.*, connection.*, dsync.*, session.created |
| Zendesk | ticket.created, ticket.status_changed, ticket.tags_changed, and more |