Table of Contents
- Why Sentry cannot ring your phone on its own
- What you need
- Step 1 — Create a channel that rings
- Step 2 — Create a Sentry internal integration
- Step 3 — Add the integration as an alert rule action
- Step 4 — Know what actually arrives
- Step 5 — Filter down to what deserves a call
- Step 6 — Give warnings a quieter door
- Ring only outside working hours
- The two traps
- Payload size, storms, and truncation
- Sharing with the team
- What this setup does not give you
- Troubleshooting
- Frequently asked questions
- Can Sentry make a phone call natively?
- Will a Sentry alert break through Do Not Disturb?
- Do I need a paid Sentry plan for webhooks?
- Why is my Sentry template variable empty?
- How do I alert on one environment only?
- Can two people get called for the same error?
- Should I filter in Sentry or in Echobell?
- Wrap-up
- Related
Sentry cannot call your phone. It can email you, post to Slack, or hand the alert to PagerDuty — but there is no built-in voice action. The way to get one without buying an incident platform is to send a Sentry issue alert to a webhook that rings: create an internal integration, point it at an Echobell calling channel, and put a filter in front of it so only the errors that actually break production get through.
This guide covers the whole path: the integration, the alert rule, the payload Sentry really sends, the templates that read it, and the two traps that make people give up on the setup.
Why Sentry cannot ring your phone on its own
Sentry's issue alert actions cover notifications (email, Slack, Discord, Microsoft Teams), ticket creation (Jira, GitHub, Azure DevOps), and handoff to a paging product (PagerDuty, Opsgenie). Every one of those ends in a screen you have to be looking at, or in a paid seat on another platform.
That is fine at 14:00. At 03:00 a Slack message is indistinguishable from silence, and a push notification loses to Do Not Disturb. For the small set of errors where a two-hour delay costs real money — checkout returning 500s, auth rejecting every login, a worker silently dropping jobs — you want a device that rings.
A webhook is the seam. Sentry can call an arbitrary HTTPS endpoint as an alert rule action; Echobell turns that HTTP request into a call-style alert that breaks through iOS Focus Mode.
What you need
- A Sentry organization where you can reach Settings → Developer Settings (owner or manager)
- Echobell installed (App Store / Google Play)
- Five minutes
Nothing has to be reachable from the internet on your side. Sentry makes the outbound request; you only receive it.
Step 1 — Create a channel that rings
In Echobell, create a channel and set its notification type to Calling. This is the whole point of the exercise: a calling channel behaves like an incoming call rather than a push, so it gets through Focus Mode and Do Not Disturb.
Give it templates that will make sense at 3 a.m. Sentry's payload is deeply nested, so the variable paths are longer than usual:
Title: {{data.event.level}}: {{data.event.metadata.type}}
Body: {{data.event.title}} — {{data.event.culprit}}
Set the link template in advanced settings so tapping the notification opens the issue:
{{data.event.web_url}}
Copy the channel's webhook URL from the channel detail view. It looks like:
https://hook.echobell.one/t/<channel-token>
Step 2 — Create a Sentry internal integration
Sentry only offers a webhook as an alert rule action through an integration, so you have to create one. It is a form, not a service — you are not writing any code.
- Go to Settings → Developer Settings → Custom Integrations
- Create New Integration → Internal Integration
- Name:
Echobell(this is the label you will pick in the alert rule) - Webhook URL: your Echobell channel URL from Step 1
- Turn on the Alert Rule Action toggle
- Permissions:
Issue & Event→ Read is enough - Under Webhooks, leave every checkbox unchecked — see the trap below
- Save
An internal integration is scoped to your organization and installs itself. You never need the token it generates for this setup.
Step 3 — Add the integration as an alert rule action
Go to Alerts → Create Alert → Issue Alert, or edit an existing rule.
Under Then perform these actions, add Send a notification via an integration and choose Echobell.
Set Action interval — the "if this alert has been triggered more than once" throttle — to at least 30 minutes. The default sends on every trigger, and an error that fires 400 times a minute will otherwise dial your phone until you turn it off.
Save, then hit the rule's test/preview so you can see a real payload arrive before you trust it.
Step 4 — Know what actually arrives
This is where most setups break, because the payload is not shaped like you would guess. Sentry wraps everything:
{
"action": "triggered",
"actor": { "id": "sentry", "name": "Sentry", "type": "application" },
"data": {
"event": {
"event_id": "e4874d664c3540c1a32eab185f12c5ab",
"level": "error",
"title": "ReferenceError: heck is not defined",
"culprit": "?(<anonymous>)",
"platform": "javascript",
"project": 1,
"release": null,
"metadata": { "type": "ReferenceError", "value": "heck is not defined" },
"tags": [["level", "error"], ["browser", "Chrome 75.0.3770"]],
"issue_id": "1117540176",
"issue_url": "https://sentry.io/api/0/issues/1117540176/",
"web_url": "https://sentry.io/organizations/test-org/issues/1117540176/events/e4874.../"
},
"triggered_rule": "Very Important Alert!"
},
"installation": { "uuid": "a8e5d2..." }
}
Four things worth knowing before you write a single template:
- Everything useful is under
data.event.{{title}}renders nothing;{{data.event.title}}renders the error. data.event.projectis a numeric ID, not a slug. If you want a readable project name in the notification, put it in the channel's title template as literal text and use one channel per project.- There is no
environmentfield. Environment arrives insidedata.event.tagsas a["environment", "production"]pair, and its position in that array is not stable — so do not index into it. Filter by environment in the Sentry rule instead (Step 6). data.triggered_ruleis the rule label. Useful in the body when one channel serves several rules.
The Sentry-Hook-Resource header is event_alert for issue alerts. You can require it in an Echobell channel condition so nothing else can ring the channel:
header["sentry-hook-resource"] == "event_alert"
Step 5 — Filter down to what deserves a call
A calling channel that rings for every new issue is worse than no channel at all: within a week you will have muted it, and then it will not ring for the one that mattered. Filter in two places.
In Sentry, use the rule's conditions and filters:
| Goal | Rule setup |
|---|---|
| Only production | Set the rule's Environment to production |
| Only real breakage | Filter: The event's level equals fatal (or error) |
| Not for one-off blips | Condition: The issue is seen more than 25 times in 1 hour |
| Only a critical path | Filter: The event's tags match transaction contains /checkout |
| Only regressions | Condition: A resolved issue changes state from resolved to unresolved |
In Echobell, use a channel condition as a backstop for things Sentry cannot express, or for changes you cannot get merged today:
data.event.level == "fatal" || data.event.level == "error"
Doing severity in the Sentry rule is generally better, because that is also where the throttling lives. Doing it in Echobell is better when you want two urgency tiers from one Sentry rule.
Step 6 — Give warnings a quieter door
The point of tiering is that the phone call keeps its meaning. Create a second Echobell channel with the Time Sensitive type, add a second Sentry rule with a lower bar, and point it at a second internal integration (one integration holds one webhook URL, so a second channel needs a second integration).
A setup that survives contact with a real week looks roughly like this:
| Sentry rule | Level / threshold | Echobell channel | Behaviour |
|---|---|---|---|
prod-fatal | fatal, production | Calling | Rings through Focus Mode |
prod-error-spike | error, seen > 100 in 1h | Time Sensitive | Lands on the lock screen, no ring |
new-issue-digest | any new issue | Normal | Ordinary push, read whenever |
Ring only outside working hours
During the day you are probably already looking at Sentry. Echobell exposes UTC system time variables to conditions, so one channel can behave differently by hour without a second Sentry rule:
data.event.level == "fatal" && (hour >= 17 || hour < 9)
Add a weekday check if your weekend is genuinely off:
data.event.level == "fatal" && (hour >= 17 || hour < 9 || dayOfWeek == 0 || dayOfWeek == 6)
All of these are UTC, so convert from your own timezone before you commit to the numbers. The conditions reference has the full variable list.
The two traps
Trap 1: checking the Webhooks boxes. An internal integration has two independent webhook paths. The Alert Rule Action toggle makes the integration selectable in alert rules — that is the one you want. The Webhooks checkboxes (issue, error, comment) subscribe you to every event of that resource: every issue created, resolved, assigned, archived, ignored, across the whole organization. Tick issue and your phone rings when a teammate resolves something. Leave them all unchecked and only your alert rules fire the webhook.
Trap 2: using the legacy Webhooks plugin. The old per-project Legacy Integrations → WebHooks plugin still exists and still works, and it looks like a shortcut because you can paste a URL without creating an integration. Its payload has a different, flatter shape, its requests are unsigned, and Sentry steers new setups away from it. If you use it, your templates need different variable paths than the ones above. Use the internal integration.
Payload size, storms, and truncation
Three limits are worth knowing before something goes wrong at scale:
- 1 MiB body. Echobell rejects trigger bodies over 1 MiB with HTTP 413. A Sentry payload carries the full stack trace and request context, which normally lands in the tens of kilobytes — but an event with a large request body can get close. There is no
max_alertsknob on Sentry's side, so the mitigation is scrubbing large request bodies in your SDK'sbeforeSend, which you want for privacy reasons anyway. - 120 requests per minute per token. Past that the trigger answers
429withRATE_LIMIT_EXCEEDEDand aRetry-After. Sentry's action interval is what keeps you under it;30 minutesis plenty. - 1500 bytes of notification body. Longer renders are truncated before they reach your device.
data.event.titleplusculpritfits comfortably; dumpingdata.event.exceptiondoes not, and is unreadable on a lock screen anyway. Keep the detail behind the link template.
Sharing with the team
An Echobell channel can be subscribed to by several people, and each subscriber picks their own notification type. The same Sentry rule can therefore ring the on-call engineer's phone while landing as an ordinary push for everyone else — no per-seat pricing, no rotation config.
What it is not is an escalation policy. There is no "if nobody acknowledges in five minutes, call the next person." If you need that, you need a real on-call platform; Echobell covers the delivery layer underneath one.
What this setup does not give you
Worth saying plainly:
- No acknowledgement. Answering the call does not tell Sentry anything, and does not stop the other subscribers' phones.
- No rotation or escalation. Everyone subscribed gets it, or nobody does.
- No deduplication beyond Sentry's. Grouping and throttling happen in the Sentry rule; Echobell delivers what arrives.
- No two-way sync. Resolving the issue in Sentry does not clear anything on your phone.
If those are dealbreakers, this is the wrong tool. If what you actually need is "wake me up when checkout breaks," it is roughly the cheapest reliable way to get it.
Troubleshooting
The rule fires but nothing arrives. Check that Alert Rule Action is on in the integration. If it is off, the integration will not appear in the rule's action list at all — and a rule saved before you enabled it keeps the stale action.
A notification arrives but is blank. Your template is reading top-level keys. Sentry nests everything under data.event.
It rings for things you did not expect. Check the Webhooks checkboxes on the integration (Trap 1), then check whether the rule's environment is set to "All Environments".
It rings repeatedly for one error. Raise the action interval on the Sentry rule. Echobell's retry setting is separate — Retry Failed Call in app settings re-dials a call you missed, which is a different thing.
Nothing ever arrives, even from the test. Trigger the channel with curl first to rule out the Echobell side:
curl -X POST https://hook.echobell.one/t/<channel-token> \
-H 'Content-Type: application/json' \
-d '{"data":{"event":{"level":"fatal","title":"Test error","culprit":"manual test","metadata":{"type":"TestError"}}}}'
If that rings and Sentry does not, the problem is in the integration, not the channel.
Frequently asked questions
Can Sentry make a phone call natively?
No. Sentry's issue alert actions are notifications, ticket creation, and integrations with paging products. A voice call requires an external service — either a paging platform like PagerDuty, or a webhook receiver that rings, like Echobell.
Will a Sentry alert break through Do Not Disturb?
Only if it arrives as a call-style alert. A calling-type Echobell channel behaves like an incoming call, which iOS Focus Mode and Do Not Disturb allow through. A normal push from any app does not.
Do I need a paid Sentry plan for webhooks?
Internal integrations and alert rule actions are available on Sentry's Developer plan and above. The webhook itself costs nothing extra.
Why is my Sentry template variable empty?
Almost always because the path is too short. The alert payload nests the event under data.event, so it is {{data.event.title}}, not {{title}}. Trigger the channel once and check the recorded request body in the app to see the exact shape you received.
How do I alert on one environment only?
Set the Environment field on the Sentry alert rule. Do not try to read it from data.event.tags — it is an array of [key, value] pairs whose order is not guaranteed.
Can two people get called for the same error?
Yes. Share the channel and have each person subscribe with the notification type they want. There is no acknowledgement, so everyone who chose "calling" gets called.
Should I filter in Sentry or in Echobell?
In Sentry when you can — the rule is also where throttling and environment scoping live. In Echobell when you want two different urgency levels out of one rule, when you need a time-of-day window, or when you cannot get the rule changed today.
Wrap-up
The setup is four things: a calling channel, an internal integration with Alert Rule Action on and the Webhooks boxes off, an alert rule narrow enough to deserve a phone call, and templates that read data.event. Everything else on this page is about keeping it narrow enough that the ring still means something a month from now.
Download Echobell for iPhone or get it on Google Play, then send the curl above before you rely on the path for anything real.