Charts and Status Data API
The Charts API provides real-time chart data for your status page monitors, including response times, uptime history, and minute-level data for detailed visualizations.
Endpoints
Status Page Charts
GET https://statuspage.me/api/status/{slug}/charts
Returns aggregated chart data for all monitors on a status page.
Minute-Level Data
GET https://statuspage.me/api/status-page/{slug}/minute-data
Returns fine-grained minute-by-minute data for detailed charts.
Status Page Charts
Example Request
curl "https://statuspage.me/api/status/your-slug/charts"
Example Response
{
"monitors": [
{
"id": 123,
"name": "API Server",
"state": "up",
"avg_response_time_today": 142,
"hourly_data": [
{"hour": 0, "avg_response": 138, "uptime": 100},
{"hour": 1, "avg_response": 145, "uptime": 100},
{"hour": 2, "avg_response": 155, "uptime": 99.5}
],
"minute_data": [
{"minute": "2025-12-09T12:00:00Z", "response_time": 140, "status": "up"},
{"minute": "2025-12-09T12:01:00Z", "response_time": 142, "status": "up"}
],
"yesterday_hourly_data": [
{"hour": 0, "avg_response": 135, "uptime": 100}
]
}
],
"overall": "operational",
"globalDaily": [
{"date": "2025-12-09", "uptime": 99.95},
{"date": "2025-12-08", "uptime": 100}
],
"timestamp": 1733749200
}
Response Fields
Monitor Object
| Field | Type | Description |
|---|---|---|
id | integer | Monitor ID |
name | string | Monitor display name |
state | string | Current state: up, down, degraded |
avg_response_time_today | integer | Average response time in ms |
hourly_data | array | Hourly aggregated data |
minute_data | array | Minute-level data points |
yesterday_hourly_data | array | Yesterday’s hourly data |
Hourly Data Point
| Field | Type | Description |
|---|---|---|
hour | integer | Hour of day (0-23) |
avg_response | integer | Average response time (ms) |
uptime | float | Uptime percentage for that hour |
Minute Data Point
| Field | Type | Description |
|---|---|---|
minute | string | ISO 8601 timestamp |
response_time | integer | Response time in ms |
status | string | Status at that minute |
Minute-Level Data
For lazy-loading detailed charts without blocking initial page load.
Example Request
curl "https://statuspage.me/api/status-page/your-slug/minute-data"
Example Response
{
"monitors": [
{
"id": 123,
"minute_data": [
{"minute": "2025-12-09T11:00:00Z", "response_time": 138, "status": "up"},
{"minute": "2025-12-09T11:01:00Z", "response_time": 142, "status": "up"},
{"minute": "2025-12-09T11:02:00Z", "response_time": 510, "status": "degraded"},
{"minute": "2025-12-09T11:03:00Z", "response_time": 145, "status": "up"}
]
}
]
}
Private Status Pages
For private (password-protected) status pages, include the auth_token:
curl "https://statuspage.me/api/status-page/your-slug/minute-data?auth_token=your-token"
Configure the auth token in your status page settings.
JavaScript Chart Example
Using Chart.js to visualize response times:
async function loadResponseTimeChart(slug) {
const response = await fetch(`https://statuspage.me/api/status/${slug}/charts`);
const data = await response.json();
// Get first monitor's minute data
const monitor = data.monitors[0];
const labels = monitor.minute_data.map(d => new Date(d.minute).toLocaleTimeString());
const values = monitor.minute_data.map(d => d.response_time);
// Create Chart.js chart
new Chart(document.getElementById('response-chart'), {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Response Time (ms)',
data: values,
borderColor: '#10b981',
tension: 0.3
}]
},
options: {
responsive: true,
scales: {
y: { beginAtZero: true }
}
}
});
}
loadResponseTimeChart('your-slug');
Auto-Reload Implementation
Build a self-updating dashboard:
class StatusDashboard {
constructor(slug, refreshInterval = 30000) {
this.slug = slug;
this.refreshInterval = refreshInterval;
this.init();
}
async init() {
await this.update();
setInterval(() => this.update(), this.refreshInterval);
}
async update() {
try {
const response = await fetch(
`https://statuspage.me/api/status/${this.slug}/charts`
);
const data = await response.json();
this.updateOverallStatus(data.overall);
this.updateMonitors(data.monitors);
this.updateTimestamp(data.timestamp);
} catch (error) {
console.error('Failed to update dashboard:', error);
}
}
updateOverallStatus(status) {
const badge = document.getElementById('overall-status');
badge.className = `status-badge ${status}`;
badge.textContent = status.replace('_', ' ');
}
updateMonitors(monitors) {
monitors.forEach(monitor => {
const el = document.getElementById(`monitor-${monitor.id}`);
if (el) {
el.querySelector('.state').textContent = monitor.state;
el.querySelector('.response-time').textContent =
`${monitor.avg_response_time_today}ms`;
}
});
}
updateTimestamp(ts) {
document.getElementById('last-updated').textContent =
`Updated: ${new Date(ts * 1000).toLocaleTimeString()}`;
}
}
// Initialize dashboard
new StatusDashboard('your-slug', 30000);
Caching
- Responses include
Cache-Control: no-storefor real-time data - Don’t cache these responses for long periods
- Recommended polling: 15-60 seconds
Error Responses
| Status | Error | Cause |
|---|---|---|
| 404 | status page not found | Invalid slug |
| 403 | status page is blocked | Page was blocked by admin |
| 401 | auth required | Private page without token |
What’s Next?
- Embed Status API for simple status data
- Availability API for uptime metrics
- Live Widget for no-code embedding