Skip to Content
Devnet Preview: data may reset, no production guarantees.
API ReferencePOST /agent/heartbeat

POST /api/v1/agent/heartbeat

Submit a paid heartbeat. Replaces the deprecated checkin endpoint with economic accountability.

Auth: Authorization: Bearer pvn_...

Base URL: https://provenonce.io

Requires an active SIGIL for root agents (depth 0). Child agents (depth > 0) can heartbeat without a SIGIL — they inherit provenance from their parent. Root agents without a SIGIL receive HTTP 403.

Request

curl -X POST https://provenonce.io/api/v1/agent/heartbeat \ -H "Content-Type: application/json" \ -H "Authorization: Bearer pvn_..." \ -d '{ "payment_tx": "5xYzAbCd...", "global_anchor": 4215 }'

Request body

FieldTypeRequiredDescription
payment_txstringYesSolana transaction signature for the heartbeat fee
global_anchornumberNoGlobal anchor index claim. Server validates and uses the true server-side value.

Response

{ "ok": true, "agent_hash": "0xfd752396...", "passport": { "format_version": 1, "agent_hash": "0xfd752396...", "agent_public_key": "...", "authority_key_id": "pvn-ed25519-3f5b2f8a1b7c9d10", "identity_class": "autonomous", "registered_at_beat": 100, "sigil_issued_at_beat": 200, "last_heartbeat_beat": 5663, "lineage_chain_hash": "0xdef456...", "issued_at": 1771310460000, "valid_until": 1771396860000, "provenonce_signature": "a1b2c3d4e5f6..." }, "lineage_proof": { "...same as passport..." }, "total_heartbeats": 142, "heartbeat_count_epoch": 142, "billing_epoch": 1, "current_beat": 5663, "fee": { "amount_sol": 0.0005, "amount_lamports": 500000, "tier": 1, "payment_tx": "5xYzAbCd..." } }
FieldTypeDescription
okbooleantrue on success
agent_hashstringAgent identity hash
passportobjectFresh Ed25519-signed Passport (see below)
lineage_proofobjectDeprecated alias for passport (identical object, sunset 2026-09-01)
total_heartbeatsnumberUpdated total heartbeat count after this heartbeat
heartbeat_count_epochnumberHeartbeat count within current billing epoch
billing_epochnumberCurrent billing epoch number
current_beatnumberCurrent beat index
feeobjectFee details for this heartbeat

Passport

Each heartbeat returns a fresh Ed25519-signed Passport, valid for 24 hours. See authority key for offline verification.

FieldTypeDescription
format_versionnumberAlways 1 — canonical field order for verification
agent_hashstringAgent identity hash
agent_public_keystring | nullAgent wallet key/address used in proof binding
authority_key_idstringAuthority key identifier used for signing
identity_classstringnarrow_task, autonomous, or orchestrator
registered_at_beatnumberBeat at registration
sigil_issued_at_beatnumber | nullBeat when SIGIL was issued
last_heartbeat_beatnumberLast attested heartbeat beat
lineage_chain_hashstringHash of lineage event chain
issued_atnumberUnix timestamp (ms)
valid_untilnumberUnix timestamp (ms) expiry
provenonce_signaturestringHex Ed25519 signature over canonical JSON

Volume-tiered fees

Heartbeat fees decrease with volume within a billing epoch (100,000 beats).

Heartbeats in epochFee per heartbeat (SOL)Tier (numeric)
1-1000.00051
101-1,0000.00032
1,001+0.00023

The fee field in the response reflects the tier applied to this heartbeat.

Heartbeat caps per epoch

Each identity class has a maximum number of heartbeats per billing epoch.

Identity classCap per epoch
narrow_task1,000
autonomous5,000
orchestrator20,000

Once the cap is reached, further heartbeats return HTTP 429 until the next epoch.

Minimum interval

Heartbeats must be at least 10 beats apart (configurable server-side). Submitting a heartbeat before the minimum interval returns HTTP 429.

{ "error": "Heartbeat too soon", "code": "HEARTBEAT_TOO_SOON", "next_eligible_beat": 5670 }

Fee split

All heartbeat fees are allocated as follows:

AllocationPercentage
Operations30%
Contributors30%
DevelopmentStarts at 15%, decays 1%/year to 5% floor
TreasuryStarts at 15%, absorbs development decay
Referral10%

Development starts at 15% and decays by 1% per year to a 5% floor. Treasury absorbs the released share.

Error responses

StatusBodyCause
400{"error": "...", "code": "PAYMENT_REQUIRED"}Missing payment_tx
400{"error": "...", "code": "PAYMENT_INVALID"}Transaction not found or amount mismatch
400{"error": "...", "code": "PAYMENT_SENDER_MISMATCH"}Payment sender doesn’t match agent wallet
401{"error": "...", "code": "AUTH_MISSING"}Missing or invalid API key
403{"error": "...", "code": "WALLET_REQUIRED"}Agent is still api-sponsored; link wallet first
403{"error": "...", "code": "SIGIL_REQUIRED"}Root agent has no SIGIL (descendants bypass)
403{"error": "...", "code": "SPONSOR_PARENT_FROZEN"}Sponsor parent is frozen
409{"error": "...", "code": "PAYMENT_ALREADY_USED"}Payment tx already used for another heartbeat
429{"error": "...", "code": "HEARTBEAT_TOO_SOON"}Below minimum 10-beat interval
429{"error": "...", "code": "VOLUME_CAP_REACHED"}Heartbeat cap exceeded for identity class
429{"error": "...", "code": "SPONSOR_CAP_REACHED"}Sponsorship epoch cap exhausted
429{"error": "...", "code": "RATE_LIMITED"}Endpoint rate limit exceeded

Rate limit: 60/min per endpoint subject

For authenticated routes, buckets are keyed by endpoint path + authenticated agent identity. If identity is missing, the server falls back to endpoint path + client IP.

Last updated on