Documentation
Schemas
The shapes that appear in more than one response, written once. These are generated from the same definitions core validates its own responses against, so a field here is a field the API returns.
32 shapes · generated from /openapi.json
StatusResponse
generatedAtstring (date-time)summaryobjectsummary.venuesintegersummary.regionsintegersummary.probeIntervalMsintegerThe fleet’s default polling interval, in milliseconds, per region. An endpoint whose provider rations its free tier can be slower;
/v1/exchanges/{venue}carries the resolved cadence per endpoint.min 1
summary.statestring"operational""degraded""outage""unknown"summary.uptimePct90dnumber | nullsummary.medianLatencyMsinteger | nullsummary.activeIncidentsintegersummary.categoriesobject[]Counts for every category up24 lists, unaffected by
category— the rest of this object describes the rows in this response, and this describes the board they came from.venuesVenueStatus[]incidentsIncident[]
ExchangeResponse
generatedAtstring (date-time)exchangeobjectexchange.idstring"binance""bybit""coinbase""kraken""okx""bitfinex""deribit""bitstamp""gemini""cryptocom""hyperliquid""upbit""binance-futures""bybit-futures""okx-futures"exchange.namestringexchange.categorystringWhat kind of infrastructure this row is: an exchange, an RPC provider, a market-data API, an oracle, a stablecoin, a bridge or a fiat ramp. It is what says which columns are honest for the row — a block lag means nothing on an exchange and an order book means nothing on an oracle — so read it before comparing two rows on the same number.
"exchange""rpc""market-data""oracle""stablecoin""bridge""ramp"exchange.symbolstring | nullThe instrument up24 probes, in this venue's own notation —
XBTUSDon Kraken,tBTCUSDon Bitfinex — not a normalised one, so it matches what you would type into that venue’s own API. Null on any category that trades no instrument, which today is everyrpcrow.exchange.quotestring | nullThe currency the symbol is priced in. Venues differ, so do not compare prices across them naively. Null on any category that trades no instrument, for the same reason
symbolis.statestring"operational""degraded""outage""unknown"sincestring (date-time)uptimePct90dnumber | nulltypicalMsinteger | nulldaysUptimeDay[]latencyobjectlatency.rangestring"24h""7d"latency.bucketMsintegermin 1
latency.pointsLatencyPoint[]endpointsobject[]streamsStreamStatus[]regionsobjectregions.selectedstringregions.compareRegionComparison[]incidentsIncident[]The 50 most recent, newest first, with each one’s official counterpart attached. Capped because the official join is one lookup per row;
incidentPatternscovers the whole window and carries a link to every incident in it.incidentPatternsobject[]officialobjectofficial.sourcestring | nullofficial.pagestring | nullofficial.observedbooleanofficial.incidentsOfficialIncident[]detectionDetectionsummaryReliabilitySummary
ReliabilityResponse
generatedAtstring (date-time)daysintegermin 1
fleetobjectfleet.venuesintegerfleet.uptimePctnumber | nullfleet.typicalP50Msinteger | nullfleet.typicalP95Msinteger | nullfleet.incidentsintegervenuesReliabilityVenue[]
DetectionResponse
generatedAtstring (date-time)daysintegermin 1
fleetDetectionvenuesobject[]
IncidentsResponse
generatedAtstring (date-time)incidentsIncident[]
IncidentDetailResponse
generatedAtstring (date-time)incidentIncidentvenueobjectvenue.idstring"binance""bybit""coinbase""kraken""okx""bitfinex""deribit""bitstamp""gemini""cryptocom""hyperliquid""upbit""binance-futures""bybit-futures""okx-futures"venue.namestringvenue.symbolstring | nullThe instrument up24 probes, in this venue's own notation —
XBTUSDon Kraken,tBTCUSDon Bitfinex — not a normalised one, so it matches what you would type into that venue’s own API. Null on any category that trades no instrument, which today is everyrpcrow.venue.quotestring | nullThe currency the symbol is priced in. Venues differ, so do not compare prices across them naively. Null on any category that trades no instrument, for the same reason
symbolis.componentobjectcomponent.idstringOne REST endpoint or one WebSocket stream of one venue —
rest:ticker,ws:book.ws:connis the shared socket itself, which is where a connection-scoped fault is recorded.matches ^(rest|ws):[a-z]+$ · e.g. "rest:ticker"
component.kindstring"rest""ws"component.labelstringcomponent.targetstring | nulleventsIncidentEvent[]errorsErrorBreakdownlatencyIncidentLatency | nulldetectionDetectionofficialobjectofficial.sourcestring | nullofficial.pagestring | nullofficial.observedbooleanrelatedIncident[]
HealthResponse
statusstringservicestring"core""web""probe"versionstringuptimeSecondsintegertimestring (date-time)
RegionsResponse
generatedAtstring (date-time)regionsRegionSummary[]quoruminteger
ThresholdsResponse
generatedAtstring (date-time)versionstringrulesPublishedRule[]stallsStallThreshold[]
Incident
idintegermin 1
slugstringStable permalink id —
{venue}-{YYYY-MM-DD}-{rest|ws}, with-2,-3for a second incident of the same shape on the same day. Never rewritten after it opens. Incidents opened before 12 Sep 2026 carry a fourth segment naming the severity they had at the moment they opened; it was dropped because severity is the one field an incident is meant to revise, and those slugs keep serving unchanged.e.g. "binance-2026-08-12-rest"
venuestring"binance""bybit""coinbase""kraken""okx""bitfinex""deribit""bitstamp""gemini""cryptocom""hyperliquid""upbit""binance-futures""bybit-futures""okx-futures"componentstringOne REST endpoint or one WebSocket stream of one venue —
rest:ticker,ws:book.ws:connis the shared socket itself, which is where a connection-scoped fault is recorded.matches ^(rest|ws):[a-z]+$ · e.g. "rest:ticker"
severitystringThe worst state reached, not the state right now — an incident is named for its peak.
"degraded""outage"startedAtstring (date-time)endedAtstring (date-time) | nullWhen the venue came back, not when the state machine finished clearing. Null while open.
durationMsintegerTo
endedAt, or to now while the incident is open.summarystringerrorClassstring | null"timeout""dns""tls""conn""http_429""http_403""http_451""http_4xx""http_5xx""bad_body""stalled""rejected""refused""unknown""lag"retractedobject | nullSet when up24 withdrew this incident as its own fault — a probe bug, not the venue. Retracted incidents are excluded from every list, count and feed; the permalink keeps serving so the record of the correction is public. Null for every incident that stands.
retracted.atstring (date-time)retracted.reasonstringofficialOfficialIncident | nullleadMsinteger | nullTheir acknowledgment minus our detection, in ms. Positive means up24 timestamped first; negative means the venue did. Null wherever
officialis null. Time order only — seesubjectMatched, which isfalseon every pairing: nothing checks that the notice is about the same fault.
IncidentEvent
atstring (date-time)kindstring"detected""escalated""acknowledged""venue-resolved""recovered"severitystring | null"degraded""outage"errorClassstring | null"timeout""dns""tls""conn""http_429""http_403""http_451""http_4xx""http_5xx""bad_body""stalled""rejected""refused""unknown""lag"titlestring | nullurlstring | null
IncidentLatency
scopestring"endpoint""venue"endpointstring | nullbucketMsintegermin 1
fromstring (date-time)tostring (date-time)pointsLatencyPoint[]
ErrorBreakdown
sourcestring | null"rollup_1m""stream_health"classesobject[]observationsintegerfailedinteger
OfficialIncident
sourcestringkindstring"incident""maintenance"titlestringurlstringstartedAtstring (date-time)endedAtstring (date-time) | nullacknowledgedAtstring (date-time)impactstring | nullobservedbooleansubjectMatchedbooleanAlways
false. Pairing is a symmetric ±6h window on the same venue and nothing tests that the notice describes the fault up24 measured — hand-checking the fleet in Aug 2026 found every pairing was a different subject. ReadleadMsas time order, not as a scoop.
Detection
incidentsintegermatchedintegeraheadUncorrelatedintegerOf
matched, how many up24 timestamped before the venue published. Time order only: pairing is a symmetric ±6h window with no test that the two describe the same fault, and every pairing carriessubjectMatched: falsefor that reason. Not a count of scoops, and not to be quoted as one.medianLeadMsinteger | nullbestLeadMsinteger | null
VenueStatus
idstring"binance""bybit""coinbase""kraken""okx""bitfinex""deribit""bitstamp""gemini""cryptocom""hyperliquid""upbit""binance-futures""bybit-futures""okx-futures"namestringcategorystringWhat kind of infrastructure this row is: an exchange, an RPC provider, a market-data API, an oracle, a stablecoin, a bridge or a fiat ramp. It is what says which columns are honest for the row — a block lag means nothing on an exchange and an order book means nothing on an oracle — so read it before comparing two rows on the same number.
"exchange""rpc""market-data""oracle""stablecoin""bridge""ramp"symbolstring | nullThe instrument up24 probes, in this venue's own notation —
XBTUSDon Kraken,tBTCUSDon Bitfinex — not a normalised one, so it matches what you would type into that venue’s own API. Null on any category that trades no instrument, which today is everyrpcrow.quotestring | nullThe currency the symbol is priced in. Venues differ, so do not compare prices across them naively. Null on any category that trades no instrument, for the same reason
symbolis.statestring"operational""degraded""outage""unknown"sincestring (date-time)uptimePct90dnumber | nullOk checks over total checks across 90 days, 0–100, floored to two decimals so 100 means no check failed. REST only — a stream has no "check" to be a denominator. Null where the venue was never measured.
typicalMsinteger | nullMedian of the last 24h of per-minute p50s, in ms. Not the 24h p50 — percentiles do not compose. The exact figure is on
/v1/exchanges/{venue}, which computes it from raw samples.measuredDaysintegerDays of the 90-day window with at least one check. Read it beside
uptimePct90d: the percentage covers these days and no others.methodologyUrlstring (uri)How every figure on this row is computed, including what counts as an ok check and how regions are combined. Travels with the row so a number quoted elsewhere keeps its method.
openIncidentsintegerunknownComponentsintegerdaysUptimeDay[]sparkinteger | null[]componentsComponentStatus[]
ComponentStatus
idstringOne REST endpoint or one WebSocket stream of one venue —
rest:ticker,ws:book.ws:connis the shared socket itself, which is where a connection-scoped fault is recorded.matches ^(rest|ws):[a-z]+$ · e.g. "rest:ticker"
kindstring"rest""ws"labelstringtargetstringstatestring"operational""degraded""outage""unknown"sincestring (date-time)errorClassstring | null"timeout""dns""tls""conn""http_429""http_403""http_451""http_4xx""http_5xx""bad_body""stalled""rejected""refused""unknown""lag"
UptimeDay
daystringuptimePctnumber | nullchecksintegerstatestring"operational""degraded""outage""unknown"
RegionSummary
idstringlabelstringcitystringcountrystringprimarybooleanreportingbooleanlastSampleAtstring (date-time) | nullsamples1hintegervenuesintegerfirstSampleAtstring (date-time) | nullWhen this probe box first shipped a sample. Read it beside
preliminary: it is the denominator behind every number this region contributes.preliminarybooleanTrue while the box has been measuring for fewer than seven days — the same window every baseline in the incident engine is computed over, so a younger region has no normal to be abnormal against and its percentiles still describe the box settling in. The readings are published either way; this says how much weight they have earned. False for a region that has never reported at all, which is
reporting: falserather than preliminary.
RegionComparison
idstringlabelstringcitystringcountrystringp50Msinteger | nullp95Msinteger | nulluptimePct24hnumber | nullchecks24hintegerpreliminarybooleanTrue while this box has been measuring for fewer than seven days. Its numbers are real measurements; they have simply not seen a full baseline window yet.
blockedobject | nullSet where this vantage point cannot measure this venue, and null — the usual case — where it can. The refused checks are out of
checks24handuptimePct24hand counted inblocked.checks24hinstead: they say what the venue does about this vantage point, not whether it is up. Readfaultbefore quoting the row —venueis the target refusing this country,vantageis up24’s own box or route failing to reach a target that is serving everyone else.blocked.faultstringvenue— the target refuses this vantage point, so its refusals say nothing about availability.vantage— up24’s own probe host or route cannot reach a target that is answering elsewhere, so the readings measure up24 rather than the target."venue""vantage"blocked.errorClassstringThe class discounted. Any other reading from this region counts as normal.
"timeout""dns""tls""conn""http_429""http_403""http_451""http_4xx""http_5xx""bad_body""stalled""rejected""refused""unknown""lag"blocked.sincestringThe first day it was measured,
YYYY-MM-DD.blocked.untilstring | nullThe day it stopped, or null while it is still in force.
blocked.notestringWhat was observed and what settled it, in plain words.
blocked.urlstring (uri) | nullThe venue’s own document, where one was readable.
blocked.checks24hintegerRefused checks in the last day. Out of the uptime denominator, kept here.
LatencyPoint
tstring (date-time)p50Msinteger | nullp95Msinteger | nullokintegertotalinteger
StreamStatus
idstringOne REST endpoint or one WebSocket stream of one venue —
rest:ticker,ws:book.ws:connis the shared socket itself, which is where a connection-scoped fault is recorded.matches ^(rest|ws):[a-z]+$ · e.g. "rest:ticker"
labelstringchannelstringstatestring"operational""degraded""outage""unknown"sincestring (date-time)connectedPct24hnumber | nulldeliveringPct24hnumber | nullmessages24hinteger | nullmaxGapMs24hinteger | nullseqGaps24hinteger | nullseqCheckedbooleanreconnects24hinteger | nullrttMsinteger | null
StreamSummary
connectedPct24hnumber | nulldeliveringPct24hnumber | nullreconnects24hinteger | nullseqGaps24hinteger | nullseqCheckedbooleanmaxGapMs24hinteger | nullcoveragePct24hnumber | nullShare of the last 24 hours, 0–100, that up24 has stream evidence for on this venue. Everything else in this object is computed over these windows only.
probeFaultbooleanTrue when some of the 24-hour window is missing or was discarded as up24’s own fault, so the percentages above describe less than a day. Never a statement about the venue.
ReliabilitySummary
daysintegerThe window asked for.
min 1
measuredDaysintegerDays of that window with any measurement at all. Quote it beside
days: a venue watched for eight days of ninety has not been 99.99% for a quarter.uptimePctnumber | nullOk checks over total checks across the window, 0–100, floored to two decimals so 100 means no check failed. REST only, as everywhere.
checksintegerThe denominator behind
uptimePct. Quote both or neither.worstDayUptimeDay | nullThe measured day with the lowest uptime. Null when nothing was measured.
typicalP50Msinteger | nullMedian of the window’s *daily* p50s, in ms — not the window’s own percentile. Percentiles do not compose, and the daily rollup is the finest grain that outlives raw retention.
typicalP95Msinteger | nullMedian of the window’s *daily* p95s, in ms. Same caveat as
typicalP50Ms.incidentsintegerIncidents up24 opened in the window. Not what the venue announced.
ReliabilityVenue
venuestring"binance""bybit""coinbase""kraken""okx""bitfinex""deribit""bitstamp""gemini""cryptocom""hyperliquid""upbit""binance-futures""bybit-futures""okx-futures"namestringcategorystringWhat kind of infrastructure this row is: an exchange, an RPC provider, a market-data API, an oracle, a stablecoin, a bridge or a fiat ramp. It is what says which columns are honest for the row — a block lag means nothing on an exchange and an order book means nothing on an oracle — so read it before comparing two rows on the same number.
"exchange""rpc""market-data""oracle""stablecoin""bridge""ramp"symbolstring | nullThe instrument up24 probes, in this venue's own notation —
XBTUSDon Kraken,tBTCUSDon Bitfinex — not a normalised one, so it matches what you would type into that venue’s own API. Null on any category that trades no instrument, which today is everyrpcrow.quotestring | nullThe currency the symbol is priced in. Venues differ, so do not compare prices across them naively. Null on any category that trades no instrument, for the same reason
symbolis.statestring"operational""degraded""outage""unknown"sincestring (date-time)openIncidentsintegersummaryReliabilitySummarystreamsStreamSummarydetectionDetectionofficialobjectofficial.sourcestring | nullofficial.pagestring | null
PublishedRule
idstringlabelstringvaluenumberunitstring"ms""count""percent""days""multiple"whystring
BlockLag
chainstringchainNamestringblockTimeMsintegerThe chain’s documented block time, from the page
blockTimeUrlnames.min 1
blockTimeUrlstring (uri)blockTimeCaveatstring | nullSet where the documented block time is a ceiling rather than a heartbeat — Arbitrum One produces a block only when there are transactions to sequence, and Base streams preconfirmations faster than its canonical block. Null where the number means what it says.
referencestringWhat the lag is measured against, in words, so the number never travels without it.
referenceMsintegerHow near in time two readings must be to be compared. Two heights read at two instants differ by whatever the chain built in between; the fleet’s polling spread is corrected out at the documented block time, one-directionally, so the correction can only remove lag and never add it — and lag smaller than this width is therefore invisible.
min 1
degradedMsintegerWhere the incident engine calls this provider degraded. Also on /v1/thresholds.
min 1
hoursintegerThe window the figures cover.
min 1
regionsBlockLagRegion[]
BlockLagRegion
regionstringtypicalBlocksnumber | nullMedian of the per-minute readings over the window, in blocks. Null where this region produced no comparable round — one provider alone is its own reference, and a lag of zero off a fleet of one would be a flattering fiction rather than a measurement.
worstBlocksnumber | nullThe largest single-minute reading in the window, in blocks.
typicalMsinteger | nulltypicalBlocksat the chain’s documented block time, which is the unit the threshold is expressed in — a threshold in blocks would be three thresholds and would fire on an idle Arbitrum minute. ReadblockTimeCaveatbefore treating it as elapsed time.minutesintegerMinutes of the window that produced a reading — the denominator behind the two figures above. Fewer than the window holds is normal: the block read is polled every 45 seconds, so about one minute in four contains no round at all.
StallThreshold
venuestring"binance""bybit""coinbase""kraken""okx""bitfinex""deribit""bitstamp""gemini""cryptocom""hyperliquid""upbit""binance-futures""bybit-futures""okx-futures"venueNamestringcomponentstringOne REST endpoint or one WebSocket stream of one venue —
rest:ticker,ws:book.ws:connis the shared socket itself, which is where a connection-scoped fault is recorded.matches ^(rest|ws):[a-z]+$ · e.g. "rest:ticker"
channelstringstallMsintegerHow long this feed may say nothing, from this region, before the window is counted as failed. Read off the measured distribution of the feed’s own quiet periods, not picked.
min 1
regionstring"eu-central""ap-southeast""us-east"regionOverridebooleanTrue where this feed is measurably quieter from this vantage point than elsewhere and so carries its own threshold. Latency is never averaged across regions for the same reason.
AlertPayload
eventstringincident.opened,incident.escalatedorincident.closed— the conventional shape for a webhook, and the field to route on.kindis the same value without the prefix.kindstringWhich of the three this is.
escalatedis separate fromopenedbecause a degradation becoming an outage is one incident throughout — the engine escalates in place rather than opening a second."opened""escalated""closed"eventIdintegerThe event’s own id. Delivery is at-least-once by design, so de-duplicate on this. Zero on a test alert, which corresponds to no event and no incident — a subscriber that keys off these ids therefore ignores tests for free instead of storing one under a fabricated real id.
incidentIdintegerThe incident all three events of one fault share, and therefore the right thing to group by — or to use as a pager’s deduplication key, so an escalation updates the page it opened and a close resolves it.
venuestringThe venue, as its id on this site.
"binance""bybit""coinbase""kraken""okx""bitfinex""deribit""bitstamp""gemini""cryptocom""hyperliquid""upbit""binance-futures""bybit-futures""okx-futures"venueNamestringThe venue’s display name, as the board writes it.
componentstringOne REST endpoint or one WebSocket stream of one venue —
rest:ticker,ws:book.ws:connis the shared socket itself, which is where a connection-scoped fault is recorded.matches ^(rest|ws):[a-z]+$ · e.g. "rest:ticker"
severitystringWhat the engine graded the incident. The two it can open at; a channel’s severity floor decides which of them reaches you.
"degraded""outage"statestringWhat the component is right now —
operationalon a close, which is the one event where this andseveritydeliberately disagree."operational""degraded""outage""unknown"summarystringOne sentence, produced by a
switchover states with the measured numbers substituted in. Never model-written, which is why it is safe to forward verbatim.errorClassstring | nullThe dominant failure behind the incident — one of
timeout,dns,tls,conn,http_429,http_403,http_451,http_4xx,http_5xx,bad_body,stalled,rejected,refused,unknown,lag— or null where there was no single one.stalledandrejectedcome only from stream monitoring: a stalled feed is not a timeout, the socket is open and the venue has simply stopped saying anything.startedAtstring (date-time)When the incident began, which is not when this event was sent.
endedAtstring (date-time) | nullNull while the incident is open. On a close it is when recovery began, not when the engine’s two-minute confirmation hold expired.
occurredAtstring (date-time)When this event was written, within one engine tick of the change it reports. The delivery timestamp is on the dashboard’s log, not in the body.
urlstringWhere a human goes to see it: the venue’s page on up24, with the window, the denominator and the vantage points the verdict was reached from.
testbooleanoptionalPresent and true only for the test button on the dashboard. Absent on every real alert.
NotifyResponse
generatedAtstring (date-time)daysintegermin 1
deliveriesintegerHow many delivered openings the two percentiles are over — deliveries only, not the skips and failures the delivery log also records, and not a backfilled event. Zero means nothing has been delivered in the window and both percentiles are
null.p50Msinteger | nullMedian of
delivered_at − startedAtacross every opening alert delivered in the window, over every channel and every account. Includes detection — the engine needs consecutive bad samples before it opens anything — so this is time from the fault, not time from the decision. Excludes any event that waited over an hour in the outbox before a delivery was claimed for it, which is a backfill rather than a notification. Null whendeliveriesis 0.p95Msinteger | nullThe same measurement at the 95th percentile: the slow tail, which is the one worth quoting at a desk. Read it against
deliveries— a p95 over a handful of alerts is that handful’s worst one. Null whendeliveriesis 0.
Error
Every failure on this API, at every status. A 4xx carries the reason; a 5xx is always the opaque string internal error, because the alternative is publishing stack shapes to strangers.
errorstring