Last updated: September 13, 2026
Reading Vendor Status Feeds Programmatically: Formats, Endpoints and Traps
The formats vendors publish status in, the endpoints worth calling, and the failure modes that make naive parsing quietly and confidently wrong.
What You Are Actually Consuming
There is no standard for status pages. There are several popular hosted platforms, each with its own JSON shape, plus a long tail of bespoke pages, plus a meaningful number of vendors who publish nothing a machine can read. Any code that consumes vendor status is really a small collection of per-platform parsers behind a normalising layer, and the interesting engineering is in the normalising layer rather than in any individual parser.
This guide is for engineers building or maintaining that layer: which endpoints are worth calling, what each format does and does not give you, and the failure modes that produce confidently wrong output. We run this at PulsAPI across 2,463 providers, and most of what follows is a list of things that broke.
Before building, decide honestly whether you need to. Two or three vendors is a weekend of work and a reasonable thing to own. Thirty vendors is a permanent maintenance commitment, because these formats change without notice and the breakage is silent. The status page aggregator buyer's guide covers that decision.
The Formats and What Each One Gives You
Hosted platforms are the good case. They expose documented JSON, and once you have a parser for the platform you have a parser for every vendor on it, which is why platform share matters so much to the economics of this. Our status page transparency report counts the current distribution across the vendors we track.
The self-hosted and bespoke cases are where the work is. Some publish an RSS or Atom feed with incidents as entries. Some render everything client side, so the HTML you fetch contains no status at all and the data arrives in a separate JSON or JSONP call you have to find. Some publish a human page and nothing else.
| Hosted platform JSON summary | Overall indicator, per-component status, open incidents with update timeline. | Region detail, usually. Component names are vendor-chosen and unstable. |
| Platform incident-only endpoint | Incidents and their lifecycle, often with better history than the summary. | Current component health. Pair it with the summary or you see incidents against unknown state. |
| RSS or Atom feed | Incident narrative and timestamps, usually with good retention. | Structured severity, component mapping, and current state. Entry order is not guaranteed. |
| Client-rendered page with side-loaded JSON | Everything the page shows, if you find the right call. | Stability. The internal endpoint is undocumented and can change in any deploy. |
| Human-readable page only | Text a person can read. | Everything else. Scraping is possible and breaks on redesign. |
| Nothing published | Nothing. | A reachability probe is the only signal available, and it proves far less. |
The Traps
Feed entries are not always in date order. This one has bitten us more than once. A vendor running its status page on a blog engine may order entries by publication, by edit, or by a sticky flag, and several publish scheduled future work alongside past incidents. Code that takes the first entry as the newest will read such a feed exactly backwards, reporting planned maintenance from next month as the current state. Sort explicitly by the timestamp you parsed, and treat entries dated in the future as scheduled rather than current.
Shared hosts return a verdict for the wrong product. Several large companies run one status page covering many products, so a request for one product's status can return the state of the entire host. If you record that as the product's status you have manufactured an outage for a service that is fine. Any parser addressing a shared host has to confirm the page is actually scoped to the product asked about and decline to answer when it is not.
Component vocabulary is not standardised and not stable. One vendor's degraded performance is another's partial outage, and the same vendor will rename components between deploys. Key components on something durable if the platform gives you an identifier, and expect to reconcile names when it does not. Components also disappear: a vendor retiring a component leaves you holding a row for something that no longer exists, and code that assumes a component seen yesterday exists today will drop or duplicate history.
Empty is not the same as healthy. A summary endpoint that returns successfully with an empty component list usually means your parser is looking in the wrong place, not that the vendor has no components. Treating an empty response as operational is how a monitoring system reports all clear during an outage. Fail loudly on a shape you did not expect.
Truncation hides the tail. Many endpoints paginate or cap the number of components returned. If you read the length of the array you received and call that the component count, you will be wrong for exactly the largest vendors, which are the ones anyone cares about. Read the total the API reports where one exists.
Polling Without Getting Blocked
Vendors do not owe you their status endpoint, and several will throttle or block a source that hammers one. Polling every provider every minute is both rude and wasteful, because most of them change state a handful of times a year.
Tier the schedule by demand. Services people actually check should refresh fast; the long tail can back off substantially, and the same total request budget then buys much better latency where it matters. Escalate anything mid-incident or freshly changed into the fast tier automatically, since the period right after a transition is when granularity is worth the most and the period when nothing has changed for months is when it is worth the least.
Use conditional requests. Sending the ETag or Last-Modified value you got last time turns an unchanged payload into a 304 with no body, which costs the vendor almost nothing and costs you no parse. Across a few thousand providers this is the difference between a polite integration and a noticeable one.
Handle your own concurrency deliberately. If you fetch and persist inside the same permit, a slow parse holds a slot that a fetch could have used, and your cycle time becomes the sum of the slowest operations instead of the slowest stage. Gate fetching and persistence separately.
Normalising Without Lying
The normalising layer has one hard rule: never invent detail the vendor did not publish. If a provider says only that something is degraded and never says where, your model records global degradation with unknown region. Filling that in with a plausible guess is worse than the gap, because downstream consumers cannot distinguish your guess from a fact.
Map vendor vocabulary into a small enumeration you control, and keep an explicit bucket for values you do not recognise. An unmapped status must surface as unknown and raise an alert, not silently fall through to operational. A vendor introducing a new severity string should look like a parser gap on a dashboard within a day.
Record what kind of signal each reading is. A parsed status page and a bare reachability probe are both useful and they are not the same claim, and a consumer deciding whether to page someone deserves to know which one it has. We keep that distinction all the way through to the public response for the same reason, as covered in vendor status page accuracy.
If you would rather consume a normalised feed than maintain parsers, PulsAPI exposes one over REST and over an MCP server for AI agents, documented on the developer hub and described in the MCP server announcement.
FAQ: Consuming Vendor Status Programmatically
Is there a standard format for status pages? No. A few hosted platforms cover a large share of vendors and each has its own JSON shape, and the remainder publish RSS, client-rendered pages, or nothing machine-readable. Any serious integration is several parsers behind one normalising layer.
How often should I poll a vendor status endpoint? Match the interval to how often the source actually changes and to how much you care about that vendor. A tiered schedule with conditional requests, plus automatic escalation for anything mid-incident, gives far better latency per request than a flat sweep.
What should I do when a vendor publishes nothing parseable? Fall back to a reachability check and label it as such. It gives you a weak global up or down signal with no component or region detail, and the labelling matters because consumers will otherwise treat it as equivalent to parsed status.
Why does my integration report a vendor as healthy during an outage? The most common causes are an empty response treated as operational, an unmapped status string falling through to a default, and a feed read in the wrong order. All three fail silently, which is why each one needs an explicit guard rather than a sensible default.
Can I just scrape the HTML? For one vendor you control the risk on, sometimes. At scale it is the least stable option available: a redesign breaks it with no error, and client-rendered pages contain no status in the HTML at all.
About the Author
Sofia builds observability tooling at PulsAPI. Previously at Datadog and Honeycomb working on metrics ingestion at scale.
Start monitoring your stack
Aggregate real-time operational data from every service your stack depends on into a single dashboard. Free for up to 5 services.