Create a heartbeat
curl -X POST https://aisenseapi.com/services/v1/heartbeat \
-H "Content-Type: application/json" \
-d '{
"expect_every_seconds": 300,
"grace_seconds": 60,
"on_miss": {
"url": "https://example.com/agent-offline",
"payload": { "agent": "worker-7" }
}
}'{
"ok": true,
"heartbeat_id": "58c85e3e8f739edcb73530d14316f2bfae9ae11bf85374b17e4c9ab75bbec5f1",
"status": "armed",
"expect_every_seconds": 300,
"grace_seconds": 60,
"next_expected_at_datetime": "2026-09-05T10:05:00Z",
"miss_due_at_datetime": "2026-09-05T10:06:00Z",
"expires_at_datetime": "2026-09-06T10:00:00Z",
"ping_count": 0,
"misses": 0,
"late": false,
"on_miss": { "type": "webhook" },
"ping_url": "https://aisenseapi.com/services/v1/heartbeat/58c85e3e.../ping",
"status_url": "https://aisenseapi.com/services/v1/heartbeat/58c85e3e..."
}Keep the full heartbeat_id or the returned URLs. The identifier has 256 random bits and works as a bearer secret. There is no list call that can recover it.
Check in after successful work
curl -X POST https://aisenseapi.com/services/v1/heartbeat/{heartbeat_id}/pingThe ping path accepts POST. Each accepted call sets last_ping_at to now, moves next_expected_at forward by the configured interval and increases ping_count. The grace period begins after that next expected time.
GET never changes a heartbeat. This prevents link scanners and prefetchers from keeping a stopped process alive.
The fixed expires_at value never moves. A monitor cannot be kept alive beyond 24 hours by sending more pings. Create a new monitor when a new 24-hour window starts.
Choose one miss action
| on_miss field | What happens | Limit |
|---|---|---|
url | AI SENSE sends a JSON POST to a public webhook. | Optional payload, maximum 32 KB as JSON |
wake_task_id | AI SENSE completes an existing Agent Wake webhook task. | The task must exist and still be working |
Send exactly one of these fields. A payload is valid only with a webhook URL.
{
"expect_every_seconds": 300,
"grace_seconds": 60,
"on_miss": {
"wake_task_id": "2eb1a08d-759f-4af9-8caa-8b02b7ca17ba"
}
}The missed event
A webhook receives a body with the monitor identity and the actual miss time. Your optional payload is included under payload.
{
"event": "heartbeat.missed",
"heartbeat_id": "58c85e3e8f739edcb73530d14316f2bfae9ae11bf85374b17e4c9ab75bbec5f1",
"last_ping_at_timestamp": 1788602400,
"last_ping_at_datetime": "2026-09-05T10:00:00Z",
"missed_at_timestamp": 1788602764,
"missed_at_datetime": "2026-09-05T10:06:04Z",
"expect_every_seconds": 300,
"grace_seconds": 60,
"payload": { "agent": "worker-7" }
}The request also carries User-Agent: AISENSE-Heartbeat/1.0 and X-AISENSE-Heartbeat-Id.
Timing and states
expect_every_seconds must be an integer from 60 to 86400. grace_seconds may be zero. Their sum cannot exceed 86400. The deadline worker runs once a minute, so allow minute-level scheduling variation.
| Status | Meaning |
|---|---|
armed | The monitor can accept a check-in. |
missed | The deadline passed and the action failed before an attempt, or delivery is being claimed. |
fired | The miss action was attempted. Check delivery.delivered for success. |
expired | The fixed lifetime ended without a miss that fell inside the lifetime. |
The miss action is claimed before network delivery and is never retried. That prevents duplicate alerts. A process failure after the claim can lose the alert, so use another layer when at-least-once delivery is required.
Read the status
curl https://aisenseapi.com/services/v1/heartbeat/{heartbeat_id}A terminal result can include terminal_at, missed_at and delivery. For a webhook, delivery.delivered: true means the target answered with a 2xx status. fired alone means only that an attempt happened.
Pinging a terminal monitor returns HTTP 409. An unknown or removed identifier returns HTTP 404.
MCP clients use create_heartbeat, read_heartbeat and ping_heartbeat for the same state.
Outbound request safety
Do not put secrets or personal data in the payload. Anyone with the heartbeat URL can read its status.
Webhook targets may use HTTP or HTTPS on port 80 or 443. Credentials and fragments in the URL are refused. The host must resolve to a public address. AI SENSE checks DNS again at delivery, pins the request to the checked address, follows no redirects and blocks private, loopback, link-local and reserved ranges.
The service stores timing state and the selected target while the monitor is armed. The target URL, payload or Agent Wake ID is removed when the monitor becomes terminal. The terminal record stays readable for up to another 24 hours, then is removed.
Useful flows
Agent run
Ping after each completed cycle. Wake a supervisor task when cycles stop.
Queue worker
Send one alert when a consumer stops making progress.
Short batch
Watch a job that should report every few minutes during a 24-hour window.
Temporary service
Monitor an ephemeral process without installing a permanent monitoring stack.