Browse the documentation

Status page API

The status page has its own API, separate from your account's. It runs on its own domain and its own database, so it keeps answering when the rest of the platform does not.

The status APIDetail
Base URLhttps://status-api.freshperf.fr/api/v1
Authenticationnone. No key, no header
MethodsGET only
Reachthe platform's public state, never your services or your account
Detailed referencestatus.freshperf.fr/en-us/api, with a try-it console

The account API's permissions, its {"data": ...} envelope, its cursors and its error markers do not apply here. This API has its own, shorter conventions.

Conventions

  • Translated fields: always both languages, {"en": "...", "fr": "..."}. There is no language parameter.
  • Timestamps: epoch milliseconds, UTC.
  • Errors: a marker alone, {"error": "NOT_FOUND"} or {"error": "VALIDATION_FAILED", "field": "range"}. Statuses 400 and 404.
  • No envelope: the response is the object itself, with no data around it.
  • Cache: the summary is computed at most every 30 seconds server-side. Polling faster returns the same content.
  • CORS: only the status page's own origins are allowed. From a server, CORS does not apply.

A rate limit guards against bursts of failing calls; a client getting 200 responses does not meet it. Polling every 30 to 60 seconds is enough.

GET /status

The shortest summary. This is what a badge or a probe needs.

curl https://status-api.freshperf.fr/api/v1/status
{
  "overall": "operational",
  "updatedAt": 1787921863099,
  "servicesUp": 5,
  "servicesDown": 0,
  "activeIncidents": 0,
  "activeMaintenances": 1
}
FieldTypeNotes
overallstringoperational, degraded_performance, partial_outage, major_outage, maintenance
updatedAtintegerepoch milliseconds
servicesUp, servicesDownintegermonitored services in each state
activeIncidents, activeMaintenancesintegercounts. The detail is in /summary

overall is derived in this order: at least one service down gives partial_outage, or major_outage when half or more are; otherwise the worst active incident decides; otherwise a maintenance in progress gives maintenance; otherwise operational.

GET /summary

Everything the home page shows, in one call.

{
  "overall": "operational",
  "updatedAt": 1787921863099,
  "servicesUp": 5,
  "servicesDown": 0,
  "groups": [
    {
      "slug": "web",
      "name": { "en": "Websites", "fr": "Sites" },
      "description": null,
      "services": [
        {
          "slug": "freshperf",
          "name": { "en": "freshperf.fr", "fr": "freshperf.fr" },
          "description": null,
          "status": "up",
          "lastCheckAt": 1787921836639,
          "latencyMs": 164,
          "uptime90d": 99.956,
          "days": [ { "date": "2026-05-31", "uptimePct": 100.0, "state": "ok" } ]
        }
      ]
    }
  ],
  "activeIncidents": [],
  "maintenance": []
}
Service fieldTypeNotes
slugstringthe identifier to pass to /services/{slug}/metrics
statusstringup, down, unknown
lastCheckAtinteger or nullepoch milliseconds of the last probe
latencyMsinteger or nulllatency of the last probe
uptime90dnumber or null90-day uptime, weighted by the number of probes
days[]arrayone object per day, oldest first
days[].datestringYYYY-MM-DD, UTC
days[].uptimePctnumber or nullnull when that day has no probe
days[].statestringok (≥ 99.5%), degraded (≥ 95%), down, no_data

activeIncidents holds the same objects as /incidents, maintenance the same as /maintenance. Disabled groups and services are never listed.

GET /services/{slug}/metrics

ParameterTypeRequiredValuesWhere it comes from
slugpathyes-/summarygroups[].services[].slug
rangequeryno, default 24h24h, 7d, 90d-
curl "https://status-api.freshperf.fr/api/v1/services/freshperf/metrics?range=7d"
{
  "slug": "freshperf",
  "range": "7d",
  "points": [ { "t": 1787835687488, "latencyMs": 149, "uptimePct": 100.0 } ]
}
rangeSourcePoints
24h, 7dthe raw probes, grouped into buckets200 at most, buckets of at least a minute
90dthe daily rollupsone per day, up to 90

t is the middle of the bucket, in epoch milliseconds. latencyMs and uptimePct are null when the bucket holds no usable probe.

ErrorStatus
{"error": "VALIDATION_FAILED", "field": "range"}400
{"error": "NOT_FOUND"}404, unknown slug or disabled service

GET /incidents

ParameterTypeRequiredValues
statequeryno, default allall, active, resolved
pagequeryno, default 0page index, zero-based
pageSizequeryno, default 101 to 50
{
  "items": [
    {
      "id": 12,
      "severity": "major",
      "status": "resolved",
      "title": { "en": "Elevated error rate", "fr": "Taux d'erreurs élevé" },
      "affectedServiceIds": [3],
      "startedAt": 1787440000000,
      "resolvedAt": 1787452000000
    }
  ],
  "page": 0,
  "pageSize": 10,
  "total": 1
}
FieldTypeNotes
severitystringminor, major, critical
statusstringinvestigating, identified, monitoring, resolved
affectedServiceIdsarray of integersinternal ids of the services hit. These are not the slug values
resolvedAtinteger or nullnull while the incident is open

With state=active the list is not paginated: page and pageSize are ignored, and total is the number of incidents returned.

GET /incidents/{id}

One incident and its full timeline, newest update first.

{
  "id": 12,
  "severity": "major",
  "status": "resolved",
  "title": { "en": "Elevated error rate", "fr": "Taux d'erreurs élevé" },
  "affectedServiceIds": [3],
  "startedAt": 1787440000000,
  "resolvedAt": 1787452000000,
  "updates": [
    {
      "status": "resolved",
      "body": { "en": "Incident resolved.", "fr": "Incident résolu." },
      "createdAt": 1787452000000
    }
  ]
}

Unknown id: 404 {"error": "NOT_FOUND"}.

GET /maintenance

ParameterTypeRequiredValues
windowqueryno, default upcomingupcoming, past, all
pagequeryno, default 0page index, zero-based. Honoured with past only
pageSizequeryno, default 101 to 50. Same rule
{
  "items": [
    {
      "id": 4,
      "title": { "en": "Database upgrade", "fr": "Mise à niveau base de données" },
      "body": { "en": "Planned upgrade.", "fr": "Mise à niveau planifiée." },
      "scheduledStart": 1787620000000,
      "scheduledEnd": 1787627200000,
      "affectedServiceIds": [1, 3],
      "state": "upcoming"
    }
  ],
  "window": "upcoming"
}

The response carries no page, pageSize or total.

windowContentsOrder
upcomingwindows that have not ended, cancelled ones excludedstart ascending
pastwindows that have endedstart descending, paginated
allall of them, cancelled includedstart descending

state is derived from the current time: cancelled, then upcoming, in_progress or completed.

Going further

status.freshperf.fr/en-us/api renders the same reference with a console to run each call from the page.

    Status page API | FreshPerf