Skip to content

Errors and limits

Every refusal comes with one body:

{
"error": {
"code": "invalid_request",
"message": "…",
"field": "intervalSec"
}
}
  • code says what was refused. It does not change, so branch on it.
  • message says what to do, in the dashboard’s words. It may change, so show it to a person, but never branch on it.
  • field names the field at fault, on a 400.

A 402 not_entitled also says what the Plan allows no more of: kind (project, monitor, heartbeat or location), plan, the Plan’s limit, and what is used. Move to a larger Plan, or make room, and send it again.

A 422 target_cap_reached also says which cap the Monitor would pass, the site it counts (key), the location it was reached from, the cap’s limit, and what it counts now (current). Choose other locations or a longer interval, as the message says.

New codes may be added. Handle a code you do not know by its status.

CodeStatusWhat to do
invalid_request400The request was not one the API takes. field names the part to change.
bad_identifier400An identifier in the path is not of the kind it names, such as a mon_… where a prj_… goes.
unauthenticated401The token is missing, mistyped, revoked or expired. Send a working one.
forbidden403A Read-only token asked for a change, or the act is one no token takes.
not_found404There is no such thing, or the token does not reach its Project.
not_entitled402The Plan allows no more. kind, plan, limit and used say what.
rate_limited429Too many requests. Wait the seconds Retry-After names, then send it again.
interval_below_floor400The interval is shorter than this Monitor type allows.
timeout_below_floor400The timeout is shorter than this Monitor type allows.
url_missing400This Monitor type needs a url.
check_not_applicable400The Check cannot run for this target. The message says why.
port_blocked400You Up? does not check a URL on this port, which browsers refuse too. Use another port.
target_cap_reached422The target is at one of its limits per domain. The message names it; other locations are one way past it.
too_few_locations422Name more locations, or none to take the Project's default.
location_unavailable422A location named cannot take new Monitors now. GET /locations lists those that can.
uptime_always_on400The Uptime Check cannot be turned off.
monitor_busy409The Monitor's locations cannot change during an Incident. Wait until it is over.
monitor_suspended409The Monitor is suspended by the Plan. Move to a larger Plan, or bring it back in place of another Monitor.
project_suspended409The Project is suspended by the Plan, so its Monitors cannot be added or changed. Move to a larger Plan.
validation_required422This Monitor needs a passed Validation run first. Start one, then create it.
validation_unavailable422A Validation run cannot be started now. Try again later.
validation_rate_limited429Too many Validation runs. Wait the seconds Retry-After names.
validation_expired422The Validation run is too old. Start a new one.
validation_mismatch422The Monitor differs from the one the Validation run checked. Run it again.
validation_failed422The Validation run did not pass. Fix what it found, then run it again.
default_rule_is_fixed409The Default rule cannot be deleted.
name_taken409Another Notification rule has this name.
paid_needs_email422 or 409A rule with a phone must also send an email, so a missed text is never the only alert. On a 409, rules names the saved rules the change would break.
paid_rule_sends_nothing422 or 409The phones on this rule would hear only warnings. On a 409, rules names the saved rules the change would break.
webhook_url_refused400The Webhook's URL is not an https URL.
address_refused400The URL leads to a private or reserved address, which You Up? never sends to. Use your endpoint's public address.
event_type_not_on_monitor400This Monitor never sends some events asked for. eventTypes names them.
too_many_webhooks409The Monitor has as many Webhooks as it may have. Delete one first.
url_taken409The Monitor already has a Webhook to this address.

The API counts each minute, by the clock, and every Plan has the same limits:

  • 120 requests a minute with one token.
  • 300 requests a minute from all of an Organization’s tokens together.
  • 60 changes a minute from all of an Organization’s tokens together. A change is any request but a GET.

A request past a limit is refused with 429 rate_limited, and is not counted. Its message names the limit it hit:

Too many requests with this API token. Try again in 12 seconds.
Too many requests from this Organization's API tokens. Try again in 12 seconds.
Too many changes from this Organization's API tokens. Try again in 12 seconds.

The Retry-After header gives the seconds to wait before you send it again.

Every answer to a working token also carries three headers, for whichever limit is nearest:

  • X-RateLimit-Limit: how many that limit allows a minute.
  • X-RateLimit-Remaining: how many are left this minute.
  • X-RateLimit-Reset: the seconds until the minute ends and the count starts again.

Starting a Validation run has a limit of its own, shared with the dashboard. Past it, the answer is 429 validation_rate_limited, with Retry-After.

Requests with a token that does not work all get the same 401. Too many of them from one address are refused with 429 for a while, whatever the token.