Runs, states and uptime
Every HTTP and MCP test runs on a schedule, and each run ends in one outcome. This page lists
the scheduling limits, what each outcome means, how outcomes move a test between states, and
how uptime is computed from them. An agent reads runs with the get_api_test_runs MCP tool and
uptime with get_uptime; in the app, open the test from the
API Tests page.
Scheduling
Section titled “Scheduling”| Setting | MCP parameter | App label | Limits | Editor default |
|---|---|---|---|---|
| Interval | intervalSeconds | Check every | At least 30 seconds | 60 seconds |
| Timeout | timeoutSeconds | Give up after | 1 to 30 seconds | 10 seconds |
| Retries | retries | Retries per run | 0 to 5 | 0 |
| Failure threshold | failureThreshold | Down after | 1 to 10 failed runs | 3 |
The timeout bounds each attempt, not the whole run. Because the timeout is at most 30 seconds and the interval at least 30, a timeout is never longer than the interval.
A run is up to 1 + retries attempts. The failure threshold is how many failed runs in a row
turn the test DOWN, and how many rate-limited runs in a row turn it RATE_LIMITED.
The trial run on save
Section titled “The trial run on save”Before a test is saved, it runs once. The trial run sends and checks exactly what the scheduled runs will, which is why it belongs here, but it has rules of its own: it decides whether the save happens at all, it is never retried, and it does not appear in the run history.
- One attempt, no retries, whatever the test’s retry setting. The trial run is not written to the run history.
- Saved only on a success. A trial run that fails, errors or is rate limited saves nothing, and there is no way to save anyway. This holds whether the test is created enabled or paused.
- On update, the trial run happens only when the change affects what the test sends or checks: the type, the HTTP target (URL, method, headers, body, credential), the MCP target, the HTTP assertions, or the timeout. Changing only the name, interval, retries, failure threshold or the enabled flag saves without one. A failed trial run leaves the existing test unchanged.
Over MCP, a refused create_api_test or update_api_test fails with a sentence that says what
failed, starting Not created: or Not updated: and ending
The test was not saved; fix its configuration and call create_api_test again. or
The existing test is unchanged; fix the configuration and call update_api_test again. A
passing save returns the run as trialRun on the test.
In the app, the save button reads Running test… while the trial run is in flight. A refused
run stays on screen in the editor, headed Trial run failed,
Trial run was rate limited by the target or Trial run could not be executed, with its cause,
latency, failed assertions, the request and response, and a note starting
The test was not saved. or Your changes were not saved.
Run outcomes
Section titled “Run outcomes”| Status | App label | Causes | What it means |
|---|---|---|---|
SUCCESS | Success | None | Every assertion passed. |
FAILURE | Failure | ASSERTION, DNS, TLS, CONNECT, TIMEOUT, BLOCKED_ADDRESS | The target is unhealthy: an assertion failed, or the target could not be reached in time. Counts toward DOWN and against uptime. |
ERROR | Error | CREDENTIAL_DECRYPT, UNEXPECTED, EXECUTOR_LOST | A problem on Fixter’s side; the test could not run. Not counted against uptime. |
RATE_LIMITED | Rate limited | RATE_LIMITED | The target answered HTTP 429. Not counted against uptime. |
MISSED | Missed | None | The run could not start in time, so the target was not probed. The row reads Never ran. Not counted against uptime. |
Only runs whose request reached the target, or tried to, count as executed runs: SUCCESS,
FAILURE and RATE_LIMITED. ERROR and MISSED runs do not count.
Failure causes
Section titled “Failure causes”Each failed or errored run carries one cause, shown in the app as:
| Cause | App label | When |
|---|---|---|
ASSERTION | Assertion failed | The target answered, and one or more assertions failed. |
DNS | DNS lookup failed | The hostname did not resolve. |
TLS | TLS handshake failed | The TLS handshake failed. |
CONNECT | Could not connect | The connection failed, or the exchange could not be completed. |
TIMEOUT | Timed out | No complete response within the timeout. |
BLOCKED_ADDRESS | Private address blocked | The target resolved to a private or internal address. See Addresses Fixter will not test. |
CREDENTIAL_DECRYPT | Credential unreadable | The stored credential could not be read on Fixter’s side. |
UNEXPECTED | Unexpected error | The credential the test points at no longer exists (credential deleted), or something else went wrong while running the test (unexpected error while running the test). |
EXECUTOR_LOST | Executor lost | Appears only on older runs; no new run gets it. |
RATE_LIMITED | Rate limited by the target | The target answered HTTP 429. |
A credential’s OAuth2 token fetch that fails is a FAILURE, not an ERROR; its message starts
oauth2 token fetch: .
Test states
Section titled “Test states”| State | App label | What it means |
|---|---|---|
UP | Up | Passing, or not yet failing enough runs in a row to be DOWN. A new enabled test starts here. |
DOWN | Down · <n> fails | The failure threshold of failed runs in a row was reached. The label carries the current streak, for example Down · 3 fails. |
RATE_LIMITED | Rate limited | The failure threshold of rate-limited runs in a row was reached. The app shows it as Rate limited. |
PAUSED | Paused | Not running on its schedule; no new runs are recorded. |
A test created disabled starts PAUSED. In the app, Pause test and Resume test on the
test’s page switch it; disable_api_test and enable_api_test do the same over MCP. Resuming
returns the test to UP with both streaks cleared.
How states change
Section titled “How states change”A test keeps two streaks: failed runs in a row and rate-limited runs in a row. Each run moves
them as follows. ERROR and MISSED runs move nothing, and pausing parks a test in PAUSED
from any state until it is enabled again, which starts it at UP.
- A
SUCCESSclears both streaks and returns aDOWNorRATE_LIMITEDtest toUP. - A
FAILUREadds to the failure streak and clears the rate-limit streak. When the failure streak reaches the failure threshold, anUPorRATE_LIMITEDtest turnsDOWN. - A
RATE_LIMITEDrun adds to the rate-limit streak. When it reaches the failure threshold, anUPorDOWNtest turnsRATE_LIMITED. With a threshold of 1, the first 429 turns the testRate limited. - An
ERRORorMISSEDrun changes neither streak, so it neither breaks a run of failures nor adds to one. - A
PAUSEDtest does not change state.
Uptime
Section titled “Uptime”Uptime over a window is:
uptime = SUCCESS / (SUCCESS + FAILURE)ERROR, MISSED and RATE_LIMITED runs are left out of both terms, because they say nothing
about whether your endpoint was up. A window with no SUCCESS or FAILURE run has no uptime
(the app shows -), not zero. Latency percentiles also count SUCCESS and FAILURE runs only.
A downtime interval is an unbroken streak of FAILURE runs, from the first failing run’s
scheduled time to the last one’s finish. Only SUCCESS and FAILURE runs shape it: an
ERROR, MISSED or RATE_LIMITED run in the middle neither ends a downtime nor starts one,
so a rate-limited episode is never downtime.
Ask your agent for a test’s uptime and it calls get_uptime, which covers the last 24 hours
unless given a window. In the app, the test’s Uptime and latency card shows Uptime,
p95 latency and Runs with a count per outcome, and the latency chart marks downtime as
bands.
Addresses Fixter will not test
Section titled “Addresses Fixter will not test”Fixter’s tests reach public addresses only:
- Public DNS only. Hostnames resolve through public DNS resolvers, never through an internal
resolver, a hosts file or search domains. An internal name therefore does not resolve and fails
as an ordinary
DNSfailure. - No private or internal addresses. If any address a hostname resolves to is private,
loopback, link-local, cloud metadata, shared address space, documentation, benchmarking,
multicast or reserved, in IPv4 or IPv6, the connection is refused. An IP address written in
the URL is judged the same way. The run fails with cause
BLOCKED_ADDRESSand the messagethe URL points at a private or internal address, which the monitor does not probe. - Redirects and OAuth2 token URLs too. Every connection passes the same check, each
redirect hop included, and so does a credential’s OAuth2 token URL. A blocked token URL fails
the run as
BLOCKED_ADDRESSwith the message prefixedoauth2 token fetch:. - No allowlist. There is no per-account exception.
A BLOCKED_ADDRESS run is a FAILURE: it is retried like any failure and counts toward
DOWN. A trial run refused this way says, over MCP,
Not created: the URL points at a private or internal address, which the monitor does not probe. Use a URL that is reachable from the public internet.
Retries and Retry-After
Section titled “Retries and Retry-After”A run retries on any failure: a failed assertion, a timeout, or a connect, DNS, TLS or
blocked-address failure, up to retries more attempts. It stops at the first attempt that is
not a failure. A 429 is never retried, so a rate-limited run is one attempt whatever the retry
setting. The app shows Took <n> attempts on a run that needed more than one.
On a 429 Fixter reads the target’s Retry-After header, as seconds or as an HTTP date. A
zero, negative, unreadable or missing value defers nothing, and the value is capped at one hour.
The next run moves to the rate-limited run’s finish time plus that Retry-After, but only when
that is later than the next normal run; a 30 second Retry-After on a five minute test defers
nothing. Runs skipped by a deferral are not recorded as MISSED.
The run message says which happened:
Rate limited by the target (HTTP 429)when nothing was deferred.Rate limited by the target (HTTP 429); next check deferred by <N> seconds, or... by <N> minutes, when the deferral moved the next run. The duration is how far past the next normal run it moved, in seconds under 120 seconds and in whole minutes from there.
An HTTP test whose status pattern accepts 429 (for example 429 or 4xx) treats a 429 as an
ordinary response, and none of this applies. See HTTP tests. For
letting the tests through a rate limiter, see
Allow tests through your firewall.
What a run records
Section titled “What a run records”One trace id per run
Section titled “One trace id per run”Every run gets one W3C trace id. Each attempt sends it to your endpoint in a traceparent
header (same trace id across a run’s retries, new span id per attempt), and
{{traceId}} is the same id. A service that propagates
incoming trace context, which OpenTelemetry SDKs do by default, continues that trace instead of
opening its own, so the spans and logs it records for the request carry Fixter’s trace id. If the
service reports to Fixter, that is what links the run to them. To keep your own ids, set a
traceparent request header on an HTTP test; a header you set yourself replaces Fixter’s.
What your agent gets
Section titled “What your agent gets”get_api_test_runs returns each run’s outcome, timing, failed assertions, traceId and
retryAfterSeconds; correlate on the traceId finds what happened inside your service. The
request and response themselves are not returned over MCP; they are in the app.
What the app shows
Section titled “What the app shows”Open a run on the test’s page:
- The run message and the failed assertions.
- The trace id, with
Open in Logs(logs for that trace around the run’s time) andView trace. Request: the method, URL, headers and body of the run’s last attempt. For an MCP test this is the last request of the session, not counting the closing sessionDELETE.Response: the status,first byteandtotaltime, headers and body, orThe target never answered.
What is redacted or cut
Section titled “What is redacted or cut”Authorization, Proxy-Authorization, Cookie, X-Api-Key and Api-Key are always shown as
<redacted>, even when typed into the test’s own headers, and so is every header and query
parameter a credential adds. The request body is shown as sent. Bodies are cut at 16 KB; a cut
response body says Body cut at 16 KB. The target returned more.