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 |
unauthenticated
Section titled “unauthenticated”401. The request has no Authorization: Bearer … header. Send the key
as described in API keys and scopes.
invalid_api_key
Section titled “invalid_api_key”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.
invalid_token
Section titled “invalid_token”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.
account_suspended
Section titled “account_suspended”401. The organization’s account is suspended, so none of its keys work. Resolve the suspension from the dashboard; the keys work again afterwards.
api_access_not_in_plan
Section titled “api_access_not_in_plan”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.
insufficient_scope
Section titled “insufficient_scope”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.
insufficient_role
Section titled “insufficient_role”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.
permission_denied
Section titled “permission_denied”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.
not_found
Section titled “not_found”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.
invalid_argument
Section titled “invalid_argument”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.
key_in_query
Section titled “key_in_query”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.
plan_limit_reached
Section titled “plan_limit_reached”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.
range_not_in_plan
Section titled “range_not_in_plan”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.
incident_resolved
Section titled “incident_resolved”409. You tried to acknowledge or unacknowledge an incident that is already resolved. Nothing to do: re-read the incident.
conflict
Section titled “conflict”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.
method_not_allowed
Section titled “method_not_allowed”405. The path exists but not for this HTTP method. Use the method listed in the API reference.
idempotency_key_reused
Section titled “idempotency_key_reused”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.
idempotency_unavailable
Section titled “idempotency_unavailable”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.
unavailable
Section titled “unavailable”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.
rate_limited
Section titled “rate_limited”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.
internal
Section titled “internal”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.