Getting started
Agent Pong runs public status pages and the incident and maintenance management behind them. Built-in health checks keep component status and the 90-day history current, and the REST API lets the monitoring you already use drive everything. Agent Pong doesn’t send alerts or page anyone.
- Sign in at agentpong.com/login. New teams are set up by our team, so get in touch if you don’t have an account yet. Everyone on a team can manage all of its pages, incidents and health checks.
- Create a status page under Status pages: a title, a slug, your logo and accent colour.
- Add components, the parts of your product readers care about, such as “API” or “Dashboard”. Group them if you have many.
- Add health checks under Health checks and link them to components, so status and history fill in by themselves.
- Optional: create a team API key under Team so your monitoring or CI can open incidents and set component status.
When something goes wrong, press Declare incident on the dashboard overview. For planned work, use Schedule maintenance.
Status pages
A status page shows the overall status, active incidents, upcoming and in-progress maintenance, each component with its 90-day history, average response times and the incidents of the last 14 days. Every incident has its own permalink with the full timeline, and the history page lists older incidents and maintenance by month. A page can also show a “How we monitor” section that lists the health checks behind each component (see Page settings). See the live demo page.
Pages work without JavaScript. With it, times switch to the reader’s time zone and tooltips and groups become interactive. They are cached briefly, and the cache is cleared whenever an incident, maintenance window, component or page setting changes.
Addresses and domains
Every page is served at https://<slug>.agentpong.com, for example https://acme.agentpong.com. https://agentpong.com/s/<slug> redirects there. Slugs are lowercase letters, digits and dashes. A few names, such as www, app, api, status and docs, are reserved.
To use your own domain, such as status.example.com, enter it in the page settings and create a CNAME record pointing to the target shown there. Our team then activates the domain for you. Until then the page stays available at its agentpong.com address.
Components
- Name and description: the description appears as a tooltip next to the name.
- Group: components with the same group name are shown together under a collapsible heading. Order components with the up and down buttons.
- Linked health checks: one or more of your team’s health checks. Their results set the component’s status and fill in its history.
- Manual status: an override you set yourself, from the dashboard or with
PATCH /components/:id. Clear it to hand status back to incidents and health checks. - Show uptime: hide the 90-day bars for components where uptime isn’t meaningful.
How status is decided
A component’s status is the most severe of three sources:
- its manual status, if one is set;
- the impact given to it by active incidents and maintenance that is in progress;
- its linked health checks: major outage when all of them are confirmed down, partial outage when some are, degraded performance when a check that is up responded slower than its
max_latency_ms. Paused checks are ignored.
A component with nothing of the above is operational. From most to least severe: major outage, partial outage, degraded performance, under maintenance, operational.
The banner at the top of the page sums up all components:
| Banner | When |
|---|---|
| Major outage, Partial outage, Degraded performance | The most severe component status, when at least one component is degraded or worse. |
| Incident in progress | An incident is open, but every component is still operational. |
| Scheduled maintenance in progress | A maintenance window is in progress and nothing is worse. |
| All systems operational | Everything else. |
90-day history
Each component shows one bar per UTC day for the last 90 days (30 on small screens). A day’s colour comes from the uptime of its linked health checks, made more severe by any incident or maintenance that affected the component that day:
| Uptime that day | Colour |
|---|---|
| 100% | Operational |
| 99% or more | Degraded performance |
| 95% or more | Partial outage |
| Less than 95% | Major outage |
| No checks | No data (grey) |
Hover or focus a day to see its date, uptime and the incidents and maintenance that touched it, with links. The uptime percentage next to the component covers all 90 days. A failure that the confirmation check clears never counts against uptime.
A new page has no history yet. Until it has 90 days of data, the bars start at the first day with check data or an incident, the axis reads “History since <date>”, and the days before it are drawn as a thin line. Nothing is filled in.
Page settings
| Setting | What it does |
|---|---|
| Title, description | Shown in the header and used for the page’s metadata. |
| Logo, dark logo, favicon | Image URLs. The dark logo is used in dark mode. Without a logo the title is shown as a wordmark. |
| Accent colour | A hex colour for links and highlights. Status colours stay the same on every page so readers can rely on them. |
| Theme | auto (follows the reader’s system), light or dark. |
| Website, support link | Links in the page header. |
| Custom domain | See Addresses and domains. |
| Automatic incidents | Open and resolve incidents from health checks. On by default. See Automatic incidents. |
| Show response times | Show a chart of average response times per component for the last 24 hours or 7 days. When it is off, response times are also left out of “How we monitor” and of the checks in status.json. |
| Show “How we monitor” | Off by default. Adds a section listing the health checks behind each component: name, public description, what is asserted in plain words, interval, confirmation, the slow threshold, the current result (with the HTTP status code when it fails), the last 30 runs and 24-hour uptime. The URL a check calls (host, path, method), headers, request bodies, asserted values and error texts are never shown. A component that hides its uptime also hides its checks’ uptime. The same data appears in status.json. |
| Show “Powered by Agent Pong” | The footer credit. |
Incidents
An incident tells readers that something is wrong, which components are affected, and what you’re doing about it. Declare one from the dashboard overview, from an incident template, or with POST /incidents.
- Status moves through
investigating,identified,monitoringandresolved. Each update can change it. Posting a non-resolved status on a resolved incident reopens it. - Impact is the overall severity:
none,minor,majororcritical. If you don’t set it, it follows the most severe component impact. - Affected components each get an impact:
degraded,partial_outage,major_outageormaintenance. While the incident is open, the component shows at least that status. - Across pages: components can come from several of your status pages. The incident appears on every page that contains one of them, so a shared backend outage can show on several product pages at once. The form lists the pages it will appear on before you post.
- Resolving closes the incident with a final message (by default “This incident has been resolved.”) and moves it to the page’s history with its duration.
- Postmortem: after it is resolved, add a write-up in the same formatting as updates. It appears on the incident’s permalink.
- Corrections: edit or delete an update, change the title or impact, or delete the whole incident. Deleting an update doesn’t roll back the status.
Updates and formatting
Each update has a status, a message and the set of affected components at that moment. The timeline on the page shows updates newest first, each with its status and time. Messages support a small markdown subset:
| Write | Shows |
|---|---|
| A blank line | A new paragraph (a single line break is kept) |
- item or * item | A bulleted list |
**bold**, *italic* | bold, italic |
`code` | code |
[text](https://example.com) | A link (http, https and mailto only) |
Everything else is shown as plain text. HTML is never rendered. Messages can be up to 20,000 characters, titles up to 200.
Automatic incidents
When automatic incidents are on for a page and a health check linked to one of its components is confirmed down, the page opens an incident by itself:
- The title is “Component outage” when all of the component’s checks are down, or “Degraded service: Component” when only some are.
- It starts as
investigatingwith the update “We’re investigating elevated errors on Component.”, posted as Automated. - Each page has at most one open automatic incident. Further failing components are added to it with a short update.
- When all its checks pass again, it resolves itself with “This incident has been resolved. Service is operating normally.”, unless a person has already posted an update. Then it adds “Automated checks are passing again.” and leaves resolving to you.
Slow responses alone never open an incident. A health check linked to components on several pages opens one incident per page.
Templates
Templates store a name, a title, a message and an impact. Pick one in the Declare incident form to fill those fields in, then adjust before posting. Manage them under Templates.
Scheduled maintenance
Schedule a window under Maintenance with a title, a message, the affected components (impact maintenance by default) and a start and end time. You enter times in your local time zone; they are stored in UTC and shown to readers in theirs, with a countdown.
| Status | Meaning |
|---|---|
scheduled | Announced on the page as upcoming. Components aren’t affected yet. |
in_progress, verifying | Running. The components show Under maintenance (or the impact you chose). |
completed | Finished, or cancelled before it started. Cancelled windows don’t appear in the 90-day bars. |
With auto start on (the default), the window starts at its start time with the update “Scheduled maintenance is now in progress.” With auto complete on, it completes at its end time with “The scheduled maintenance has been completed.” You can also start, complete or cancel a window by hand and post updates while it runs. Windows can be up to 31 days long. Readers can subscribe to upcoming maintenance through the page’s iCal feed.
Health checks
Health checks feed component status and the 90-day history. There are two kinds:
- HTTP checks send a request to a URL on a schedule and check the response against your assertions.
- Heartbeat checks wait for your job to call them. If no ping arrives in time, the check is down. See Heartbeats.
Each check records the location it ran from when it is known. Choosing specific regions isn’t supported. Requests identify themselves with the user agent Agent Pong/0.1 (+https://agentpong.com/bot), so you can allow them through a firewall or exclude them from analytics. What the checker does, for the operators of the sites you check.
A health check is pending (no result yet), up, down or paused. Paused checks aren’t run and don’t affect component status. In the API, health checks are called monitors.
HTTP options
| Field | Default | Description |
|---|---|---|
url | required | An http:// or https:// URL. Private IP ranges, localhost, internal hostnames and URLs with embedded credentials are refused. |
method | GET | GET, HEAD, POST, PUT, PATCH, DELETE or OPTIONS. |
headers | {} | Up to 20 request headers, for example an authorization header. host, content-length, connection, transfer-encoding and user-agent are set automatically. |
body | none | Request body for POST, PUT, PATCH and similar methods, up to 16 KB. |
timeout_ms | 10000 | Give up after this many milliseconds (1,000 to 30,000). A timeout is a failed check. |
follow_redirects | true | Follow up to five redirects to the final response. Every hop must pass the same address rules as url. Set to false to assert on the redirect itself, for example expected_status: "301". |
Assertions
Each HTTP check is evaluated in a fixed order: status, keyword, JSON path. The first assertion that fails becomes the reason for the failed check.
Expected status
expected_status accepts single codes, ranges and classes, separated by commas. The default is 200-299.
| Value | Passes when the status is |
|---|---|
200-299 | any 2xx code |
2xx | the same, written as a class |
200,401 | exactly 200 or 401, useful for endpoints that should refuse anonymous requests |
2xx,301 | any 2xx code, or 301 |
Keyword
Set keyword to a string that must appear in the response body (keyword_mode: "contains", the default) or must not appear ("not_contains"). Matching is case-sensitive. The first 256 KB of the body is searched.
JSON path
Set json_path to a dotted path into a JSON response, with json_op and json_value to compare it. Paths look like data.status, items[0].id or list[-1] (negative indexes count from the end). A leading $. is optional.
json_op | Passes when the value at the path |
|---|---|
exists | is present (no json_value needed) |
eq | equals json_value |
neq | does not equal json_value |
gt | is a number greater than json_value |
lt | is a number less than json_value |
contains | contains json_value: a substring of a string, an item of an array or a key of an object |
A failure reads like JSON data.EUR: path not found. If the body isn’t valid JSON, the check fails with that reason.
Response time
max_latency_ms is a response-time budget, not an assertion. A slower response still passes, but while the latest response is over budget, linked components show degraded performance. Leave it empty to ignore response times.
# Fail unless the API reports a positive EUR rate; show degraded above 1 s
{
"url": "https://api.example.com/v1/rates?base=USD",
"expected_status": "200-299",
"json_path": "data.EUR",
"json_op": "gt",
"json_value": "0",
"max_latency_ms": 1000
}
Schedules and confirmation
HTTP checks run every interval_s seconds: 60, 120, 300, 600, 1800 or 3600. The default is one minute. Checks are spread across the minute so your endpoints don’t all get hit at the same second.
When a check fails, Agent Pong runs a confirmation check about fifteen seconds later instead of waiting for the next interval. The health check goes down only after confirm_count consecutive failures (1 to 5, default 2). A failure that the confirmation check clears stays visible in the recent checks, but it doesn’t count against uptime or the 90-day bars. Once an outage is confirmed, every failed check in it counts, including the first one.
Going down records the start of a down period with a snapshot of the failing response (status, selected headers, the first 2 KB of the body, latency and location), updates linked components and, if the page allows it, opens an automatic incident. The first successful check ends the down period.
Editing a health check schedules a check right away. You can also press Check now in the dashboard or call POST /monitors/:id/check.
Heartbeats
Heartbeat checks watch jobs that run on their own: backups, billing runs, queue workers, imports. Each one has a unique ping URL:
https://agentpong.com/hb/<token>
Send a GET, POST or HEAD request to it whenever the job finishes successfully. Two settings decide when a heartbeat is late:
interval_s: how often you expect a ping, from one minute to seven days.grace_s: extra time allowed, from zero to 24 hours (default 300 seconds).
If no ping arrives within interval_s + grace_s of the last one (or of creating the check), it goes down with the cause missed heartbeat. The next ping brings it back up.
# crontab: nightly backup at 03:00, ping only if it succeeded
0 3 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 --retry 3 https://agentpong.com/hb/<token> > /dev/null
# GitHub Actions
- name: Report to Agent Pong
if: success()
run: curl -fsS -m 10 --retry 3 "https://agentpong.com/hb/${{ secrets.AGENTPONG_HEARTBEAT }}"
Treat the ping URL as a secret. Anyone with it can mark the job as healthy.
Feeds, widget and badges
Every status page has machine-readable versions at its own address. None of them need authentication. Replace <page> with the page’s address, such as https://acme.agentpong.com or your custom domain.
| URL | Returns |
|---|---|
<page>/status.json | The page, its overall status, components with 90 days of history, active incidents with their updates, and upcoming maintenance. CORS is open, so you can fetch it from a browser. Also at agentpong.com/s/<slug>.json. |
<page>/feed.atom | An Atom feed of incidents and maintenance. |
<page>/maintenance.ics | An iCal feed of maintenance windows for calendar apps. |
<page>/widget.js | A small script that adds a status pill linking to the page. |
agentpong.com/badge/page/<slug>.svg | An SVG badge with the page’s overall status. |
The “Subscribe to updates” menu on each page lists these links and the embed snippet. The page and its feeds are cached for up to 15 seconds.
status.json
curl -s https://acme.agentpong.com/status.json
{
"page": { "slug": "acme", "title": "Acme Status", "url": "https://acme.agentpong.com", ... },
"status": { "indicator": "degraded", "description": "Degraded performance" },
"components": [
{ "id": "cmpPay7Rk2Qa", "name": "Payments API", "group": "API",
"status": "degraded", "status_label": "Degraded performance",
"uptime_90d": "99.91", "latency_ms": 212,
"days": [ { "date": "2026-07-15", "status": "operational", "uptime": "100.00", "incidents": [] }, ... ] }
],
"active_incidents": [
{ "id": "incQ2v8Lm0Xc", "title": "Elevated error rates on the Payments API", "impact": "minor",
"status": "monitoring", "started_at": 1791861120, "url": "https://acme.agentpong.com/incidents/incQ2v8Lm0Xc",
"components": [ { "id": "cmpPay7Rk2Qa", "name": "Payments API", "impact": "degraded" } ],
"updates": [ { "status": "monitoring", "body": "...", "body_html": "<p>...</p>", "created_at": 1791864720 } ] }
],
"maintenance": [],
"generated_at": 1791864840
}
status.indicator:operational,degraded,partial_outage,major_outage,maintenanceorincident.- Component
status:operational,degraded,partial_outage,major_outageormaintenance. Daystatuscan also benodata. daysalways has 90 entries, oldest first, by UTC date. All timestamps are Unix seconds.
Health checks in status.json
When the page shows “How we monitor”, every component also has a checks array and the document gets a checks_summary object (checks, components, min_interval_s, max_interval_s, description). Each check has:
| Field | Description |
|---|---|
id | An opaque ID that stays the same for this check on this page. It is not the monitor ID from the API. |
name, description | The check’s name (without the page’s product name in front) and its public description, or null |
type | http or heartbeat |
verifies | What the check asserts, in plain words (“Expects HTTP 200 and the expected text in the response body”). The asserted values themselves are not included. |
interval_s, confirm_count, max_latency_ms | Schedule, confirmations and the slow threshold (null when none) |
result, result_label | pass, slow, fail, pending or paused, and a label such as “Failing” or “Failed, re-checking” |
last_checked_at | Unix seconds, or null |
last_status_code | HTTP status code of the latest run; null when no response arrived, and for heartbeats |
last_latency_ms | Response time of the latest run; null for heartbeats and when the page hides response times |
uptime_24h | Uptime over the last 24 hours ("99.95"); null without data or when the component hides its uptime |
Widget
Add one script tag where the pill should appear, for example in your footer. It shows the page’s current status and links to the page. It has no dependencies and makes no extra requests.
<script src="https://acme.agentpong.com/widget.js" async></script>
<!-- Optional: force a theme, or place the pill inside another element -->
<script src="https://acme.agentpong.com/widget.js" data-theme="dark" data-target="#footer-status" async></script>
data-theme is auto (default, follows the visitor’s system), light or dark. data-target is a CSS selector; without it the pill appears right after the script tag.
Badges
Options, as query parameters: label sets the text on the left (default status), and style is flat (default) or flat-square.
<!-- README.md -->


REST API
The API lives at https://agentpong.com/api/v1. It takes and returns JSON and covers incidents, status pages, components and health checks. Use it to let your monitoring, CI or deploy scripts drive your status pages.
Authentication
Create an API key under Team. Keys act on your team’s pages, incidents and health checks. They look like ap_live_ followed by 32 characters. The key is shown once; we store only a hash. Send it as a bearer token:
curl https://agentpong.com/api/v1/pages \
-H "Authorization: Bearer ap_live_..."
Revoke a key and it stops working immediately. Keys are also revoked when the account that created them is deleted.
Responses
Successful responses wrap their result in data: an object for single resources, an array for lists. Request bodies must be sent with content-type: application/json. Timestamps are Unix seconds.
{ "data": { "id": "incQ2v8Lm0Xc", "title": "Elevated error rates on the Payments API", "status": "investigating", ... } }
Errors
Errors use standard HTTP status codes and a consistent body. Validation errors on health checks also list the problem for each field:
{ "error": { "code": "not_found", "message": "Incident not found" } }
{ "error": {
"code": "validation_failed",
"message": "confirm_count: Confirmations must be between 1 and 5.",
"fields": { "confirm_count": "Confirmations must be between 1 and 5." }
} }
| Code | Status | Meaning |
|---|---|---|
bad_request | 400 | The body isn’t a JSON object, contains unknown fields, or a value is invalid. |
unauthorized | 401 | Missing, malformed or revoked API key. |
limit_reached | 403 | Your team has reached a resource limit. Contact us to raise it. |
not_found | 404 | The resource doesn’t exist or doesn’t belong to your team. |
conflict | 409 | The action doesn’t fit the current state, for example starting maintenance that already started. |
unsupported_media_type | 415 | The request body wasn’t sent as application/json. |
validation_failed | 422 | One or more health check fields are invalid. See fields. |
internal_error | 500 | Something went wrong on our side. |
Incidents and maintenance
Incidents and maintenance windows share one object: id, kind (incident or maintenance), title, status, impact, automatic (opened by a health check), started_at, resolved_at, scheduled_start, scheduled_end, auto_start, auto_complete, cancelled, postmortem, its components (each with id, name, impact and the page slug), the pages it appears on (with public url on single incidents), latest_update, and on single incidents all updates, newest first. Times can be sent as Unix seconds or as ISO 8601 timestamps with a time zone.
List your team’s incidents and maintenance, newest first. Query parameters: filter (active, resolved, maintenance or all, the default), q to search titles, limit (1 to 100, default 25) and offset. The response also has total, limit and offset for paging.
Declare an incident. It appears right away on every page that contains one of its components.
| Field | Description |
|---|---|
title | Required. Up to 200 characters. |
body | Required. The first update, in the markdown subset. |
components | Array of { "component_id", "impact" }, with impact degraded, partial_outage, major_outage or maintenance. Components can come from any of your pages. |
status | investigating (default), identified, monitoring or resolved. |
impact | none, minor, major or critical. Defaults to the most severe component impact. |
started_at | When it began, if earlier than now. |
curl https://agentpong.com/api/v1/incidents \
-H "Authorization: Bearer $AGENTPONG_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Elevated error rates on the Payments API",
"body": "Some card payments are failing. We are investigating.",
"components": [{ "component_id": "cmpPay7Rk2Qa", "impact": "degraded" }]
}'
Returns 201 with the new incident in data.
To schedule maintenance instead, send "kind": "maintenance" with title, body, components, scheduled_start and scheduled_end, and optionally auto_start and auto_complete (both true by default). Component impact defaults to maintenance.
curl https://agentpong.com/api/v1/incidents \
-H "Authorization: Bearer $AGENTPONG_KEY" \
-H "Content-Type: application/json" \
-d '{
"kind": "maintenance",
"title": "Database upgrade",
"body": "Writes may be delayed by up to a minute.",
"components": [{ "component_id": "cmpPay7Rk2Qa" }],
"scheduled_start": "2026-10-18T02:00:00Z",
"scheduled_end": "2026-10-18T03:00:00Z"
}'
One incident with its components, full timeline and the pages it appears on.
Change title, impact or started_at; for maintenance also scheduled_start, scheduled_end, auto_start and auto_complete. Set postmortem to markdown, or to null to clear it. No update is posted to the timeline.
Delete the incident and its updates from every page. Returns {"data": {"id": "...", "deleted": true}}. This can’t be undone.
Post an update. body is required. status keeps the current status if you leave it out. impact changes the overall impact. components, if given, replaces the set of affected components and their impacts; send an empty array to clear it. Returns 201 with the updated incident.
curl https://agentpong.com/api/v1/incidents/incQ2v8Lm0Xc/updates \
-H "Authorization: Bearer $AGENTPONG_KEY" \
-H "Content-Type: application/json" \
-d '{ "status": "identified", "body": "A configuration change caused timeouts. Rolling back." }'
Resolve with an optional final body (default “This incident has been resolved.”). For maintenance, this completes the window. Returns 409 if it is already resolved.
Start a scheduled maintenance window now, or cancel it before it starts, with an optional body. Returns 409 if the window has already moved on.
Pages and components
Your team’s status pages with their slug, title, public url, settings and current overall status.
The live state of one page: its settings and overall status, components (each with id, status, manual_status and the status from its health checks), active_incidents and maintenance. This is where you find component IDs for the calls above.
Set manual_status to operational, degraded, partial_outage, major_outage or maintenance, or to null to clear the override. The page updates right away. Useful when another tool already knows a component’s state:
curl -X PATCH https://agentpong.com/api/v1/components/cmpPay7Rk2Qa \
-H "Authorization: Bearer $AGENTPONG_KEY" \
-H "Content-Type: application/json" \
-d '{ "manual_status": "partial_outage" }'
Health checks
Health checks are monitors in the API. A monitor has the fields described in HTTP options, Assertions and Heartbeats, plus read-only state:
| Field | Description |
|---|---|
id | Monitor ID |
name, type | Display name; http or heartbeat |
description | Optional, up to 300 characters, writable. A plain-language note on what the check proves. It is public: status pages that show “How we monitor” display it next to the check, and status.json includes it. |
status, paused | pending, up, down or paused; whether checks are paused |
interval_s, confirm_count | Schedule and confirmations |
heartbeat_url, grace_s, last_ping_at | Heartbeat checks only |
last_checked_at, last_status_code, last_latency_ms, last_error | The most recent result |
fail_streak | Consecutive failed checks |
created_at | Unix seconds |
List your team’s health checks.
Create a health check. name is required, plus url for HTTP checks. Unknown fields are rejected so typos don’t pass silently. The first check runs within a minute. Link it to a component in the dashboard.
curl https://agentpong.com/api/v1/monitors \
-H "Authorization: Bearer $AGENTPONG_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Checkout API",
"type": "http",
"url": "https://api.example.com/v1/health",
"expected_status": "200",
"keyword": "\"ok\":true",
"max_latency_ms": 800,
"interval_s": 60,
"confirm_count": 2
}'
# A heartbeat check that expects a ping every hour, with 10 minutes' grace
curl https://agentpong.com/api/v1/monitors \
-H "Authorization: Bearer $AGENTPONG_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Hourly import", "type": "heartbeat", "interval_s": 3600, "grace_s": 600 }'
Returns 201 with the new monitor in data. For heartbeats, give your job its heartbeat_url.
One monitor, with an extra uptime object holding the uptime percentage for 24h, 7d, 30d and 90d (null where there is no data yet).
Change any writable field except type. Fields you leave out keep their values. A check is scheduled right away.
Delete a monitor with its results, and unlink it from its components. Returns {"data": {"id": "...", "deleted": true}}. This can’t be undone.
Pause stops checks and sets the status to paused, so it no longer affects components. Resume sets it back to pending and checks again within a minute.
Queue an immediate check of an HTTP monitor. Returns 202 with {"data": {"id": "...", "queued": true}}.
Recent check results, newest first. limit is 1 to 1,000 (default 100). Each has ts, ok, status_code, latency_ms, error and colo (the location the check ran from, when known). Individual results are kept for seven days.
The latest 50 down periods, newest first, with started_at, resolved_at, cause and the response snapshot.
Limits
| What | Limit |
|---|---|
| Fastest HTTP check interval | Every minute |
| Request timeout | 1 to 30 seconds (default 10) |
| Response body read for keyword and JSON assertions | First 256 KB |
| Request body | 16 KB |
| Custom request headers | 20 per health check |
| Confirmations before down | 1 to 5 |
| Heartbeat period | 1 minute to 7 days, plus up to 24 hours’ grace |
| Incident title / update message / postmortem | 200 / 20,000 / 50,000 characters |
| Maintenance window | Up to 31 days |
| Raw check results | Kept 7 days |
| Hourly summaries (uptime history) | Kept while the health check exists |
| Status pages, components and health checks | Set per team. Contact us if you need more. |
Questions this page doesn’t answer? Contact us.