Skip to content

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.

FieldTypeDefaultDescription
friendly_namestringnoneDisplay name shown in the dashboard. 1 to 99 characters.
service_iduuid | nullnoneCreate only: assign the monitor to a service in your account. Unknown or foreign service IDs return 404. Change an existing assignment from Services.
check_typestringhttphttp, tcp or ping. Create only: an update that sends another value is refused with check_type cannot be changed.
uristringrequiredTarget 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.
methodstringrequiredAny 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_secondsintrequiredSeconds between checks. Must be at least 60 and a multiple of 60.
run_interval_thirty_secondsboolfalseRun every 30 seconds instead. Only valid together with run_interval_seconds: 60.
timeout_msintrequiredPer-request timeout in milliseconds. Maximum 60000.
check_regionsstring[]see default locationsLocation ids the check runs from. More than one needs a paid uptime plan. See check locations.
min_healthy_regionsint1Minimum 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_thresholdint1Consecutive failed checks required before the monitor transitions to failed and alerts. 1 to 10. See requiring N failed checks.
recheck_on_failureenumplan defaultCheck 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 /check-locations/default 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_runsint2Consecutive 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_overridebool | nullnullWhether 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_redirectsbooltrueFollow HTTP redirects before evaluating the response.
request_bodystringnoneBody sent with the request.
content_typeenumnoneContent-Type of the request body. See content types.
auth_typeenumnonebasic, digest, or bearer.
auth_usernamestringnoneUsername for basic / digest auth.
auth_passwordstringnonePassword for basic / digest auth.
auth_bearer_tokenstringnoneToken for bearer auth.
success_http_codesint[]noneStatus codes that force a success. Each must be a valid HTTP status code.
failure_http_codesint[]noneStatus codes that force a failure. Each must be a valid HTTP status code.
custom_http_headersmapnoneExtra request headers as {name: value}. A secret header here is how you allowlist our checks.
keyword_searchstringnoneText to search for in the response body. Maximum 1000 characters; an empty string is treated as unset.
keyword_search_invertedboolfalseInvert the assertion: fail when the keyword IS found.
keyword_search_case_sensitiveboolfalseMatch case-sensitively.
keyword_search_regexboolfalseInterpret keyword_search as a regular expression.
json_pathstringnoneJSONPath 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_expectedstringnoneWhen set, at least one json_path match must equal this value.
group_notification_idsuuid[]default groupNotification 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_tlsbooltrueProvision a paired TLS check for the URL’s hostname.
tls_portint443Port the TLS check connects to, 1 to 65535. Needs monitor_tls. See TLS port.
alert_on_invalid_certificatebooltrueAlert when browsers would reject the certificate. Ignored without monitor_tls; a PUT without it keeps the current value. See invalid certificate alerts.
monitor_dnsbooltrueProvision 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_speedboolfalseProvision a paired page-speed (Lighthouse) check on a slower schedule.
tagsstring[]noneFree-form tags. Used for grouping and maintenance-window matching.
http_versionenumautoPreferred HTTP version for the check transport. See HTTP versions.
web_bot_authboolfalseSign 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.
stateenumactiveUpdate only. active or paused. Paused checks stop running and alerting.
final_uristringnoneExpected 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.

FieldTypeDescription
iduuidCheck ID.
account_iduuidOwning account.
current_statusenumSee status enum.
last_run_atrfc3339 | nullMost recent check execution.
last_status_change_atrfc3339 | nullWhen current_status last transitioned.
created_atrfc3339When the check was created.
flap_holdboolThe flap hold value in effect: flap_hold_override when it is set, otherwise the account’s flap_hold notification setting.
tls_job_iduuid | nullPaired TLS check, if monitor_tls is on.
dns_job_iduuid | nullPaired domain expiry check, if monitor_dns is on and the domain is registrable.
page_speed_job_iduuid | nullPaired page-speed check, if monitor_page_speed is on.
group_notificationsobject[] | nullFull notification-group objects resolved from group_notification_ids.
tls_portintFetch one check only, when TLS monitoring is on. The port the TLS check uses.
alert_on_invalid_certificateboolFetch one check only, when TLS monitoring is on. Whether an invalid certificate alerts.
partial_failureobject | absentPresent while runs pass the quorum but some locations fail: failed_locations (location ids), total_locations and since (rfc3339). Never paged.
not_checked_reasonstring | nullSet 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.

