UptimeProject

API reference

Read-only API for cloud provider uptime rankings and historical availability data. Backed by an independent fleet of probes measuring real cloud services on a 1-minute cadence; aggregated into per-minute and per-day time-series rollups and served as cacheable JSON.

All /v1/* GET responses are stamped with Cache-Control: public, max-age=300, s-maxage=300 (5 minutes) by default. The OpenAPI spec endpoint uses a longer 1-hour TTL because the spec only changes on releases.

Errors use a single envelope: {"error": "<human-readable string>"}. The error string is for humans; clients should branch on the HTTP status code.

Base URL
https://api.uptimeproject.org
Version
v1
Authentication
None
Specification
openapi.json

services

Per-service metadata, current status, and headline availability.

GET /v1/services

List active services

Returns every service registered as active = true in the registry. Each row carries the service's identity, headline availability over the last 30 and 90 days, and current consensus status. Intended for building a directory of services, or for taking a full snapshot of the catalog in one request.

Availability values come from the per-day rollup (excluding unknown minutes from the denominator); a null value means "no measurements in the window yet".

Responses

Responses for GET /v1/services
Status Body Description
200 array of ServiceSummary

A non-empty array of services. Order is unspecified.

500 APIError

Unexpected server-side error. Body is the standard error envelope; the error string is intentionally generic and clients should not try to parse it for diagnostics.

Request

curl https://api.uptimeproject.org/v1/services

Response

            [
  {
    "id": "aws-s3-us-east-1",
    "name": "AWS S3",
    "category": "object-storage",
    "region": "us-east-1",
    "provider": "Amazon Web Services",
    "show_on_leaderboard": true,
    "homepage_url": "https://aws.amazon.com/s3/",
    "status_page_url": "https://status.aws.amazon.com/rss/s3-us-east-1.rss",
    "current_status": "up",
    "checks_count": 3,
    "availability_24h": 99.99,
    "availability_7d": 99.98,
    "availability_30d": 99.97,
    "availability_90d": 99.91
  }
]
          
GET /v1/services/{id}

Fetch a single service by id

Returns the same fields as /v1/services for one service, plus the active checks that produce its measurements and each probe's most-recent view of the service. Deactivated services and unknown ids both return 404: the API does not surface "this service used to exist" as a distinct state.

Parameters

Parameters for GET /v1/services/{id}
Name In Type Description
id required path string

Slug-style service identifier from the registry, e.g. aws-s3-us-east-1, cloudflare-cdn. Lower-case and dash-separated, and stable across releases. Regional services carry their region in the id, so the identifier for a service is not the provider's product name.

Responses

Responses for GET /v1/services/{id}
Status Body Description
200 ServiceDetail

Service exists and is active.

404 APIError

The service id is not registered, or the service is deactivated. The two cases collapse to the same response; the API does not expose deactivated-vs-never-existed.

500 APIError

Unexpected server-side error. Body is the standard error envelope; the error string is intentionally generic and clients should not try to parse it for diagnostics.

Request

curl https://api.uptimeproject.org/v1/services/aws-s3-us-east-1

Response

            {
  "id": "aws-s3-us-east-1",
  "name": "AWS S3",
  "category": "object-storage",
  "region": "us-east-1",
  "provider": "Amazon Web Services",
  "show_on_leaderboard": true,
  "homepage_url": "https://aws.amazon.com/s3/",
  "status_page_url": "https://status.aws.amazon.com/rss/s3-us-east-1.rss",
  "current_status": "up",
  "checks_count": 3,
  "availability_24h": 99.99,
  "availability_7d": 99.98,
  "availability_30d": 99.97,
  "availability_90d": 99.91,
  "checks": [
    {
      "id": "aws-s3-us-east-1-http-main",
      "check_type": "http",
      "target": "https://s3.us-east-1.amazonaws.com/",
      "interval_sec": 60
    }
  ],
  "probes": [
    {
      "probe_id": "hzr-fsn1",
      "status": "up",
      "latency_ms": 42
    }
  ]
}
          

uptime

Time-series availability data for charts and timelines.

GET /v1/services/{id}/uptime

Time-series availability for one service

Returns availability data over the requested period as an ordered series of buckets plus a rolled-up summary. Bucket size is chosen by the period:

periodbucket sizepoints
24h5 minutes289
7d1 hour169
30d1 day30
90d1 day90
1y1 day365

The 24h and 7d windows are inclusive of both ends, which is where the extra point over 288 and 168 comes from. Counts assume a full window of history; a service registered more recently returns fewer points.

The summary's availability_pct is computed across the whole period, not as an average of per-bucket percentages, so partial buckets at the leading edge don't get equal weight to full ones.

Parameters

Parameters for GET /v1/services/{id}/uptime
Name In Type Description
id required path string

Slug-style service identifier from the registry, e.g. aws-s3-us-east-1, cloudflare-cdn. Lower-case and dash-separated, and stable across releases. Regional services carry their region in the id, so the identifier for a service is not the provider's product name.

period query UptimePeriod (enum)

Time window to return. Defaults to 30d.

Responses

Responses for GET /v1/services/{id}/uptime
Status Body Description
200 UptimeSeries

Service exists and the requested period is valid.

400 APIError

The period query parameter is not one of the supported values.

404 APIError

The service id is not registered, or the service is deactivated. The two cases collapse to the same response; the API does not expose deactivated-vs-never-existed.

500 APIError

Unexpected server-side error. Body is the standard error envelope; the error string is intentionally generic and clients should not try to parse it for diagnostics.

Request

curl https://api.uptimeproject.org/v1/services/aws-s3-us-east-1/uptime

Response

            {
  "service_id": "aws-s3-us-east-1",
  "period": "24h",
  "points": [
    {
      "bucket": "2026-05-08T09:00:00Z",
      "availability_pct": 100,
      "status": "up",
      "down_minutes": 0,
      "degraded_minutes": 0,
      "latency_p50_ms": 87
    }
  ],
  "summary": {
    "availability_pct": 100,
    "total_down_minutes": 0,
    "total_degraded_minutes": 0,
    "latency_p50_ms": 142
  }
}
          

leaderboard

Ranked best-of lists by category and time window.

GET /v1/leaderboard

Ranked best-of list of active services

Returns active services ranked by average availability over the requested window. Ranks are 1-based and dense, with no gaps, ordered by availability descending and broken by name ascending.

A service with no measurements in the window collapses to availability_pct: 0 with current_status: unknown and ranks at the bottom. It stays in the list rather than disappearing, so a client can tell "no data yet" apart from "ranked last".

The category filter accepts any of the registry-defined category strings. An unknown value returns 400 rather than an empty list, which would mask a typo.

Parameters

Parameters for GET /v1/leaderboard
Name In Type Description
period query LeaderboardPeriod (enum)

Window over which availability is averaged. Defaults to 30d. Narrower than the set /v1/services/{id}/uptime accepts; see LeaderboardPeriod for which values are excluded and why.

category query Category (enum)

Optional category filter. When omitted, all active services rank together; when present, only services in the matching category are ranked.

Responses

Responses for GET /v1/leaderboard
Status Body Description
200 LeaderboardResponse

Ranked entries (possibly empty after a category filter).

400 APIError

period is not in the leaderboard whitelist, or category is non-empty and not a known category.

500 APIError

Unexpected server-side error. Body is the standard error envelope; the error string is intentionally generic and clients should not try to parse it for diagnostics.

Request

curl https://api.uptimeproject.org/v1/leaderboard

Response

            {
  "period": "7d",
  "category": "object-storage",
  "entries": [
    {
      "rank": 1,
      "service_id": "aws-s3-us-east-1",
      "name": "AWS S3",
      "category": "object-storage",
      "availability_pct": 100,
      "current_status": "up",
      "rank_change": 0
    }
  ],
  "generated_at": "2026-05-08T09:00:00Z"
}
          

meta

Machine-readable spec and the docs redirect.

GET /v1/openapi.json

Machine-readable API specification

Returns this OpenAPI 3.1 document as JSON, for clients that generate code from OpenAPI (e.g. openapi-typescript).

Served with a 1-hour TTL, longer than the 5 minutes the data endpoints use, because the spec only changes on releases.

Responses

Responses for GET /v1/openapi.json
Status Body Description
200 object

The OpenAPI 3.1 document.

Request

curl https://api.uptimeproject.org/v1/openapi.json
GET /v1/docs

Redirect to the human-readable API reference

Returns a 302 redirect to uptimeproject.org/docs/api, the human-readable rendering of this document.

Exposed on the API host so a developer who lands on the raw base URL, or a CLI that follows redirects, reaches the readable view in one hop. That page is generated at build time from a copy of this document, so it stays readable while the API is unreachable.

Responses

Responses for GET /v1/docs
Status Body Description
302 none

Redirect to the marketing-site docs page.

Request

curl https://api.uptimeproject.org/v1/docs

Schemas

Response shapes referenced above. Fields marked required are always present; the rest may be absent.

Status

Probe-consensus status for a service or bucket.

  • up: at least a majority of probes succeeded
  • degraded: some probes failing, but not the majority
  • down: every probe failed
  • unknown: fewer than 3 probes reported, which is too few to call a consensus

UptimePeriod

Period accepted by /v1/services/{id}/uptime. Bucket size is fixed per period (see endpoint description).

One of: 24h , 7d , 30d , 90d , 1y

LeaderboardPeriod

Period accepted by /v1/leaderboard. Subset of UptimePeriod: 24h is excluded as too noisy for ranking (one bad hour would flip a service to last place); 1y is excluded as too lagging (rewards last-year stability over current performance).

One of: 7d , 30d , 90d

Category

Service category. Mirrors the registry's category names verbatim, so the value is object-storage (hyphenated), not storage.

One of: iaas , cdn , dns , object-storage , dev-infra , email , payments , ai

APIError

Canonical error envelope used by every non-2xx response. The error string is human-readable and may change between deploys, so clients should branch on the HTTP status.

Fields of the APIError object
Field Type Description
error required string

Human-readable error message.

Example: not found

ServiceSummary

One row of /v1/services, and the base that ServiceDetail extends. Carries identity, headline availability, current consensus status, and the number of active checks, so a client can summarise the whole catalog without fetching each service.

Fields of the ServiceSummary object
Field Type Description
id required string

Slug-style identifier from the registry.

Example: aws-s3-us-east-1

name required string

Human-readable service name.

Example: AWS S3

category required Category (enum)
region string

Provider region for regional services. Omitted for global services (CDNs, DNS resolvers, payment APIs).

Example: us-east-1

provider string

Brand or parent company behind the service. Editorial rather than derived from id or name: every aws-* service reports "Amazon Web Services" whatever the product is called, and linode reports "Akamai / Linode" for the parent company. Omitted when the registry row carries no provider.

Example: Amazon Web Services

show_on_leaderboard required boolean

Whether the service appears on public ranking surfaces. true, the default, lists it on the leaderboard and the services index. false keeps it probed and queryable through /v1/services/{id} and /v1/services/{id}/uptime but off those rankings, which is how a newly onboarded service is held back until it has enough history to rank fairly.

Always present, never omitted: an absent field would read as "the API does not know" rather than "hidden".

Example: true

homepage_url required string (uri)

Public landing page for the service. Always present.

Example: https://aws.amazon.com/s3/

status_page_url string (uri)

The provider's own status page, where it publishes one. Omitted rather than empty when it does not, so a client never has to special-case "".

Carried on the list endpoint as well as the detail one, so rendering a directory of services needs a single request.

Example: https://status.aws.amazon.com/rss/s3-us-east-1.rss

current_status required Status (enum)
checks_count required integer

Number of active checks measuring this service. Checks registered but not yet active are excluded, so the count matches what the fleet is really executing. 0 for a newly registered service whose checks have not landed yet.

Example: 3

availability_24h required number or null

Availability percent over the rolling trailing 24 hours, computed from the per-minute consensus aggregate, with unknown minutes excluded from the denominator.

Measured directly rather than derived from the per-day rollup, whose buckets are anchored to UTC midnight: averaging a partial today against yesterday would bias against a service that was unhealthy hours ago. null when the window has no measurements yet.

Example: 99.99

availability_7d required number or null

Availability percent over the trailing 7 days, derived from the per-day rollup (same source as availability_30d / availability_90d). null when the window has no measurements yet.

Example: 99.98

availability_30d required number or null

Availability percent over the trailing 30 days, derived from the per-day rollup (excludes unknown minutes from the denominator). null when the window has no measurements yet.

Example: 99.97

availability_90d required number or null

Same as availability_30d, over 90 days.

Example: 99.91

ServiceDetail

Body of GET /v1/services/{id}. Every field of ServiceSummary, plus the active checks that produce the measurements and each probe's most-recent view of the service.

Fields of the ServiceDetail object
Field Type Description
id required string

Slug-style identifier from the registry.

Example: aws-s3-us-east-1

name required string

Human-readable service name.

Example: AWS S3

category required Category (enum)
region string

Provider region for regional services. Omitted for global services (CDNs, DNS resolvers, payment APIs).

Example: us-east-1

provider string

Brand or parent company behind the service. Editorial rather than derived from id or name: every aws-* service reports "Amazon Web Services" whatever the product is called, and linode reports "Akamai / Linode" for the parent company. Omitted when the registry row carries no provider.

Example: Amazon Web Services

show_on_leaderboard required boolean

Whether the service appears on public ranking surfaces. true, the default, lists it on the leaderboard and the services index. false keeps it probed and queryable through /v1/services/{id} and /v1/services/{id}/uptime but off those rankings, which is how a newly onboarded service is held back until it has enough history to rank fairly.

Always present, never omitted: an absent field would read as "the API does not know" rather than "hidden".

Example: true

homepage_url required string (uri)

Public landing page for the service. Always present.

Example: https://aws.amazon.com/s3/

status_page_url string (uri)

The provider's own status page, where it publishes one. Omitted rather than empty when it does not, so a client never has to special-case "".

Carried on the list endpoint as well as the detail one, so rendering a directory of services needs a single request.

Example: https://status.aws.amazon.com/rss/s3-us-east-1.rss

current_status required Status (enum)
checks_count required integer

Number of active checks measuring this service. Checks registered but not yet active are excluded, so the count matches what the fleet is really executing. 0 for a newly registered service whose checks have not landed yet.

Example: 3

availability_24h required number or null

Availability percent over the rolling trailing 24 hours, computed from the per-minute consensus aggregate, with unknown minutes excluded from the denominator.

Measured directly rather than derived from the per-day rollup, whose buckets are anchored to UTC midnight: averaging a partial today against yesterday would bias against a service that was unhealthy hours ago. null when the window has no measurements yet.

Example: 99.99

availability_7d required number or null

Availability percent over the trailing 7 days, derived from the per-day rollup (same source as availability_30d / availability_90d). null when the window has no measurements yet.

Example: 99.98

availability_30d required number or null

Availability percent over the trailing 30 days, derived from the per-day rollup (excludes unknown minutes from the denominator). null when the window has no measurements yet.

Example: 99.97

availability_90d required number or null

Same as availability_30d, over 90 days.

Example: 99.91

checks required array of CheckSummary

Active checks for this service. Always an array, never null, and empty for a newly registered service whose checks have not landed yet.

probes required array of ProbeStatus

Each vantage point's current view of the service, taken from the most-recent minute that probe reported on, within a 5-minute lookback. A probe that has not reported inside that window is absent from the array rather than listed as unknown. Always an array, never null, and empty for a service with no recent measurements.

CheckSummary

One active check on a service. Published so that what is measured, and how, can be checked rather than taken on trust.

Fields of the CheckSummary object
Field Type Description
id required string

Stable check identifier, formed from the service id, the check type and the target it covers.

Example: aws-s3-us-east-1-http-main

check_type required string

Probe type. Currently one of http, tls, storage, dns. Typed as a string rather than an enum so adding a probe type stays a non-breaking change.

Example: http

target required string

What the probe hits: a URL, an IP and port, a hostname. The format depends on check_type.

Where the real target embeds a private identifier, such as a storage bucket name, the API substitutes a redacted placeholder of the same shape (for example https://redacted.s3.eu-west-1.amazonaws.com/probe.bin). The check is still described, down to the operation and the region, without publishing the identifier. Only the public wire shape is substituted; the probe hits the real target.

Example: https://s3.us-east-1.amazonaws.com/

interval_sec required integer

Probe cadence in seconds.

Example: 60

ProbeStatus

One vantage point's most-recent view of a service, returned inside ServiceDetail.probes.

Status uses the same vocabulary as the service-wide consensus (up, down, degraded) but is computed per probe, across the service's checks within the most-recent minute that probe reported on: up if every check succeeded, down if none did, degraded in between. There is no unknown, because a probe that has not reported inside the 5-minute lookback is absent from the array.

Fields of the ProbeStatus object
Field Type Description
probe_id required string

Stable probe identifier from the fleet registry, e.g. hzr-fsn1. Use it as the key when joining probes against probe metadata such as location and provider.

Example: hzr-fsn1

status required enum

Per-probe consensus across the service's checks within the most-recent reported minute. unknown is not valid here: a probe with no recent report is absent from the array entirely.

One of: up , down , degraded

Example: up

latency_ms required integer or null

p50 latency this probe observed in the most-recent minute, taken as the maximum across the service's checks, so a service whose HTTPS check is fast and TLS check is slow reports the slower number.

null when every measurement in that minute failed, which is a different case from the probe not reporting at all: that probe is absent from the array.

Example: 42

UptimePoint

One bucket on the uptime time series. Bucket size depends on the requested period (see /v1/services/{id}/uptime).

Fields of the UptimePoint object
Field Type Description
bucket required string (date-time)

Timestamp at the start of the bucket, UTC, RFC 3339.

Example: 2026-05-08T09:00:00Z

availability_pct required number

Percent of measured minutes in the bucket that were classified up. 0 when the bucket has no measured minutes (in which case status is unknown).

status required Status (enum)
down_minutes required integer

Count of minutes in the bucket with consensus down.

degraded_minutes required integer

Count of minutes in the bucket with consensus degraded.

latency_p50_ms required integer or null

Success-count-weighted p50 (median) response time, in milliseconds, across every check and probe pair inside the bucket. null when the bucket contained no successful measurement, so a chart should break the latency line there rather than plot a zero.

Example: 87

UptimeSummary

Rolled-up totals for the whole period. availability_pct is count-weighted across every measured minute (NOT an average of per-bucket percentages) so partial buckets don't get equal weight to full ones.

Fields of the UptimeSummary object
Field Type Description
availability_pct required number

100 * total_up / (total_up + total_down + total_degraded) across every measured minute in the period. 0 when no minute had measured data.

total_down_minutes required integer

Sum of down_minutes across every point.

total_degraded_minutes required integer

Sum of degraded_minutes across every point.

latency_p50_ms required integer or null

Success-count-weighted p50 response time, in milliseconds, across every successful measurement in the period. null when the period contained zero successful measurements. Useful as the headline "Average response time" for a service detail page.

Example: 142

UptimeSeries

Body of GET /v1/services/{id}/uptime.

Fields of the UptimeSeries object
Field Type Description
service_id required string

Echoed back from the path parameter.

Example: aws-s3-us-east-1

period required UptimePeriod (enum)
points required array of UptimePoint

Buckets in ascending bucket-time order. Always renders as a JSON array (never null); empty [] is valid for a service with no measurements yet.

summary required UptimeSummary

LeaderboardEntry

One ranked row in /v1/leaderboard.

Fields of the LeaderboardEntry object
Field Type Description
rank required integer

1-based, dense rank within this response. Tie-breaker is name ASC. Clients should NOT recompute rank; the server's tie-breaker is part of the methodology.

service_id required string

Slug-style identifier; cross-references /v1/services/{id}.

Example: aws-s3-us-east-1

name required string

Human-readable service name.

Example: AWS S3

category required Category (enum)
availability_pct required number

Average availability percent over the requested period. Services with no measurements collapse to 0 (paired with current_status: unknown).

current_status required Status (enum)
rank_change integer or null

Rank movement against the previous publication, positive for an improvement and negative for a decline. Always absent in v1, because historical leaderboard state is not persisted yet. The field appears once it is.

LeaderboardResponse

Body of GET /v1/leaderboard.

Fields of the LeaderboardResponse object
Field Type Description
period required LeaderboardPeriod (enum)
category Category (enum)

Echoed when a ?category= filter was applied; absent on the unfiltered call.

entries required array of LeaderboardEntry

Ranked rows, ordered by rank ASC. Always renders as a JSON array (never null); empty [] is valid after a category filter that matches no services.

generated_at required string (date-time)

Server wall-clock at response build time, UTC, RFC 3339. Useful for cache debugging, and for rendering an "as of" line alongside a ranking.

Example: 2026-05-08T09:00:00Z