Skip to documentation
InBrief

Badges, feeds & calendar

Live badges, lifecycle subscriptions, and scheduled maintenance in calendar clients

Public surfaces

On this page8

The public, unauthenticated embed surface of a status page. No API key anywhere on this page: everything here is public information by design, same as the status page itself. The dashboard's Status page → Embeds & feeds page generates feed and calendar URLs with copy buttons, alongside the named badge and widget editors. The public badge routes below remain compatible for existing installations.

All examples use the permanent page address acme.inbrief.sh. A live custom domain can also serve the legacy public routes, but copied machine integrations should keep the permanent address so a later custom-domain change does not strand them.

Named badges and the status widget

Each badge or widget you create under Status page → Embeds & feeds is an installation with a public id: emb_ followed by 21 lowercase letters and digits. The editor gives you snippets to paste. The addresses below are always on your page's permanent address, and each one answers only for an installation that belongs to that page.

URLWhat it is
/embed/v1/widget.jsThe loader script. Give it data-installation="emb_…" and it draws that widget where the tag sits. If the widget is switched off for your page, the script is empty and does nothing.
/embed/v1/installations/{id}/frameThe widget as a page of its own, for an <iframe>.
/embed/v1/installations/{id}/badge.svgThe installation's badge as an SVG image, for a README or anywhere scripts cannot run.
/embed/v1/installations/{id}/config.jsonThe installation's settings as JSON. The loader reads it; the editor calls it the widget JSON URL.

The loader snippet is one async script tag whose src is https://acme.inbrief.sh/embed/v1/widget.js, with data-installation set to the installation's id and referrerpolicy="no-referrer". Copy it from the editor rather than typing it.

A badge never breaks: an unknown, removed or switched-off installation draws a grey unknown badge instead. The frame and config.json answer 404 in that case, config.json with the body {"available":false}, and those answers are never cached.

Successful answers are cached publicly for up to five minutes, and for less when a service is about to go stale. Each carries a strong ETag; send it back as If-None-Match and an unchanged answer is 304 with no body. If-Modified-Since is not used. The script and both JSON documents can be fetched from any website.

Page status as JSON

Request
https://acme.inbrief.sh/embed/v1/pages/pg_…/status.json?lang=ar

The current state of the page and each public service in one small document, for code that draws its own indicator. It is what the widget itself reads. The address contains your page's public key, pg_ followed by 21 lowercase letters and digits. Copy the address from Status page → Embeds & feeds, under Status JSON. ?lang= picks one of the languages your page publishes.

Response
{
  "schemaVersion": 1,
  "language": "en",
  "page": {
    "slug": "acme",
    "name": "Acme",
    "url": "https://status.example.com/",
    "overall": "degraded",
    "lastCheckedAt": "2026-10-15T09:41:00.000Z"
  },
  "services": [
    {
      "slug": "checkout-api",
      "name": "Checkout API",
      "measurement": "degraded",
      "freshness": "live",
      "maintenance": "none",
      "overall": "degraded",
      "lastCheckedAt": "2026-10-15T09:41:00.000Z"
    }
  ],
  "activeIncidents": [
    {
      "id": "inc_01",
      "title": "Slow checkout",
      "summary": "Payments are taking longer than usual. We are looking into it.",
      "impact": "degraded",
      "phase": "investigating",
      "serviceSlugs": [
        "checkout-api"
      ],
      "startedAt": "2026-10-15T09:30:00.000Z",
      "updatedAt": "2026-10-15T09:35:00.000Z",
      "url": "https://status.example.com/incidents/inc_01"
    }
  ],
  "activeMaintenances": []
}

overall is one of operational, degraded, outage, maintenance, stale, paused or unknown. An active incident's impact wins over everything else, then active maintenance, then a paused or stale monitor, then the latest check. A key that does not belong to the page on that address answers 404. Caching, ETags and cross-origin access work as for the other addresses in this section.

Legacy badge routes

These shields.io-style SVG routes remain available for compatibility with existing embeds. A shared cache keeps a badge for at most 30 seconds, and for less when the monitor behind it is about to go stale. Every response carries a strong ETag; send it back as If-None-Match and an unchanged badge answers 304 with no body. The dashboard does not configure these routes; it configures named badges instead. See the badges and widgets guide.

URLWhat it shows
/badge.svgThe whole page: operational, degraded (some monitors down), down, or unknown.
/badge/{service}.svgOne monitor, labelled with its name: operational, down, or unknown.

{service} is the monitor's slug, visible in the dashboard's monitor list, or programmatically in GET /api/public/{slug}/summary (each entry's slug field).

Styles

?style=uptime replaces the status word with a 30-day uptime figure, e.g. 99.97%. The window is fixed at 30 days regardless of the history window your page displays. That is the badge convention, and the two are different measurements.

Response
[![status](https://acme.inbrief.sh/badge/api.svg)](https://acme.inbrief.sh/)

Language

?lang= draws the badge in one of the languages your page publishes, so a badge embedded on an Arabic marketing site reads in Arabic even when your page's default is English. Without it the badge uses your page's default language. A language your page does not publish falls back to that default rather than failing, the same way an unrecognised style does.

Response
[![status](https://acme.inbrief.sh/badge/api.svg?lang=ar)](https://acme.inbrief.sh/)

JSON variant

/badge.json and /badge/{service}.json return the same data in the shields.io endpoint-badge schema, so shields.io can render it in any of its own styles:

Response
{
  "schemaVersion": 1,
  "label": "Checkout API",
  "message": "operational",
  "color": "#2F7A55"
}

Never a dead end

A badge URL never 404s. An unrecognised service slug (renamed, deleted, or a typo) and even an unrecognised hostname render the grey unknown badge, because a broken image icon in someone else's README reads as the service itself being broken, so the badge always draws.

Feeds

/feed.xml (RSS 2.0) and /feed.atom (Atom) serialise the same latest 100 public lifecycle events. That includes incident opening, meaningful updates and resolution; maintenance announcement, updates, overrun, completion and cancellation; and postmortem publication. Both addresses use the same two optional query filters:

FilterEffect
?lang={code}The feed in any language the page publishes (en, ar, fr, es). An unpublished code falls back to the default language.
?service={slug}Only events that touched that monitor. An unknown slug yields valid empty feeds, never a 404, because a renamed monitor must not hard-break a standing subscription.

Filters combine with &:

Request
https://acme.inbrief.sh/feed.xml?service=api&lang=ar
Request
https://acme.inbrief.sh/feed.atom?service=api&lang=ar

Both feeds are cached for five minutes.

A page created before lifecycle feeds existed serves the older feed instead: /feed.xml carries its incident ledger, the latest 100 incidents, and /feed.atom answers 404.

Maintenance calendar

/maintenance.ics is an iCalendar subscription containing up to 150 scheduled/open one-off windows and the 50 most recent completed or cancelled windows. Add it once to a calendar client and later schedule changes move the same event instead of creating duplicates.

FilterEffect
?lang={code}Localised event title and summary in a language the page publishes. An unpublished code falls back to the page default.
Request
https://acme.inbrief.sh/maintenance.ics?lang=ar

Times are absolute UTC instants and calendar apps display them in each reader's timezone. Rescheduling preserves the event UID and advances its sequence and timestamp. Recent cancelled work remains in the bounded feed with STATUS:CANCELLED. The calendar is cached for five minutes.