Use case · Maintenance & incidents

Maintenance notices that come and go on time

Warn users the day before, show a banner while the work runs, and let both disappear on their own. If plans change, one cancel takes a notice back from every screen. No banner component to deploy, no status page to send people to.

created in
dashboard or api
audience
everyone or tags
shown as
sheet, then banner
sdk
react · react native

How the notices get made

Planned maintenance is two notifications your team schedules in the dashboard. Unplanned incidents come from your own tooling over the API. Either way, your app shows them the same way.

01 · Your app, once

Decide how a notice looks

A notice says how it wants to be shown in its data, and your app reads it. Here a banner stays across the top of the web app for as long as it is live, and a sheet pops up once on mobile when it arrives.

Every feed item carries its expiresAt, so the banner can count down to the end of the window.

import { useNotifications } from "@notificationstream/react";
import { useEffect, useState } from "react";

// Across the top of every page, for as long as a notice is live
export function MaintenanceBanner() {
  const { items } = useNotifications();
  const now = useNow(30_000);
  const notice = items.find(
    (n) => n.data?.display === "banner" && (n.expiresAt === null || n.expiresAt > now),
  );
  if (!notice) return null;
  return <Banner title={notice.title} body={notice.body} endsAt={notice.expiresAt} />;
}

// Re-renders on a timer, so the banner leaves right at expiresAt
function useNow(interval: number) {
  const [now, setNow] = useState(Date.now);
  useEffect(() => {
    const timer = setInterval(() => setNow(Date.now()), interval);
    return () => clearInterval(timer);
  }, [interval]);
  return now;
}

02 · Your team, for planned maintenance

Schedule both notices in the dashboard

The heads-up goes out right away with "display": "sheet" and expires when the window opens.

The banner is scheduled for the start of the window and expires at its end. Nobody needs to be awake at 02:00: it goes live and disappears on time.

Both stay editable until they go live. If the window moves after that, cancel the notice and send a new one.

03 · Your incident tooling, for the unplanned

Send and take back notices from code

When an incident opens, your tooling sends a banner to the customers it affects, here everyone tagged with the region. Store the notification id with the incident.

Published notifications don’t change, so an update cancels the banner and sends a new one. When the incident is resolved, a cancel removes it from every feed.

import { NotificationStream } from "@notificationstream/node";

const ns = new NotificationStream({ secretKey: process.env.NOTIFICATIONSTREAM_SECRET_KEY });

// An incident is opened: a banner for the customers in the affected region
export async function onIncidentOpened(incident) {
  const notice = await ns.notifications.create(
    {
      audience: { type: "tags", tags: [`region:${incident.region}`], match: "any" },
      category: "maintenance",
      contents: { en: { title: incident.title, body: incident.summary } },
      data: { display: "banner", incidentId: incident.id },
    },
    { idempotencyKey: `incident:${incident.id}:${incident.updatedAt}` },
  );
  await db.incidents.update(incident.id, { noticeId: notice.id });
}

// An update is posted: swap the banner for one with the new text
export async function onIncidentUpdated(incident) {
  await ns.notifications.cancel(incident.noticeId);
  await onIncidentOpened(incident);
}

// Resolved: take the banner back from every screen
export async function onIncidentResolved(incident) {
  await ns.notifications.cancel(incident.noticeId);
}

What your users see

A warning before, not an error during
The heads-up reaches users the day before, while there is time to plan around it.
Live and gone on schedule
Scheduled notices go live at their publish time and leave every feed when they expire.
Taken back in one call
A cancel reaches apps with realtime within seconds and everyone else on their next feed check.
Only the customers affected
Target tags such as region:eu or a segment, so an EU outage doesn’t alarm users in the US.
One notice, web and mobile
Both SDKs get the same notification and each app shows it its own way.
A record afterwards
Expired and canceled notices stay in your dashboard history, with their status.

Plan

Scheduling ahead, tag audiences and realtime need Growth or Scale. On Starter, publish notices right away to everyone and let them expire.

More use cases

Build it this week

Start a free trial, drop the SDK into your app and send your first notification from the dashboard.