Pellet Docs
API

REST API

HTTP endpoints for Pellet read queries and Wallet operations. Hosted at https://pellet.network.

All endpoints are hosted at https://pellet.network. Responses are JSON. CORS is open on the read endpoints.

Two surfaces:

  • Read — read-only queries against the public ledger. Unauthenticated.
  • Wallet — pairing, authorize, and payment operations. Bearer-authenticated for /pay; cookie-session-authenticated for the /device/* flow.

Read · /api/*

Live observability over autonomous economic activity on Tempo. See Methodology.

EndpointDescription
GET /api/dashboard?w=24h|7d|30d|allHeadline stats: tx count, agents active, service revenue, providers detected. Plus topServices, topAgents, topProviders, recentEvents arrays. Cache: 5min edge.
GET /api/servicesAll curated MPP services (id ends in -mpp) with 24h + 7d aggregates.
GET /api/services/[id]Service detail: head metadata, 30-day trend, recent 50 events. For tempo-gateway-mpp: also includes a providers[] aggregate (Pattern A address-attributed + Pattern B fingerprint-grouped).
GET /api/agentsAll watched non-MPP entities.
GET /api/agents/[id]Agent detail. Same shape as service detail.
GET /api/events/[id]Single event with provenance: agent, counterparty, amount, tx hash, log index, source block, methodology version, related events from the same tx.
GET /api/search?q=<query>Unified search across events (by tx hash or counterparty), agents/services (by id, label, wallet), labeled addresses. Min query length 2.
GET /api/feedServer-sent-events stream pushing new events as they're matched. Off by default — set NEXT_PUBLIC_LIVE_FEED=1 to enable.

Schema notes

  • Amounts are uint256 strings — parse with BigInt. Divide by 1e6 for USDC display value.
  • Timestamps are ISO 8601 strings on the wire — parse with new Date().
  • Addresses are stored lowercase; normalize on input.
  • methodology_version indicates which version of the matcher decoded the row.
  • source_block lets you re-derive any number against the raw events table on-chain.

Example

curl https://pellet.network/api/dashboard?w=24h
# → {
#   "windowHours": 24,
#   "txCount": 837,
#   "agentsActive": 6,
#   "amountSumWei": "308012247916",        # uint256 wei; /1e6 → $308k
#   "providersDetected": 10,
#   "topServices": [...],
#   "topAgents": [...],
#   "topProviders": [...],
#   "recentEvents": [...]
# }

Wallet · /api/wallet/*

Pairing + authorize + payment surface. Read more at Pellet Wallet and CLI.

Device-code pairing

EndpointDescription
POST /api/wallet/device/startIssue a device-code pairing. Body: { agent_label?: string }. Returns { code, device_id, approve_url, expires_at, poll_interval_seconds, pairing_id }. 5-min TTL.
GET /api/wallet/device/poll?device_id=<id>CLI poll. Returns { status: 'pending' | 'expired' | 'claimed' | 'approved' }. On first approved poll, mints + returns the bearer token (exactly once).
POST /api/wallet/device/approve-initBrowser kicks off approval. Cookie-authenticated (user must complete WebAuthn first). Body: { code, spend_cap_wei, per_call_cap_wei, session_ttl_seconds }. Generates the agent EOA, encrypts at rest, returns { credential_id, public_key_uncompressed, agent_key_address, agent_private_key, chain, account_keychain_address, expiry_unix, ... }. Browser uses these to construct the on-chain authorize call via viem.
POST /api/wallet/device/approve-finalizeBrowser POSTs { code, tx_hash } after the authorize tx confirms. Server fetches the receipt, verifies status=success + to=AccountKeychain + from=user.managed_address, persists authorize_tx_hash + on_chain_authorized_at. Flips pairing to approved.

WebAuthn (passkey enrollment + login)

EndpointDescription
POST /api/wallet/webauthn/register/optionsBrowser kicks off passkey enrollment. Returns PublicKeyCredentialCreationOptions. Sets a signed challenge cookie.
POST /api/wallet/webauthn/register/verifyBrowser submits the attestation. Server verifies, persists wallet_users row with the COSE pubkey + derives the Tempo address. Sets a 30min user-session cookie.
POST /api/wallet/webauthn/auth/optionsSign-in options for an existing credential.
POST /api/wallet/webauthn/auth/verifySign-in verify. Bumps passkey_sign_count, sets the user-session cookie.

Payment

EndpointDescription
POST /api/wallet/paySign + broadcast a transferWithMemo on Tempo. Bearer-authenticated. Body: { to, amount_wei, memo?, token? }. Server validates caps, decrypts the agent session key, signs via viem/tempo, broadcasts via withRelay (sponsored gas), bumps spend_used_wei. Returns { tx_hash, explorer_url, from, to, amount_wei, memo, token, spend_used_wei_after, spend_cap_wei }.

Auth shape

curl -X POST https://pellet.network/api/wallet/pay \
  -H 'Authorization: Bearer pwk_svuEqyiz…' \
  -H 'Content-Type: application/json' \
  -d '{
    "to": "0x000000000000000000000000000000000000dead",
    "amount_wei": "500000",
    "memo": "first payment"
  }'

The bearer token is what the CLI persists to ~/.pellet/config.json after pellet auth start. Server compares sha256(bearer) against wallet_sessions.bearer_token_hash.

Errors

StatusReason
401Missing or invalid bearer; missing user-session cookie
403session expired, session revoked, session not yet on-chain authorized, per-call cap exceeded, lifetime cap exceeded
400amount_wei not positive, to not a valid address, body malformed
500On-chain payment failed, server-side state corruption

Source