HTTP check reference
The full request/response schema is in the auto-generated API Reference. This page is the human-readable cheat sheet for POST /http/job and PUT /http/job/{job_id}. The same endpoints create TCP port checks and ping checks, whose own fields are on their pages.
Request settings
Section titled “Request settings”| Field | Type | Default | Description |
|---|---|---|---|
friendly_name | string | none | Display name shown in the dashboard. 1 to 99 characters. |
service_id | uuid | null | none | Create only: assign the monitor to a service in your account. Unknown or foreign service IDs return 404. Change an existing assignment from Services. |
check_type | string | http | http, tcp or ping. Create only: an update that sends another value is refused with check_type cannot be changed. |
uri | string | required | Target URL. Must parse as an absolute URI with a host, with the http or https scheme. https is required unless monitor_tls is explicitly false. Any other scheme, tcp:// and ping:// included, is refused with Invalid uri scheme. |
method | string | required | Any valid HTTP method token (GET, POST, HEAD, …). Required for HTTP checks. A TCP port or ping check takes none, or TCP or PING to match its type. |
run_interval_seconds | int | required | Seconds between checks. Must be at least 60 and a multiple of 60. |
run_interval_thirty_seconds | bool | false | Run every 30 seconds instead. Only valid together with run_interval_seconds: 60. |
timeout_ms | int | required | Per-request timeout in milliseconds. Maximum 60000. |
check_regions | string[] | see default locations | Location ids the check runs from. More than one needs a paid uptime plan. See check locations. |
min_healthy_regions | int | 1 | Minimum locations that must pass for the check to count as healthy. At least 1, at most the number of check_regions. In a run where some locations return no result, it is capped at the number that did. |
confirmation_threshold | int | 1 | Consecutive failed checks required before the monitor transitions to failed and alerts. 1 to 10. See requiring N failed checks. |
recheck_on_failure | enum | plan default | Check each failed location once more before a failed run counts: off, same_location or another_cloud. A create that leaves it out stores another_cloud on a paid uptime plan when another cloud provider can run the check, otherwise same_location (always, for a ping check); GET / returns the value. Choosing another_cloud without a paid uptime plan returns 403 with multi_region_requires_paid_plan. Monitors created before this field existed have off. See recheck before alerting. |
recovery_period_runs | int | 2 | Consecutive healthy checks before the all clear is sent and any automatic incident resolves. 1 to 10; 1 is immediate. Monitors created before this field existed have 1. See recovery and flapping. |
flap_hold_override | bool | null | null | Whether this monitor holds short outages while it flaps. null follows the account’s notification settings (on by default), true always holds, false never holds. On update, leaving it out keeps the current value. A request that sends flap_hold sets this override. See recovery and flapping. |
follow_redirects | bool | true | Follow HTTP redirects before evaluating the response. |
request_body | string | none | Body sent with the request. |
content_type | enum | none | Content-Type of the request body. See content types. |
auth_type | enum | none | basic, digest, or bearer. |
auth_username | string | none | Username for basic / digest auth. |
auth_password | string | none | Password for basic / digest auth. |
auth_bearer_token | string | none | Token for bearer auth. |
success_http_codes | int[] | none | Status codes that force a success. Each must be a valid HTTP status code. |
failure_http_codes | int[] | none | Status codes that force a failure. Each must be a valid HTTP status code. |
custom_http_headers | map | none | Extra request headers as {name: value}. A secret header here is how you allowlist our checks. |
keyword_search | string | none | Text to search for in the response body. Maximum 1000 characters; an empty string is treated as unset. |
keyword_search_inverted | bool | false | Invert the assertion: fail when the keyword IS found. |
keyword_search_case_sensitive | bool | false | Match case-sensitively. |
keyword_search_regex | bool | false | Interpret keyword_search as a regular expression. |
json_path | string | none | JSONPath asserted on a JSON response body, such as $.status or $.items[0].id ($, .key, ["key"], [index] and [*]). Fails when the body is not JSON or nothing non-null matches. |
json_path_expected | string | none | When set, at least one json_path match must equal this value. |
group_notification_ids | uuid[] | default group | Notification groups to fire on state change. Maximum 10, no duplicates, must belong to your account. On create, omitting it (or sending null) attaches your account’s default group; [] notifies no one. |
monitor_tls | bool | true | Provision a paired TLS check for the URL’s hostname. |
tls_port | int | 443 | Port the TLS check connects to, 1 to 65535. Needs monitor_tls. See TLS port. |
alert_on_invalid_certificate | bool | true | Alert when browsers would reject the certificate. Ignored without monitor_tls; a PUT without it keeps the current value. See invalid certificate alerts. |
monitor_dns | bool | true | Provision a paired domain expiry check for the URL’s registrable domain. Silently skipped at create time, and rejected with 400 on update, when the host is on a shared platform suffix such as *.vercel.app. |
monitor_page_speed | bool | false | Provision a paired page-speed (Lighthouse) check on a slower schedule. |
tags | string[] | none | Free-form tags. Used for grouping and maintenance-window matching. |
http_version | enum | auto | Preferred HTTP version for the check transport. See HTTP versions. |
web_bot_auth | bool | false | Sign each check request with Web Bot Auth, so bot protection that supports it, such as Cloudflare, can recognize Site Qwality Monitor. HTTP checks only. See blocked by bot protection. |
state | enum | active | Update only. active or paused. Paused checks stop running and alerting. |
final_uri | string | none | Expected final URL after redirects. A mismatch fails the check. |
PUT /http/job/{job_id} takes the same fields, all optional; a request with no fields is rejected. Sending check_regions: [] on update leaves regions unchanged. Fields you leave out keep their values; send auth_type, content_type or custom_http_headers as null to remove them. custom_http_headers replaces the whole map.
Read-only fields
Section titled “Read-only fields”| Field | Type | Description |
|---|---|---|
id | uuid | Check ID. |
account_id | uuid | Owning account. |
current_status | enum | See status enum. |
last_run_at | rfc3339 | null | Most recent check execution. |
last_status_change_at | rfc3339 | null | When current_status last transitioned. |
created_at | rfc3339 | When the check was created. |
flap_hold | bool | The flap hold value in effect: flap_hold_override when it is set, otherwise the account’s flap_hold notification setting. |
tls_job_id | uuid | null | Paired TLS check, if monitor_tls is on. |
dns_job_id | uuid | null | Paired domain expiry check, if monitor_dns is on and the domain is registrable. |
page_speed_job_id | uuid | null | Paired page-speed check, if monitor_page_speed is on. |
group_notifications | object[] | null | Full notification-group objects resolved from group_notification_ids. |
tls_port | int | Fetch one check only, when TLS monitoring is on. The port the TLS check uses. |
alert_on_invalid_certificate | bool | Fetch one check only, when TLS monitoring is on. Whether an invalid certificate alerts. |
partial_failure | object | absent | Present while runs pass the quorum but some locations fail: failed_locations (location ids), total_locations and since (rfc3339). Never paged. |
not_checked_reason | string | null | Set only while an active check is not being run. quota: the account’s uptime quota for this period is used up. See not checked. |
The response also returns service_id as a UUID or null.
Status enum
Section titled “Status enum”| Status | Meaning |
|---|---|
success | The monitor is not in a confirmed failure. A monitor whose recent checks have failed but not yet met its confirmation_threshold stays success. |
failed | Confirmed failure. Notifications fire, and a service in auto mode that the monitor belongs to opens an incident. |
pending_failure | Legacy value that nothing sets. Treat it as success if you encounter it on an old record. |
Not checked
Section titled “Not checked”When an account uses up its uptime quota for the period and the plan stops checks at the limit, active checks are skipped until the quota resets or the plan is upgraded. Meanwhile GET /http/job/{job_id} and GET /monitors return not_checked_reason: "quota" for each active check, and the dashboard shows Not checked: quota. current_status keeps its last value, so do not read it as up. A paused check shows as paused. The first skipped run of each period records a quota_not_checked monitor event.
Monitor events
Section titled “Monitor events”GET /monitors/{monitor_id}/events?kind=http|cron|browser&limit=25 lists things that happened to a monitor besides going down and recovering, newest first. kind defaults to http; limit is 1 to 100 (default 25).
kind | Recorded when |
|---|---|
quota_not_checked | The first run of a usage period was skipped because the quota is used up. data has product and period. |
schedule_missing | A daily sweep found the monitor’s schedule (or its TLS or domain check’s schedule) missing or switched off. data.repaired says whether it was switched back on. The account owners are emailed. |
tls_unknown | The TLS check could not connect for more than a day. The account owners are emailed. |
recheck | A failed location was checked once more before the run counted. data has location_id, failure_reason and response_http_code (the first failure), recheck_location_id, and outcome: passed, failed or no_answer. |
inconclusive_run | One location of several answered, and it failed. The status did not change. data has selected, reported and failed_locations. |
degraded_quorum | A second inconclusive run in a row took the monitor down on fewer locations. data has transition_id and locations. |
partial_failure | A run passed while some locations failed, the first in a row. data has failed_locations and total_locations. |
recovery_pending | The monitor recovered and the all clear waits for the recovery period. data.runs_needed is the period. |
recovery_reset | A check failed during the recovery period, so the count restarted. |
recovery_confirmed | The recovery period passed and the all clear went out. |
flap_started | The monitor started flapping. data has transitions and window_minutes. |
flap_break_through | A held outage lasted long enough to be sent. data.break_through_minutes is the limit. |
flap_ended | The monitor was stable long enough to stop flapping. data.held counts the outages held. |
Returns 404 when the monitor is not in your account and 400 for an unknown kind. New event kinds may be added; ignore ones you do not know.
Check locations
Section titled “Check locations”Location ids follow <provider>-<region>, for example aws-us-east-1 or gcp-asia-southeast1. The live list, with each location’s city, country and provider, is on the locations page. From the API, call GET /check-locations (the location below is an example of the shape):
{ "default_location_id": "aws-us-east-1", "locations": [ { "id": "gcp-asia-southeast1", "provider": "gcp", "provider_name": "Google Cloud", "provider_region": "asia-southeast1", "city": "Singapore", "country_code": "SG", "continent": "asia", "label": "Singapore · Google Cloud", "status": "live", "is_default": false, "capabilities": ["http", "tcp", "icmp"] } ]}Discover ids through this endpoint rather than hardcoding a city list.
Only locations with status: "live" and "http" in capabilities can be selected for an HTTP check. A TCP port check needs "tcp", which every location has, and a ping check needs "icmp", which only the Google Cloud locations have. The list also carries draining and retired locations so older results keep a readable label: a draining location keeps serving monitors that already use it but cannot be newly selected, and a retired one no longer runs.
How check_regions is validated on create and update:
| You send | Result |
|---|---|
| A live location id | Accepted. |
A retired id: aws-us-east-2 or aws-us-west-1 | Accepted and replaced with aws-us-east-1, its replacement. |
| An id that does not exist | 400 with Invalid check_regions <value>. |
| A location that cannot run this check type | 400. |
| More than one location without a paid uptime plan | 403 with multi_region_requires_paid_plan. |
On every scheduled run, each selected location makes the request and records its own result, with that location’s id in check_region. Each result counts as one check toward your monthly check volume, and so does each recheck of a failed location. A location that cannot return a result in a run (its provider is unreachable, for example) is left out of that run: nothing is recorded or billed for it, and the quorum is evaluated over the locations that did report. If a monitor has exactly one location and it cannot report, the default location is tried instead when it is different and enough execution time remains, and its result is recorded under the default’s id. If no location returns a result, the monitor’s status stays unchanged. With two or more locations, a run where only one answered and it failed is inconclusive: the status changes only if the next run is inconclusive too.
Outages list each failing location: GET /http/job/{job_id}/events returns failed_locations, total_locations and degraded_quorum on each outage, and held_reason: "flap" with held_released_at when its alert was held for flapping.
Default locations
Section titled “Default locations”A create that leaves out check_regions (or sends []) runs from aws-us-east-1. On a paid uptime plan it runs from two locations instead: aws-us-east-1 plus a healthy location on another cloud provider in the same country (the same city first), with min_healthy_regions: 1, so you are alerted only when both fail. Each create picks again, and an existing monitor never changes. A ping check, which aws-us-east-1 cannot run, defaults to one live Google Cloud location in the United States on every plan, because no other cloud provider runs ping: a healthy one first, otherwise a degraded one. In practice that is gcp-us-east4 (Virginia), or gcp-us-west2 (Los Angeles) while Virginia is unhealthy, and never a location abroad. With no live ping location in the United States, a ping create without check_regions is refused with Invalid check_regions aws-us-east-1: location does not run icmp checks.
The pair is the default only while the account’s projected monthly checks, the new monitor included, stay within half of its monthly uptime check quota (the free allowance plus the uptime plan). Otherwise the default is one location. Choosing locations yourself is never refused by this rule.
GET /check-locations/default returns what a create would get, and the projection behind it. Pass the new monitor’s run_interval_seconds (60 to 86400), and optionally check_type (http, tcp or ping; default http), run_interval_thirty_seconds, monitor_tls and monitor_dns. For an HTTP check monitor_tls and monitor_dns default to true; for a TCP port or ping check monitor_tls does not apply and monitor_dns defaults to false. An invalid interval returns 400. API keys need read:monitors.
{ "check_regions": ["aws-us-east-1", "gcp-us-east4"], "min_healthy_regions": 1, "single_location_reason": null, "recheck_on_failure": "another_cloud", "projection": { "checks_per_location_per_month": 43200, "paired_checks_per_month": 60, "monitor_checks_per_month": 86460, "account_checks_per_month": 120000, "quota": 600000, "pair_quota_percent": 50 }}single_location_reason is null for the pair, or says why the default is one location: plan (no paid uptime plan), quota (the pair would pass half the quota) or no_healthy_pair (no healthy location on another provider in the default’s country right now). recheck_on_failure is the value a create that leaves it out would store. The projection counts a 30-day month: one check per location per run, a 30-second monitor runs twice a minute, and the TLS and domain expiry checks paired with an HTTP monitor run daily (30 a month each). account_checks_per_month covers the account’s active HTTP monitors on the locations each one runs from.
HTTP versions
Section titled “HTTP versions”| Value | Behavior |
|---|---|
auto | Prefer HTTP/2 via ALPN, fall back to HTTP/1.1 (default). |
http1_1 | Force HTTP/1.1 only. Best for some CDN / bot-management edges. |
http2 | Require HTTP/2; the check fails if it cannot be negotiated. |
http2_with_fallback | Explicit prefer-h2-with-fallback. Same transport behavior as auto. |
The negotiated version observed on each run is recorded on the check result.
Content types
Section titled “Content types”| Value | Sent as |
|---|---|
json | application/ |
xml | application/ |
form_url_encoded | application/ |
text | text/ |
Endpoints
Section titled “Endpoints”| Method | Path | Purpose |
|---|---|---|
POST | /http/ | Create. |
GET | /http/ | Fetch one check. |
PUT | /http/ | Update (partial). |
DELETE | /http/ | Delete. |
GET | /http/ | List, with sort/filter query params. check_type=http, tcp or ping keeps one kind. |
GET | /http/ | Distinct tags across your checks. |
GET | /http/ | Recent check runs. |
GET | /http/ | Recent check results per location. |
GET | /check-locations | Every check location, with its status and capabilities. |
GET | /check-locations/ | The default locations for a new monitor, with the check projection. |
GET | /http/ | Status-transition events. |
GET | /monitors/ | Monitor events: quota skips, missing schedules, TLS checks that cannot connect. |
GET | /http/ | Uptime percentage and incident count for a date range. |
GET | /http/ | Per-phase timing (dns/tcp/tls/ttfb/download). |
GET | /http/ | Full detail for one recorded result. |
GET | /http/ | Pre-signed download for a failed check’s full response body. |
GET | /http/ | Check results as CSV (timings and outcome, no bodies). |
POST | /http/ | Create monitors from a CSV: HTTP, TCP, ping, heartbeat and DNS rows, duplicates skipped, with dry_run for a preview. |
POST | /monitors/ | Import monitors from UptimeRobot, Pingdom, StatusCake or Better Stack with that tool’s API key, duplicates skipped, with dry_run for a preview. |
GET | /monitors | Every monitor of every type, paged. check_type=http, tcp or ping keeps uptime monitors of that kind, and each uptime row carries check_type. |
GET | /monitors/ | Monitor counts. by_type.http covers every uptime monitor, and by_check_type splits those counts into http, tcp and ping. |
GET | /http/ | Latest page-speed result. |
GET | /http/ | Page-speed history. |
Response bodies
Section titled “Response bodies”Every check records its outcome, status code and per-phase timings. The response body is kept only when a check fails. Check results are kept for 90 days, or as long as the body for a failed check when your plan keeps bodies longer. Charts and figures for older ranges use hourly summaries, kept for 25 months.
When a check fails, the result carries:
response_body: the first 8 KB of the response, for display.body_bytes: the true size of the captured body. If it is larger thanresponse_body, the inline copy is the head of a bigger document.body_truncated,body_available,body_expired: whether the snippet is partial, whether the stored body can be downloaded now, and whether one was captured but has aged out of your plan’s window.
Call GET /http/job/result/{job_result_id}/body for a pre-signed URL to the
stored body, valid for one hour. The stored download contains at most the first 3 MiB of a failed response; it may be shorter than body_bytes, and body_truncated indicates truncation. It answers 404 when no body was captured
(a passing check) and 410 when one was captured but falls outside your
retention window. How long a body stays readable depends on your plan (see
plan limits); up to 365 days is available on request.
A keyword assertion is evaluated against the live response while the check
runs, never against the stored copy, so a keyword failure always carries the
body that failed it even though the status code was 200.
Keyword and JSON path assertions look at the first 10 MB of the response. A
keyword found there passes. When the response is larger and the first 10 MB
cannot decide the assertion (the keyword is not there, the keyword is inverted,
or any JSON path), the check fails with failure_reason body_too_large
instead of guessing. The rest of the response is still read, so a connection
that drops late still fails the check.
See also
Section titled “See also”- HTTP checks overview for the concept and lifecycle.
- TLS check reference for the paired certificate check.
- Allowlisting our checks for firewalls and bot protection.
- API Reference for wire-level shapes.