---
title: "Heartbeat Run"
method: POST
path: "/runs/{id}/heartbeat"
tags: ["runs"]
---

# Heartbeat Run

`POST /runs/{id}/heartbeat`

## Request

- Base URL: `https://app.tascan.io/api/v1`
- URL: `https://app.tascan.io/api/v1/runs/{id}/heartbeat`
- Auth: HTTP bearer

Extend a claimed local run's lease and mark it running (POST /runs/:run_id/heartbeat -> heartbeat_agent_run). ok false with reason not_live means the run is no longer yours -- the sweep expired it, or it was never yours to begin with -- STOP, do not finish it. Never mints a completion or a receipt. Requires agent:dispatch:code. A run outside your org is 404, never 403.

## Path parameters

- `id` string, required

## Request body

- object
  - `run_id` string, required: The run ID from tascan_claim_run's response.
  - `instance` string, required: The SAME instance string you claimed with -- a mismatch answers not_live.
  - `extend_seconds` integer: Optional: push expires_at out to now + this many seconds (60-86400) if that is later than the current lease -- never shortens it.

## Response `200`

Success. JSON body: { data: ... } or an error object { error, message }.

## Other responses

- `4XX`: Client error (validation, auth, scope, rate limit).

---

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