API, CLI and MCP
We offer three ways to access your account, with the same limits as your plan.
API
REST, from a pipeline, a script or your own tooling. A token you issue and revoke yourself.
CLI
One simple Python file, nothing to install. It uses the API. This can be used by somebody at a terminal: list what is down, add or update monitors.
MCP
Via the MCP-server you can let Claude or anything that speaks the protocol the agent can read your account and make changes, as you, in a conversation.
Your API token
Make one under API tokens in your account. It is shown once, we keep only a fingerprint of it, and it belongs to you rather than to the organisation: it can do no more than you can, and it stops working if you leave or your role changes.
Send it as Authorization: Bearer n404_... on every call. The first one worth making is /api/v1/me, which answers which organisation the token acts for, which role it carries and which of the two scopes it has: a person with two accounts has two tokens and no other way to tell which one is in an environment variable.
What is in version 1
| Call | What it does |
|---|---|
| GET /api/v1/me | What this token is, and which organisation it acts for |
| GET /api/v1/monitors | Every monitor, oldest first |
| POST /api/v1/monitors | Create one, against the same rules the form obeys |
| GET /api/v1/monitors/{id} | One monitor |
| PATCH /api/v1/monitors/{id} | Change its name, address, interval or config, or pause it |
| DELETE /api/v1/monitors/{id} | Delete it, and its history with it |
| GET /api/v1/monitors/{id}/status | What it is doing now, and its uptime over a window |
| GET /api/v1/groups | Every group, with how many monitors are in it |
| POST /api/v1/groups | Create one; a name that exists returns the group that has it |
| GET /api/v1/groups/{id} | One group |
| PATCH /api/v1/groups/{id} | Rename it, or change its description |
| DELETE /api/v1/groups/{id} | Delete it. Its monitors stay, ungrouped |
| GET /api/v1/incidents | Outages, newest first, filtered by state, monitor or period |
| GET /api/v1/incidents/{id} | One incident, with the probes that saw and confirmed it |
| GET /api/v1/maintenance | Maintenance windows and what they cover |
| GET /api/v1/maintenance/{id} | One window, with the monitors and groups it covers |
| POST /api/v1/maintenance | Schedule one, on your organisation's clock, so a deploy can open a window before it starts |
| DELETE /api/v1/maintenance/{id} | Delete it. What it already covered stays covered |
| GET /api/v1/status-pages | Every status page, and whether it is switched on |
| GET /api/v1/status-pages/{id} | One page, and what is published on it |
| POST /api/v1/status-pages/{id}/monitors | Put a monitor on the page, under the name its audience should read |
| DELETE /api/v1/status-pages/{id}/monitors/{id} | Take it off this page. Other pages keep it |
| POST /api/v1/status-pages/{id}/groups | Put a group on the page; the monitors in it come too |
| DELETE /api/v1/status-pages/{id}/groups/{id} | Take the heading off. Its monitors stay published |
Every id in a path or a body is the UUID. Writing needs a read and write token and a role that may write.
The document is in the OpenAPI 3.1 format. It describes every call. You can use it to generate a client with openapi-generator, oapi-codegen.
Version 1 only ever grows: a field may be added, none is removed or retyped, and a second version would be a second path. So a generated client keeps working, and regenerating it is how you pick up what is new.
A client, if you want one
One file, Python 3.9 or newer, no dependencies. Download it and put your token in the environment. It does everything the API does, because every command is one call to the routes above.
curl -O https://nomore404.com/api/nomore404.py
curl -s https://nomore404.com/api/nomore404.py.sha256 | sha256sum -c
chmod +x nomore404.py
export N404_TOKEN=n404_...
./nomore404.py monitors list
./nomore404.py monitors add --type https --target shop.example.com
./nomore404.py incidents --state open
The token comes from N404_TOKEN or from a nomore404.env file beside the script.
For an assistant
An assistant can read this account and change it, over the Model Context Protocol.
One address, nothing to install
Paste this where your assistant asks for a custom connector. It will send you here to sign in and to say which organisation the connection is for, and that is the whole setup.
It acts as you: your role is read on every call, so an assistant connected by somebody who may only read can only read. It reads monitors, outages, uptime, maintenance windows and groups, and it can add and change them, which includes deleting a monitor and the history with it. Disconnect it whenever you like from API tokens, where it is listed beside them.
Failures, and long lists
One error shape
The status says the category. The body says which failure it was, with a code to branch on and a sentence to read. The sentence may be reworded in any release, so nothing should parse it.
{
"error": {
"code": "monitor_not_found",
"message": "Nothing here with that id."
}
}
Cursors, not offsets
A listing answers with items and next_cursor. Pass the cursor back to get the next page, and stop when it is null. Incidents arrive while you are reading them, and an offset would quietly show you one row twice and never show you the next.
GET /api/v1/incidents?limit=50
GET /api/v1/incidents?limit=50&cursor=...
Limits
One token may make 120 calls a minute. Every answer carries RateLimit-Remaining and RateLimit-Reset, so a well-behaved client can pace itself instead of finding the limit by hitting it. When the account goes over the limit you will see a 429 response with Retry-After.