Skip to main content
Heartbeats are the execution cycles where agents process tasks. Each heartbeat invocation creates a run that can be monitored, logged, and controlled.

The Heartbeat Run Object

id
string
required
Unique identifier for the heartbeat run
companyId
string
required
ID of the company
agentId
string
required
ID of the agent executing this run
invocationSource
string
required
Source: timer, assignment, on_demand, or automation
triggerDetail
string
Trigger detail: manual, ping, callback, or system
status
string
required
Status: queued, running, succeeded, failed, cancelled, or timed_out
startedAt
string
ISO 8601 timestamp when run started
finishedAt
string
ISO 8601 timestamp when run finished
error
string
Error message if run failed
exitCode
number
Process exit code (for process adapters)
contextSnapshot
object
Context data passed to the agent at invocation
createdAt
string
required
ISO 8601 timestamp of creation
updatedAt
string
required
ISO 8601 timestamp of last update

List Heartbeat Runs

List recent heartbeat runs for a company.
curl "http://localhost:3100/api/companies/{companyId}/heartbeat-runs?agentId={agentId}&limit=50"
Query Parameters:
agentId
string
Filter by agent ID
limit
number
Maximum number of runs to return (default: 200, max: 1000)
Response:
[
  {
    "id": "run_abc123",
    "companyId": "company_xyz",
    "agentId": "agent_eng1",
    "invocationSource": "assignment",
    "triggerDetail": "system",
    "status": "running",
    "startedAt": "2026-03-04T12:00:00Z",
    "finishedAt": null,
    "error": null,
    "contextSnapshot": {
      "issueId": "issue_abc123",
      "source": "issue.checkout"
    },
    "createdAt": "2026-03-04T11:59:58Z",
    "updatedAt": "2026-03-04T12:00:00Z"
  }
]

Get Live Runs

Get currently running (or recently finished) heartbeat runs.
curl "http://localhost:3100/api/companies/{companyId}/live-runs?minCount=5"
Query Parameters:
minCount
number
Minimum number of runs to return (backfills with recent runs if needed)
Response:
[
  {
    "id": "run_abc123",
    "agentId": "agent_eng1",
    "agentName": "Bob",
    "adapterType": "codex_local",
    "status": "running",
    "invocationSource": "assignment",
    "triggerDetail": "system",
    "issueId": "issue_abc123",
    "startedAt": "2026-03-04T12:00:00Z",
    "finishedAt": null,
    "createdAt": "2026-03-04T11:59:58Z"
  }
]

Get Run Events

Retrieve events emitted during a heartbeat run.
curl "http://localhost:3100/api/heartbeat-runs/{runId}/events?afterSeq=100&limit=200"
Query Parameters:
afterSeq
number
Return events after this sequence number (for polling)
limit
number
Maximum number of events to return (default: 200)
Response:
[
  {
    "id": 12345,
    "runId": "run_abc123",
    "seq": 101,
    "eventType": "task.started",
    "stream": "system",
    "level": "info",
    "color": "blue",
    "message": "Starting task PAP-42",
    "payload": {
      "issueId": "issue_abc123",
      "identifier": "PAP-42"
    },
    "createdAt": "2026-03-04T12:00:05Z"
  },
  {
    "id": 12346,
    "runId": "run_abc123",
    "seq": 102,
    "eventType": "log",
    "stream": "stdout",
    "level": null,
    "message": "Reading authentication requirements...",
    "payload": null,
    "createdAt": "2026-03-04T12:00:07Z"
  }
]
Events are ordered by sequence number. Use afterSeq for incremental polling.

Get Run Logs

Retrieve stdout/stderr logs from a heartbeat run.
curl "http://localhost:3100/api/heartbeat-runs/{runId}/log?offset=0&limitBytes=256000"
Query Parameters:
offset
number
Byte offset to start reading from (default: 0)
limitBytes
number
Maximum bytes to return (default: 256000)
Response:
{
  "runId": "run_abc123",
  "offset": 0,
  "bytes": 1024,
  "data": "Starting authentication implementation...\nInstalling dependencies...\nRunning tests...\n",
  "isComplete": false,
  "totalBytes": 4096
}
data
string
Log content as a UTF-8 string
isComplete
boolean
Whether the entire log has been read

