---
title: "Dispatch an ad-hoc check from the probe fleet"
method: POST
path: "/api/v1/monitors/{monitorID}/test"
---

# Dispatch an ad-hoc check from the probe fleet

`POST /api/v1/monitors/{monitorID}/test`

## Request

- Base URL: `https://api.uptimemonitoring.com`
- URL: `https://api.uptimemonitoring.com/api/v1/monitors/{monitorID}/test`
- Auth: HTTP bearer

Runs one immediate check against the monitor's configured target. Does not
modify monitor state, evidence buffer, or incidents. Only monitors of a
type the check engine currently supports (`http`, `ping`, `tcp`) can be
tested; a monitor of any other type returns 400 — unreachable in
production after issue #209, since no such monitor can be created or
persisted, but preserved as a defensive check. Rate limited to 1 call
per monitor per 10 seconds.

## Path parameters

- `monitorID` integer, required

## Query parameters

- `region` 'EU' | 'US-E' | 'US-W' | 'ASIA' | 'OCE' | 'SA'

## Response `200`

Check completed

- TestResult
  - `monitor_id` integer
  - `timestamp` string, date-time
  - `region` string
  - `probe_location` string
  - `state` 'up' | 'down'
  - `status_code` integer
  - `error` string
  - `body_bytes` integer
  - `timings` Timings
    - `total_ms` number, float
    - `dns_ms` number, float
    - `tcp_ms` number, float
    - `tls_ms` number, float
    - `ttfb_ms` number, float
    - `server_ms` number, float
  - `packet_loss_pct` number: Ping-only packet loss percentage (0-100). Omitted (not present in the object) when not measured — every non-ping check result, and a ping probe-side failure that never reached the target. A measured 0% loss is present with value 0, distinct from omitted.

## Other responses

- `400`: Unsupported monitor type or invalid region. The unsupported-type body is byte-identical to `POST`/`PUT /api/v1/monitors`'s: `type '<type>' is not available yet; the check engine currently supports: http, ping, tcp`.
- `403`: Target URL resolves to a blocked address (SSRF)
- `404`: Monitor not found
- `429`: One of three independent rate limiters fired: * **Per-monitor minimum-interval limiter (`MonitorTestLimiter`)** — another test for the same monitor ran too recently. Body: `too many tests for this monitor; retry in <N>s`. * **Per-account dispatcher cap (`AccountRateLimiter`)** — the authenticated account exceeded its 200/min cap on the authenticated `/api/v1/*` surface. See `components.responses.RateLimited`. * **Per-domain dispatch cap (`DomainLimiter`)** — too many checks have been dispatched to this monitor's eTLD+1 across ALL accounts within the rolling window. The cap protects third-party sites from coordinated-monitoring overload (e.g. N free-tier accounts each pointing a monitor at the same victim). Body: `domain rate limit exceeded; retry in <N>s`. The bucket is keyed on the public-suffix-trimmed apex (`api.victim.com` and `www.victim.com` share one bucket). The `Retry-After` header gives the integer seconds until the next allowed dispatch under whichever limiter fired. Scales differ: per-monitor (~tens of seconds), per-account (sub-second to seconds), per-domain (up to one minute).
- `502`: No healthy probe or probe-level error
- `503`: The dispatcher's global kill switch is engaged; no checks will be dispatched until an operator lifts it. The `Retry-After` header suggests a polite re-try window.

---

[API](https://skmtc.dev/uptimemonitoring/apis/uptimemonitoring-com-api.md) · [All operations](https://skmtc.dev/uptimemonitoring/apis/uptimemonitoring-com-api/llms.txt) · [OpenAPI document](https://skmtc.dev/uptimemonitoring/apis/uptimemonitoring-com-api/revisions/ddcb2a8bc70f?raw)
