← Back to blog

A status badge that's safe to put on any website

2026-10-26

engineeringstatus-pages

A status badge is a small piece of your monitoring that you hand to strangers. It renders on your marketing site, in a README or on a customer portal, for anyone who loads the page. So the questions to ask about it are mostly about what it doesn't do: what it leaks, what it lets someone guess, and what happens when it's switched off.

Archer is okokumo's badge. The first-check guide gives it one paragraph. This post goes through the code behind it.

The snippet

Open a check, expand Archer — public status badge, switch on Enable public status badge, then pick a style and a theme. The dashboard builds the snippet for you:

<iframe src="https://app.okokumo.com/embed/YOUR_TOKEN?variant=compact&theme=light" width="160" height="190" style="border:none;" title="Status badge"></iframe>

Choosing Detailed (30-day bar) changes it to variant=detailed at width="520" height="140". Dark changes it to theme=dark. That's the whole option set. Any theme other than dark renders light, and any variant other than detailed renders the compact ring.

Archer is on every paid plan. On Free, the enable call returns 403 Archer requires a paid plan.

The token is the credential

The route is GET /embed/:token on the API, with no session and no API key. A site embedding your badge couldn't send either. The token is 16 bytes from crypto/rand, hex-encoded to 32 characters, and it is minted the first time you enable the badge. Heartbeat ping URLs are built the same way.

The token addresses one check's badge and nothing more. It can't be used against /v1, and it isn't included in your data export. The export code says so explicitly: ping and embed tokens are "live credentials that address a check publicly", not configuration you need in order to move.

Unknown and disabled look the same

The handler does one lookup: a check whose embed_token matches and whose embed_enabled is true. If either condition fails, the response is the same 404 with the same unknown badge message.

That's deliberate. If a disabled badge answered differently from a token that never existed, every 404 would tell an attacker which guesses had once been real. With identical answers there's nothing to learn from probing, and the token space is 2¹²⁸ anyway. The route is also rate-limited per IP to 60 requests a minute, with a 429 and Retry-After past that.

The one route built to be framed

Pages that hand out access are the usual clickjacking targets. okokumo's OAuth consent screen sends X-Frame-Options: DENY and Content-Security-Policy: frame-ancestors 'none', because a framed Approve button would give an access token to whoever framed it.

The embed route is the opposite case. Its only job is to be loaded inside someone else's <iframe>, so it must never carry either header. The comment on the route's registration says it "must NEVER be wrapped in frame-blocking middleware", and a regression test fails the build if the handler ever sets X-Frame-Options or a frame-ancestors directive. Caddy passes /embed/* straight to the Go API without adding any frame headers.

Being safe to frame is easier when there's nothing on the page to act on. The badge has no forms, no buttons, no JavaScript and no session. Its only interactive element is the footer link.

What a visitor sees

The page is a hand-built HTML string, without a template engine or a build step. It contains:

  • The check's name, HTML-escaped. This is your check name exactly as it appears in the dashboard, so rename prod-api-lb-healthz to "API" before you embed it.
  • Compact: a 96 px ring. Its colour is the check's current state (green up, red down, grey unknown), and the label inside is 30-day uptime with one decimal, e.g. 99.9%.
  • Detailed: 30 squares, one per UTC day, oldest on the left. Each is up, down, partial (amber) or no data (grey). This variant shows no percentage.
  • A footer: the okokumo mark and "Powered by Okokumo", linking to https://okokumo.com/?ref=archer-badge in a new tab.

The page doesn't show the URL or host being checked, the check type, the interval, response times, error messages, alert channels or your organization name.

The percentage is successful probes divided by all probes over the last 30 UTC days, today included. What "99.9% uptime" actually counts works through the arithmetic, including why a 3-minute outage still rounds to 100.0% on a badge. A check with no results anywhere in the window shows – rather than 0% or 100%.

The two themes use the dashboard's own colours in dark (#0f1419 background, #4ade80 up, #f7768e down). Light uses deeper shades (#16a34a, #dc2626, amber #d97706), because a filled shape on white needs more contrast than pastel text on near-black.

Paused means paused, nothing more

A check can be paused by hand or automatically after a plan downgrade, and the dashboard records which. The badge shows neither. A paused check renders its name and one neutral line, Monitoring paused. The compact ring goes grey with – in place of the percentage. It isn't red, because a pause isn't an outage. It isn't green either, even if the last recorded state was up.

The detailed bar keeps the days recorded before the pause. Paused days have no results, so they're grey. A test sets the pause reason to plan_downgrade and fails if that string ever appears in the response. Your visitors don't need to know why you paused monitoring, and they won't learn whether it had anything to do with billing.

Caching

A successful response carries Cache-Control: public, max-age=60, so a state change can take up to about a minute to show. The 404 is returned before that header is set and carries no cache header at all.

Disabling, and rotation

Switching the toggle off sets embed_enabled to false. From the next uncached request, every copy of the snippet, wherever it was pasted, gets the same 404 as a token that never existed. In the browser, the frame shows a one-line JSON error instead of your badge, so remove the snippet too.

The token itself is kept, so switching the badge back on brings back the same URL, and you don't have to find and re-paste every embed. Downgrading to Free does the same: it disables every badge in the organization and keeps the tokens. Re-upgrading and switching a badge back on restores its old URL.

There's no button to rotate the token yet. Today the only way to kill a URL is to switch the badge off, and switching it back on revives that same URL. The exposure is a read-only view of a name and a status, but if you want a URL that's no longer in circulation, that's a fair thing to want and we've noted it.

For more than one check, with incidents and 90 days of history, use Tower, on Pro and Business. Your status page is not a dashboard covers what belongs on one.