StatusMeaning
successThe monitor is not in a confirmed failure. A monitor whose recent checks have failed but not yet met its confirmation_threshold stays success.
failedConfirmed failure. Notifications fire, and a service in auto mode that the monitor belongs to opens an incident.
pending_failureLegacy value that nothing sets. Treat it as success if you encounter it on an old record.

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.

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).

kindRecorded when
quota_not_checkedThe first run of a usage period was skipped because the quota is used up. data has product and period.
schedule_missingA 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_unknownThe TLS check could not connect for more than a day. The account owners are emailed.
recheckA 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_runOne location of several answered, and it failed. The status did not change. data has selected, reported and failed_locations.
degraded_quorumA second inconclusive run in a row took the monitor down on fewer locations. data has transition_id and locations.
partial_failureA run passed while some locations failed, the first in a row. data has failed_locations and total_locations.
recovery_pendingThe monitor recovered and the all clear waits for the recovery period. data.runs_needed is the period.
recovery_resetA check failed during the recovery period, so the count restarted.
recovery_confirmedThe recovery period passed and the all clear went out.
flap_startedThe monitor started flapping. data has transitions and window_minutes.
flap_break_throughA held outage lasted long enough to be sent. data.break_through_minutes is the limit.
flap_endedThe 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.

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 sendResult
A live location idAccepted.
A retired id: aws-us-east-2 or aws-us-west-1Accepted and replaced with aws-us-east-1, its replacement.
An id that does not exist400 with Invalid check_regions <value>.
A location that cannot run this check type400.
More than one location without a paid uptime plan403 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.

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.

ValueBehavior
autoPrefer HTTP/2 via ALPN, fall back to HTTP/1.1 (default).
http1_1Force HTTP/1.1 only. Best for some CDN / bot-management edges.
http2Require HTTP/2; the check fails if it cannot be negotiated.
http2_with_fallbackExplicit prefer-h2-with-fallback. Same transport behavior as auto.

The negotiated version observed on each run is recorded on the check result.

ValueSent as
jsonapplication/json
xmlapplication/xml
form_url_encodedapplication/x-www-form-urlencoded
texttext/plain
MethodPathPurpose
POST/http/jobCreate.
GET/http/job/{job_id}Fetch one check.
PUT/http/job/{job_id}Update (partial).
DELETE/http/job/{job_id}Delete.
GET/http/jobsList, with sort/filter query params. check_type=http, tcp or ping keeps one kind.
GET/http/tagsDistinct tags across your checks.
GET/http/job/{job_id}/recentRecent check runs.
GET/http/job/{job_id}/recent-checksRecent check results per location.
GET/check-locationsEvery check location, with its status and capabilities.
GET/check-locations/defaultThe default locations for a new monitor, with the check projection.
GET/http/job/{job_id}/eventsStatus-transition events.
GET/monitors/{monitor_id}/eventsMonitor events: quota skips, missing schedules, TLS checks that cannot connect.
GET/http/job/{job_id}/uptime_percentageUptime percentage and incident count for a date range.
GET/http/job/{job_id}/performancePer-phase timing (dns/tcp/tls/ttfb/download).
GET/http/job/result/{job_result_id}/detailsFull detail for one recorded result.
GET/http/job/result/{job_result_id}/bodyPre-signed download for a failed check’s full response body.
GET/http/job/{job_id}/results/exportCheck results as CSV (timings and outcome, no bodies).
POST/http/jobs/importCreate monitors from a CSV: HTTP, TCP, ping, heartbeat and DNS rows, duplicates skipped, with dry_run for a preview.
POST/monitors/importImport monitors from UptimeRobot, Pingdom, StatusCake or Better Stack with that tool’s API key, duplicates skipped, with dry_run for a preview.
GET/monitorsEvery 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/totalsMonitor counts. by_type.http covers every uptime monitor, and by_check_type splits those counts into http, tcp and ping.
GET/http/job/{job_id}/page_speedLatest page-speed result.
GET/http/job/{job_id}/page_speed/historyPage-speed history.

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 than response_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.