Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
getsentry avatar

Notification Platform

  • 24 installs
  • 44.5k repo stars
  • Updated August 5, 2026
  • getsentry/sentry

notification-platform is an agent skill that Guide for adding notifications, custom renderers, or new providers to Sentry's NotificationPlatform. Use when asked to "add notification", "new notification", ".

About

Guide for adding notifications, custom renderers, or new providers to Sentry's NotificationPlatform. Use when asked to "add notification", "new notification", "notification platform", "send notification", "notification template", "notification renderer", "notification provider", "NotificationPlatform", "notify user", "send email notification", "send slack notification". --- name: notification-platform description: Guide for adding notifications, custom renderers, or new providers to Sentry's NotificationPlatform. Use when asked to "add notification", "new notification", "notification platform", "send notification", "notification template", "notification renderer", "notification provider", "NotificationPlatform", "notify user", "send email notification", "send slack notification". --- # NotificationPlatform Guide Sentry's NotificationPlatform is a provider-based system for sending notifications across Email, Slack, Discord, and MS Teams. You define data + template, register it, and the platform handles rendering and delivery per provider. ## Glossary | Concept | Role | Location | | ------------------------------ | --------------------------------------------------------------------.

  • NotificationPlatform Guide
  • Add the enum value under the appropriate category comment:
  • Add it to `NOTIFICATION_SOURCE_MAP` under the matching category key:
  • `source` is a **class variable** (no type annotation), not a dataclass field
  • Use `frozen=True` for serialization safety

Notification Platform by the numbers

  • 24 all-time installs (skills.sh)
  • Ranked #1,397 of 2,153 Testing & QA skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
At a glance

notification-platform capabilities & compatibility

