Sentry webhooks: internal integrations, headers, signature and alerts

To test Sentry webhooks, create an internal integration with a free webhooks.sh bin as its webhook URL, then trigger an issue or alert: each payload and its Sentry-Hook headers show up live. No signup; a bin lasts 48 hours and takes 100 requests a day.

Sentry sends webhooks as JSON POST requests from its integration platform whenever issues, errors, comments or alerts change. The quickest way to inspect a real Sentry webhook payload is to create an internal integration and set its webhook URL to a free bin: no signup, good for 48 hours, up to 100 requests a day. Below we cover setting up the integration, the Sentry-Hook-* headers, resources and actions, verifying Sentry-Hook-Signature, and the 1 second response timeout.

Point a Sentry internal integration at a bin

Sentry's webhook docs recommend pointing an integration at an HTTP catch-all URL so you can look at the JSON payloads before writing code.

  1. Open view.webhooks.page in your browser to create a free bin, or run curl -X POST https://webhooks.sh/v1/bins to get an ingest_url and view_url.
  2. In Sentry, go to Settings > Developer Settings and create an internal integration; it installs on your organization automatically as soon as you save it.
  3. Paste the bin's ingest URL into Webhook URL when creating the integration (any path works, like https://<bin>.webhooks.page/sentry), and select the resources you want webhooks for, such as issue, error or comment.
  4. If you want alert webhooks, turn on the Alert Action toggle in the integration, then open an alert rule and add the action Send a notification via <your integration>.
  5. Trigger an issue or alert in Sentry and watch the request show up in your bin's viewer.
# 1. Create a free bin (or open view.webhooks.page)
curl -X POST https://webhooks.sh/v1/bins

# 2. Sentry: Settings > Developer Settings > internal
#    integration, Webhook URL:
#    https://<bin>.webhooks.page/sentry
# 3. Trigger an issue or alert, then read the capture:
curl -H "x-view-key: <view key>" \
  https://view.webhooks.page/api/bins/<bin>/deliveries

Sentry-Hook headers in a free bin

Every Sentry integration webhook sends Content-Type: application/json, Request-ID, Sentry-Hook-Resource, Sentry-Hook-Timestamp and Sentry-Hook-Signature. A free bin redacts headers whose names contain authorization, cookie, key, token or secret, so all five Sentry headers and their full values stay visible in the browser, including Sentry-Hook-Signature.

Your handler should route requests using Sentry-Hook-Resource. Inside the JSON body, every delivery has the top-level fields action, installation (an object containing the installation uuid), data and actor. That actor is the user who triggered the change, the integration itself, or Sentry for automatic actions (type set to application, id set to sentry, name set to Sentry).

HeaderWhat it holdsIn a free bin
Sentry-Hook-ResourceResource that fired, for example issueVisible
Sentry-Hook-SignatureHex HMAC-SHA256 of the body, keyed with the Client SecretVisible
Sentry-Hook-TimestampTimestamp of the requestVisible
Request-IDUnique ID for tracking the requestVisible
Content-Typeapplication/jsonVisible

Resources and actions

Each Sentry-Hook-Resource value comes with its own set of action values and payload fields. Issue alerts arrive with Sentry-Hook-Resource set to event_alert and action set to triggered, carrying the event under data.event and the label of the rule that fired in data.triggered_rule.

A couple of resources don't fire for every setup: error webhooks are only available on Business and Enterprise plans, and installation webhooks (created or deleted) are only sent to public integrations, so an internal integration won't receive them.

ResourceActionsNotes
issuecreated, resolved, assigned, archived, unresolvedStatus and substatus in the payload
event_alerttriggeredIssue alert rules
metric_alertcritical, warning, resolvedMetric alert rules
errorcreatedBusiness and Enterprise plans
commentcreated, updated, deletedComments on issues
installationcreated, deletedPublic integrations only

Verify Sentry-Hook-Signature