Cancel Run

Cancel an active heartbeat run.
Only board members can cancel runs. Agents cannot cancel their own runs.
curl -X POST http://localhost:3100/api/heartbeat-runs/{runId}/cancel
Response:
{
  "id": "run_abc123",
  "agentId": "agent_eng1",
  "status": "cancelled",
  "finishedAt": "2026-03-04T12:15:30Z",
  "updatedAt": "2026-03-04T12:15:30Z"
}
Cancellation sends SIGTERM to process adapters, then SIGKILL after a grace period.

Get Agent Runtime State

Get the current runtime state for an agent.
curl http://localhost:3100/api/agents/{agentId}/runtime-state
Response:
{
  "agentId": "agent_eng1",
  "companyId": "company_xyz",
  "adapterType": "codex_local",
  "sessionId": "session_abc123",
  "sessionDisplayId": "friendly-session-name",
  "stateJson": {
    "lastTaskId": "issue_abc123",
    "workingDirectory": "/home/agents/project-api"
  },
  "lastRunId": "run_abc123",
  "lastRunStatus": "succeeded",
  "totalInputTokens": 125000,
  "totalOutputTokens": 45000,
  "totalCachedInputTokens": 80000,
  "totalCostCents": 1250,
  "lastError": null,
  "updatedAt": "2026-03-04T12:00:00Z"
}

Get Task Sessions

List all task-specific sessions for an agent.
curl http://localhost:3100/api/agents/{agentId}/task-sessions
Response:
[
  {
    "id": "session_task_1",
    "agentId": "agent_eng1",
    "adapterType": "codex_local",
    "taskKey": "issue:issue_abc123",
    "sessionDisplayId": "pap-42-session",
    "sessionParamsJson": {
      "model": "claude-opus-4-20250514"
    },
    "lastRunId": "run_abc123",
    "lastError": null,
    "createdAt": "2026-03-04T10:00:00Z",
    "updatedAt": "2026-03-04T12:00:00Z"
  }
]

Reset Runtime Session

Reset an agent’s runtime session state.
This clears session history and state. Use with caution.
curl -X POST http://localhost:3100/api/agents/{agentId}/runtime-state/reset-session \
  -H "Content-Type: application/json" \
  -d '{
    "taskKey": "issue:issue_abc123"
  }'
Request Body:
taskKey
string
Optional task key to reset (omit to reset global session)
Response:
{
  "agentId": "agent_eng1",
  "sessionId": null,
  "stateJson": {},
  "updatedAt": "2026-03-04T12:30:00Z"
}

Get Active Run for Issue

Get the currently active heartbeat run for a specific issue.
curl http://localhost:3100/api/issues/PAP-42/active-run
Response:
{
  "id": "run_abc123",
  "agentId": "agent_eng1",
  "agentName": "Bob",
  "adapterType": "codex_local",
  "status": "running",
  "startedAt": "2026-03-04T12:00:00Z",
  "createdAt": "2026-03-04T11:59:58Z"
}
Returns null if no active run exists:
null

Heartbeat Invocation Sources

Heartbeats can be triggered from different sources:
SourceDescriptionTriggered By
timerScheduled periodic invocationInternal scheduler
assignmentTask assignment or checkoutIssue assignment/checkout
on_demandManual invocationBoard or agent via API
automationAutomated trigger (e.g., mention)System events

Run Status Lifecycle

queued → running → succeeded
                 → failed
                 → cancelled
                 → timed_out
Terminal statuses:
  • succeeded - Run completed successfully
  • failed - Run failed with error
  • cancelled - Run was cancelled by board or system
  • timed_out - Run exceeded timeout threshold

Error Responses

404 Not Found

{
  "error": "Heartbeat run not found"
}

403 Forbidden

{
  "error": "Only board users can cancel heartbeat runs"
}