Skip to content

Notifications that leave through one door.

Relay is the notification product for email, SMS, WhatsApp, and in-app. Your app posts once. We write an outbox row per channel, retry failures, and give operators a console to watch delivery.

Click to dispatch

Your event. Our outbox. Their inbox.

  1. POST /v1/messages

    App fires an event

    Tenants authenticate with an API key. One payload names the event and the recipient. Relay does not share the operator session with apps.

  2. notification_outbox

    Rows per channel

    Each hop is its own row: pending, processing, sent, or failed. Backoff runs from one minute to one hour so a stuck SMS never queues email.

  3. operator console

    Someone can see it

    Operators sign in to manage tenants, sending domains, SMTP, templates, and the live outbox — the same canvas the burst on this page is drawing.

Four channels. Same event.

Pick the channel the person is actually on. Relay keeps the fan-out honest: one event, independent delivery.

Email

Transactional mail through sending domains and SMTP. Receipts, password resets, and lifecycle copy in one hop.

SMS

Short, time-critical alerts. Each row retries on its own clock so a slow carrier never blocks email.

WhatsApp

Conversation-shaped delivery for the same event. Same payload, different channel row in the outbox.

In-app

Feed and bell for people already inside the product. No extra vendor round-trip for the in-product copy.

One call from the product.

Send with an app key. Mailbox, campaigns, people lists, automations, apps, tags, and team are in the same OpenAPI file — Scalar and Swagger on the docs site.

Open API docs
curl -X POST "https://relay.example/v1/messages" \
  -H "Authorization: Bearer $RELAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event": "order.paid",
    "title": "Order paid",
    "body": "Thanks — we have your order.",
    "to": { "email": "ops@example.com" }
  }'

Run Relay as an operator. Send through it as a tenant.

Sign in