> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pult.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Status pages

> A public page with your components, their uptime and your incidents, kept up to date by Pult watching your app.

Pult already talks to your app all day, so it knows when your app stops answering. A status page turns that into something your customers can see. It also tells your team the moment something goes down.

```ts theme={null}
import { slack, status } from "pult"
import { oncall } from "./roles"

export const statusPage = status({
  title: "Acme",
  components: {
    api: { label: "API", monitored: true },
    web: { label: "Website", check: "https://acme.com/health" },
    git: "Git hosting",
  },
  alert: [oncall, slack("incidents")],
})
```

A project has one status page. It runs in your last environment, the one your config treats as production, and its address is `status.pult.sh/<organization>/<project>`.

## Components

Each component is something your customers recognise. It can be kept up to date in three ways:

* **`monitored: true`** follows Pult's connection to your app. If your app uses `listen()`, Pult notices when the connection drops. With webhooks, Pult sends your app a signed ping every minute, which the `pult` package answers for you. The component goes down when your app has been unreachable for longer than `after` (two minutes by default, so a restart during a deploy doesn't count), and it comes back as soon as your app does.
* **`check`** is an address Pult fetches on a schedule. Any response in the 200s or 300s counts as up. Use it for the parts your customers actually load, like your website or a health endpoint.
* **Everything else** is set by your team in the console, or by your app.

Your app can set any component's state when it knows better:

```ts theme={null}
await pult.status.set("git", "degraded")
```

The states are `operational`, `degraded`, `partial`, `down` and `maintenance`.

## Alerts

`alert` takes roles and Slack channels, like [notifications](/build/notifications). Everyone in them hears when a monitored component or a check goes down, and again when it's back, with how long it was out.

## Incidents

When something's wrong, post an incident from Status in the console: a title, where it stands (investigating, identified, monitoring or resolved), what people should know, and how badly each component is affected, from degraded performance to a major outage. That impact is what the top of your page shows. Each update you post appears on the public page right away. Resolving an incident puts its components back to operational, except ones Pult still sees failing, which stay as they are until your app or their check recovers. Pult never posts incidents on its own, so the words customers read are always yours.

Roles need `status: true` to change components and post incidents. Admins always can. Every change is in the audit log.

## The public page

The page shows each component's state, 90 days of history with its uptime, the incidents happening now and the ones from the last two weeks. Older incidents are on its history page, kept for as long as your plan keeps history. It's plain HTML that loads instantly and works in light and dark.

## Making it yours

```ts theme={null}
export const statusPage = status({
  title: "Acme",
  logo: { light: "https://acme.com/logo.svg", dark: "https://acme.com/logo-dark.svg" },
  website: "https://acme.com",
  css: readFileSync(new URL("./status.css", import.meta.url), "utf8"),
  components: { ... },
})
```

* `logo` replaces the title at the top. Pass one address, or a light and a dark one.
* `website` is where the logo or title links to.
* `css` is added after the page's own styles, so anything you write wins. Any way of getting a string works, whether it's a file you read or a template literal.

The colors are variables on `:root`, set separately for light and dark: `--bg`, `--panel`, `--raised`, `--line`, `--text`, `--muted`, `--faint`, and the state colors `--signal` (operational), `--warn` (degraded and partial outages), `--danger` (major outages) and `--info` (maintenance). The parts of the page have plain class names you can target: `.overall`, `.component`, `.label`, `.state`, `.bars`, `.bar`, `.legend`, `.incident` (with `.active` while it's ongoing), `.update`, `.when` and `.meta`. A component or bar in a given state also has `.state-operational`, `.state-degraded` and so on.

```css theme={null}
@import url("https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@400;500;600&display=swap");
:root { --signal: #6d5bd0; }
@media (prefers-color-scheme: dark) {
  :root { --bg: #0b0b12; }
}
body { font-family: "Instrument Sans", sans-serif; }
```

Keep it under 50 KB. `pult check` tells you if a logo or website isn't a web address.

## Your own domain

On the Team plan and up, you can serve it from your own domain. Add the domain in your project's settings under Status page, then point a CNAME record at the address shown there. It goes live with its own certificate a few minutes later.

## What each plan includes

Every plan gets a status page, app monitoring and alerts. Plans differ in how many addresses Pult checks and how often:

| | Free | Team | Business | Enterprise |
| - | - | - | - | - |
| Checks | 3 | 10 | 50 | No limit |
| How often | Every 5 minutes | Every minute | Every 30 seconds | Every 30 seconds |
| Custom domain | No | Yes | Yes | Yes |

Checks beyond your plan's number stay on the page as you set them, and the console tells you they aren't being checked.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.