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.
| Endpoint | Description |
|---|---|
GET /api/dashboard?w=24h|7d|30d|all | Headline stats: tx count, agents active, service revenue, providers detected. Plus topServices, topAgents, topProviders, recentEvents arrays. Cache: 5min edge. |
GET /api/services | All 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/agents | All 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/feed | Server-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
uint256strings — parse withBigInt. Divide by1e6for USDC display value. - Timestamps are ISO 8601 strings on the wire — parse with
new Date(). - Addresses are stored lowercase; normalize on input.
methodology_versionindicates which version of the matcher decoded the row.source_blocklets you re-derive any number against the raweventstable 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
| Endpoint | Description |
|---|---|
POST /api/wallet/device/start | Issue 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-init | Browser 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-finalize | Browser 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)
| Endpoint | Description |
|---|---|
POST /api/wallet/webauthn/register/options | Browser kicks off passkey enrollment. Returns PublicKeyCredentialCreationOptions. Sets a signed challenge cookie. |
POST /api/wallet/webauthn/register/verify | Browser 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/options | Sign-in options for an existing credential. |
POST /api/wallet/webauthn/auth/verify | Sign-in verify. Bumps passkey_sign_count, sets the user-session cookie. |
Payment
| Endpoint | Description |
|---|---|
POST /api/wallet/pay | Sign + 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
| Status | Reason |
|---|---|
| 401 | Missing or invalid bearer; missing user-session cookie |
| 403 | session expired, session revoked, session not yet on-chain authorized, per-call cap exceeded, lifetime cap exceeded |
| 400 | amount_wei not positive, to not a valid address, body malformed |
| 500 | On-chain payment failed, server-side state corruption |
Source
- API endpoints:
app/api/ - Wallet endpoints:
app/api/wallet/