n8n
Every workflow execution can end with a heartbeat. One HTTP Request node on the success path, one on the error path.
The setup
Add an HTTP Request node at the end of your workflow:
- Method:
GET - URL:
https://eu.ingest.agentping.io/v1/ping?key={{ $env.AGENTPING_PING_TOKEN }}&agent=support-triage&status=ok
Store the ping token as an n8n environment variable, not inline. The token is per-agent; one per workflow keeps blast radius small.
For richer payloads, use POST against /v1/heartbeats with a JSON body assembled from n8n expressions:
{
"id": "{{ $execution.id }}",
"agent": "support-triage",
"status": "ok",
"started_at": "{{ $execution.startedAt }}",
"finished_at": "{{ $now }}",
"provider": "openai",
"model": "{{ $node[\"OpenAI\"].json.model }}",
"input_tokens": {{ $node["OpenAI"].json.usage.prompt_tokens }},
"output_tokens": {{ $node["OpenAI"].json.usage.completion_tokens }},
"metadata": {
"execution_id": "{{ $execution.id }}",
"tickets_processed": {{ $node["Triage Loop"].json.count }}
}
}
$execution.id is a useful idempotency key; retries become no-ops rather than duplicates.
Capturing cost
If your workflow calls an LLM via n8n's AI Agent, LLM Chain, OpenAI or Anthropic nodes, the node output already carries the model and a token usage block. Send those straight through and AgentPing prices the run from your rate card. There is no cost maths to do in the workflow.
Add model and the token counts to the ping URL (or the POST body above):
https://eu.ingest.agentping.io/v1/ping?key={{ $env.AGENTPING_PING_TOKEN }}&agent=support-triage&status=ok&provider=openai&model={{ $node["OpenAI"].json.model }}&input_tokens={{ $node["OpenAI"].json.usage.prompt_tokens }}&output_tokens={{ $node["OpenAI"].json.usage.completion_tokens }}
The exact field path varies by node and version: usage.prompt_tokens / usage.completion_tokens on the OpenAI and Anthropic nodes, tokenUsage.promptTokens / tokenUsage.completionTokens on the LangChain-based AI Agent and LLM Chain nodes. Map whichever your node exposes. If the model has no rate-card entry the run still records, at zero cost, and shows up in the unpriced-models banner on the Spend page.
Already have a dollar figure? Send cost_usd instead and it overrides token pricing. See Heartbeats for why heartbeat cost is trusted.
Status from exit state
Wire a second HTTP Request node to n8n's error connector with status=fail:
https://eu.ingest.agentping.io/v1/ping?key={{ $env.AGENTPING_PING_TOKEN }}&agent=support-triage&status=fail&metadata={{ $json.error.message | url_encode }}
Two nodes, same agent, opposite outcomes.
Schedule monitoring
If the workflow runs on a Schedule Trigger, set the same cron on the agent. Pulse pages you when a run misses its window. n8n tells you a run happened; Pulse tells you when one didn't.