Developers
API documentation
The Infra Agent REST API gives you full programmatic control of your organization: create and manage monitors of every type, acknowledge and resolve incidents, configure alert channels, schedule maintenance windows, publish status pages, organize apps, and manage members and invitations from scripts, deploy pipelines, or your own tooling.
https://infraagent.app/api/v1
Every response is JSON and includes a success flag. Failed requests return { "success": false, "error": "..." } with a matching HTTP status code.
Authentication
API keys are personal: each key belongs to the member who created it and acts with that member's permissions. A key can see and do exactly what its owner can in the dashboard, nothing more: an owner's key can manage the whole organization, a plain member's key only reaches the apps that member has been granted. If the owner's role changes the key follows, and it stops working the moment they leave the organization. Create keys under API in the dashboard. A full-access key can change or delete anything its owner can, while a read-only key can only list and read. The read-only key works for every GET endpoint; POST, PATCH, and DELETE require full access.
Treat every key like a password: keep it in environment variables or a secret manager, never in source control or client-side code, and use a read-only key wherever writing is not needed. The full key is shown once at creation, so store it right away. If a key leaks, revoke it from the dashboard; it stops working immediately.
Send the key with every request, either as a bearer token or an X-Api-Key header:
curl -H "Authorization: Bearer YOUR_API_KEY" \ https://infraagent.app/api/v1/monitors curl -H "X-Api-Key: YOUR_API_KEY" \ https://infraagent.app/api/v1/monitors
Apps
Monitors, alert channels, maintenance windows, and status pages each live inside an app (a project within your organization). Endpoints that create one of these accept an appIdfield. If your key can reach a single app you can omit it; with more than one it is required. A member's key only sees the apps that member has been granted. List your apps via GET /apps.
Errors
400The query parameters or request body failed validation. The error message names the offending field.401The API key is missing or invalid.403The key lacks access: a read-only key on a write endpoint, a non-admin's key on an admin-only endpoint or without any app access, or the request exceeds a plan limit (monitor count, check interval, status pages, seats, SMS).404The resource does not exist or belongs to another organization.412A required server-side integration is not configured (for example SMS delivery).Endpoints
Monitors
/monitorsList every monitor in your organization, oldest first. Each monitor includes id, name, type, status, enabled, target, intervalSeconds, and check timestamps. Disabled monitors report their status as paused.
- status
- up | down | paused | pending
- Only return monitors with this status.
- type
- http | tcp | ssl | heartbeat | dns | domain
- Only return monitors of this type.
- appId
- string
- Only return monitors in this app.
- limit
- integer, 1-500, default 100
- Page size.
- offset
- integer, default 0
- Number of monitors to skip.
/monitors/{id}A single monitor with its full config, the latest 25 checks as recentChecks, and the currently open incident as openIncident (or null). Heartbeat monitors also include their ping URL as heartbeatUrl.
/monitorsFull accessCreate a monitor. The config object depends on the monitor type; unlisted config fields get sensible defaults. Attach alert channels by passing channels as an array of { "channelId": "...", "notifyOn": "down" | "up" | "both" }. Returns 201 with the created monitor.
- name
- string, required
- Display name, 1-120 characters.
- type
- http | tcp | ssl | heartbeat | dns | domain, required
- What kind of check to run.
- config
- object, required
- Type-specific settings, see the table below.
- intervalSeconds
- integer, 30-86400, required
- How often the monitor is checked. Plan limits apply; domain monitors check at most hourly.
- enabled
- boolean, default true
- Start checking immediately.
- channels
- array, default []
- Alert channels to notify, with per-channel notifyOn and optional messageTemplate.
- appId
- string
- App to create the monitor in. Optional for single-app organizations.
- http
- url (required), method, expectedStatusRange, keyword, keywordMode, requestHeaders, followRedirects, timeoutMs, degradedMs
- Checks a URL and optionally asserts a keyword is present or absent.
- tcp
- host (required), port (required), timeoutMs
- Checks that a TCP port accepts connections.
- ssl
- host (required), port, warnDays, timeoutMs
- Warns before the TLS certificate expires.
- heartbeat
- graceSeconds, token (optional, autogenerated)
- Your job pings us; the monitor goes down when pings stop. The response includes heartbeatUrl.
- dns
- host (required), recordType, expectedValues, timeoutMs
- Resolves a DNS record and optionally asserts its values.
- domain
- domain (required), warnDays, timeoutMs
- Warns before the domain registration expires.
curl -X POST \
-H "Authorization: Bearer YOUR_MAIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Marketing site",
"type": "http",
"intervalSeconds": 60,
"config": { "url": "https://example.com/health" }
}' \
https://infraagent.app/api/v1/monitors/monitors/{id}Full accessUpdate a monitor. Send a JSON body with at least one field; anything omitted is left unchanged. Setting enabled to false pauses the monitor, true resumes it. A provided config replaces the stored config wholesale, and a provided channels array replaces all channel attachments.
- name
- string, 1-120 characters
- Rename the monitor.
- enabled
- boolean
- Pause (false) or resume (true) checks.
- intervalSeconds
- integer, 30-86400
- How often the monitor is checked.
- type
- http | tcp | ssl | heartbeat | dns | domain
- Change the monitor type. Send a matching config alongside it.
- config
- object
- Replace the type-specific settings.
- channels
- array
- Replace the attached alert channels.
/monitors/{id}/runFull accessRun the monitor's check immediately, outside its normal schedule, and return the result. Useful right after creating or reconfiguring a monitor.
/monitors/{id}Full accessDelete a monitor. Check history and past incidents are kept for your records, but the monitor stops running and disappears from lists immediately.
Incidents
/incidentsList incidents across all monitors, newest first. Each incident includes id, monitorId, monitorName, startedAt, resolvedAt, durationSeconds, cause, and lastError.
- status
- open | resolved
- Only open (unresolved) or resolved incidents.
- monitorId
- string
- Only incidents for this monitor.
- limit
- integer, 1-200, default 50
- Page size.
- offset
- integer, default 0
- Number of incidents to skip.
/incidents/{id}/acknowledgeFull accessMark an incident as acknowledged so your team knows it is being handled.
/incidents/{id}/resolveFull accessManually resolve an open incident. Most incidents resolve themselves when the monitor recovers; use this for stragglers.
Alert channels
/channelsList alert channels. Channel configs hold webhook URLs and provider tokens, so the config field is only included when using a full-access key.
/channels/{id}A single alert channel. Same key rules as the list.
/channelsFull accessCreate an alert channel. Supported types: email, sms, slack, discord, telegram, pushbullet, pushover, pagerduty, zapier, splunk, and webhook. New SMS phone numbers are texted a verification code (returned as codesSentTo) and must be confirmed in the dashboard before they receive alerts.
- type
- string, required
- One of the channel types above.
- name
- string, required
- Display name, 1-120 characters.
- config
- object, required
- Type-specific settings: webhookUrl for Slack/Discord/Zapier/webhook, recipients for email, phoneNumbers for SMS, botToken and chatId for Telegram, and so on. Validation errors name what is missing.
- enabled
- boolean, default true
- Whether the channel sends alerts.
- messageTemplate
- string
- Custom alert message template. Defaults to the standard template.
- appId
- string
- App to create the channel in. Optional for single-app organizations.
/channels/{id}Full accessUpdate an alert channel. Send at least one of type, name, enabled, config, messageTemplate. A provided config replaces the stored one wholesale.
/channels/{id}Full accessDelete an alert channel and detach it from every monitor.
/channels/{id}/testFull accessSend a sample "down" alert through the channel to confirm it is wired up correctly. Returns the delivery result, or a 400 explaining why nothing was sent.
Maintenance windows
/maintenance-windowsList maintenance windows, newest first. While a window is active, matching monitors stay quiet: no alerts, no new incidents.
/maintenance-windowsFull accessSchedule a maintenance window. Set monitorId to quiet a single monitor, or leave it null to quiet the whole app.
- startsAt
- ISO 8601 datetime, required
- When the window opens.
- endsAt
- ISO 8601 datetime, required
- When the window closes. Must be after startsAt.
- monitorId
- string or null
- Limit the window to one monitor.
- reason
- string
- Shown wherever the window is displayed.
- appId
- string
- App the window applies to. Optional for single-app organizations.
/maintenance-windows/{id}A single maintenance window.
/maintenance-windows/{id}Full accessUpdate a window's startsAt, endsAt, monitorId, or reason.
/maintenance-windows/{id}Full accessDelete a maintenance window. Alerts resume immediately.
Status pages
/status-pagesList status pages with their monitor counts.
/status-pages/{id}A single status page with its placed monitors in display order.
/status-pagesFull accessCreate a status page. Plan limits on the number of status pages apply. Place monitors by passing monitors as an array of { "monitorId": "...", "displayName": "...", "sortOrder": 0 }.
- title
- string, required
- Page title, 1-120 characters.
- slug
- string, required
- Public address of the page. Lowercased and slugified.
- description
- string
- Shown under the title.
- isPublic
- boolean, default true
- Whether the page is publicly reachable.
- monitors
- array, default []
- Monitors to place on the page.
- appId
- string
- App to create the page in. Optional for single-app organizations.
/status-pages/{id}Full accessUpdate a status page. A provided monitorsarray replaces the page's monitor placement wholesale.
/status-pages/{id}Full accessDelete a status page. Its public URL stops working immediately.
Apps
/appsList the organization's apps with their monitor counts.
/appsAdmin onlyCreate an app. Body: name (required) and an optional slug. Creating the first real app renames the auto-created "Default" app in place, keeping its monitors.
/apps/{id}Admin onlyRename an app or change its slug.
/apps/{id}Admin onlyDelete an app and everything in it: monitors, alert channels, maintenance windows, and status pages. This cannot be undone.
Organization
/organizationThe organization's name, slug, and logo.
/organizationAdmin onlyUpdate the organization's name or slug.
/organization/membersList members with their role (owner, admin, or member), name, and email.
/organization/members/{id}Admin onlyChange a member's role between member and admin. The owner's role can't be changed.
/organization/members/{id}Admin onlyRemove a member from the organization. The owner can't be removed.
/organization/invitationsAdmin onlyList pending invitations, including any pre-assigned apps.
/organization/invitationsAdmin onlyInvite people by email. Each address receives an invitation email; re-inviting a pending address resends it. Plan seat limits apply.
- emails
- array of strings, required
- Up to 50 email addresses.
- role
- member | admin, default member
- Role granted on acceptance.
- appIds
- array of strings, default []
- Apps a plain member can see after joining. Admins always see every app.
/organization/invitations/{id}Admin onlyRevoke a pending invitation so the emailed link stops working.
Billing
/billingRead-only plan and usage overview: plan id and name, plan limits, current usage (monitors, status pages, members), and subscription status. Plan changes go through the dashboard's billing settings.
Example: pause a monitor
Pause checks during a deploy with a full-access key, then flip enabled back to true when you are done:
curl -X PATCH \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"enabled": false}' \
https://infraagent.app/api/v1/monitors/{id}