Shadow Outage Ledger: Vendor-Claimed Status
Pricing
from $10.00 / 1,000 run_starts
Shadow Outage Ledger: Vendor-Claimed Status
Run this on a short schedule. Each run reads what the vendor status page claims and measures a public endpoint of the same service from outside. Each check writes one typed event: MATCH, SHADOW_OUTAGE when the endpoint fails and the vendor still claims th
Pricing
from $10.00 / 1,000 run_starts
Rating
0.0
(0)
Developer
kingii98
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Shadow Outage Ledger: Vendor-Claimed Status Against Measured Reachability
A vendor status page tells you what the vendor wants to say. This Actor tells you what you measured. Run it on a short schedule. Each run reads the public status document of each vendor and, at the same time, probes a public endpoint of the same service from outside. It then writes one typed event for each vendor.
The value is the unbroken record. The open dispute windows and the last vendor claim live in the key-value store between runs, so a window that opens at 02:10 and closes at 03:40 is one window with one length, and not 6 unrelated rows.
What each run writes
One typed event for each vendor checked:
| Event | Meaning |
|---|---|
MATCH | Nothing to dispute. The endpoint answers as expected, or the endpoint fails and the vendor already declares the incident. |
SHADOW_OUTAGE | The endpoint fails for you and the vendor still claims that all systems operate. The first such check opens a mismatch window. |
LATE_ACKNOWLEDGEMENT | The endpoint still fails and the vendor now declares the incident. The window closes, and the row carries the delay from your first failed check. |
RECOVERED | The endpoint answers as expected again while a window is open. The window closes with its full length. |
CHECK_ERROR | The check could not be made: the status document is unreadable, or the probe target is refused by the private-address rule. No window opens, because a dispute window must not rest on a guess. |
Each event holds both timestamps (when you measured, and when the vendor page
last changed), the measured status code, the latency in milliseconds, the number
of probes, the vendor status text and the state of the mismatch window. Each run
also writes one run_summary record with the counts.
Input
| Field | Default | Meaning |
|---|---|---|
vendors | 3 public examples | 1 to 25 vendors. Each entry: name, status_json_url, probe_url, probe_method (GET or HEAD), expect_status (default [200]). |
checkIntervalMinutes | 15 | The interval of your schedule. The run measures the gap since the last check against it, and each event says whether the ledger is unbroken. |
maxProbeAttempts | 3 | The largest number of probes of one target in one run. A healthy target costs one request. |
requestTimeoutSeconds | 20 | Timeout for the status read and for each probe. |
concurrency | 5 | The largest number of vendors checked at the same time. |
maxRedirects | 5 | The largest number of redirects for one read or one probe. Every hop is checked again. |
maxResponseBytes | 2000000 | The largest body this Actor reads. |
stateStoreName | shadow-outage-ledger-state | The named key-value store that carries the ledger. Give a second schedule a second name. |
stateRetentionHours | 720 | How long a vendor stays in the stored ledger after the input stops naming it. |
Every field has a default, so a run with an empty input succeeds and checks the three public examples.
status_json_url must be a public Statuspage v2 status document (normally
https://status.<vendor>.com/api/v2/status.json) or an Instatus summary
document. probe_url must be a public endpoint that needs no credentials.
State between runs
Each run gets its own default key-value store, so a ledger kept there would
start again on every run. The ledger therefore lives in a named store: the
record SHADOW_OUTAGE_LEDGER_STATE in the store that stateStoreName names.
The account keeps that store between runs.
The record holds, for each vendor, the last claim, the last measurement and the open mismatch window. Two rules keep it safe over a long life:
- The record names its schema version. A record of another version is dropped, the ledger starts again, and the run summary says so.
- The record is pruned on every write. A vendor the input no longer names is
kept for
stateRetentionHoursand is then dropped, and the record never holds more than 200 vendors.
Two schedules that share one store name write over each other. Give each schedule its own name.
Pricing: pay per event
| Event | Unit | Counted |
|---|---|---|
run_start | one run | Once for each run, charged first. It covers the container start and the read and write of the ledger store. |
vendor_check | one vendor checked in one run | Once for each vendor actually checked. It covers one status read and up to 3 probes. A vendor entry this Actor cannot read, and a vendor the charge limit does not cover, are not checked and are not charged. |
mismatch_window_event | one window opened or closed | Once when a mismatch window opens, and once when it closes. A long outage therefore costs two, and not one for each check inside it. |
The run never checks more vendors than its charge limit allows. A vendor left
out gets a skipped_vendor row.
What this Actor does not do
It uses HTTP only. It uses no browser, no proxy, no credentials and no paid API. It refuses a target that resolves to a private or reserved address, at every redirect hop.
A business verdict is never a failed run. A shadow outage, an unreadable status page, a refused probe target and an input that breaks a bound are all reported in the dataset and in the status message, and the run ends SUCCEEDED. A FAILED run means a real malfunction.
Development
uv run pytestuv run ruff check .