To verify a Sentry webhook signature, compute an HMAC-SHA256 hex digest over the raw request body bytes using your integration's Client Secret as the key, and check that it matches Sentry-Hook-Signature. Always pass the exact raw body bytes as received into HMAC-SHA256, because parsing the JSON and serializing it again doesn't always produce the same bytes and will break the signature check. Compare the digests in constant time, and note that requests from Sentry UI components send Sentry-App-Signature instead of Sentry-Hook-Signature.

Because a bin doesn't redact Sentry-Hook-Signature, you can copy a captured body and header into the HMAC signature verifier with your Client Secret to test a real delivery by hand before writing the check in code.

import hashlib, hmac

def verify_signature(raw_body: bytes, signature, client_secret):
    if not signature:
        return False
    digest = hmac.new(client_secret.encode("utf-8"), raw_body,
                      hashlib.sha256).hexdigest()
    return hmac.compare_digest(digest, signature)

# Flask: verify_signature(request.get_data(),
#     request.headers.get("sentry-hook-signature"), secret)

Respond within 1 second

Sentry expects your webhook endpoint to respond within 1 second, and anything slower counts as a timeout. A free bin answers right away with HTTP 200 and a small JSON body like {"ok":true,"delivery_id":"..."}, so it won't time out while you inspect payloads. When you write your own handler, verify Sentry-Hook-Signature, drop the payload into a queue or database, return 200 right away, and run any slow work in the background.

While testing on a free bin, keep the limits in mind: 100 requests per day (resetting at midnight UTC) and request bodies up to 100KB. Over those caps the bin returns 429 (daily_cap_reached) or 413 (body_too_large), so on a busy Sentry organization only subscribe to the resources and alert rules you actually need to inspect (see our webhook troubleshooting guide if deliveries stop showing up).

Keep the URL or relay to localhost

A free bin expires after 48 hours and its viewer keeps the latest 10 requests. If you want to keep the same webhooks.page URL plugged into your Sentry integration longer, claim the bin from the viewer with a free Google sign-in before the 48 hours are up: the expiry timer stops and new requests are kept for 30 days on a rolling basis, with the same 100 requests a day and 100KB body limits.

When you're ready to run your own handler locally, the Solo plan ($12/month) gives you persistent named endpoints on webhooks.host, 250,000 requests per billing period, 5MB bodies, and the wsh CLI. You can stream live Sentry deliveries straight to your dev server with wsh listen <endpoint> --to localhost:3000 and replay captured requests while you work on your code. Solo's built-in signature verification covers Stripe, GitHub and Shopify, so you'll still verify Sentry-Hook-Signature in your own application.

FAQ

How do I test Sentry webhooks?

In Sentry, go to Settings > Developer Settings, create an internal integration with a free bin's ingest URL as the Webhook URL, and select the resources you want to receive. Trigger an issue or alert and the JSON payload and Sentry-Hook-* headers show up live in the browser with no signup.

How do I verify a Sentry webhook signature?

Compute the HMAC-SHA256 hex digest of the raw request body bytes using your integration's Client Secret, then compare it in constant time against the Sentry-Hook-Signature header. Do not parse and re-serialize the JSON before hashing, as that can change the bytes.

What headers does a Sentry webhook send?

Every integration webhook includes Content-Type: application/json, Request-ID, Sentry-Hook-Resource, Sentry-Hook-Timestamp and Sentry-Hook-Signature. Requests coming from UI components use Sentry-App-Signature for the signature header instead.

How fast does my endpoint need to respond to Sentry?

Your endpoint must respond within 1 second, or Sentry treats the delivery as a timeout. Verify the signature, return HTTP 200 right away, and handle the payload asynchronously.

How do I send Sentry alerts to a webhook?

Turn on the Alert Action toggle in your internal integration's settings, then edit your alert rule and add the action Send a notification via <your integration>. Issue alerts arrive with Sentry-Hook-Resource set to event_alert and metric alerts arrive as metric_alert.

Why am I not getting Sentry error webhooks?

Webhooks for the error resource are only available on Sentry Business and Enterprise plans, and you also have to subscribe the integration to error under Settings > Developer Settings.

Last updated

Try it in 10 seconds.

Create a free bin at view.webhooks.page — no signup, no install. Point your sender at the URL and watch requests land live. Bins expire after 48 hours.