Skip to main content
Private alpha, partial coverage. The API is in private alpha (release_status: "alpha_partial"): a token is required and only some protocols are covered. See Supported protocols.
This page takes you from zero to a wallet snapshot, then shows how to read it and how to handle values that are unknown. All examples use this base URL and, during the alpha, an access token in an environment variable:

Base URL and access token

  • Production: https://api.lucidblock.xyz. Local development: http://127.0.0.1:8789 (pnpm dev).
  • During the private alpha every /v1/* route except /v1/health needs a token. Request one at <CONTACT_EMAIL>. Send it as Authorization: Bearer $LUCIDBLOCK_TOKEN on every request. Never put it in a URL.
  • /v1/health, /openapi.json and / need no token.

Your first request in 60 seconds

The first request for a wallet nobody has looked up recently returns 202 with a scan job: the API has queued a bounded scan of the supported protocols. Poll the job (it costs 1 rate-limit unit; a wallet read costs 5), wait the number of seconds in Retry-After / retry_after_seconds, and when the job reaches succeeded or partial, request the wallet again to get the 200 snapshot. A wallet with a fresh snapshot returns 200 straight away.
Simplest integration: add ?wait=8. The API then holds a cold request open for up to 8 seconds while the scan runs and answers with the 200 snapshot in one call in most cases. If the scan takes longer you get the same 202 as without wait, so keep the polling loop below as the fallback. wait is 0 to 10 seconds (default 0) and the call costs 5 units once. See Integrate with ?wait=8.
The full flow with polling as the fallback:
A captured 202 (from local development):
GET /v1/solana/wallets/BWJUG6W67qRq7Xbkv3cLo7m4zEr21oJKg93ens3mLmBg/defi-positions → 202 (captured 2026-11-12 from local positions-202)

Reading a response

Read a snapshot in this order. The captured response below is a native-stake wallet (two stake accounts the wallet can withdraw).
  1. coverage: did we look everywhere we support? coverage.status is complete_for_supported_protocols here, and every entry of coverage.protocols is complete. A missing position means something only for protocols listed complete (Concepts: coverage vs valuation).
  2. totals: total_value_usd is a real total only when coverage is complete and every counted leg is priced; otherwise it is null and total_null_reasons says why. known_value_usd is the sum of the legs we could price (Concepts: totals).
  3. positions[]: each position has assets, debts and rewards legs. Each leg has an exact amount, a value_usd (or null), its pricing_source and valuation_status, and whether it counts (in_totals) (Concepts: positions, legs and roles).
GET /v1/solana/wallets/G4VmLamEV6h15gndx7nHn8TTcu7fJkBBNVN3wTugMNtH/defi-positions → 200 (captured 2026-11-12 from local positions-native-stake)

Other useful first requests

Rate limits

60 units per minute per IP: a wallet read costs 5 units, everything else costs 1, and at most 20 requests per hour may start a new scan. Every response carries RateLimit-Remaining; a 429 carries Retry-After. Details: Rate limits and access.

Next steps