A public status page for your app: whether your API, sign-in, storage, functions and website are up, 90 days of history, incidents, maintenance, e-mail subscribers, Slack and webhook alerts, your own domain, a badge and JSON.
The status page tells your app's users whether things work before they write to support. It lives at https://<ref>.p.stitchdb.com/status, is checked every minute from your project's own server, and shows each component's state now and over the last 90 days, the incidents you post and planned maintenance. Embed a badge in your README or help center, or read the state as JSON in your app.
#Turn it on
In Studio open Integrations › Status page and click Turn on status page (project admins). It starts with your project's services: API, Authentication, Database, File storage, Edge Functions and Realtime, as many as your plan includes. The first checks run within a minute; the 90-day bars fill in as days pass.
#Components
Each component is one line on the page. Rename them for your users (Sign-in instead of Authentication), reorder or remove them, and add your own URLs, such as your website or your own API server.
| Check | How it is checked |
|---|---|
| API | GET /rest/v1/ through your project’s public address with the anon key |
| Authentication | GET /auth/v1/health |
| File storage | GET /storage/v1/bucket |
| Edge Functions | The functions router at /functions/v1/ |
| Realtime | The Realtime service at /realtime/v1/ |
| Database | select 1 on your database |
| One of your URLs | GET on an https URL you give, on a public address |
A check passes when the service answers within 10 seconds without a server error (a 401 or 404 from the service still means it is up). An answer slower than 3 seconds counts as degraded. One failed check shows the component as degraded; two in a row as an outage. The page shows the change at once and lists it under Recent status changes in Studio.
#History
Every check is counted per day in your database (schema _stitch_status, kept 90 days). A day is red when the component was down for 5 minutes or more (or under 99% up), yellow when it was down briefly or slow for over 10% of checks. Hover a day to see its uptime and the minutes down; the percentage under the bars is the uptime over the 90 days.
#Incidents
When something breaks, tell your users before they ask. Report incident takes a title, the impact, the affected components and a first message:
- Minor: the components show as degraded.
- Major or Critical: the components show as an outage, even while the checks still pass (for problems the checks cannot see, such as wrong data or a broken payment flow).
Post updates as you go: Investigating, Identified, Monitoring, Resolved. Every update is listed under the incident with its time. A resolved incident moves to Past incidents, which stay on the page as a record. You can edit an update's text afterwards (a typo), or delete an incident posted by mistake.
#Scheduled maintenance
Schedule maintenance takes a start and an optional end time and the components it affects. It is listed at the top of the page while it is Scheduled. Post an In progress update when it starts, and the components show as maintenance instead of an outage; post Completed when you are done.
#Notifications
#E-mail subscribers
E-mail subscribers are included from the Pro plan. Turn on Visitors can subscribe by e-mail under Notifications and the page gets a Get updates by e-mail form. A visitor enters an address and gets a confirmation e-mail; once confirmed, they get an e-mail each time you post an incident, schedule maintenance or post an update, with the message, the affected components and a link to the page.
- E-mails are sent with your Authentication e-mail settings: your own SMTP server if you set one, otherwise ours, from your verified sender domain if you added one.
- Every e-mail has an unsubscribe link and the
List-Unsubscribeheaders, so mail apps show a one-click Unsubscribe button. Links in e-mails open a page with a button, so mail scanners that open links do not confirm or unsubscribe anyone. - The form answers the same for an address that is already subscribed, so nobody can find out who is. A network address can sign up 5 times an hour, and addresses not confirmed within 7 days are removed.
- Only what you post is e-mailed. The checks' own findings (a component going down by itself) go to webhooks, not to subscribers.
In Studio, View subscribers lists the addresses (project admins can remove one). Your own site can sign people up too, with POST /status/v1/subscribe and a JSON body {"email": "…"}.
#Slack and webhooks
Under Slack and webhooks add up to 5 places to notify: a Slack channel (an incoming webhook URL from Slack's Incoming Webhooks app) or your own https endpoint, for example to page your on-call team. Each one gets incidents and maintenance (new and every update), and optionally outages found by the checks, and recoveries: when a component goes down after two failed checks in a row, and when it answers again. Slow minutes and single failed checks are not sent.
POST https://yourapp.com/hooks/status
StitchDB-Event: status.incident.created
StitchDB-Webhook-Timestamp: 1793011200
StitchDB-Signature: v1=5f0c…
{
"type": "status.incident.created",
"page": { "title": "Acme status", "url": "https://status.acme.dev/" },
"incident": { "id": "3f9a1c2b7d", "title": "Sign-in errors", "impact": "major", "status": "investigating",
"components": ["auth"], "created_at": "2026-10-26T09:00:00.000Z", "resolved_at": null },
"update": { "at": "2026-10-26T09:00:00.000Z", "status": "investigating", "message": "Some sign-ins fail…" }
}| Event | When |
|---|---|
status.incident.created | An incident or maintenance is posted |
status.incident.updated | An update is posted (including Resolved and Completed) |
status.component.down | A component is down: two failed checks in a row (component, status, previous, detail, at) |
status.component.recovered | It answers again |
Check the signature before you trust a request: v1= followed by the hex HMAC-SHA256, with the webhook's signing secret (Studio › Signing secret), of <StitchDB-Webhook-Timestamp>.<raw body>. Reject timestamps older than 5 minutes. A failed delivery is tried once more after 2 seconds; Recent deliveries in Studio shows what was sent and what failed.
import crypto from 'node:crypto'
function verify(req, rawBody, secret) {
const ts = req.headers['stitchdb-webhook-timestamp']
const want = 'v1=' + crypto.createHmac('sha256', secret).update(`${ts}.${rawBody}`).digest('hex')
const got = req.headers['stitchdb-signature'] || ''
return Math.abs(Date.now() / 1000 - Number(ts)) < 300 && got.length === want.length
&& crypto.timingSafeEqual(Buffer.from(got), Buffer.from(want))
}#On your own domain
Show the page at status.yourapp.com: add the domain under Settings › Custom domains (Custom domains, Pro and up), and once it is live tick Use for the status page. The root of that domain then opens the status page, and links in e-mails and webhooks use it. The badge and JSON are at https://status.yourapp.com/status/v1/badge.svg and /status/v1/status.json; the page stays at https://<ref>.p.stitchdb.com/status too.
#Look
Set the page title (by default your project's name), a description, a link to your site, a logo (an https image URL) and the link colour. The page follows the visitor's light or dark mode and works on phones. On Pro and up you can hide the Powered by StitchDB link.
#Embed it
#Badge
An SVG badge with the overall state, or one component's with ?component=<id>. Change the left text with ?label=.
[](https://<ref>.p.stitchdb.com/status)<a href="https://<ref>.p.stitchdb.com/status">
<img src="https://<ref>.p.stitchdb.com/status/v1/badge.svg?component=api&label=API" alt="API status" height="20">
</a>#status.json
The same data as the page, open to any site (CORS), for a banner in your app when something is down:
const res = await fetch('https://<ref>.p.stitchdb.com/status/v1/status.json')
const status = await res.json()
if (status.overall !== 'operational') showBanner(status.overall_label)
// {
// "title": "Acme status", "overall": "degraded", "overall_label": "Some systems are degraded",
// "components": [{ "id": "auth", "name": "Sign-in", "status": "degraded", "response_ms": 3410,
// "uptime_90d": 99.982, "history": [{ "day": "2026-10-25", "uptime": 99.3, "status": "degraded" }, …] }],
// "incidents": [{ "title": "Slow sign-in", "impact": "minor", "status": "monitoring", "updates": [ … ] }],
// "updated_at": "2026-10-25T12:00:00.000Z"
// }| Field | Values |
|---|---|
overall, components[].status | operational, degraded, down, maintenance, unknown (no checks yet) |
incidents[].impact | minor, major, critical, maintenance |
incidents[].status | investigating, identified, monitoring, resolved; maintenance: scheduled, in_progress, completed |
#Limits
E-mails to subscribers have a monthly allowance per project when they go through the StitchDB sender (one e-mail per subscriber per update, confirmation e-mails included). An update that would pass it is not e-mailed (webhooks and Slack still get it) and Recent deliveries says so. With your own SMTP server (Authentication › SMTP) there is no StitchDB allowance.
| Limit | Free | Pro | Scale | Enterprise |
|---|---|---|---|---|
| Status page components per project | 5 | 15 | 30 | 50 |
| Status page checks of your own URLs | 1 | 5 | 15 | 30 |
| Status page without StitchDB branding | 0 | 1 | 1 | 1 |
| Status page e-mail subscribers | 0 | 1,000 | 10,000 | 50,000 |
| Status page e-mails per month (our sender, per project) | 0 | 440 | 1,300 | 1,100 |