Service webhooks (GitLab, Sentry, Linear, Stripe, PagerDuty)

GitLab, Sentry, Linear, Stripe and PagerDuty can post their own events into a channel as cards, through an incoming webhook's service URL, each checked with that service's signature.

Before you start

How it works

Every incoming webhook has one URL per service, made by adding the service's name to the end:

Service URL Secret you paste into Missived
GitLab …/hooks/<id>/<token>/gitlab The webhook's signing token (whsec_…), or on older GitLab a secret token you make up
Sentry …/hooks/<id>/<token>/sentry The internal integration's Client Secret
Linear …/hooks/<id>/<token>/linear The webhook's signing secret
Stripe …/hooks/<id>/<token>/stripe The destination's signing secret (whsec_…)
PagerDuty …/hooks/<id>/<token>/pagerduty The subscription's signing secret (shown once)

Each of these services makes its own signing secret, so the order is always the same:

  1. In Missived, open Org Settings → Integrations → Incoming webhooks. Make a webhook (pick the service under "Made for" and the page shows that service's steps), or open an existing one and choose Connect a service.
  2. In the service, add a webhook with the URL Missived shows.
  3. Copy the secret the service gives you and paste it into Missived.

Missived keeps the secret encrypted and never shows it again, only its last four characters. You can replace it, or forget it, under Connect a service.

Every delivery's signature is checked against the exact bytes received before anything is read. Then:

Cards are posted by the webhook's bot, with its name and an APP badge.

GitLab

Works with GitLab.com and self-managed GitLab.

  1. In the project (or group): Settings → Webhooks → Add new webhook. URL: the /gitlab URL.
  2. GitLab 19.1 and later: choose Generate signing token, copy it (it starts with whsec_ and is shown once) and paste it in Missived as the Signing token. Retries of one delivery are recognised and posted once.
  3. Older GitLab has no signing token. Make up a long random value, put it in GitLab's Secret token field, and paste the same value in Missived as the Secret token (older GitLab). This is weaker; switch to a signing token when you upgrade. With both set, the signing token wins.
  4. Tick the triggers you want, save, and use Test → Push events.

Posts: pushes (up to five commits, with a compare link); branches and tags created or deleted; merge requests opened, merged, closed, reopened or approved; issues opened, closed or reopened; comments on issues, merge requests and commits; pipelines that passed, failed or were cancelled; deployments that succeeded or failed; new releases; wiki pages created or updated.

Never posted: confidential issues, and internal or confidential comments, even if those triggers are ticked. Everything else is ignored. On a self-managed instance served over plain http://, cards keep their text but drop their links.

Sentry

  1. In Sentry: Settings → Developer Settings → Custom Integrations → Create New Integration → Internal Integration. Webhook URL: the /sentry URL.
  2. Turn on Alert Rule Action. Under Webhooks, tick issue (and comment and error if you want them). Give it Read on Issue & Event. Save.
  3. Copy its Client Secret (under Credentials) and paste it into Missived.
  4. Add "Send a notification via ⟨your integration⟩" to an issue or metric alert rule.

Sentry expects an answer within a second, so Missived answers { "ok": true, "queued": true } as soon as the signature checks out, and posts a moment later.

Posts: a "Sentry is connected" card when the integration is installed; issues that are new, resolved, assigned, archived or regressed (with level, project and assignee); alert-rule notifications; metric alerts (critical, warning, resolved); new errors; new comments. Anything else is ignored.

Linear

  1. In Linear: Settings → API → Webhooks → New webhook (workspace admins). URL: the /linear URL.
  2. Pick the teams and the data change events: Issues, Comments, Projects, Project updates, Documents, Cycles. Create it.
  3. Copy the signing secret from the webhook's page and paste it into Missived.

Linear's signed timestamp must be within a minute of Missived's clock, as Linear recommends.

Posts: issues created, moved to another state (completed and cancelled say so), assigned or unassigned; new comments; projects created or moved to another status; project updates, with their health; documents and cycles created.

Ignored: other changes, such as title edits, labels and sort order, so a busy team's channel stays readable.

Stripe

This is for your own Stripe account. It has nothing to do with paying for Missived.

  1. In Stripe: Workbench → Webhooks → Add destination → Webhook endpoint, with snapshot events.
  2. Choose these events: checkout.session.completed, payment_intent.succeeded, payment_intent.payment_failed, charge.refunded, charge.dispute.created, invoice.paid, invoice.payment_failed, customer.subscription.created, customer.subscription.deleted, payout.paid, payout.failed.
  3. Endpoint URL: the /stripe URL.
  4. Reveal secret and paste the whsec_… value into Missived. Test mode and live mode have different secrets. Never paste an API key (sk_…); Missived refuses one.

Signatures may be up to five minutes old. When you roll the secret in Stripe, it signs with both for a while: paste the new one then.

Posts: new orders and subscription checkouts, payments received or failed, refunds, disputes (with the respond-by date), invoices paid or failed, subscriptions started or cancelled, payouts sent or failed. Each card shows the amount in the charge's currency, the customer's name (or their email when there's no name) and a link to the Stripe dashboard. Test-mode events say "test mode". Card details never appear.

Ignored: every other event type.

PagerDuty

  1. In PagerDuty: Integrations → Generic Webhooks (v3) → New Webhook. Webhook URL: the /pagerduty URL.
  2. Scope it to a service or team and pick the incident events. Add the webhook.
  3. PagerDuty shows the signing secret once: paste it into Missived.
  4. Send Test Event posts a "PagerDuty is connected" card.

During a secret change PagerDuty sends several signatures; any one that matches is accepted.

Posts: incidents triggered, acknowledged, unacknowledged, escalated, reassigned, resolved, reopened or with a changed priority; notes added; status updates; responders added. Cards show the service, urgency, priority and, when an incident is triggered, reassigned or escalated, who it's assigned to.

Ignored: everything else, such as tasks, workflows and services.

Manage secrets over the API

A token with the webhooks:write scope can paste or forget a service's secret, as Connect a service does:

curl -X PUT https://api.missived.com/v1/orgs/<orgId>/incoming-webhooks/<id>/providers/stripe \
  -H "Authorization: Bearer $MISSIVED_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"signingSecret": "whsec_…"}'

See setIncomingWebhookProviderSecret and Manage webhooks over the API for who may do this.

What data moves

Limits

The incoming webhook limits apply: 5 requests per 2 seconds and 30 a minute per webhook, bodies up to 1 MiB, and 30 failed signatures in 10 minutes from one address get that address 429. A webhook that stays over its limit for an hour pauses itself and its creator gets an email.

Troubleshooting

Open the webhook's Recent deliveries on the Integrations page: it lists the last 50 requests as posted, ignored, duplicate, refused (with the reason) or rate limited.