Skip to content

Errors

Every error response is an RFC 9457 application/problem+json body:

{
"type": "https://monitorable.io/docs/api/errors#invalid_argument",
"title": "Invalid argument",
"status": 400,
"detail": "name: this field is required",
"code": "invalid_argument",
"request_id": "9f1c2e7a4b6d"
}
Field Meaning
type A URL that points at the section of this page for the code.
title A short fixed title for the code.
status The HTTP status, repeated in the body.
detail A plain sentence about this occurrence. It can change; do not parse it.
code A stable string. Branch on this, not on the status or the detail.
request_id The id of the request, also sent as the X-Request-Id header. Quote it when you ask for help.
class Only on rate_limited: the limit class that was exceeded.

Codes are stable; new codes can be added, so treat an unknown code as a generic error for its status.

Code Status
unauthenticated 401
invalid_api_key 401
account_suspended 401
api_access_not_in_plan 403
invalid_token 401
insufficient_scope 403
insufficient_role 403
permission_denied 403
not_found 404
invalid_argument 400
key_in_query 400
plan_limit_reached 402
range_not_in_plan 403
incident_resolved 409
conflict 409
method_not_allowed 405
idempotency_key_reused 422
idempotency_unavailable 503
unavailable 503
rate_limited 429
internal 500

401. The request has no Authorization: Bearer … header. Send the key as described in API keys and scopes.

401. The key is not recognised: it is misspelled, was revoked, or has passed its expiry date. Check the value, then create a new key under Team → API keys if it was revoked or expired.

401. Returned by the MCP server to an app that signed in with a Monitorable account (not to an API key, which gets invalid_api_key). The sign-in expired, was revoked, or was disconnected under Account → Connected apps, or you were removed from the organization. The response carries WWW-Authenticate: Bearer error="invalid_token", which tells the app to sign in again. An access token lasts one hour and the app renews it itself, so you only see this when the connection is gone: sign in again from the app.

401. The organization’s account is suspended, so none of its keys work. Resolve the suspension from the dashboard; the keys work again afterwards.

403. API access is turned off for this plan; every current plan includes it. Keys are paused, not revoked, and work again once access returns.

403. The key is valid but lacks the scope the endpoint needs; detail names it. Create a key with the scope, or use a preset that has it — see which scope each endpoint needs. On the MCP server, an app that signed in with a Monitorable account gets the same code with WWW-Authenticate: Bearer error="insufficient_scope" naming the scope needed. Apps that support it ask you to approve more access on the spot; otherwise disconnect under Account → Connected apps and connect again. Organization members can only approve read access, so a write tool stays unavailable to them.

403. The key has the member role and the call changes something, or an enrollment is attempted with a member-role key. Create the key with the admin role.

403. The key is valid, but the call is not allowed for it, and no more specific code applies; detail says what was refused. Use a key whose scope and role cover the call, as described in API keys and scopes.

404. The resource does not exist in the key’s organization — including a server or incident that belongs to someone else. Deleting a server twice answers 404 the second time, which is safe to treat as done. Unknown paths answer 404 too.

400. A parameter or body field is missing, malformed or out of range; detail names the field, for example name: this field is required, name: must be at most 100 characters or server_ref: must not contain whitespace or control characters. Fix the request; retrying it unchanged fails again.

400. An API key was sent in the query string (?api_key=, ?token=, ?access_token= or ?key=). Send it in the Authorization header and remove it from the URL.

402. The call would exceed a limit of the organization’s plan, for example the number of servers; detail names the limit (max_servers is <limit> on your plan). Remove something or upgrade — see pricing. The installer prints this as Plan limit reached and installs nothing.

403. A metrics request asks for data further back than the plan keeps. detail names the plan and its window. The API refuses instead of clamping silently, so automation never reads a different window than it asked for. Request a shorter range; Metrics history explains the retention levels.

409. You tried to acknowledge or unacknowledge an incident that is already resolved. Nothing to do: re-read the incident.

409. The call clashes with the current state of the resource and no more specific code applies; detail names the state. Re-read the resource, then retry if the call still makes sense.

405. The path exists but not for this HTTP method. Use the method listed in the API reference.

422. The Idempotency-Key was already used with a different request body. Use a new key for a new request, or send the original body again. See Rate limits and retries.

503. The call carried an Idempotency-Key and Monitorable could not check it, or another request with the same key is still in progress. No server was created by this call — it fails closed rather than risk a duplicate. Retry the same request after a few seconds (a Retry-After header says how long when the other request is still running); leaving out the header skips the check, at the cost of retry safety.

503. Monitorable is temporarily unable to serve the call; nothing was changed. Retry after a few seconds, waiting for Retry-After when it is present. If it persists, send the request_id to support.

429. The key exceeded the limit for a class of calls; the body’s class names it. Wait for the number of seconds in the Retry-After header, then retry. Details and headers are on Rate limits and retries.

500. Something failed on Monitorable’s side; detail is always internal error. Retry after a moment; if it persists, send the request_id to support.

Responses the web layer produces itself carry the same body: a path that does not exist is not_found, a wrong HTTP method is method_not_allowed, and a temporarily unavailable service is unavailable.