Introduction
StatusPage.io is the go-to tool for publishing real-time service status updates, preventing support ticket spam during incidents. In 2026, with the rise of cloud-native stacks, automating StatusPage via its REST API is essential for integrating monitoring into CI/CD pipelines, PagerDuty alerts, or Grafana observability.
This intermediate tutorial walks you through creating functional TypeScript scripts to list pages, update components, publish incidents, and push metrics. Imagine a GitHub Actions deployment that automatically creates an incident during downtime. Every step includes complete, copy-paste-ready code with error handling. By the end, you'll master the API to scale your DevOps operations. Ready to turn your status pages into proactive systems? (128 words)
Prerequisites
- Active StatusPage.io account with an existing page (create a free one at statuspage.io).
- API token from Account Settings > API > Your pages > API tokens (read/write).
- Node.js 20+ installed.
- Basic knowledge of TypeScript and the Fetch API.
- Page ID (e.g.,
abc123xyz) and token stored in environment variables (STATUSPAGE_PAGE_IDandSTATUSPAGE_TOKEN).
Initialize the Node.js Project
Create a dedicated scripts directory to test the API. Use npm init for a minimal setup. Store secrets in a .env file (install dotenv). This project will serve as the base for all subsequent scripts, avoiding redundancy.
Project Initialization
#!/bin/bash
mkdir statuspage-automation
cd statuspage-automation
npm init -y
npm install typescript @types/node dotenv ts-node
npx tsc --init --target es2022 --module commonjs --outDir dist --rootDir src
mkdir src
echo "STATUSPAGE_PAGE_ID=your_page_id_here
STATUSPAGE_TOKEN=your_token_here" > .env
mkdir distThis Bash script sets up a ready-to-use TypeScript project with dotenv for secrets. It configures tsconfig.json for ES2022 and CommonJS, compatible with Node 20+. Run it for a 30-second setup; adjust paths if needed.
List Components on a Page
Start by validating your API access by listing the components on your page. The /pages/{page_id}/components.json endpoint returns all tracked services. This confirms your token and identifies IDs for later updates.
List Components Script
import 'dotenv/config';
import fetch from 'node-fetch';
const PAGE_ID = process.env.STATUSPAGE_PAGE_ID!;
const TOKEN = process.env.STATUSPAGE_TOKEN!;
const BASE_URL = 'https://api.statuspage.io/v1';
async function listComponents() {
try {
const response = await fetch(`${BASE_URL}/pages/${PAGE_ID}/components.json`, {
headers: {
'Authorization': `OAuth ${TOKEN}`,
'X-Requested-With': 'XMLHttpRequest'
}
});
if (!response.ok) throw new Error(`Erreur HTTP: ${response.status}`);
const data = await response.json();
console.log('Composants:', data);
} catch (error) {
console.error('Erreur:', error);
}
}
listComponents();This script fetches the API with OAuth authentication and required headers. It handles basic HTTP errors and logs the JSON response. Run with npx ts-node src/list-components.ts after filling .env; replace PAGE_ID with yours to see your components.
Update a Component's Status
Components represent your services (API, DB, etc.). Set them to 'major_outage' during alerts to notify users instantly. Use PUT on /components/{component_id}. Get the ID from the previous script.
Update a Component
import 'dotenv/config';
import fetch from 'node-fetch';
const PAGE_ID = process.env.STATUSPAGE_PAGE_ID!;
const TOKEN = process.env.STATUSPAGE_TOKEN!;
const BASE_URL = 'https://api.statuspage.io/v1';
const COMPONENT_ID = 'your_component_id_here'; // Remplacez par ID réel
const status = 'major_outage'; // Options: operational, minor, major_outage, under_maintenance
async function updateComponent() {
try {
const response = await fetch(`${BASE_URL}/pages/${PAGE_ID}/components/${COMPONENT_ID}.json`, {
method: 'PUT',
headers: {
'Authorization': `OAuth ${TOKEN}`,
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/json'
},
body: JSON.stringify({ component: { status } })
});
if (!response.ok) throw new Error(`Erreur: ${response.status}`);
const data = await response.json();
console.log('Composant mis à jour:', data);
} catch (error) {
console.error('Erreur:', error);
}
}
updateComponent();This code sends a PUT request with JSON payload to change the status. Valid values are listed in the comment. Test carefully in production; it will trigger RSS/email/Slack subscribers. Add pre-checks for production use.
Publish an Incident
Incidents are temporary events with updates. Create one for planned or unplanned downtime via POST /incidents.json. Add 'wants_twitter', 'wants_email' for channels.
Create an Incident
import 'dotenv/config';
import fetch from 'node-fetch';
const PAGE_ID = process.env.STATUSPAGE_PAGE_ID!;
const TOKEN = process.env.STATUSPAGE_TOKEN!;
const BASE_URL = 'https://api.statuspage.io/v1';
async function createIncident() {
try {
const response = await fetch(`${BASE_URL}/pages/${PAGE_ID}/incidents.json`, {
method: 'POST',
headers: {
'Authorization': `OAuth ${TOKEN}`,
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/json'
},
body: JSON.stringify({
incident: {
name: 'Déploiement API v2.1',
status: 'investigating',
message: 'Déploiement en cours, impacts mineurs possibles.',
wants_twitter: false,
wants_email: true,
wants_sms: false,
wants_webhooks: true,
wants_stickies: false
}
})
});
if (!response.ok) throw new Error(`Erreur: ${response.status}`);
const data = await response.json();
console.log('Incident créé:', data.id);
} catch (error) {
console.error('Erreur:', error);
}
}
createIncident();Full payload for an 'investigating' incident. Customize name/message/status (investigating, identified, watching, resolved). This activates configured notifications. The returned ID is for future updates.
Push Custom Metrics
StatusPage supports graphs via metrics. Set one up in the UI (Graph Settings), then push data points via POST /pages/{page_id}/metrics/{metric_id}/data_points.json. Perfect for latency from UptimeRobot.
Push a Metric
import 'dotenv/config';
import fetch from 'node-fetch';
const PAGE_ID = process.env.STATUSPAGE_PAGE_ID!;
const TOKEN = process.env.STATUSPAGE_TOKEN!;
const BASE_URL = 'https://api.statuspage.io/v1';
const METRIC_ID = 'your_metric_id_here'; // Créez en UI d'abord
time = new Date().toISOString();
value = 150.5; // Ex: timestamp, latency ms
async function pushMetric() {
try {
const response = await fetch(`${BASE_URL}/pages/${PAGE_ID}/metrics/${METRIC_ID}/data_points.json`, {
method: 'POST',
headers: {
'Authorization': `OAuth ${TOKEN}`,
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/json'
},
body: JSON.stringify([
{
timestamp: timestamp,
value: value
}
])
});
if (!response.ok) throw new Error(`Erreur: ${response.status}`);
console.log('Métrique poussée avec succès');
} catch (error) {
console.error('Erreur:', error);
}
}
pushMetric();Array of points for efficient batching. Use ISO8601 timestamp and numeric value. Create the metric in the UI first (e.g., 'API Latency'). Ideal for cron jobs or observability webhooks.
Receive StatusPage Webhooks
Set up webhooks in the UI to receive updates (incident created/resolved). Here's a basic Express endpoint to log/validate. Integrate with Slack or a database.
Express Webhook Server
import express from 'express';
import 'dotenv/config';
const app = express();
app.use(express.json());
app.post('/statuspage-webhook', (req, res) => {
console.log('Webhook reçu:', JSON.stringify(req.body, null, 2));
const event = req.body.event || 'unknown';
if (event === 'incident_created') {
console.log('Nouvel incident:', req.body.data);
// Intégrez PagerDuty/Slack ici
}
res.status(200).json({ status: 'received' });
});
const PORT = 3000;
app.listen(PORT, () => console.log(`Webhook listener on port ${PORT}`));Minimal Express server for /statuspage-webhook. Logs payloads and filters events. Add npm i express @types/express; run with npx ts-node. Secure with HMAC in production.
Best Practices
- Use environment variables for tokens: never hardcode them; integrate with GitHub Secrets for CI/CD.
- Rate limiting: API limited to 300 req/min; add delays or queues for bursts.
- Idempotence: Check existing status before updates to avoid loops.
- Structured logging: Use Winston or console.table to trace API calls.
- Unit tests: Mock fetch with MSW to validate payloads without real calls.
Common Errors to Avoid
- Missing X-Requested-With header: Returns 401 Unauthorized; always include it.
- Insufficient token scopes: Create a 'read+write' token per page, not global if sensitive.
- Malformed timestamps for metrics: Use strict ISO8601, UTC.
- No async/await handling: Always use try/catch for fetch promises.
Next Steps
- Official docs: StatusPage API.
- Integrate with Terraform: Use the StatusPage provider for IaC.
- Self-hosted alternatives: Cachet or Upptime (GitHub).
- Discover our DevOps trainings at Learni to master advanced monitoring with Prometheus/Grafana.