Capabilities
notificationplatform guide · add the enum value under the appropriate categor · add it to `notification_source_map` under the ma · `source` is a **class variable** (no type annota · use `frozen=true` for serialization safety
Use cases
documentation
From the docs

What notification-platform says it does

--- name: notification-platform description: Guide for adding notifications, custom renderers, or new providers to Sentry's NotificationPlatform.
SKILL.md
--- # NotificationPlatform Guide Sentry's NotificationPlatform is a provider-based system for sending notifications across Email, Slack, Discord, and MS Teams.
SKILL.md
You define data + template, register it, and the platform handles rendering and delivery per provider.
SKILL.md
Frozen dataclass carrying the payload for a single notification.
SKILL.md
npx skills add https://github.com/getsentry/sentry --skill notification-platform

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs24
repo stars44.5k
Last updatedAugust 5, 2026
Repositorygetsentry/sentry

What problem does notification-platform solve for developers using this skill?

Guide for adding notifications, custom renderers, or new providers to Sentry's NotificationPlatform. Use when asked to "add notification", "new notification", "notification platform", "send notificati

Who is it for?

Developers who need notification-platform patterns described in the cached skill documentation.

Skip if: Skip when docs are empty or the task is outside the skill's documented scope.

When should I use this skill?

Guide for adding notifications, custom renderers, or new providers to Sentry's NotificationPlatform. Use when asked to "add notification", "new notification", "notification platform", "send notificati

What you get

Actionable workflows and conventions from SKILL.md for notification-platform.

Files

SKILL.mdMarkdownGitHub ↗

NotificationPlatform Guide

Sentry's NotificationPlatform is a provider-based system for sending notifications across Email, Slack, Discord, and MS Teams. You define data + template, register it, and the platform handles rendering and delivery per provider.

Glossary

ConceptRoleLocation
NotificationDataProtocol. Frozen dataclass carrying the payload for a single notification. Must declare a source class variable.types.py
NotificationTemplateAbstract class. Converts NotificationData into a NotificationRenderedTemplate. Registered per NotificationSource.types.py
NotificationRenderedTemplateDataclass. Provider-agnostic output: subject, body blocks, actions, chart, footer, optional email paths.types.py
NotificationProviderProtocol. Knows how to validate a target, pick a renderer, and send the final renderable (Email, Slack, etc.).provider.py
NotificationRendererProtocol. Converts a NotificationRenderedTemplate into a provider-specific renderable (HTML email, Slack blocks, etc.).renderer.py
NotificationTargetProtocol. Identifies the recipient: email address, channel ID, or DM user ID. Two concrete classes: GenericNotificationTarget (email) and IntegrationNotificationTarget (Slack/Discord/MSTeams).target.py
NotificationServiceEntry point. Orchestrates lookup, rendering, and delivery. Provides has_access(), notify_target(), notify_async(), notify_sync().service.py

All paths below are relative to src/sentry/notifications/platform/.

Step 1: Determine Your Operation

I want to...Go to
Add a new notification (most common)Steps 2-5
Add a custom renderer for an existing providerStep 6
Add an entirely new providerStep 7

After any operation, continue to Step 8 (Test) and Step 9 (Verify).

Step 2: Define the Notification Source

Every notification needs a unique NotificationSource enum value and must be mapped to a NotificationCategory. A NotificationSource should represent the domain or feature that a given notification belongs to.

For examples, load src/sentry/notifications/platform/types.py.

File: types.py

1. Add the enum value under the appropriate category comment:

class NotificationSource(StrEnum):
    # MY_CATEGORY
    MY_NEW_SOURCE = "my-new-source"

2. Add it to NOTIFICATION_SOURCE_MAP under the matching category key:

NOTIFICATION_SOURCE_MAP[NotificationCategory.MY_CATEGORY].append(
    NotificationSource.MY_NEW_SOURCE
)

If no existing NotificationCategory fits, add a new one to the NotificationCategory enum first, then create its entry in NOTIFICATION_SOURCE_MAP.

All NotificationCategory options are defined in the src/sentry/notifications/platform/types.py file.

Step 3: Create the Notification Data

The data class is a frozen dataclass implementing the NotificationData protocol. It carries everything the template needs to render.

File: templates/<your_notification>.py (new file)

from dataclasses import dataclass
from sentry.notifications.platform.types import NotificationData, NotificationSource

@dataclass(frozen=True)
class MyNotificationData(NotificationData):
    source = NotificationSource.MY_NEW_SOURCE  # class variable, not a field
    title: str
    detail_url: str

Rules:

  • source is a class variable (no type annotation), not a dataclass field
  • Use frozen=True for serialization safety
  • Only include fields needed by the template's render() method
  • Avoid Django model instances; use primitive types or simple dataclasses for async serialization
For full examples (DataExportSuccess, DataExportFailure), load references/data-and-templates.md.

Step 4: Create the Notification Template

The template converts your data into a provider-agnostic NotificationRenderedTemplate.

Same file as Step 3: templates/<your_notification>.py

from sentry.notifications.platform.registry import template_registry
from sentry.notifications.platform.types import (
    NotificationCategory,
    NotificationRenderedAction,
    NotificationRenderedTemplate,
    NotificationTemplate,
    ParagraphBlock,
    PlainTextBlock,
)

@template_registry.register(MyNotificationData.source)
class MyNotificationTemplate(NotificationTemplate[MyNotificationData]):
    category = NotificationCategory.MY_CATEGORY
    example_data = MyNotificationData(
        title="Example title",
        detail_url="https://example.com",
    )

    def render(self, data: MyNotificationData) -> NotificationRenderedTemplate:
        return NotificationRenderedTemplate(
            subject=data.title,
            body=[
                ParagraphBlock(blocks=[PlainTextBlock(text="Something happened.")])
            ],
            actions=[
                NotificationRenderedAction(label="View Details", link=data.detail_url)
            ],
        )

Available body block types:

Refer to src/sentry/notifications/platform/types.py for the latest available block types.

Register the import in templates/__init__.py:

from .my_notification import MyNotificationTemplate

This import is required so the @template_registry.register decorator executes at startup (via sentry/notifications/apps.py).

For the full rendered template field reference and more examples, load references/data-and-templates.md.

Step 5: Register Rollout and Send

Rollout registration

The platform uses a tiered rollout system. Each notification source must be added to the appropriate rollout option before it will be delivered.

Rollout options are configured externally in sentry-options-automator (not this repo). The option keys are:

Rollout stageOption key
Internal testingnotifications.platform-rollout.internal-testing
Sentry orgsnotifications.platform-rollout.is-sentry
Early adopternotifications.platform-rollout.early-adopter
General accessnotifications.platform-rollout.general-access

Each option is a Dict mapping source string to rollout rate (0.0-1.0). Example:

{"my-new-source": 1.0}

These options are registered in src/sentry/options/defaults.py (already done for the four stages above).

Sending pattern

from sentry.notifications.platform.service import NotificationService
from sentry.notifications.platform.target import GenericNotificationTarget
from sentry.notifications.platform.types import (
    NotificationProviderKey,
    NotificationTargetResourceType,
)

data = MyNotificationData(title="Export ready", detail_url="https://...")

# Guard with rollout check
if NotificationService.has_access(organization, data.source):
    service = NotificationService(data=data)
    target = GenericNotificationTarget(
        provider_key=NotificationProviderKey.EMAIL,
        resource_type=NotificationTargetResourceType.EMAIL,
        resource_id=user.email,
    )
    service.notify_async(targets=[target])
For target types, async/sync decisions, and strategy patterns, load references/targets-and-sending.md.

Step 6: Add a Custom Renderer

Custom renderers bypass the default template-to-renderable conversion for a specific provider + category combination. Use when the default block-based rendering is too limiting (e.g., interactive Slack buttons, rich card layouts).

When to use:

  • The notification needs provider-specific interactive elements (buttons with action IDs, rich text blocks)
  • The rendered output structure differs significantly from subject + body + actions
  • You need to render different data types differently within the same provider

How it works: Override get_renderer() on the provider to return your custom renderer class for the relevant category:

# In the provider class
@classmethod
def get_renderer(
    cls, *, data: NotificationData, category: NotificationCategory
) -> type[NotificationRenderer[MyRenderable]]:
    if category == NotificationCategory.MY_CATEGORY:
        return MyCustomRenderer
    return cls.default_renderer

File placement: {provider}/renderers/{name}.py (e.g., slack/renderers/seer.py)

For architecture details and the full Seer Slack renderer example, load references/custom-renderers.md.

Step 7: Add a New Provider

Adding a new provider requires implementing the NotificationProvider protocol, a default NotificationRenderer, and registering both. This should only be done when onboarding a new integration provider.

High-level steps:

1. Create {provider_name}/provider.py with provider + default renderer classes 2. Register with @provider_registry.register(NotificationProviderKey.MY_PROVIDER) 3. Add NotificationProviderKey.MY_PROVIDER to the NotificationProviderKey enum in types.py 4. Import the provider in sentry/notifications/apps.py 5. Gate availability behind a feature flag in is_available()

For the full provider scaffold and protocol requirements, load references/provider-template.md.

Step 8: Test

Test directory: tests/sentry/notifications/platform/

Template test

class TestMyNotificationTemplate:
    def test_render(self):
        data = MyNotificationData(title="Test", detail_url="https://example.com")
        template = MyNotificationTemplate()
        rendered = template.render(data)

        assert rendered.subject == "Test"
        assert len(rendered.body) == 1
        assert len(rendered.actions) == 1
        assert rendered.actions[0].link == "https://example.com"

    def test_render_example(self):
        template = MyNotificationTemplate()
        rendered = template.render_example()
        assert rendered.subject  # Verify example_data produces valid output

Service integration test

from unittest.mock import patch
from sentry.notifications.platform.service import NotificationService

class TestMyNotificationService:
    @patch("sentry.notifications.platform.email.provider.EmailNotificationProvider.send")
    def test_notify_target(self, mock_send):
        data = MyNotificationData(title="Test", detail_url="https://example.com")
        service = NotificationService(data=data)
        target = GenericNotificationTarget(
            provider_key=NotificationProviderKey.EMAIL,
            resource_type=NotificationTargetResourceType.EMAIL,
            resource_id="user@example.com",
        )
        service.notify_target(target=target)
        assert mock_send.called

Custom renderer test

If you added a custom renderer, test that the provider dispatches to it:

def test_get_renderer_returns_custom():
    data = MySpecialData(source=NotificationSource.MY_SOURCE, ...)
    renderer = MyProvider.get_renderer(data=data, category=NotificationCategory.MY_CATEGORY)
    assert renderer is MyCustomRenderer

Step 9: Verify

Pre-flight checklist before submitting:

  • [ ] NotificationSource enum value added to types.py
  • [ ] Source added to NOTIFICATION_SOURCE_MAP under correct category
  • [ ] Data class is @dataclass(frozen=True) with source as class variable
  • [ ] Template registered with @template_registry.register(DataClass.source)
  • [ ] Template imported in templates/__init__.py
  • [ ] example_data on template produces valid output via render_example()
  • [ ] Rollout option value configured (or ticket filed for sentry-options-automator)
  • [ ] Sending code guarded with NotificationService.has_access()
  • [ ] Tests pass: pytest -svv --reuse-db tests/sentry/notifications/platform/
  • [ ] Pre-commit passes on all modified files

Related skills

FAQ

What does notification-platform do?

Guide for adding notifications, custom renderers, or new providers to Sentry's NotificationPlatform. Use when asked to "add notification", "new notification", "notification platform", "send notification", "notification t

When should I use notification-platform?

Guide for adding notifications, custom renderers, or new providers to Sentry's NotificationPlatform. Use when asked to "add notification", "new notification", "notification platform", "send notification", "notification t

Is notification-platform safe to install?

Review the Security Audits panel on this page before installing in production.

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.