Source: https://cli.nylas.com/guides/sentry-email-alerts-cli

# Send Sentry Issue Alerts by Email (CLI)

Forward Sentry issue alerts to email through a webhook handler that parses the issue title, level, and permalink, then sends an enriched message with nylas email send.

Written by [Hazik](https://cli.nylas.com/authors/hazik) Director of Product Management

Reviewed by [Qasim Muhammad](https://cli.nylas.com/authors/qasim-muhammad)

Updated June 9, 2026

> **TL;DR:** Point a Sentry issue alert at a webhook URL, parse the JSON payload for `issue_alert` fields, and call [`nylas email send`](https://cli.nylas.com/docs/commands/email-send) from the handler. The payoff at the end: a one-line tag that lets recipients reply-filter by severity.

## Why route a Sentry alert through email instead of the built-in one?

Sentry already emails project members, but the built-in notification stops at Sentry's template and recipient list. Routing the alert through a webhook handler that calls the Nylas CLI lets you reshape the subject, pick recipients per error level, and attach internal runbook links. The handler runs `nylas email send` with full control over the message.

Sentry's integration platform delivers issue alerts as HTTP POST requests with a JSON body. The free Developer plan allows custom internal integrations, and Sentry documents the webhook resource as `event_alert` and `issue_alert`. According to the Sentry webhooks documentation, each request carries a `Sentry-Hook-Resource` header so your handler can branch on the event type. One small handler replaces a paid alerting add-on, and the CLI removes any SMTP setup from that handler.

## How do I receive the Sentry issue alert payload?

A Sentry issue alert webhook is an HTTP POST your handler must accept and parse. The body is JSON with a top-level `data.event` object holding the issue title, level, and a `web_url` permalink. Your handler reads those three fields, then shells out to the CLI. Sentry retries failed webhook deliveries automatically, so return a non-2xx status when your handler fails to trigger another attempt.

Configure the alert under Alerts in your Sentry project, add a webhook action, and point it at your handler URL. For local testing you can capture and inspect a real Nylas-style webhook payload with the CLI's own tunnel server, which is handy while you shape the parser. The `nylas webhook server` command opens a local listener on a chosen port.

```bash
# Inspect incoming webhook payloads locally while you build the handler
nylas webhook server --port 4000
```

## How do I enrich the email with issue title, level, and permalink?

Enrichment means lifting the three high-signal fields out of the payload and placing them where a recipient scans first: the subject line and the first body line. The handler reads `title`, `level` (one of `fatal`, `error`, `warning`, or `info`), and the `web_url` permalink, then composes a message. This takes about 15 lines of shell.

The example below uses `jq` to extract fields from the POST body, then calls `nylas email send` with a subject that leads with the level and title. The `--track-label` flag tags the message `sentry-alert` so you can find every routed alert later, and `--metadata` stores the issue level as a filterable key.

```bash
#!/usr/bin/env bash
# handler.sh -- reads a Sentry issue-alert JSON body on stdin
payload="$(cat)"

title=$(printf '%s' "$payload" | jq -r '.data.event.title')
level=$(printf '%s' "$payload" | jq -r '.data.event.level')
url=$(printf '%s' "$payload" | jq -r '.data.event.web_url')

nylas email send "$NYLAS_GRANT_ID" \
  --to "$ALERT_EMAIL_TO" \
  --subject "[$level] $title" \
  --body "Sentry issue: $title

Level: $level
Permalink: $url" \
  --track-label sentry-alert \
  --metadata level="$level" \
  --yes \
  --json
```

## How do I route by severity and send richer HTML?

Severity routing sends `fatal` and `error` issues to an on-call address while `warning` and `info` go to a quieter list. A single shell case statement picks the recipient before the send. Sentry assigns each event one of 5 documented levels, so the routing table stays small and predictable.

For a scannable message, write a short HTML block and pass it as the `--body`, which accepts HTML or plain text. Keep it to a heading, the permalink, and the level. The command below builds the body from the parsed fields and routes the recipient by level, so a fatal error reaches the right inbox within seconds of Sentry firing the alert.

```bash
case "$level" in
  fatal|error) to="$ONCALL_EMAIL" ;;
  *)           to="$DIGEST_EMAIL" ;;
esac

body="<h1>Sentry: $title</h1>
<p>Level: <strong>$level</strong></p>
<p><a href=\"$url\">Open the issue in Sentry</a></p>"

nylas email send "$NYLAS_GRANT_ID" \
  --to "$to" \
  --subject "[$level] $title" \
  --body "$body" \
  --track-label sentry-alert \
  --yes \
  --json
```

## Why keep the API key and grant out of the handler code?

The handler needs a Nylas API key and a sender grant ID, and both belong in environment variables, not in the script. Read `NYLAS_API_KEY` and `NYLAS_GRANT_ID` from the process environment so the same handler file is safe to commit. A dedicated automation grant is easier to audit and revoke than a developer mailbox, and rotating it takes 1 command.

Configure credentials once with `nylas auth config --api-key` for interactive use, or export the variables in the service that runs the handler for headless deployments. Never echo the key in logs. The CLI reads the key from the environment, so the handler passes only the grant ID, recipient, and message content on the command line.

```bash
# Headless: export credentials in the service that runs handler.sh
export NYLAS_API_KEY="nyk_..."
export NYLAS_GRANT_ID="grant-uuid"
export NYLAS_DISABLE_KEYRING=1

# Verify the grant can send before wiring the webhook
nylas email list "$NYLAS_GRANT_ID" --limit 1 --json
```

## Next steps

- [Send Email from CircleCI Pipelines](https://cli.nylas.com/guides/circleci-email-notifications) — Send CircleCI email notifications on failed builds with Nylas CLI
- [Prometheus Alertmanager email alerts](https://cli.nylas.com/guides/prometheus-alertmanager-email) -- route metric alerts through the same CLI handler pattern
- [Grafana alert emails from the CLI](https://cli.nylas.com/guides/grafana-alert-emails-cli) -- forward dashboard alerts with enriched bodies
- [Terraform email alerts](https://cli.nylas.com/guides/terraform-email-alerts) -- send notifications from infrastructure runs
- [Email to GitHub issues](https://cli.nylas.com/guides/email-to-github-issues) -- the inverse flow, turning inbound mail into tracked work
- [Send email from the terminal](https://cli.nylas.com/guides/send-email-from-terminal) -- every flag the send command accepts
- [Getting started with Nylas CLI](https://cli.nylas.com/guides/getting-started) -- install and authenticate in under two minutes
- [Command reference](https://cli.nylas.com/docs/commands) -- email send and webhook command flags
- [Sentry integration platform webhooks](https://docs.sentry.io/product/integrations/integration-platform/webhooks/) -- request format and the `Sentry-Hook-Resource` header
- [Sentry issue alert webhooks](https://docs.sentry.io/product/integrations/integration-platform/webhooks/issue-alerts/) -- the `issue_alert` payload and its fields
- [Sentry alert types](https://docs.sentry.io/product/alerts/alert-types/) -- issue alerts versus metric alerts
- [RFC 5322](https://datatracker.ietf.org/doc/html/rfc5322) -- internet message format for the email the handler sends
