Docs / Protocol reference
HTTP API
Read-only records of bonded services, warranty claims and protocol events, built for third-party apps, mobile clients and autonomous agents. The chain is the source of truth; the API is an indexed, cacheable view of it.
OpenAPI 3.1 document: /docs/api/openapi.json (also served by the API itself at /v1/openapi.json). Base URL: https://api.lopw.com.
Endpoints
| Method and path | Returns | Parameters |
|---|---|---|
GET /healthz | { status, indexed_ledger, indexed_at }; 503 with a problem when unhealthy | — |
GET /v1/openapi.json | This document | — |
GET /v1/{network}/stats | Stats: network-wide totals | network |
GET /v1/{network}/services | { data: Service[], next_cursor } | state, cursor, limit |
GET /v1/{network}/services/{id} | Service | id: 64 hex |
GET /v1/{network}/services/{id}/claims | { data: Claim[], next_cursor }, newest first | outcome, cursor, limit |
GET /v1/{network}/services/{id}/events | { data: Event[], next_cursor }, newest first | cursor, limit |
GET /v1/{network}/claims | { data: Claim[], next_cursor }, newest first | outcome, cursor, limit |
GET /v1/{network}/stream | text/event-stream of contract events | after (or the Last-Event-ID header) |
GET /v1/{network}/scenarios | Scenario[] with plain-language notes and recent runs | runs 0 to 100, default 5 |
GET /v1/rates | Exchange-rate snapshot with exact cross rates | base, symbols, date |
network is testnet or mainnet. limit is 1 to 200, default 50. Operator-only endpoints under /v1/admin/ are not public.
Schemas
| Schema | Fields |
|---|---|
Service | service_id, seller, state, stake, min_stake, pending_withdrawal, terms_hash, key_version, claims { paid, rejected, total_paid }, registered_at, updated_at |
Claim | id, service_id, predicate_id 1 to 6, outcome paid | rejected, reason not_proven | not_verifiable | null, buyer, amount, payment_reference, transaction, ledger, occurred_at |
Event | id, kind (for example service_registered, deposited, slashed, state_changed, claim_paid, claim_rejected), service_id, contract_id, transaction, ledger, topics, data, occurred_at |
Stats | services, active_services, total_stake, claims_paid, claims_rejected, total_paid, indexed_ledger |
Scenario | id, title, summary, why, steps[], expected, service, totals { runs, passed }, runs[] with outcome pass | fail, observed, payment_tx, claim_tx, payout, stake_before, stake_after |
Problem | type, title, status, code (stable, mirrors contract error names where applicable), detail |
Amounts are decimal strings in the stake asset’s smallest unit (USDC: 7 decimals); 32-byte values are lowercase hex; times are Unix seconds; state is one of Pending, Active, Suspended, Unbonding, Closed.
Pagination, caching, limits, errors
- Pagination: pass the previous page’s
next_cursorascursor;nullmeans the end. - Caching: reads carry
ETag; sendIf-None-Matchto receive304 Not Modified. - Rate limits: advertised with
RateLimit-*headers; exceeding them returns429withRetry-After. - Errors:
application/problem+jsonwithstatus400, 404 or 429 and a machine-readablecode. - CORS: open on read endpoints; no cookies.
Live stream
GET /v1/testnet/stream
Accept: text/event-stream
id: 00000000000000123
event: claim_paid
data: { "id": "…", "kind": "claim_paid", "service_id": "…", "contract_id": "C…", "transaction": "…", "ledger": 5021500, "topics": [ … ], "data": { … }, "occurred_at": 1790991420 }Each message has id (event ID), event (the kind) and data (an Event). Resume after a disconnect with the Last-Event-ID header or ?after=<id>. Monitoring is built on this stream plus direct chain reads.