Public wallet preview API
Contract 1.0 · Responsible team: Reclaim / MarketWhale · Reviewed 2026-09-09
Start with a public address
GET /api/v1/preview accepts one publicKey parameter. It reads Solana mainnet account state without signing, preparing transactions, creating a referral, or enrolling a wallet. No API key or wallet installation is required.
curl --get --fail-with-body \
--data-urlencode 'publicKey=YOUR_PUBLIC_WALLET_ADDRESS' \
https://reclaim.mwh.app/api/v1/previewReplace the placeholder with your public address. OpenAPI 3.1 contract · Illustrative JSON response. The example is a fixture, not a current observation of that wallet.
CLI and a runnable example
From a source checkout containing preview v1, install dependencies and run the command below. The npm silent flag suppresses npm’s own command banner so stdout contains exactly one JSON document; compiler diagnostics go to stderr.
npm install
npm --silent run wallet:check -- YOUR_PUBLIC_WALLET_ADDRESS --json
# Or, without dependencies (Node.js 20+):
node scripts/preview-wallet.mjs YOUR_PUBLIC_WALLET_ADDRESSThe CLI repository includes the runnable script and versioned agent guide. This integration is a source-checkout feature; no new npm package, release tag, or MCP installation is advertised here.
CLI exit codes: 0 = provisional eligible preview, 3 = valid empty or blocked preview, 2 = invalid input, 4 = throttled, 1 = transport, stale, or incompatible response. JSON mode requires an explicit public address and never loads a local signer. Without --json, the CLI prints an explanation of deductions.
Interpret the result
All amounts are decimal lamport strings. Parse them with BigInt or arbitrary-precision integers. The service and referral portions are separate deductions; with no referral input, both portions go to the service. The estimated net excludes network fees, which are null because no transaction is built. Batch rounding can change final deductions.
Reclaim deducts 10% of recovered account lamports: 6% service and 4% referral. Without a valid external referral, both portions go to the service.
At a wallet balance of 0.0001 SOL or less, the subsidized flow adds 0.0001 SOL per closed account. An additional account-rent charge can apply when no native SOL token account exists. Network fees and rounding can also change the final balance.
See the full fees and eligibility reference. Preview amounts are estimates.
accounts.candidates counts empty accounts the wallet can close after reserving one native SOL account. Accounts with a different close authority are excluded from the estimate. eligible means that the preview’s supported checks passed; it does not prove a transaction will succeed. Unknown Token-2022 extension requirements, signing capability, changed account state, or insufficient network-fee funds can still prevent execution.
observation records the lowest and highest context slots returned by the balance and token-account reads at confirmed commitment. These reads are not an atomic snapshot. The optional rent-minimum RPC has no context slot. Refresh after expiresAt (30 seconds), and recheck before signing even if that time has not passed.
{
"schemaVersion": "1.0",
"publicKey": "AuPp4YTMTyqxYXQnHc5KUc6pUuCSsHQpBJhgnD45yqrf",
"network": "mainnet-beta",
"observation": {
"commitment": "confirmed",
"minSlot": 101,
"maxSlot": 102,
"observedAt": "2026-09-09T12:00:00.000Z",
"expiresAt": "2026-09-09T12:00:30.000Z"
},
"accounts": {
"scanned": 2,
"empty": 2,
"candidates": 2,
"protected": 0
},
"amounts": {
"walletBalanceLamports": "1000000000",
"grossRentLamports": "4078560",
"deductions": {
"serviceLamports": "244713",
"referralPortionLamports": "163142",
"referralRecipient": "service",
"subsidyLamports": "0",
"serviceAccountRentLamports": "0",
"networkFeeLamports": null
},
"estimatedNetLamports": "3670705",
"estimatedNetIncludesNetworkFee": false
},
"eligibility": {
"status": "eligible",
"reasonCodes": []
},
"warnings": [
"ESTIMATE_NOT_SIMULATED",
"NETWORK_FEE_UNKNOWN",
"BATCH_ROUNDING_MAY_DIFFER"
],
"continueUrl": "https://reclaim.mwh.app/"
}Empty and unsupported wallets
- NO_EMPTY_ACCOUNTS: no zero-balance token accounts were found.
- ONLY_PROTECTED_NATIVE_ACCOUNT: no closable empty account remains after reserving one native SOL account.
- MISSING_NATIVE_SOL_ACCOUNT: a subsidized wallet has exactly one closable empty account and no native SOL token account.
- UNSUPPORTED_CLOSE_AUTHORITY: empty accounts exist, but the wallet cannot close them. When other accounts are closable, they remain eligible and this code appears as a warning.
- NO_POSITIVE_ESTIMATE: estimated deductions consume the gross amount.
Blocked and zero-result previews return HTTP 200 with structured eligibility reasons. No candidate list is silently truncated. Token-2022 accounts carry a validation warning; non-empty accounts, arbitrary program accounts, and mint accounts are not candidates. An off-curve owner needs program signing, which the ordinary browser/CLI signer does not provide.
Errors and request limits
- 400 INVALID_REQUEST / INVALID_PUBLIC_KEY: supply exactly one canonical base58 public address. Extra or duplicate parameters are rejected.
- 422 WALLET_TOO_LARGE: more than 5,000 accounts or more than 6 MiB of aggregate RPC response bytes. There is no partial estimate.
- 429 RATE_LIMITED: retry after the Retry-After interval. Capacity is shared globally: 120 requests per fixed minute across preview and enrollment endpoints, not 120 per wallet.
- 503 RPC_UNAVAILABLE / SERVICE_UNAVAILABLE: upstream response or quota storage unavailable. Retry later with backoff.
- 504 RPC_TIMEOUT: the 12-second total RPC deadline expired. No automatic server retry occurs.
A preview makes at most five RPC calls with at most three in parallel. The rate limiter has a separate two-second deadline and fails closed in production. Responses use no-store and noindex headers; indexable documentation is the discovery surface. GET supports public cross-origin reads without credentials.
Address handling and retention
The public preview endpoint does not save submitted addresses or balances, create referral records, or send preview events to analytics. Operational preview logs contain only API version, status, and duration. Quota records contain an aggregate minute counter and expire via DynamoDB TTL after one day; deletion is asynchronous.
The address is sent to the configured Solana RPC provider and appears in the request URL. Hosting/access logs, client/browser history, and the RPC provider may retain it under their own policies. This endpoint does not enforce a deletion period for those external records, so it is not a promise of zero retention. For retention questions, contact MarketWhale.
The website separately calls POST /api/reclaim/enroll for funded connected wallets. That operation creates a persistent referral profile. The website also has its own wallet interaction analytics. It is not called by this preview endpoint or the public-address CLI command.
Continue only within the user’s chosen scope
Explain the estimate, uncertainties, and costs. Offer the browser signing flow or advanced local execution when wanted. A preview is not authorization to sign. The current CLI signer does not independently enforce a complete instruction/destination/fee policy, so this API is not an unattended-signing integration.
MCP packaging is deferred until the contract is stable and preview adoption is demonstrated. Protocol sources: getTokenAccountsByOwner, getBalance, and CloseAccount.