---
title: "Get ping instructions for a check"
method: GET
path: "/api/v1/checks/{id}/ping-instructions"
tags: ["Checks"]
---

# Get ping instructions for a check

`GET /api/v1/checks/{id}/ping-instructions`

## Request

- Base URL: `https://app.lastping.dev`
- URL: `https://app.lastping.dev/api/v1/checks/{id}/ping-instructions`
- Auth: API key in header `X-Api-Key`

Returns everything needed to make this monitor actually report: the
ping URL, copy-paste check-in snippets, and the three reporting
mechanisms (`how_to`, `hook_install`, `run_wrapper`) together.

This is the exact payload the MCP `get_ping_instructions` tool
returns — call this endpoint right after creating a check to hand an
agent (or a human) everything it needs in one response, rather than
composing curl commands from `ping_url` by hand.

Also carries the OpenTelemetry environment lines
(`otel_traces_endpoint`, `otel_resource_attributes`,
`otel_headers_hint`, `otel_env_lines`) for a run that wants to send
traces alongside its pings — see those fields' own descriptions on
`PingInstructions`.

`hook_tool=codex` or `hook_tool=antigravity` makes `hook_install` that
tool's install instead of Claude Code's; nothing else in the response changes.

404 if the check does not exist in the authenticated project (no
existence oracle).

## Query parameters

- `hook_tool` 'claude-code' | 'codex' | 'antigravity'

## Response `200`

Ping instructions for this check.

- PingInstructions: Everything needed to make a monitor actually report: the ping URL, copy-paste check-in snippets, and the three MECHANISMS for reporting, returned together. This is the exact payload the MCP `get_ping_instructions` tool returns — both surfaces are rendered from the same source, so they can never describe the reporting protocol differently. `reporting_options` explains how to choose between `how_to` (the universal manual protocol — works in any agent, any language, any tool, with no prerequisite), `hook_install` (an optional shortcut, Claude Code specific), and `run_wrapper` (wraps a launched command — cron, CI, a script — so a separate process reports for you). Read it before defaulting to the raw curl list.
  - `monitor_id` string, uuid, required
  - `monitor_name` string, required
  - `ping_url` string, required: The success-ping URL — a bare POST (or GET/HEAD) reports success.
  - `success_url` string, required: Identical to `ping_url`; present under both names for readability at each call site.
  - `start_url` string, required: `{ping_url}/start` — send before long or possibly-hung runs, to enable overrun/never-finished detection.
  - `fail_url` string, required: `{ping_url}/fail` — reports a failed run.
  - `step_url` string, required: `{ping_url}/step?rid=<run-id>&step=<step-name>` — a liveness marker inside an already-started run. `<run-id>` and `<step-name>` are literal placeholders to fill in, not escaped example values.
  - `curl_success` string, required
  - `curl_start` string, required
  - `curl_fail` string, required
  - `curl_step` string, required: A worked curl example carrying a literal `$RID` shell variable and a sample step label.
  - `cron_example` string, required: A one-liner pairing a job with its success ping, for a crontab entry.
  - `run_example` string, required: The whole armed run in the order it happens — start, steps, terminal ping — sharing one `$RID`, which the individual curl_* fields cannot show on their own.
  - `step_timeout_s` integer, nullable, required: The monitor's stall budget, echoed back so the caller can see whether the steps it is about to emit are actually watched. `null` means stall detection is off (the default).
  - `reporting_options` string, required: The decision rule for choosing between `how_to`, `hook_install` and `run_wrapper`, keyed on what the monitored thing IS.
  - `run_wrapper` string, required: The `lastping run` command-wrapper snippet. Fits anything launched as a command; cannot send `blocked` or `note`.
  - `hook_install` string, required: The one-time hook install, Claude Code's by default, or Codex's or Antigravity CLI's with `hook_tool`. Specific to that tool; installed once, it reports runs from the tool's own hooks.
  - `how_to` string, required: The manual protocol prompt — the universal path, fitting any agent, any language, any tool.
  - `how_to_steps` string, required: Explains step reporting (`curl_step`) and whether stall detection is armed on this monitor.
  - `expectations_how_to` string, required: How to commit, at the START of a run, to the criteria that run will be judged by when it closes — before the outcome is knowable. Immutable once declared; declaring nothing is allowed and leaves the monitor's own assertions in force.
  - `failure_inbox_how_to` string, required: The RETURN path: how to read what broke while this agent was not running (`GET /api/v1/agents/{id}/open-incidents`) and how to write the diagnosis back onto the incident a human reads (`POST /api/v1/incidents/{id}/notes`). Every other field here is about reporting outward; this is the only one that flows back.
  - `discovery_how_to` string, required: How to find what ELSE ought to be monitored — crontab lines, GitHub Actions schedules, Kubernetes CronJobs, systemd timers — and reconcile the scan into monitors via `POST /api/v1/discovery/reconcile`. Scanning is entirely agent-side; LastPing never reads a repository or logs into a host. Carries the three rules that make the scan safe: propose what you found and get agreement before creating anything, READ the host's timezone rather than assume one for `crontab` and `systemd-timer` sources (they fire in local time), and the fact that reconcile never deletes, pauses or edits anything — which is what makes it safe to re-run as drift detection. Project-scoped rather than check-scoped, and served here on purpose: this is the endpoint an agent is already told to call right after creating a monitor, which is the moment the question "what else here is unwatched?" is both live and answerable.
  - `otel_traces_endpoint` string, required: The OTLP/HTTP traces endpoint — the ping HOST alone (e.g. `https://ping.lastping.dev/v1/traces`), not this monitor's own `ping_url`: the Bearer-authenticated `/v1/traces` route takes its project from the API key, not a path segment. Standard OTel exporters need only this value and a header to start sending traces with no code change.
  - `otel_resource_attributes` string, required: The literal `OTEL_RESOURCE_ATTRIBUTES` value: this monitor's id. A run id is optional (each trace becomes its own run without one), so none is baked in.
  - `otel_headers_hint` string, required: The literal `OTEL_EXPORTER_OTLP_HEADERS` value, with a placeholder for a tracing key: an `ingest` key bound to this monitor (`POST /api/v1/checks/{id}/ingest-keys`), never the caller's own read, write or admin key. The monitor-URL form (`{ping_url}/v1/traces`) needs no header at all: the monitor id in the URL is itself the capability.
  - `otel_env_lines` string[], required: Ready-to-source shell `export` statements, one string per line: `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` (the signal-specific variable, so it carries the full `/v1/traces` path), `OTEL_EXPORTER_OTLP_PROTOCOL` (required: Python's distro otherwise picks a protocol LastPing does not accept), `OTEL_RESOURCE_ATTRIBUTES` and `OTEL_EXPORTER_OTLP_HEADERS`. Kept for compatibility; `GET /api/v1/checks/{id}/trace-setup` is the complete, per-tool form.
  - `tracing_how_to` string, required: The tracing section of the protocol prompt: what an agent does, itself, to make its tool send OpenTelemetry to this monitor (pick its tool, fetch that tool's block from `GET /api/v1/checks/{id}/trace-setup` with `tool` set, write the files, keep the key out of committed code and never echo it, send a test span and report where it landed), and the content default (prompts and commands are not stored unless a person turns on "Store prompts and commands" for the monitor). It never contains a key. The per-tool blocks are not in this payload.

## Other responses

- `400`: id is not a valid UUID, or `hook_tool` is not one of the listed values (`UNKNOWN_HOOK_TOOL`).
- `401`: Missing or invalid API key.
- `404`: Check not found in this project.

---

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