---
title: Heartbeats
description: One-shot run for cron, curl, and anything that can't host an SDK.
section: pulse
order: 2
---

# Heartbeats

One HTTP call, one finished run, for cron, GitHub Actions, n8n, Zapier, Make, or anything that can fire a single request. Heartbeats land in the same dashboard, alerts, and history as full SDK runs; upgrading to the SDK later does not migrate data.

## Two surfaces

| Endpoint | Use when |
|----------|----------|
| [`GET /v1/ping`](/docs/api/ping) | Cron, wget, shell. Everything in the query string. |
| [`POST /v1/heartbeats`](/docs/api/heartbeats) | JSON body with explicit timestamps, output, and richer metadata. |

```bash
curl 'https://eu.ingest.agentping.io/v1/ping?key=ping_eu_<token>&agent=daily-summary&status=ok&cost_usd=0.084'
```

Or from an SDK: `agentping.heartbeat("daily-summary", status="ok", cost_usd=0.084)`.

If the caller has the model and token usage but not a dollar figure (an n8n AI node, a script that read the provider's `usage` block), send `model` plus `input_tokens` / `output_tokens` and AgentPing prices the run from your rate card. A `cost_usd`, when supplied, always wins.

```bash
curl 'https://eu.ingest.agentping.io/v1/ping?key=ping_eu_<token>&agent=daily-summary&status=ok&provider=openai&model=gpt-4o&input_tokens=1240&output_tokens=380'
```

Status is `ok` (default), `fail`, `timeout`, or `start` (opens a long-running run; send `ok`/`fail` at the end and duration is the gap). See [`GET /v1/ping`](/docs/api/ping) for the full parameter list.

## Always use a ping token

Pass a `ping_<region>_...` token, never a full API key, in URL-based calls. A ping token is scoped to one agent and can only fire heartbeats, so a leak is contained to a falsified status for one job; a leaked API key is a full team compromise. Each agent issues its own token in settings (shown once at creation; after rotation the old token keeps working for 24 hours).

:::warning
Never put a full API key (`apk_...`) in a URL. Query strings leak through access logs, browser history, and referer headers. Use a ping token, or pass it in the `X-AgentPing-Key` header.
:::

Runtime recipes: [curl](/docs/integrations/curl), [cron](/docs/integrations/cron), [GitHub Actions](/docs/integrations/github-actions), [n8n](/docs/integrations/n8n), [Make](/docs/integrations/make), [Zapier](/docs/integrations/zapier), [Claude Routines](/docs/integrations/claude-routines).
