Skip to content

API and integrations

Aloft ships a small REST API under /api/v1 for managing monitors and reading a status overview from your own scripts and automation. This guide covers creating a key, authenticating, the available endpoints, rate limits, and the interactive docs.

API keys live under API in the top navigation.

  1. Open API in the top navigation.
  2. Under Create a key, give the key a descriptive name (for example ci-deploy-checks) and submit.
  3. The raw token is displayed exactly once, immediately after creation. Copy it now and store it in your secrets manager.

Each key is scoped to the organization it was created in. The token grants that organization’s effective rights to whoever holds it, regardless of who minted it. A token looks like ur_ followed by 24 random characters; the UI shows only the first 12 characters (ur_xxxxxxxx…) for identification.

On the API page, each key in Your keys has a Revoke button. Revoking is immediate — any request using that token afterward gets a 401. Revoking is also admin-only.

Every /api/v1 request must carry the token in an Authorization header using the Bearer scheme:

Terminal window
curl -H "Authorization: Bearer ur_your_token_here" \
https://aloft.example.com/api/v1/monitors

Replace https://aloft.example.com with your deployment’s URL throughout this guide.

A missing or malformed header returns 401:

{ "error": "Missing or malformed Authorization header. Expected 'Bearer <token>'." }

An unrecognised token also returns 401:

{ "error": "Invalid API token" }

All endpoints are rooted at /api/v1. Resources are scoped to the organization the key belongs to — you only ever see and touch that org’s monitors.

GET /api/v1/monitors returns every monitor in the org.

Terminal window
curl -H "Authorization: Bearer ur_your_token_here" \
https://aloft.example.com/api/v1/monitors
{ "monitors": [ { "id": "...", "name": "My site", "type": "http", "status": "up" } ] }

POST /api/v1/monitors creates a monitor. name, type, and url are required; everything else has sensible defaults (for example intervalSeconds defaults to 300 and confirmationCount to 2). Returns 201 with the created monitor.

Terminal window
curl -X POST \
-H "Authorization: Bearer ur_your_token_here" \
-H "Content-Type: application/json" \
-d '{"name":"My site","type":"http","url":"https://example.com"}' \
https://aloft.example.com/api/v1/monitors
{ "monitor": { "id": "...", "name": "My site", "type": "http" } }

A validation failure returns 400 with an error message and an issues array. Referencing a channel the org doesn’t own returns 403.

GET /api/v1/monitors/{id} returns one monitor plus computed stats and its five most recent incidents. Returns 404 if the monitor isn’t in your org.

Terminal window
curl -H "Authorization: Bearer ur_your_token_here" \
https://aloft.example.com/api/v1/monitors/MONITOR_ID
{ "monitor": { "id": "...", "name": "My site" }, "stats": { }, "recentIncidents": [ ] }

Update a monitor (PATCH partial, PUT full)

Section titled “Update a monitor (PATCH partial, PUT full)”

There are two ways to update a monitor:

  • PATCH — a partial merge. Send only the fields you want to change; Aloft merges them onto the existing monitor and re-validates.
  • PUT — a full replace. You must send the complete monitor input, just like a create.
Terminal window
# PATCH — bump just the interval
curl -X PATCH \
-H "Authorization: Bearer ur_your_token_here" \
-H "Content-Type: application/json" \
-d '{"intervalSeconds":120}' \
https://aloft.example.com/api/v1/monitors/MONITOR_ID
Terminal window
# PUT — replace the whole monitor
curl -X PUT \
-H "Authorization: Bearer ur_your_token_here" \
-H "Content-Type: application/json" \
-d '{"name":"My site","type":"http","url":"https://example.com","intervalSeconds":120}' \
https://aloft.example.com/api/v1/monitors/MONITOR_ID

Both return 200 with the updated { "monitor": … }, 400 on a validation error, or 404 if the monitor isn’t in your org.

DELETE /api/v1/monitors/{id} removes the monitor and its history.

Terminal window
curl -X DELETE \
-H "Authorization: Bearer ur_your_token_here" \
https://aloft.example.com/api/v1/monitors/MONITOR_ID
{ "ok": true }

GET /api/v1/status is a fast “is anything down?” snapshot for automation. It returns monitor counts and the org’s currently open incidents.

Terminal window
curl -H "Authorization: Bearer ur_your_token_here" \
https://aloft.example.com/api/v1/status
{
"counts": { "total": 12, "up": 11, "down": 1, "paused": 0 },
"openIncidents": [
{
"incidentId": "...",
"monitorId": "...",
"monitorName": "My site",
"startedAt": "2026-06-02T10:00:00.000Z",
"cause": "Connection refused"
}
]
}

Each API key is limited to 600 requests per minute. Every response — success or failure — carries X-RateLimit-* headers so you can see your remaining budget:

  • X-RateLimit-Limit — the per-minute ceiling (600).
  • X-RateLimit-Remaining — requests left in the current window.
  • X-RateLimit-Reset — when the window resets.

When you exceed the limit, requests return 429:

{ "error": "Rate limit exceeded" }

Back off until the window resets (the X-RateLimit-Reset header tells you when) and retry.

  • Swagger UI is served at /api/v1/docs for browsing and trying endpoints interactively.
  • The OpenAPI 3.1 spec is at /api/v1/openapi.json, which you can feed to client generators such as openapi-typescript or openapi-generator.

Heartbeat monitors are not driven through /api/v1. Instead, your job posts to a dedicated, token-in-the-URL ingest endpoint to assert it’s alive. See Heartbeat monitors for the endpoint, the token, and how the grace period works.