# Uptime Thing

> Uptime monitoring from several independent networks. A check is only reported down when
> vantage points on different networks agree, so one flaky route does not page anybody.

## Getting started: give your human one link

You can set someone up whether or not they have an account yet. Their part is a link, an
email code, a card in Stripe Checkout and one Allow. You never handle a password or a key.

Uptime Thing is in private beta. Every page your human opens, the link and the pricing page
included, first asks for an access code, then carries on to where they were going. The code
comes from whoever invited them, not from you or from this file. Without it they cannot sign
up yet: say so, rather than starting another authorization.

1. Start a device authorization (RFC 8628):
   `curl -X POST https://app.uptimething.com/oauth/device_authorization -d client_id=uptimething-agent`
   The answer has a `verification_uri_complete`, a `user_code`, a `device_code` and an
   `interval` in seconds.
2. Give your human the `verification_uri_complete` link and the `user_code`, and tell them
   to open it. If they have no account, the page has them create one, pick a plan and pay,
   then brings them back to approve you. Plans and prices are on https://app.uptimething.com/pricing. Which plan
   is their decision, so say what each costs and let them pick.
3. While they do that, poll every `interval` seconds:
   `curl -X POST https://app.uptimething.com/oauth/token -d client_id=uptimething-agent -d grant_type=urn:ietf:params:oauth:grant-type:device_code -d device_code=<device_code>`
   `authorization_pending` means keep waiting. `slow_down` means add 5 seconds to the
   interval. `access_denied` means they said no. `expired_token` means the link ran out:
   it lasts 10 minutes, or 30 if your human has to create an account or subscribe on the
   way. Start a new authorization and give them the new link.
4. Approval returns an `access_token` and a `refresh_token`. Send the access token as
   `Authorization: Bearer <token>` to the REST API and to MCP. It lasts two hours. Renew it
   with `grant_type=refresh_token`, and your human does not have to approve you again.

The link grants everything except changing the plan and deleting the account. Those need
your human's approval at the time (MCP's step-up).

To give the access back, revoke it:
`curl -X POST https://app.uptimething.com/oauth/revoke -d client_id=uptimething-agent -d token=<refresh_token>`
Deleting your copy of the token does not revoke it. Your human can also disconnect you
under Account, AI assistants, at https://app.uptimething.com/account/assistants.

Already connected some other way? These still work:

- **MCP** at https://app.uptimething.com/mcp (Streamable HTTP), with OAuth 2.1 and discovery at
  https://app.uptimething.com/.well-known/oauth-protected-resource/mcp. In Claude Code, no registration is needed:
  `claude mcp add --transport http uptimething https://app.uptimething.com/mcp --client-id uptimething-agent
  --callback-port 33418` (any free port), then authenticate from `/mcp`.
- **An API key** your human creates at https://app.uptimething.com/account/api-keys, for scripts and CI.

## API

- [OpenAPI description](https://app.uptimething.com/api/v1/openapi.json): every endpoint, generated from the code that
  serves it.

Authentication is a bearer token: the access token from Getting started, or an API key
(`ut_live_…`). Both carry per-resource scopes.

Writes accept an `Idempotency-Key` header, 8 to 255 characters (a UUID does). Retrying with the same
key returns the original response rather than repeating the work, which matters for
anything that retries automatically.

Errors are RFC 9457 problem documents. Branch on `type`, which is a stable slug, rather than
on the prose in `title`.

## Notes

- Lists are cursor-paginated. Follow `next_cursor` until it is null. Do not construct one.
- Times are RFC 3339.
- Money is in minor units.
