Unclaimed Wallet API: backend integration brief Canonical guide: https://docs.unclaimedsol.com/api Contract revision: 18d446761b7d243b1c1a686f06ceb116d50378a5 (SDK preview.5) OBJECTIVE Implement server-side wallet analysis, explicit pagination and safe error handling. Current partner access is analysis-only. Do not implement signing, submission, claim execution or partner attribution without separately activated access. The API covers supported token-account cleanup and excess-lamport opportunities; it is not the full Unclaimed SOL consumer product. READ THESE SOURCES OpenAPI request/response contract (authoritative types and constraints): https://raw.githubusercontent.com/unclaimed-sol/unclaimed-wallet-sdk/18d446761b7d243b1c1a686f06ceb116d50378a5/openapi/analysis.yaml SDK validation and retry reference: https://github.com/unclaimed-sol/unclaimed-wallet-sdk/tree/18d446761b7d243b1c1a686f06ceb116d50378a5/src SDK usage: https://github.com/unclaimed-sol/unclaimed-wallet-sdk/blob/18d446761b7d243b1c1a686f06ceb116d50378a5/README.md 1. CONNECT Use direct HTTPS from Go, Python, Rust or any backend, or the optional @unclaimedsol/wallet-sdk@0.1.0-preview.5 for Node.js 22-24 (ESM/TypeScript). Direct HTTPS integrations do not need npm or the SDK version header. Endpoint: POST https://unclaimedsol.com/api/v1/check-wallet Headers: Authorization: Bearer Content-Type: application/json Accept: application/json Idempotency-Key: Body: {"wallet":"","mode":"safe","limit":20,"includeAirdrops":false} Obtain the activated key from the partner's backend secret loader. Do not ask for it in a chat, put it in browser code, commit it, or log it. The frontend calls the partner's authenticated backend; do not expose an unrestricted proxy. For SDK use, UNCLAIMED_API_ORIGIN is https://unclaimedsol.com with no /api/v1 suffix. The SDK does not load .env automatically. 2. VALIDATE AND DISPLAY Validate both successful and error envelopes against the pinned contract. Match the returned wallet to the request; enforce hasMore/nextCursor consistency, cursor format and first-page-only walletModulesIncluded semantics. Follow the SDK reference's schema and response checks rather than accepting arbitrary JSON. Read opportunities and protections from data.items. Keep exact base-unit amounts as decimal strings. Null values are unavailable, never zero. Do not count protected accounts or action=none as recoverable value or allow their selection. A stale_price result is valid: positive tokens remain protected and non-executable; independently verified empty accounts may still appear. Enforce the full stale conditional in the contract. Never relabel stale prices as zero or no_price. Required protection/account lookup failures still return 503 incomplete. Show returned fee/net estimates, not a promise of recovery. Estimates exclude network/setup costs. Deduplicate across loaded pages and do not double-count alternative/overlapping opportunities; mirror the SDK summarizeOpportunities helper or use it directly. Totals cover only loaded pages. Keep execution controls disabled when executionSession is null or executionSupported is false. 3. PAGINATION AND IDEMPOTENCY Persist each exact body and its idempotency key before sending; survive restarts. For an explicit user-requested next page, keep the wallet/settings unchanged, copy data.pagination.nextCursor into cursor, and persist a new key. Only do so when hasMore is true and nextCursor is present. SDK: nextWalletPage(input, page). Do not automatically paginate or retry. Unknown outcome (timeout, lost/malformed response, request_in_progress, platform_unavailable): retain and retry the exact original body and key. Parsed retryable terminal failure (including incomplete or platform_failure_recorded): a deliberate new attempt uses a new saved key. Honor retryAfterMs and any Retry-After delay. Never retry a nonretryable refusal without correcting its cause. For snapshot_expired or a deliberate fresh analysis, omit the cursor and save a new key. After a confirmed failed analysis and server correction, start this way. Reusing the old request/key replays its stored result; it does not refresh data. 4. LIMITS Confirm the partner's assigned policy. The current invited rollout permits 2 requests/minute and one in flight. Pace all calls, pages and replays at least 31 seconds apart and honor longer server delays. Allowance: 100 provider stages per customer per UTC day, within a shared 300-stage pool. New first pages reserve 3 stages; next pages reserve 1. Failed/uncertain reservations remain spent. Stored replays need no new provider stages but still consume request-rate capacity. Stop fresh attempts when exhausted; wait for the next UTC day or contact support. At most 400 token accounts/wallet and 200/page; start with limit=20. 5. OFFLINE ACCEPTANCE FIRST Use synthetic fixtures; do not scan real wallets to test application wiring. Verify: success with protected stale_price and empty siblings; exact amounts and non-overlapping totals; user-requested pagination; same-key retry after an unknown outcome; new-key fresh analysis after a confirmed terminal failure; rate pacing; no execution controls and no exposed credentials. Optional fixture app: npm install --save-exact --ignore-scripts @unclaimedsol/wallet-sdk@0.1.0-preview.5 node node_modules/@unclaimedsol/wallet-sdk/examples/reference/server.mjs Open http://127.0.0.1:4317. It uses synthetic data and requires no API key. Before any live acceptance, agree the wallet scope and finite request/provider allowance with the partner. Prior owner test allowances cannot be reused. DELIVERABLE Provide the integration patch, configuration variable names without secret values, offline test results, and any unresolved contract questions. Keep execution off.