Skip to content

Alerts and tickets

Alerts and tickets from other tools open incidents in Awaiting fix. When a pull request that mentions the incident (for example "Fixes INC-16") merges, time travel starts.

Every source posts to APP_URL/api/webhooks/<source>?workspace=<login>. The exact URL is shown under Integrations for each source.

Sources

SourcePathAuthenticationTakenMapped by
Sentrysentrysentry-hook-signature HMAC; secret from SentryNew issuesProject slug
PagerDutypagerdutyX-PagerDuty-Signature HMAC; secret from PagerDutyincident.triggered, incident.resolvedService
incident.ioincidentioStandard Webhooks; secret (whsec_…) from incident.ioIncident created and status updated (v2)Incident type
LinearlinearLinear-Signature HMAC plus webhookTimestamp; secret from LinearIssues labelled incidentTeam key
RootlyrootlyTokenincident.created, incident.mitigated, incident.resolvedFirst service
OpsgenieopsgenieTokenCreate and Close alert actionsEntity
DatadogdatadogTokenTriggered and re-triggered monitorsservice: tag
JirajiraTokenCreated or updated issues of type Bug or Incident, or labelled incidentProject key
Generic webhookwebhookStandard Webhooks; secret generated by Aftershockincident.* eventsservice

Sentry and PagerDuty are on for everyone. The others are in Settings → Labs ("incident.io, Rootly, Opsgenie, Datadog, Linear, Jira and generic webhooks") while they are in beta. With the flag off, their endpoints answer 404.

Connecting a source

  1. Open Integrations and pick the source.
  2. Set up the secret:
    • Sentry, PagerDuty, incident.io, Linear create their own signing secret. Copy it from the provider and use Save signing secret.
    • Generic webhook and the token sources: Generate signing secret or Generate token. It is shown once.
  3. Paste the webhook URL into the provider.
  4. Map provider names to repositories, for example checkout:ecommerce-api, web:storefront-web. An unmapped alert goes to the repository with the same name, or to your only repository.
  5. Send test delivery signs a harmless ping with the stored secret and runs it through the real endpoint.

Token sources

Rootly, Opsgenie, Datadog and Jira don't publish a signing scheme Aftershock can verify, so they use a per-workspace token. Send it in one of these ways, best first:

  • Authorization: Bearer <token>
  • X-Aftershock-Token: <token>
  • &token=<token> on the URL, only for tools that can't set headers. URLs end up in proxy and provider logs, so rotate the token if one leaks.

Datadog payload

In Integrations → Webhooks, use this payload and mention @webhook-<name> in a monitor:

{"id":"$AGGREG_KEY","title":"$EVENT_TITLE","message":"$EVENT_MSG","transition":"$ALERT_TRANSITION","link":"$LINK","tags":"$TAGS"}

Jira

Use an Automation rule: Issue created → Send web request to the URL, method POST, with the token header and the web request body "Issue data (Jira format)". Native Jira webhooks work too if your Jira can add a header.

Generic webhook

Sign with Standard Webhooks (webhook-id, webhook-timestamp, webhook-signature) using the generated secret:

{ "type": "incident.created", "data": { "id": "evt-42", "title": "Invoices sent twice", "description": "Retry ran after success", "service": "billing", "url": "https://status.example.com/42" } }

Safety

  • Signatures and tokens are compared in constant time before the body is parsed.
  • Signed timestamps (Standard Webhooks, Linear) must be within five minutes of now, so captured deliveries can't be replayed later.
  • Bodies over 256 KiB are refused.
  • Each source is rate limited per sender.
  • The same alert (by provider id) never opens a second incident.
  • Unknown workspaces, unknown sources and sources switched off all answer the same 404.
  • Links from payloads are kept only if they are http(s).
Edit this page on GitHub