Notifications
A workspace where every lane event lands in your inbox is unusable. A workspace where no event lands anywhere is dangerous. Notifications are the routing layer in between — they take the firehose of lane events and deliver the slice you actually need to the channel where your team already lives.
SprintLoop ships first-party integrations for Slack, Microsoft Teams, and Discord, plus a generic incoming-webhook target for anything else. The setup is the same shape across all four.
What gets routed
The full lane event taxonomy:
| Event | Fires when |
|---|---|
lane.opened | A lane is created (manual, from issue, or harness-initiated) |
lane.dispatched | The lane’s harness starts executing |
lane.tool_blocked | A tool call is denied by scope or policy |
lane.review_requested | The harness signals “ready for review” |
lane.review_verdict | A reviewer (Architect / Security / QA / custom) emits a verdict |
lane.signed_off | The owner approves the lane |
lane.merged | The PR merges on GitHub/GitLab and the lane closes |
lane.canceled | The lane is canceled (race loser, manual cancel, timeout) |
lane.policy_denied | Dispatch was blocked by a policy rule |
lane.federation_stamped | The lane’s chain head is signed into the federation root |
Plus workspace-scoped events: member.invited, member.joined, policy.updated, audit.exported. Most teams ignore these in their default channels.
Connect Slack
From the workspace web app: Settings → Notifications → Add Slack workspace. The OAuth flow asks for the standard chat:write and incoming-webhook scopes — no admin permissions, no DM read, nothing else.
After install, you’ll be back in SprintLoop with the Slack workspace listed. Click Add channel to wire a routing rule:
- Pick the Slack channel (the dropdown only shows channels the bot has been invited to — invite the bot by typing
/invite @SprintLoopin the channel first). - Pick the events you want to route (default:
lane.review_requested,lane.merged,lane.policy_denied). - Optional filters: scope to a repo, scope to a specific reviewer’s verdicts, scope to lanes owned by certain users.
- Save.
The bot posts a one-time confirmation message in the channel so you know routing is live.
What the Slack payload looks like
A lane.review_requested event lands as:
🔵 Lane ready for review: Refactor auth refresh logic
Owner:
@alex· Repo:acme/payments· Harness: Claude Code · Diff: +124 / −38 · Files: 7Reviewer verdicts: Architect ✅ · Security ✅ · QA ⚠️ (coverage drop in
auth/refresh.ts)
The buttons are not just links — they’re Slack interactive components. Clicking Approve in Slack signs off on the lane (after a confirmation modal); the action is signed by your Slack identity tied to your SprintLoop account.
A lane.policy_denied event lands as a red attachment with the rule name, the lane’s brief, and a link to the policy editor.
Connect Microsoft Teams
Teams uses the Incoming Webhook connector. From SprintLoop: Settings → Notifications → Add Teams channel.
You’ll be asked to paste a Teams incoming webhook URL. To get one: in the Teams channel, click the three-dot menu → Connectors → Incoming Webhook → Configure. Name it “SprintLoop” and copy the URL.
Paste it into SprintLoop. The same per-event filters apply.
Teams doesn’t support interactive message buttons the same way Slack does, so the Approve button is a deep link to the workspace approval page rather than an inline action. Otherwise the payload is equivalent.
Connect Discord
Discord also uses incoming webhooks. Server settings → Integrations → Webhooks → New Webhook. Copy the URL.
In SprintLoop: Settings → Notifications → Add Discord channel. Paste the URL. Pick events. Save.
Discord renders the lane-event embeds in its native rich-embed style. Verdict checkmarks become Discord emoji; the diff size and reviewer summary land in the embed footer.
Generic incoming webhooks
For anything else — a custom Slack-compatible bot, an internal status board, a PagerDuty-on-policy-denied flow — use Settings → Notifications → Generic webhook.
Paste any HTTPS URL. Pick events. SprintLoop sends a JSON POST per event with this shape:
{ "event": "lane.review_requested", "ts": "2026-05-09T14:31:08.221Z", "workspace": "acme", "lane": { "id": "ln_2K8m...", "title": "Refactor auth refresh logic", "owner_email": "alex@acme.test", "repo": "acme/payments", "harness": "claude-code", "diff": { "additions": 124, "deletions": 38, "files_changed": 7 }, "verdicts": [ { "reviewer": "architect", "verdict": "approve", "confidence": 0.92 }, { "reviewer": "security", "verdict": "approve", "confidence": 0.88 }, { "reviewer": "qa", "verdict": "has_questions", "confidence": 0.71, "rationale": "Coverage delta -2.4% on auth/refresh.ts" } ], "url": "https://app.sprintloop.ai/lanes/ln_2K8m..." }, "signature": "v1=..."}Every webhook payload is signed with HMAC-SHA256 over the raw body. The signing secret is shown once at creation; verify the X-SprintLoop-Signature header on your end before trusting the payload.
Filter recipes
A few filter combinations worth copying:
- High-signal #engineering channel.
lane.review_requestedANDlane.mergedANDlane.policy_denied. Skip everything else. - Security on-call channel. All events filtered to lanes that touched
**/auth/**,**/billing/**, or any path under the policy file’srequire.reviewer: securityrules. - Race-only channel.
lane.dispatchedANDlane.canceledfiltered to lanes that are part of a race. Useful for tuning racing. - PagerDuty-on-policy-denied. Send
lane.policy_deniedto a generic webhook pointing at PagerDuty’s events API. Fires a low-urgency incident; useful in regulated workspaces.
Rate limits
Slack and Teams rate-limit incoming webhooks at ~1 req/sec. SprintLoop coalesces bursts: if 12 lane events fire in 1 second, they get batched into a single message with one summary header and 12 line items. The batch threshold is configurable (default: coalesce within a 5-second window).
For generic webhooks, no batching is applied by default — each event is a separate POST. If you need batching, set batch_window_seconds on the channel config.
What’s not in v1
We don’t yet support email notifications (use generic webhooks → SendGrid for now), SMS, or in-app push to mobile devices outside of the SprintLoop iOS/Android apps. Those are on the roadmap; the rate-limit story for SMS in particular needs more thought.