{"openapi":"3.0.0","info":{"title":"bluepages.fyi API","description":"Cryptocurrency address identity lookup service with cluster detection. Maps cryptocurrency addresses (ETH, BTC, LTC, BCH, SOL, TRON, DASH, DOGE, XMR, ZEC, ADA, XLM, ALGO, BNB, LSK, SC, TON, Celestia, XRP) to Twitter, email, Farcaster, and other identities. Includes cluster analysis to find related addresses controlled by the same entity.\n\n**Concepts — Identity:** An *identity* is a non-address handle linked to one or more cryptocurrency addresses. Supported types: Twitter handle (with or without `@`), email address, Farcaster username, or generic username. The `identity` query parameter on `/check` and `/data` accepts any of these; the server detects the type automatically.\n\n**Authentication & pricing:** The lookup endpoints (`/check`, `/data`, `/batch/check`, `/batch/data`) require payment. Two options: (1) **x402** — pay per-request in USDC on Base; unauthenticated requests receive `402 Payment Required` with payment instructions; or (2) **API key** — send `X-API-KEY: <key>` header; requests are debited from prepaid credits (see `GET /api/packages`). Obtain an API key by signing in with Ethereum: `GET /api/nonce` then `POST /api/auth`. Other endpoints (`/opt-out`, `/opt-out/status`, `/api/packages`) are free.","version":"2.1.0","contact":{"url":"https://bluepages.fyi"}},"servers":[{"url":"https://bluepages.fyi","description":"Production server"}],"paths":{"/check":{"get":{"operationId":"checkExistence","summary":"Check if address or identity exists","description":"Check whether a cryptocurrency address or identity exists in the database. Paid: $0.001 per request via x402, or credits via `X-API-KEY`.","parameters":[{"name":"address","in":"query","description":"Cryptocurrency address to check (ETH, BTC, LTC, BCH, SOL, TRON, DASH, DOGE, XMR, ZEC, ADA, XLM, ALGO, BNB, LSK, SC, TON, Celestia, XRP). Matching is case-insensitive within a valid address shape. Either address or identity must be provided.","required":false,"schema":{"type":"string","example":"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1"}},{"name":"identity","in":"query","description":"Identity to check. Either address or identity must be provided.","required":false,"schema":{"type":"string","example":"@vitalikbuterin"}}],"responses":{"200":{"description":"Existence check result","content":{"application/json":{"schema":{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time"},"query":{"type":"object","properties":{"type":{"type":"string","description":"Query type (e.g., 'address' or 'identity')"},"value":{"type":"string","description":"Normalized query value"}}},"exists":{"type":"boolean","description":"Whether any identity data exists for the queried input"},"types":{"type":"array","items":{"type":"string"},"description":"Identity types found (e.g., ['twitter', 'farcaster'])"},"message":{"type":"string"}}}}}},"402":{"description":"Payment required (x402 protocol (USDC on Base) or a valid `X-API-KEY` with sufficient credits)"}}}},"/data":{"get":{"operationId":"getData","summary":"Get full identity and cluster data","description":"Retrieve full identity data for an address or identity, including all linked identities (Twitter, email, Farcaster) and cluster information showing other addresses controlled by the same entity. Paid: $0.05 per request via x402, or credits via `X-API-KEY`.","parameters":[{"name":"address","in":"query","description":"Cryptocurrency address to query (ETH, BTC, LTC, BCH, SOL, TRON, DASH, DOGE, XMR, ZEC, ADA, XLM, ALGO, BNB, LSK, SC, TON, Celestia, XRP). Matching is case-insensitive within a valid address shape. Either address or identity must be provided.","required":false,"schema":{"type":"string","example":"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1"}},{"name":"identity","in":"query","description":"Identity to query. Either address or identity must be provided.","required":false,"schema":{"type":"string","example":"@vitalikbuterin"}},{"name":"maxClusterSize","in":"query","description":"Maximum number of cluster addresses to return (default: 100)","required":false,"schema":{"type":"integer","default":100}},{"name":"fullCluster","in":"query","description":"Set to 'true' to return all cluster addresses (can be large)","required":false,"schema":{"type":"boolean","default":false}},{"name":"includeUnidentified","in":"query","description":"Set to 'true' to include cluster members without known identities","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Successfully retrieved data. Response shape depends on the query type: address lookup returns a single record, identity lookup returns a list of matching records.","content":{"application/json":{"schema":{"oneOf":[{"type":"object","description":"Address lookup response (query.type === 'address')","properties":{"timestamp":{"type":"string","format":"date-time"},"query":{"type":"object","properties":{"type":{"type":"string","enum":["address"]},"value":{"type":"string"}}},"found":{"type":"boolean","enum":[true]},"address":{"type":"string","description":"Resolved Ethereum address"},"identities":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["twitter","email","farcaster","username"]},"value":{"type":"string"},"source":{"type":"string"}}}},"cluster":{"type":"object","properties":{"id":{"type":"string"},"source":{"type":"string"},"identified":{"type":"boolean"},"totalAddresses":{"type":"integer"},"addresses":{"type":"array","items":{"type":"string"}},"truncated":{"type":"boolean"}}},"twitterSearch":{"type":"object","description":"Pointer to the /search/tweets endpoint for live Twitter/X search","properties":{"available":{"type":"boolean"},"endpoint":{"type":"string","description":"Full endpoint URL with address"},"price":{"type":"string","description":"Cost per search"}}},"labels":{"type":"array","description":"Known labels for this address (e.g., CEX, DEX, bridge)","items":{"type":"object","properties":{"type":{"type":"string","description":"Label category (e.g., 'cex')"},"name":{"type":"string","description":"Entity name (e.g., 'Binance')"},"detail":{"type":"string","description":"Specific wallet identifier (e.g., 'Binance 1')"},"source":{"type":"string","description":"Data source (e.g., 'hildobby')"}}}},"sanctions":{"type":"array","description":"Sanctions entries for this address from all sources (current and historical)","items":{"type":"object","properties":{"source":{"type":"string","description":"Sanctions list source identifier (e.g., 'ofac_sdn', 'uk_ofsi')"},"entity":{"type":"string","description":"Sanctioned entity name (e.g., 'LAZARUS GROUP')"},"programs":{"type":"array","items":{"type":"string"},"description":"Sanctions programs or regimes (e.g., ['CYBER2', 'DPRK'])"},"addedAt":{"type":"string","description":"Date added to sanctions list (YYYY-MM-DD)"},"removedAt":{"type":"string","nullable":true,"description":"Date removed from sanctions list (null if still active)"},"active":{"type":"boolean","description":"Whether the sanction is currently active"}}}}}},{"type":"object","description":"Identity lookup response (query.type === 'identity')","properties":{"timestamp":{"type":"string","format":"date-time"},"query":{"type":"object","properties":{"type":{"type":"string","enum":["identity"]},"value":{"type":"string"}}},"found":{"type":"boolean","enum":[true]},"totalMatches":{"type":"integer"},"results":{"type":"array","items":{"type":"object","description":"A matched record: spreads the same fields as the address-lookup response, with extra matchType/matchedValue fields.","properties":{"matchType":{"type":"string"},"matchedValue":{"type":"string"},"address":{"type":"string"},"identities":{"type":"array","items":{"type":"object"}},"cluster":{"type":"object"},"labels":{"type":"array","description":"Known labels for this address (e.g., CEX, DEX, bridge)","items":{"type":"object","properties":{"type":{"type":"string","description":"Label category (e.g., 'cex')"},"name":{"type":"string","description":"Entity name (e.g., 'Binance')"},"detail":{"type":"string","description":"Specific wallet identifier (e.g., 'Binance 1')"},"source":{"type":"string","description":"Data source (e.g., 'hildobby')"}}}},"sanctions":{"type":"array","description":"Sanctions entries for this address from all sources (current and historical)","items":{"type":"object","properties":{"source":{"type":"string"},"entity":{"type":"string"},"programs":{"type":"array","items":{"type":"string"}},"addedAt":{"type":"string"},"removedAt":{"type":"string","nullable":true},"active":{"type":"boolean"}}}}}}}}}]}}}},"402":{"description":"Payment required (x402 protocol (USDC on Base) or a valid `X-API-KEY` with sufficient credits)"},"404":{"description":"Not found — includes a twitterSearch hint for address queries","content":{"application/json":{"schema":{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time"},"query":{"type":"object"},"found":{"type":"boolean","enum":[false]},"message":{"type":"string"},"twitterSearch":{"type":"object","description":"Pointer to the /search/tweets endpoint for live Twitter/X search","properties":{"available":{"type":"boolean"},"endpoint":{"type":"string"},"price":{"type":"string"}}}}}}}},"503":{"description":"Database initializing — retry shortly"}}}},"/search/tweets":{"get":{"operationId":"searchTweets","summary":"Search Twitter/X for tweets mentioning an address","description":"Live search of Twitter/X for tweets that mention a given cryptocurrency address. Charged whenever the search ran, even if no tweets are found. Not charged when the search backend is unavailable (503). Paid: $0.05 per request via x402, or 50 credits via `X-API-KEY`.","parameters":[{"name":"address","in":"query","description":"Cryptocurrency address to search for on Twitter/X.","required":true,"schema":{"type":"string","example":"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1"}}],"responses":{"200":{"description":"Search results (may be empty if no tweets found)","content":{"application/json":{"schema":{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time"},"query":{"type":"object","properties":{"type":{"type":"string","enum":["address"]},"value":{"type":"string"}}},"tweets":{"type":"object","description":"Tweet search results (count may be 0). A backend failure is a 503, not a null here.","properties":{"count":{"type":"integer","description":"Number of tweets found"},"results":{"type":"array","items":{"type":"object"},"description":"Array of tweet objects"}}}}}}}},"400":{"description":"Missing or invalid address parameter"},"402":{"description":"Payment required (x402 protocol (USDC on Base) or a valid `X-API-KEY` with sufficient credits)"},"503":{"description":"Search backend unavailable (timeout, no scraper accounts, upstream error). Not charged: no credits deducted, no x402 settlement."}}}},"/opt-out/status":{"get":{"operationId":"getOptOutStatus","summary":"Check opt-out status for an address","description":"Check whether a given address has opted out of appearing in bluepages.fyi lookups.","parameters":[{"name":"address","in":"query","description":"Ethereum address to check","required":true,"schema":{"type":"string","example":"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1"}}],"responses":{"200":{"description":"Opt-out status","content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string","description":"Normalized (lowercased) address"},"optedOut":{"type":"boolean"},"timestamp":{"type":"string","format":"date-time","nullable":true,"description":"When the opt-out was recorded. Null if not opted out."}}}}}},"400":{"description":"Missing or invalid address parameter"}}}},"/opt-out":{"post":{"operationId":"optOut","summary":"Opt an address out of lookups","description":"Opt an address out by signing an EIP-4361 (Sign-In with Ethereum) message with the wallet that controls it. Flow: (1) `GET /api/nonce`; (2) build a SIWE message with `domain` matching this API's host (e.g., `bluepages.fyi`), your address, the nonce, the statement `Opt out of Bluepages data.`, and an expiration within 5 minutes; (3) sign it with `personal_sign`; (4) POST the message and signature. The address that is opted out is the one recovered from the signature — there is no separate `address` field. The nonce is consumed on first use, so each signature works exactly once; fetch a fresh nonce per attempt.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["message","signature"],"properties":{"message":{"type":"string","description":"Full EIP-4361 message text that was signed. Must carry a one-time nonce from `GET /api/nonce`, this API's host as its domain, and an expiration time."},"signature":{"type":"string","description":"Hex signature from personal_sign (0x-prefixed)"},"twitter":{"type":"string","description":"Optional Twitter handle to opt out alongside the address"}}}}}},"responses":{"200":{"description":"Opt-out processed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"record":{"type":"object","description":"The stored opt-out record (only present on success)","properties":{"address":{"type":"string"},"twitter":{"type":"string","nullable":true},"signature":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"message":{"type":"string","description":"The message that was signed"},"cascadedAddresses":{"type":"array","items":{"type":"string"},"description":"Related addresses also opted out via cluster cascade"},"cascadedIdentities":{"type":"array","items":{"type":"string"},"description":"Related identities also opted out via cascade"}}},"cascaded":{"type":"object","properties":{"addresses":{"type":"integer"},"identities":{"type":"integer"}}},"error":{"type":"string","description":"Present when success is false (e.g., 'Invalid signature', 'Address already opted out')"}}}}}},"400":{"description":"Missing message/signature, invalid address in the SIWE message, or invalid Twitter handle","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"string"}}}}}},"401":{"description":"Rejected SIWE message — domain mismatch, expired message, invalid or already-used nonce, or signature does not match the address","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"string"}}}}}}}}},"/batch/check":{"post":{"operationId":"batchCheck","summary":"Batch existence check","description":"Check existence for up to 50 addresses and/or identities in a single request. Paid: flat $0.04 per batch via x402; or via `X-API-KEY` at 40 credits per found item + 1 credit per not-found item.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"addresses":{"type":"array","items":{"type":"string"},"description":"Cryptocurrency addresses to check"},"identities":{"type":"array","items":{"type":"string"},"description":"Identities to check (Twitter handles, emails, usernames)"}},"description":"Combined size of addresses + identities must not exceed 50."}}}},"responses":{"200":{"description":"Batch check results","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"timestamp":{"type":"string","format":"date-time"},"totalItems":{"type":"integer"},"results":{"type":"object","properties":{"addresses":{"type":"object","description":"Keyed by the input address. Value is `{exists, types[]}` or `{error}`.","additionalProperties":{"type":"object","properties":{"exists":{"type":"boolean"},"types":{"type":"array","items":{"type":"string"},"description":"Identity types found (e.g., twitter, farcaster)"},"error":{"type":"string"}}}},"identities":{"type":"object","description":"Keyed by the input identity. Value is `{exists, types[]}`.","additionalProperties":{"type":"object","properties":{"exists":{"type":"boolean"},"types":{"type":"array","items":{"type":"string"},"description":"Identity types found"}}}}}}}}}}},"400":{"description":"Invalid body — missing arrays, empty batch, or more than 50 combined items"},"402":{"description":"Payment required (x402 protocol (USDC on Base) or a valid `X-API-KEY` with sufficient credits)"}}}},"/batch/data":{"post":{"operationId":"batchData","summary":"Batch full data lookup","description":"Retrieve full identity data for up to 50 addresses and/or identities in a single request. Paid: flat $2.00 per batch via x402, or credits via `X-API-KEY`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"addresses":{"type":"array","items":{"type":"string"},"description":"Cryptocurrency addresses to look up"},"identities":{"type":"array","items":{"type":"string"},"description":"Identities to look up (Twitter handles, emails, usernames)"}},"description":"Combined size of addresses + identities must not exceed 50."}}}},"responses":{"200":{"description":"Batch data results","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"timestamp":{"type":"string","format":"date-time"},"totalItems":{"type":"integer"},"results":{"type":"object","properties":{"addresses":{"type":"object","description":"Keyed by the input address. Value is `{found:true, address, identities[], labels[], sanctions[], cluster}`, `{found:false}`, or `{error}`.","additionalProperties":{"type":"object"}},"identities":{"type":"object","description":"Keyed by the input identity. Value is `{found:true, totalMatches, results[]}` or `{found:false}`.","additionalProperties":{"type":"object"}}}}}}}}},"400":{"description":"Invalid body — missing arrays, empty batch, or more than 50 combined items"},"402":{"description":"Payment required (x402 protocol (USDC on Base) or a valid `X-API-KEY` with sufficient credits)"}}}},"/api/packages":{"get":{"operationId":"listPackages","summary":"List available credit packages and pricing","description":"Returns the catalog of purchasable credit packages and current pricing.","responses":{"200":{"description":"Package catalog","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"packages":{"type":"object","description":"Purchasable credit packages, keyed by package name (e.g., 'starter', 'pro', 'enterprise').","additionalProperties":{"type":"object","properties":{"credits":{"type":"integer"},"priceUsd":{"type":"number"},"priceUsdc":{"type":"integer","description":"Price in USDC base units (6 decimals)"}}}},"pricing":{"type":"object","description":"Credit cost per endpoint, keyed by path (e.g., '/check', '/data', '/batch/check', '/batch/data').","additionalProperties":{"type":"integer"}}}}}}}}}},"/api/nonce":{"get":{"operationId":"getSiweNonce","summary":"Get a nonce for SIWE authentication","description":"Returns a nonce (valid 5 minutes) to embed in a Sign-In with Ethereum (EIP-4361) message for `POST /api/auth` or `POST /api/regenerate-key`. Rate limited per IP together with the auth endpoints.","responses":{"200":{"description":"Nonce issued","content":{"application/json":{"schema":{"type":"object","properties":{"nonce":{"type":"string","description":"Value for the Nonce field of the SIWE message"}}}}}},"429":{"description":"Too many auth attempts from this IP"}}}},"/api/auth":{"post":{"operationId":"authenticateSiwe","summary":"Sign in with Ethereum to create or fetch your API key","description":"Authenticate by signing an EIP-4361 (Sign-In with Ethereum) message with your wallet. Flow: (1) `GET /api/nonce`; (2) build a SIWE message with `domain` matching this API's host (e.g., `bluepages.fyi`), your address, the nonce, and an expiration within 5 minutes; (3) sign it with `personal_sign`; (4) POST the message and signature. Creates a new account (0 credits) on first sign-in, otherwise returns the existing account including its API key. The nonce is consumed on first use — fetch a fresh one per attempt.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["message","signature"],"properties":{"message":{"type":"string","description":"Full EIP-4361 message text that was signed"},"signature":{"type":"string","description":"Hex signature from personal_sign (0x-prefixed)"}}}}}},"responses":{"200":{"description":"Authenticated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"isNew":{"type":"boolean","description":"True if this sign-in created the account"},"user":{"type":"object","properties":{"address":{"type":"string"},"apiKey":{"type":"string","description":"Send as X-API-KEY on paid endpoints"},"credits":{"type":"integer"},"points":{"type":"integer"},"totalRequests":{"type":"integer"},"createdAt":{"type":"string"},"lastUsedAt":{"type":"string","nullable":true},"suspended":{"type":"boolean"}}}}}}}},"400":{"description":"Missing message/signature or invalid address in the SIWE message"},"401":{"description":"Rejected SIWE message — domain mismatch, expired message, invalid or already-used nonce, or signature does not match the address"},"429":{"description":"Too many auth attempts from this IP"}}}},"/api/regenerate-key":{"post":{"operationId":"regenerateApiKey","summary":"Regenerate your API key (invalidates the old one)","description":"Issue a new API key for your account, invalidating the previous key. Requires the same SIWE flow as `POST /api/auth`: fetch a fresh nonce, sign an EIP-4361 message, and POST it with the signature.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["message","signature"],"properties":{"message":{"type":"string","description":"Full EIP-4361 message text that was signed"},"signature":{"type":"string","description":"Hex signature from personal_sign (0x-prefixed)"}}}}}},"responses":{"200":{"description":"New key issued; the old key is now invalid","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"apiKey":{"type":"string"}}}}}},"400":{"description":"Missing message/signature or invalid address in the SIWE message"},"401":{"description":"Rejected SIWE message — domain mismatch, expired message, invalid or already-used nonce, or signature does not match the address"},"429":{"description":"Too many auth attempts from this IP"}}}}},"components":{"schemas":{}}}