Skip to content
Learni
View all tutorials
DevOps

How to Automate StatusPage with Its API in 2026

Lire en français

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_ID and STATUSPAGE_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

setup.sh
#!/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 dist

This 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

src/list-components.ts
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

src/update-component.ts
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

src/create-incident.ts
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

src/push-metric.ts
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

src/webhook-server.ts
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.