Quickstart
This assumes a running instance — see Installation.
1. Register a contract
POST the contract id. Sierpe reads its on-chain spec, classifies it (SAC
by executable, wasm events from contractspecv0), and starts a
descending backfill while following the tip:
curl -X POST localhost:8080/v1/contracts \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"contract_id": "CBMLLYBH...", "from": "genesis",
"kinds": ["events", "state", "movements"]}'
kinds picks what gets derived — events, state, transfers,
trustlines, movements. Omitting it gives events and state
(transfers too for a SAC). If you care about deposits — anything
entering or leaving the contract — include movements; see step 5.
from takes "genesis" or a ledger number. Adding a kind later reopens
the history walk for it, so nothing is lost by starting small.
Registration is idempotent. DELETE stops indexing but keeps the data;
re-registering resumes where it left off. If HTTP_BASIC_AUTH is set,
add -u user:password to every request in this guide.
2. Watch it work
curl localhost:8080/v1/contracts/CBMLLYBH...
The response includes the classification, discovered event names, backfill progress and derived coverage — the exact ledger ranges Sierpe can answer for.
3. Query events
Filters follow the proposed getEvents v2 semantics — positional topic
filters, opaque cursors:
curl "localhost:8080/v1/contracts/CBMLLYBH.../events?topic0=<base64-scval>&limit=100"
Every page declares coverage and a scanStatus:
| scanStatus | Meaning |
|---|---|
COMPLETE |
The full requested range was scanned |
HAS_MORE |
More results — follow the cursor |
WAITING_FOR_LEDGERS |
Part of the range isn’t indexed yet |
OLDEST_REACHED |
You hit the oldest ledger Sierpe has |
The cursor encodes the whole query, so pagination never drifts: passing a cursor and different filters is a 400, by design.
4. Query contract state
Current snapshot of storage entries, or the full change history of any entry with provenance:
curl "localhost:8080/v1/contracts/CBMLLYBH.../state?key=<base64-scval>"
curl "localhost:8080/v1/contracts/CBMLLYBH.../state/history?startLedger=..."
5. See what moved in and out
With the movements kind, every token transfer that names your contract
as sender or recipient lands here — whoever emitted it. A payment of any
asset to your contract is emitted by the asset’s own SAC, and you do
not need to register that SAC:
curl "localhost:8080/v1/contracts/CBMLLYBH.../movements?role=recipient"
Each row carries role, transferType, the exact amount in raw token
units, tokenContractId (the asset’s real identity) and the
counterparty. Two caveats the response itself repeats: movements are
evidence of token events, not a balance, and amounts from different
tokenContractId values must never be summed — different tokens,
different scales.
The backfill derives movement history from before the contract was registered, so yesterday’s deposits appear too.