Alerts that matter. Rules you can read.
Configure thresholds, route them where humans actually look, and sync resolutions back into the tracker.
Anatomy of a rule
{
"projectId": "uuid",
"name": "Payment crash spike",
"trigger_type": "issue_spike",
"conditions": { "threshold": 50, "window_minutes": 15, "severity": "high" },
"actions": [
{ "type": "slack", "webhook_url": "https://hooks.slack.com/..." },
{ "type": "pagerduty", "integration_key": "..." }
],
"enabled": true
}Trigger types
| Type | Fires when… |
|---|---|
new_issue | A new unique fingerprint is seen for the first time. |
issue_regression | A previously-resolved issue reappears in a new release. |
issue_spike | Sliding-window event rate breaches threshold. |
security_event | SDK reports rooted / jailbroken / overlay / cert-pinning failure. |
pre_crash_state | High-risk watchdog breadcrumb captured before clean exit. |
battery_drain_threshold | Battery drops faster than configured rate. |
performance_threshold | P95 cold-start or ANR rate exceeds limit. |
critical_path | Glob match on perf_screen, perf_transaction_name, or latest navigation breadcrumb. |
Action types
Slack
{ "type": "slack", "webhook_url": "https://hooks.slack.com/services/..." }Posts a Block Kit message with severity color, exception preview, and Resolve / Ignore / View buttons (when SLACK_ACTION_SIGNING_SECRETis set). Button payloads are JWT-signed (HS256, 24h) and verified against the Slack request signature on the interactive endpoint.
Generic webhook
{ "type": "webhook", "url": "https://...", "headers": {} }POST with the fired-alert envelope as JSON. No retry on 5xx (use a queue downstream).
{ "type": "email", "to": "ops@example.com" }Sent via Resend. TillPulse-branded HTML with severity color, top stack frames, breadcrumb tail, device facts, and a deep link back to the issue.
PagerDuty
{ "type": "pagerduty", "integration_key": "..." }Events API v2. dedup_key = TillPulse issue ID, so resolving the issue here resolves the incident there.
Microsoft Teams
{ "type": "msteams", "webhook_url": "https://outlook.office.com/webhook/..." }Adaptive MessageCard with severity color and links.
Tracker integrations
Linear
Settings → Integrations → Linear. Paste a personal API key. The SDK uses Linear's GraphQL issueCreate with raw key auth (not Bearer).
On the issue detail page, Create Linear ticket creates a Linear issue, stores the link in tracker_tickets, and listens for Linear webhooks (HMAC-SHA256, header Linear-Signature) — when the Linear issue is closed, the TillPulse issue auto-resolves.
Jira
REST v3, Basic auth (email:apiToken). ADF body. Webhooks come in unsigned, so you set a shared ?token= on the URL and configureJIRA_WEBHOOK_TOKEN in the env. Resolved / Closed status maps toissues.status='resolved'.
GitHub
Settings → Integrations → GitHub. Paste a repo URL and click Generate webhook secret. Add the resulting webhook URL to GitHub. The receiver verifies X-Hub-Signature-256with timing-safe HMAC against the per-project secret. push events upsert commits + files-changed; the worker uses this to populate issues.git_blame_owneron first creation by basename matching against the top app frames.
Critical path matching
{
"trigger_type": "critical_path",
"conditions": {
"patterns": ["checkout/*", "PaymentScreen", "navigate:/cart"]
}
}Globs are tested against the event's perf_screen, perf_transaction_name, and the latest navigation breadcrumb's target — first match wins. Useful for "alert me only when the crash is in checkout" without writing a custom dashboard query.
Acknowledging alerts
Three ways:
- Click Ack on the dashboard's Alerts page.
- Click the Ack button on a Slack message.
- Call
POST /api/alerts/:alertId/ackfrom your own tooling.