# Put your status page on your own domain

Pro and Business accounts can serve their status page at a hostname you own,
like `status.example.com`, instead of `ups.dev/<slug>`. Setup is two DNS
records and one API call to check them. Your `ups.dev/<slug>` URL keeps working
afterwards.

## 1. Tell ups.dev the hostname

```
PUT https://ups.dev/api/v1/status_pages/:id/custom_domain
Authorization: Bearer <api token>
{"custom_domain": "status.example.com"}
```

The response lists the two records to create, with your verification token
filled in. On the free plan it answers `402 plan_required` and says how to
upgrade. The MCP tool `set_custom_domain` does the same thing.

## 2. Add two DNS records

| Type  | Name                                 | Value                                  |
|-------|--------------------------------------|----------------------------------------|
| CNAME | `status.example.com`                 | `custom.ups.dev`                       |
| TXT   | `_ups-challenge.status.example.com`  | `ups-domain-verification=<your token>` |

The TXT record proves the domain is yours; the CNAME sends traffic to us. Both
are required.

- **Most DNS consoles append the zone for you.** In a zone for `example.com`,
  type just `status` and `_ups-challenge.status`. Typing the full name usually
  creates `status.example.com.example.com`, which won't verify. If that
  happens, the verify response says where it found your records and which
  names to enter instead.
- **Cloudflare DNS:** set the CNAME to *DNS only* (grey cloud). A proxied
  record hides the `custom.ups.dev` target, so routing can't be verified and
  we can't issue your certificate.
- **Apex domains** (`example.com` itself) can't hold a CNAME. Use your
  provider's ALIAS/ANAME/flattening record pointing at `custom.ups.dev`, or A
  records with the same addresses `custom.ups.dev` resolves to.

## 3. Verify

```
POST https://ups.dev/api/v1/status_pages/:id/custom_domain/verify
```

Run it once the records exist; it checks live DNS every time, so retry freely
while records propagate. The response reports `ownership` and `routing`
separately, each with what we expected and what we saw. MCP:
`verify_custom_domain`.

Once both pass, the first HTTPS visit to your hostname gets a Let's Encrypt
certificate issued on the spot, which takes a few seconds. After that the
page, its feed, incident pages and email subscribe all work on your domain.

## Later

- `GET /api/v1/status_pages/:id/custom_domain` shows the current state;
  `DELETE` removes the domain.
- Changing the hostname issues a new token, so you'll add a new TXT record and
  verify again.
- If the subscription lapses, the domain stops serving until you pay again.
  Your records and token are kept, so one `POST .../verify` brings it back.
