---
title: "Record a runner machine heartbeat and telemetry snapshot"
method: POST
path: "/agents/machines/heartbeat"
tags: ["Agents"]
---

# Record a runner machine heartbeat and telemetry snapshot

`POST /agents/machines/heartbeat`

## Request

- Base URL: `https://api.apphandoff.com/api`
- URL: `https://api.apphandoff.com/api/agents/machines/heartbeat`
- Auth: API key in cookie `sb-access-token`

OAuth-authenticated machine presence sidecar. Upserts the caller-owned
machine and refreshes its heartbeat timestamp. Users with access to
multiple billing accounts must send an in-scope `billing_account_id`.
Rate limited (600/min/IP).

## Request body

- object: Telemetry caps: JSON.stringify(cli_meta).length + JSON.stringify(usage_snapshot).length must be <= 32,768 characters; each session must be <= 4,096 serialized characters; all telemetry combined must be <= 65,536 serialized characters.
  - `machine_id` string, required
  - `name` string, required
  - `hostname` string
  - `backend` string
  - `capabilities` string[]
  - `cli_meta` object
  - `usage_snapshot` object
  - `sessions` object[]
  - `active_lanes` object[]
    - `run_id` string, uuid, required
    - `phase` string
    - `started_at` string
  - `billing_account_id` string, uuid

## Response `200`

Machine heartbeat recorded

- object
  - `ok` true, required
  - `machine_id` string, required
  - `server_time` string, date-time, required

## Other responses

- `400`: Invalid request
- `401`: Not authenticated
- `403`: Forbidden
- `409`: Resource state conflict
- `429`: Rate limited
- `500`: Server error

---

[API](https://skmtc.dev/apphandoff/apis/apphandoff-api.md) · [All operations](https://skmtc.dev/apphandoff/apis/apphandoff-api/llms.txt) · [OpenAPI document](https://skmtc.dev/apphandoff/apis/apphandoff-api/revisions/9f138fe46d56?raw)
