---
title: GET /v1/ping
description: The query-string heartbeat endpoint built for cron lines, wget, and curl one-liners.
section: api
order: 5
---

# GET /v1/ping

Single-request convenience over `POST /v1/heartbeats`. Everything goes in the query string, response is `OK\n`, fits in a cron line. Used by shell scripts, n8n HTTP nodes, Lambda last lines, GitHub Actions steps.

GET requests are conventionally side-effect-free; this one creates database records. JSON bodies are too much friction for the calling environments that hit this endpoint.

```
https://eu.ingest.agentping.io/v1/ping
```

## Query parameters

| Parameter | Required | Description |
|-----------|----------|-------------|
| `key` | Yes (or via header) | Ping token (`ping_...`, recommended) or full API key (`apk_...`, discouraged). See [Authentication](/docs/api/auth). |
| `agent` | Yes | Agent slug. New agents auto-created. |
| `status` | No (default `ok`) | `ok`, `fail`, `start`, `timeout`. `start` opens without finishing. |
| `cost_usd` | No | Numeric cost in US dollars. Overrides token pricing when both are sent. |
| `model` | No | Model id (e.g. `gpt-4o`, `claude-sonnet-4-6`). With token counts and no `cost_usd`, AgentPing prices the run from your rate card. |
| `provider` | No | Provider (e.g. `openai`, `anthropic`). Pairs with `model` for pricing. |
| `input_tokens` | No | Prompt/input tokens. Priced against the rate card when `model` is set. |
| `output_tokens` | No | Completion/output tokens. Priced against the rate card when `model` is set. |
| `cached_input_tokens` | No | Cache-read tokens, billed at the cached rate. |
| `duration_ms` | No | If absent, computed from a prior `start` ping with the same `id`. |
| `id` | No | Client-generated run ID. |
| `metadata` | No | Single string up to 256 characters, stored as a `note`. Requires a metadata-eligible plan (Team or above); silently dropped on Starter. For richer, use [`POST /v1/heartbeats`](/docs/api/heartbeats). |

## Response

`200 OK` with the smallest possible body:

```
OK
```

Pass `Accept: application/json` for the full JSON response:

```json
{
  "id": "run_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b9",
  "agent": "daily-summary",
  "status": "ok",
  "received_at": "2026-05-15T14:32:12.450Z"
}
```

Failures use `text/plain` so they're readable in shell output:

```
HTTP/1.1 400 Bad Request
Content-Type: text/plain

missing required parameter: agent
```

```
HTTP/1.1 401 Unauthorized
Content-Type: text/plain

This ping token is scoped to agent "daily-summary".
You attempted to fire a heartbeat for "competitor-scan".
```

## Examples

Cron daily heartbeat:

```cron
0 9 * * *  /usr/bin/wget -qO- 'https://eu.ingest.agentping.io/v1/ping?key=ping_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b6&agent=daily-summary&status=ok'
```

Failure ping with cost and a note:

```bash
curl 'https://eu.ingest.agentping.io/v1/ping?key=ping_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b6&agent=invoice-sync&status=fail&cost_usd=0.011&metadata=stripe%20rate%20limit'
```

Let AgentPing price the run from token counts (no cost maths in your workflow):

```bash
curl 'https://eu.ingest.agentping.io/v1/ping?key=ping_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b6&agent=lead-enrichment&status=ok&provider=openai&model=gpt-4o&input_tokens=1240&output_tokens=380'
```

Send `model` plus `input_tokens` / `output_tokens` (both from your AI node's usage block) and AgentPing computes the cost from your rate card. If the model has no rate-card entry the run is still recorded, at zero cost, and surfaces in the unpriced-models banner on the Spend page. Pass `cost_usd` instead when you already have a dollar figure; it always wins.

Header-auth variant for environments where query strings get logged:

```bash
curl -H "X-AgentPing-Key: ping_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b6" \
  'https://eu.ingest.agentping.io/v1/ping?agent=daily-summary&status=ok'
```

## Authentication

| Credential | When to use |
|------------|-------------|
| `ping_<region>_...` | Recommended. Scoped to one agent, can only fire heartbeats. A leak compromises one agent's status. |
| `apk_<region>_...` | Accepted but strongly discouraged. Full team key in a URL leaks through access logs, shell history, browser history, referer headers. |

The dashboard's "copy curl one-liner" always uses a `ping_` token.

:::warning
Never put an `apk_` key in a URL. Use a ping token for cron, curl, webhook URLs. Reserve the API key for header-based SDK calls.
:::

A credential whose region segment doesn't match the endpoint returns `401 Unauthorized` before any database lookup. A ping token used against a non-scope agent returns `401` with both slugs named. See [Authentication](/docs/api/auth).
