---
title: "Renouveler le bail vivant d'un runner"
method: POST
path: "/api/v1/runners/lease/heartbeat"
tags: ["AI Workforce", "Runner local"]
---

# Renouveler le bail vivant d'un runner

`POST /api/v1/runners/lease/heartbeat`

## Request

- Base URL: `https://arcadeops.leadalpes.fr`
- URL: `https://arcadeops.leadalpes.fr/api/v1/runners/lease/heartbeat`
- Auth: none required

Authentifie le runner par le certificat et l'enveloppe Ed25519 signée du corps, puis exige messageType runner.lease.heartbeat, scopeType RUNNER, scopeId égal au runnerId authentifié et le scope commands.claim. Le payload suit RunnerHeartbeatPayload. La réponse est une enveloppe signée par le control plane, liée à la requête ; un bail expiré n'est jamais ranimé. Aucune authentification HTTP n'est utilisée.

## Request body

- RunnerHeartbeatRequest
  - `certificate` object, required
    - `schemaVersion` 'arcade.runner-certificate.v0', required
    - `certificateSerial` string, uuid, required
    - `runnerId` string, required
    - `organizationId` string, required
    - `keyId` string, required
    - `publicKeySpkiBase64` string, required
    - `issuerKeyId` string, required
    - `validFrom` string, date-time, required
    - `validUntil` string, date-time, required
    - `usages` string[], required
    - `signature` string, required
  - `envelope` object, required
    - `schemaVersion` 'arcade.runner.v0', required
    - `messageId` string, uuid, required
    - `messageType` string, required
    - `scopeType` 'RUNNER' | 'ATTEMPT', required
    - `scopeId` string, required
    - `producerType` 'CONTROL_PLANE' | 'RUNNER' | 'ADAPTER' | 'VERIFIER', required
    - `producerId` string, required
    - `streamId` string, uuid, required
    - `organizationId` string, required
    - `projectId` string, nullable, required
    - `missionId` string, nullable, required
    - `attemptId` string, nullable, required
    - `runnerId` string, required
    - `fencingEpoch` integer, nullable, required
    - `sequence` integer, required
    - `timestamp` string, date-time, required
    - `idempotencyKey` string, required
    - `payloadHash` string, required
    - `payload` unknown
    - `signingKeyId` string, nullable
    - `signature` string, nullable

## Response `200`

Bail renouvelé et réponse de contrôle signée

- RunnerHeartbeatResponse
  - `envelope` object, required
    - `schemaVersion` 'arcade.runner.v0', required
    - `messageId` string, uuid, required
    - `messageType` string, required
    - `scopeType` 'RUNNER' | 'ATTEMPT', required
    - `scopeId` string, required
    - `producerType` 'CONTROL_PLANE' | 'RUNNER' | 'ADAPTER' | 'VERIFIER', required
    - `producerId` string, required
    - `streamId` string, uuid, required
    - `organizationId` string, required
    - `projectId` string, nullable, required
    - `missionId` string, nullable, required
    - `attemptId` string, nullable, required
    - `runnerId` string, required
    - `fencingEpoch` integer, nullable, required
    - `sequence` integer, required
    - `timestamp` string, date-time, required
    - `idempotencyKey` string, required
    - `payloadHash` string, required
    - `payload` unknown
    - `signingKeyId` string, nullable
    - `signature` string, nullable

## Other responses

- `400`: Enveloppe ou payload de heartbeat invalide
- `403`: Signature, identité, binding RUNNER, scope ou bail vivant refusé
- `413`: Corps de requête trop volumineux
- `429`: Limite de requêtes atteinte
- `503`: Racine de certificats runner indisponible

---

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