Docs / API and integrations
API
The API speaks JSON over HTTPS. Everything here is also described in an OpenAPI 3.1 spec, ready for Postman, Insomnia or a generated client.
#Authentication
The account owner creates keys under Account → API keys. Send one with every request:
curl https://pulsefast.io/api/v1/monitors -H "Authorization: Bearer $PULSEFAST_API_KEY"
A key works for the whole account. It's shown once, so store it in your secret manager. Delete it from the same page to revoke it.
#Errors and limits
Errors come back as {"error": "…"}, with a message meant for people:
| Status | Meaning |
|---|---|
400 |
Malformed JSON, or a field the API doesn't know (typos are caught, not ignored). |
401 |
Missing or wrong key. |
402 |
Your plan's limit is reached, e.g. its number of monitors. |
404 |
Doesn't exist, or isn't yours. |
422 |
A value isn't valid; the message says which. |
429 |
Over 120 requests a minute for the account. Wait for the Retry-After seconds. |
#Endpoints
| Method and path | What it does |
|---|---|
GET /api/v1/monitors |
List monitors, with status and 24-hour uptime |
POST /api/v1/monitors |
Create a monitor |
GET /api/v1/monitors/{id} |
Get one |
PATCH /api/v1/monitors/{id} |
Change some fields |
DELETE /api/v1/monitors/{id} |
Delete it and its history |
GET /api/v1/monitors/{id}/incidents |
Its incidents |
GET /api/v1/maintenance |
List maintenance windows |
POST /api/v1/maintenance |
Start or schedule one |
DELETE /api/v1/maintenance/{id} |
End or cancel one |
POST /api/v1/deploys |
Record a deploy |
GET /api/v1/deploys |
Recent deploys |
GET /api/v1/channels |
Alert channel IDs |
GET /api/v1/status-pages |
Status pages |
Endpoints your systems call without an API key are covered elsewhere:
- Heartbeats (
/hb/{token}): see Monitor cron jobs. - Alert intake (
/in/{token}): see Alert sources. - Agent callbacks (
/v1/dispatches/{id}/status): see Agent on-call.
All of them are in the OpenAPI spec.
#Monitors
#List
GET /api/v1/monitors
{
"monitors": [
{
"id": 12,
"name": "API",
"type": "http",
"url": "https://api.example.com/health",
"interval_seconds": 30,
"timeout_seconds": 10,
"retries": 1,
"method": "GET",
"header_names": ["Authorization"],
"keyword": "ok",
"ssl_warn_days": 14,
"remind_seconds": 0,
"paused": false,
"channel_ids": [3, 4],
"status": "up",
"uptime_24h": 0.9998,
"created_at": "2026-10-01T09:00:00Z"
}
]
}
status is up, down, pending, unknown, paused or suspended (over your plan's limit). Header values are never returned. Heartbeat monitors have heartbeat_url and grace_seconds instead of url.
#Get
GET /api/v1/monitors/{id}
#Create
POST /api/v1/monitors
curl -X POST https://pulsefast.io/api/v1/monitors \
-H "Authorization: Bearer $PULSEFAST_API_KEY" \
-d '{
"name": "Checkout API",
"url": "https://api.example.com/v1/health",
"interval_seconds": 30,
"method": "POST",
"headers": [{"name": "Authorization", "value": "Bearer …"}, {"name": "Content-Type", "value": "application/json"}],
"body": "{\"ping\": true}",
"keyword": "\"status\":\"error\"",
"keyword_absent": true,
"channel_ids": [3]
}'
| Field | Notes |
|---|---|
type |
http (default), port or heartbeat. Can't be changed later. |
name |
Required, up to 80 characters. |
url |
http monitors: a full URL. port monitors: host:port. |
interval_seconds |
http/port: 5, 10, 30, 60, 120, 300, 600, 900, 1800 or 3600, no faster than your plan. heartbeat: 60, 300, 900, 1800, 3600, 21600, 43200, 86400 or 604800. |
timeout_seconds |
1–30. |
grace_seconds |
heartbeat: 60, 300, 900, 1800, 3600 or 21600. |
retries |
0–5. |
method, headers, body |
http only. Body up to 16 KB, not with GET or HEAD. |
keyword, keyword_absent |
http only. With keyword_absent: true, the keyword must not appear. |
expect_status |
List of status codes; empty means any 2xx/3xx. |
ssl_warn_days |
0–90; 0 turns it off. |
remind_seconds |
0 (alert once), 300, 600, 900, 1800, 3600, 7200 or 21600. |
channel_ids |
Channels to alert, from GET /api/v1/channels. |
paused |
true to stop checks and alerts. |
Returns 201 with the monitor. Fields you leave out get your plan's defaults: its fastest interval, a timeout, and retries.
The same request from code:
// Node 18+ or the browser
const res = await fetch("https://pulsefast.io/api/v1/monitors", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.PULSEFAST_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ name: "Checkout API", url: "https://api.example.com/v1/health", interval_seconds: 30 }),
});
if (!res.ok) throw new Error((await res.json()).error);
const monitor = await res.json();
import os, requests
res = requests.post(
"https://pulsefast.io/api/v1/monitors",
headers={"Authorization": f"Bearer {os.environ['PULSEFAST_API_KEY']}"},
json={"name": "Checkout API", "url": "https://api.example.com/v1/health", "interval_seconds": 30},
)
res.raise_for_status()
monitor = res.json()
#Update
PATCH /api/v1/monitors/{id} changes only the fields you send. Sending "headers": [] removes saved headers; leaving headers out keeps them.
curl -X PATCH https://pulsefast.io/api/v1/monitors/12 \
-H "Authorization: Bearer $PULSEFAST_API_KEY" -d '{"paused": true}'
#Delete
DELETE /api/v1/monitors/{id} returns 204. The monitor's history is deleted too.
#Incidents
GET /api/v1/monitors/{id}/incidents?limit=50 (up to 500), newest first:
{"incidents": [{"id": 345, "started_at": "2026-10-12T09:40:31Z", "resolved_at": "2026-10-12T09:43:02Z", "cause": "HTTP 502"}]}
resolved_at is null while the incident is ongoing.
#Maintenance windows
#Start one
POST /api/v1/maintenance
| Field | Notes |
|---|---|
title |
Required, shown on status pages. |
duration_minutes |
1–1440. |
start |
RFC 3339 time; defaults to now. |
monitor_ids |
Defaults to every monitor. |
weekly |
Repeat every week. |
time_zone |
IANA name for weekly windows, e.g. Europe/Lisbon. Defaults to UTC. |
A deploy step in CI:
curl -fsS -X POST https://pulsefast.io/api/v1/maintenance \
-H "Authorization: Bearer $PULSEFAST_API_KEY" \
-d '{"title": "Deploy '"$GIT_SHA"'", "duration_minutes": 10}'
#List and delete
GET /api/v1/maintenance lists windows; DELETE /api/v1/maintenance/{id} removes one (end it early).
#Deploy markers
Tell Pulsefast when you deploy, so incidents show what changed just before they started. Add one call at the end of your deploy step:
curl -fsS -X POST https://pulsefast.io/api/v1/deploys \
-H "Authorization: Bearer $PULSEFAST_API_KEY" \
-d '{"service": "checkout", "version": "'"$GIT_SHA"'", "environment": "production"}'
| Field | Notes |
|---|---|
version |
Required: commit SHA, tag or build number. |
service |
Optional. Incidents for that service show its deploys; deploys without a service show on every incident. |
environment |
Defaults to production. |
url, description |
Optional: a link to the commit or release, and a note. |
at |
RFC 3339 time; defaults to now. |
GET /api/v1/deploys?service=checkout lists the last 30 days.
#Channels and status pages
GET /api/v1/channels returns id, name and type for each alert channel (settings and secrets aren't included). GET /api/v1/status-pages returns each page's id, title, url, custom_domain and monitor_ids.
View as Markdown · Something unclear? Tell us