{"openapi":"3.0.0","info":{"title":"WDK Indexer API","description":"API for querying blockchain token transfers and balances across multiple networks. Authenticated endpoints require an API key passed via the X-API-KEY header.","version":"1.0.0"},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-KEY","description":"API key obtained via the registration form. Include in the X-API-KEY header for all authenticated requests."}},"schemas":{}},"paths":{"/api/v1/health":{"get":{"summary":"Deep health check endpoint","tags":["Health"],"description":"Checks internal dependencies and blockchain indexer sync status. Returns HTTP 200 only when the overall status is `healthy`. Returns HTTP 503 for any non-healthy overall status (`degraded` or `unhealthy`), so readiness probes and load balancers can rely on the HTTP status code alone.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","degraded","unhealthy"],"example":"healthy"},"timestamp":{"type":"string","format":"date-time"},"deployEnvironment":{"type":"string","example":"production"},"deployedVersion":{"type":"string","example":"1.1.2"},"summary":{"type":"object","properties":{"healthy":{"type":"integer","example":10},"unhealthy":{"type":"integer","example":2},"total":{"type":"integer","example":12}}},"checks":{"type":"object","properties":{"dependencies":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","unhealthy"],"example":"healthy"}}},"indexers":{"type":"object","additionalProperties":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","unhealthy"],"example":"healthy"},"rpcLatencyMs":{"type":"number","example":45},"lag":{"type":"number","example":3},"dependencies":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","unhealthy"],"example":"healthy"}}}}}}}}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","degraded","unhealthy"],"example":"healthy"},"timestamp":{"type":"string","format":"date-time"},"deployEnvironment":{"type":"string","example":"production"},"deployedVersion":{"type":"string","example":"1.1.2"},"summary":{"type":"object","properties":{"healthy":{"type":"integer","example":10},"unhealthy":{"type":"integer","example":2},"total":{"type":"integer","example":12}}},"checks":{"type":"object","properties":{"dependencies":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","unhealthy"],"example":"healthy"}}},"indexers":{"type":"object","additionalProperties":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","unhealthy"],"example":"healthy"},"rpcLatencyMs":{"type":"number","example":45},"lag":{"type":"number","example":3},"dependencies":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","unhealthy"],"example":"healthy"}}}}}}}}}}}}}}}},"/api/v1/chains":{"get":{"summary":"Get supported blockchains and tokens","tags":["Chains"],"description":"Returns the list of all supported blockchains and their available tokens. Endpoint to discover valid blockchain and token combinations before calling other endpoints. This endpoint reads directly from the server configuration and requires no authentication.","responses":{"200":{"description":"List of supported blockchains with their tokens and case sensitivity rules","content":{"application/json":{"schema":{"description":"List of supported blockchains with their tokens and case sensitivity rules","type":"object","properties":{"chains":{"type":"array","description":"All supported blockchains.","items":{"type":"object","properties":{"name":{"type":"string","description":"Blockchain identifier used as the {blockchain} path parameter in other endpoints."},"tokens":{"type":"array","description":"Token identifiers available on this blockchain, used as the {token} path parameter.","items":{"type":"string"}},"caseSensitive":{"type":"object","description":"Case sensitivity rules. If present, addresses are preserved as-is (case-sensitive). If absent, addresses are automatically lowercased.","properties":{"address":{"oneOf":[{"type":"boolean"},{"type":"string"}],"description":"Indicates address case sensitivity. When the caseSensitive object is present, addresses are not lowercased regardless of this field value."},"tx":{"type":"boolean","description":"true = transaction hashes are case-sensitive."},"block":{"type":"boolean","description":"true = block identifiers are case-sensitive."}},"additionalProperties":false}},"required":["name","tokens"],"additionalProperties":false}}},"additionalProperties":false}}}},"500":{"description":"Internal Server Error - indexer service unavailable or unexpected failure","content":{"application/json":{"schema":{"description":"Internal Server Error - indexer service unavailable or unexpected failure","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}}}}},"/api/v1/{blockchain}/{token}/{address}/token-transfers":{"get":{"summary":"Get token transfers for an address","tags":["Token Transfers"],"description":"Retrieve the token transfer history for a specific wallet address on a given blockchain. Returns incoming and outgoing transfers sorted by block number.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":10},"in":"query","name":"limit","required":false,"description":"Maximum number of transfers to return."},{"schema":{"type":"integer","minimum":0,"default":0},"in":"query","name":"fromTs","required":false,"description":"Start timestamp in milliseconds (inclusive). Use 0 to query from the beginning."},{"schema":{"type":"integer","minimum":0},"in":"query","name":"toTs","required":false,"description":"End timestamp in milliseconds (inclusive). Omit to query up to the latest available data."},{"schema":{"type":"string","enum":["ethereum","arbitrum","avalanche","polygon","plasma","sepolia","tron","ton","bitcoin","spark"]},"in":"path","name":"blockchain","required":true,"description":"Blockchain network identifier. Use GET /api/v1/chains to see all available options."},{"schema":{"type":"string","enum":["usdt","xaut","usat","btc"]},"in":"path","name":"token","required":true,"description":"Token identifier. Must be a valid token for the specified blockchain."},{"schema":{"type":"string","minLength":1},"in":"path","name":"address","required":true,"description":"Wallet address to query. Format varies by blockchain (e.g. 0x... for EVM, bc1... for Bitcoin, T... for Tron)."}],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Token transfer history for the queried address","content":{"application/json":{"schema":{"description":"Token transfer history for the queried address","type":"object","properties":{"transfers":{"type":"array","description":"List of token transfers sorted by block number.","items":{"type":"object","properties":{"blockchain":{"type":"string","description":"Blockchain where the transfer occurred."},"blockNumber":{"type":"integer","description":"Block number containing the transfer."},"transactionHash":{"type":"string","description":"Hash of the transaction."},"transferIndex":{"type":"integer","description":"Index of the transfer within the transaction."},"token":{"type":"string","description":"Token identifier."},"amount":{"type":"string","description":"Transfer amount as a decimal string."},"timestamp":{"type":"integer","description":"Block timestamp in milliseconds since Unix epoch."},"transactionIndex":{"oneOf":[{"type":"integer"},{"type":"null"}],"description":"Position of the transaction within the block."},"logIndex":{"oneOf":[{"type":"integer"},{"type":"null"}],"description":"Event log index for EVM chains. null for non-EVM chains like Bitcoin."},"from":{"oneOf":[{"type":"string"},{"type":"null"}],"description":"Sender wallet address."},"to":{"oneOf":[{"type":"string"},{"type":"null"}],"description":"The recipient's address"},"label":{"type":"string","description":"A label associated with the transfer, if any"},"metadata":{"oneOf":[{"type":"object","additionalProperties":true},{"type":"null"}],"description":"Chain-specific extra data attached to the transfer, if any."}},"additionalProperties":true}}},"additionalProperties":false}}}},"400":{"description":"Bad Request - invalid parameters, address format, blockchain, or token","content":{"application/json":{"schema":{"description":"Bad Request - invalid parameters, address format, blockchain, or token","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"401":{"description":"Unauthorized - expired API key","content":{"application/json":{"schema":{"description":"Unauthorized - expired API key","type":"object","properties":{"error":{"type":"string","description":"Authentication error type"},"message":{"type":"string","description":"Authentication error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"403":{"description":"Forbidden - missing or invalid API key","content":{"application/json":{"schema":{"description":"Forbidden - missing or invalid API key","type":"object","properties":{"error":{"type":"string","description":"Authorization error type"},"message":{"type":"string","description":"Authorization error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"description":"Too Many Requests - rate limit exceeded","type":"object","properties":{"error":{"type":"string","description":"Rate limit error type"},"message":{"type":"string","description":"Rate limit error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"500":{"description":"Internal Server Error - indexer service unavailable or unexpected failure","content":{"application/json":{"schema":{"description":"Internal Server Error - indexer service unavailable or unexpected failure","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}}}}},"/api/v1/{blockchain}/{token}/{address}/token-balances":{"get":{"summary":"Get token balance for an address","tags":["Token Balances"],"description":"Retrieve the current token balance for a specific wallet address on a given blockchain. Returns a single balance amount representing how much of the specified token the address currently holds.","parameters":[{"schema":{"type":"string","enum":["ethereum","arbitrum","avalanche","polygon","plasma","sepolia","tron","ton","bitcoin","spark"]},"in":"path","name":"blockchain","required":true,"description":"Blockchain network identifier. Use GET /api/v1/chains to see all available options."},{"schema":{"type":"string","enum":["usdt","xaut","usat","btc"]},"in":"path","name":"token","required":true,"description":"Token identifier. Must be a valid token for the specified blockchain."},{"schema":{"type":"string","minLength":1},"in":"path","name":"address","required":true,"description":"Wallet address to query. Format varies by blockchain (e.g. 0x... for EVM, bc1... for Bitcoin, T... for Tron)."}],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Current token balance for the queried address","content":{"application/json":{"schema":{"description":"Current token balance for the queried address","type":"object","properties":{"tokenBalance":{"type":"object","description":"Balance information.","properties":{"blockchain":{"type":"string","description":"Blockchain queried."},"token":{"type":"string","description":"Token queried."},"amount":{"type":"string","description":"Current balance as a decimal string."}},"additionalProperties":false}},"additionalProperties":false}}}},"400":{"description":"Bad Request - invalid parameters, address format, blockchain, or token","content":{"application/json":{"schema":{"description":"Bad Request - invalid parameters, address format, blockchain, or token","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"401":{"description":"Unauthorized - expired API key","content":{"application/json":{"schema":{"description":"Unauthorized - expired API key","type":"object","properties":{"error":{"type":"string","description":"Authentication error type"},"message":{"type":"string","description":"Authentication error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"403":{"description":"Forbidden - missing or invalid API key","content":{"application/json":{"schema":{"description":"Forbidden - missing or invalid API key","type":"object","properties":{"error":{"type":"string","description":"Authorization error type"},"message":{"type":"string","description":"Authorization error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"description":"Too Many Requests - rate limit exceeded","type":"object","properties":{"error":{"type":"string","description":"Rate limit error type"},"message":{"type":"string","description":"Rate limit error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"500":{"description":"Internal Server Error - indexer service unavailable or unexpected failure","content":{"application/json":{"schema":{"description":"Internal Server Error - indexer service unavailable or unexpected failure","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}}}}},"/api/v1/blockchains/{blockchain}/{token}/token-transfers/{transactionHash}":{"get":{"summary":"Get transfers for a transaction","tags":["Token Transfers"],"description":"Retrieve the transfer records of a single transaction for one token, read from the chain. Only transfers of the requested token are returned, so a transaction moving several tokens has to be queried once per token. Returns 404 when the transaction moved no amount of that token, including when the transaction id does not exist at all.","parameters":[{"schema":{"type":"string","enum":["ethereum","arbitrum","avalanche","polygon","plasma","sepolia","tron","ton","bitcoin","spark"]},"in":"path","name":"blockchain","required":true,"description":"Blockchain network identifier. Use GET /api/v1/chains to see all available options."},{"schema":{"type":"string","enum":["usdt","xaut","usat","btc"]},"in":"path","name":"token","required":true,"description":"Token identifier. Must be a valid token for the specified blockchain."},{"schema":{"type":"string","minLength":1,"maxLength":255},"in":"path","name":"transactionHash","required":true,"description":"Transaction id/hash, as returned in the `transactionHash` field of transfers. Format varies by blockchain (e.g. 0x... for EVM, hex for TON, base58 signature for Solana)."}],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Transfer records for the queried transaction","content":{"application/json":{"schema":{"description":"Transfer records for the queried transaction","type":"object","properties":{"transfers":{"type":"array","description":"All transfers recorded under this transaction for the requested token.","items":{"type":"object","properties":{"blockchain":{"type":"string","description":"Blockchain where the transfer occurred."},"blockNumber":{"type":"integer","description":"Block number containing the transfer."},"transactionHash":{"type":"string","description":"Hash of the transaction."},"transferIndex":{"type":"integer","description":"Index of the transfer within the transaction."},"token":{"type":"string","description":"Token identifier."},"amount":{"type":"string","description":"Transfer amount as a decimal string."},"timestamp":{"type":"integer","description":"Block timestamp in milliseconds since Unix epoch."},"transactionIndex":{"oneOf":[{"type":"integer"},{"type":"null"}],"description":"Position of the transaction within the block."},"logIndex":{"oneOf":[{"type":"integer"},{"type":"null"}],"description":"Event log index for EVM chains. null for non-EVM chains like Bitcoin."},"from":{"oneOf":[{"type":"string"},{"type":"null"}],"description":"Sender wallet address."},"to":{"oneOf":[{"type":"string"},{"type":"null"}],"description":"The recipient's address"},"label":{"type":"string","description":"A label associated with the transfer, if any"},"metadata":{"oneOf":[{"type":"object","additionalProperties":true},{"type":"null"}],"description":"Chain-specific extra data attached to the transfer, if any."}},"additionalProperties":true}}},"additionalProperties":false}}}},"400":{"description":"Bad Request - invalid parameters, address format, blockchain, or token","content":{"application/json":{"schema":{"description":"Bad Request - invalid parameters, address format, blockchain, or token","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"401":{"description":"Unauthorized - expired API key","content":{"application/json":{"schema":{"description":"Unauthorized - expired API key","type":"object","properties":{"error":{"type":"string","description":"Authentication error type"},"message":{"type":"string","description":"Authentication error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"403":{"description":"Forbidden - missing or invalid API key","content":{"application/json":{"schema":{"description":"Forbidden - missing or invalid API key","type":"object","properties":{"error":{"type":"string","description":"Authorization error type"},"message":{"type":"string","description":"Authorization error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"404":{"description":"Not Found - the transaction has no transfers of the requested token","content":{"application/json":{"schema":{"description":"Not Found - the transaction has no transfers of the requested token","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"description":"Too Many Requests - rate limit exceeded","type":"object","properties":{"error":{"type":"string","description":"Rate limit error type"},"message":{"type":"string","description":"Rate limit error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"500":{"description":"Internal Server Error - indexer service unavailable or unexpected failure","content":{"application/json":{"schema":{"description":"Internal Server Error - indexer service unavailable or unexpected failure","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}}}}},"/api/v1/batch/token-transfers":{"post":{"summary":"Get token transfers for multiple addresses","tags":["Token Transfers"],"description":"Retrieve token transfer history for multiple addresses in a single request. Each item in the batch is processed independently - if one item fails (e.g. invalid address), the others still return results. The response array maintains the same order as the request. Maximum 10 items per batch.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","description":"Array of transfer query objects. Maximum 10 items.","minItems":1,"maxItems":10,"items":{"type":"object","properties":{"blockchain":{"type":"string","enum":["ethereum","arbitrum","avalanche","polygon","plasma","sepolia","tron","ton","bitcoin","spark"],"description":"Blockchain network identifier."},"token":{"type":"string","enum":["usdt","xaut","usat","btc"],"description":"Token identifier."},"address":{"type":"string","minLength":1,"description":"Wallet address to query."},"limit":{"type":"integer","minimum":1,"maximum":1000,"default":10,"description":"Maximum number of transfers to return for this address."},"fromTs":{"type":"integer","minimum":0,"default":0,"description":"Start timestamp in milliseconds (inclusive)."},"toTs":{"type":"integer","minimum":0,"description":"End timestamp in milliseconds (inclusive)."}},"required":["blockchain","token","address"],"additionalProperties":false}}}},"description":"Array of transfer query objects. Maximum 10 items."},"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Array of results in the same order as the request. Each element is either a transfer result or an error object.","content":{"application/json":{"schema":{"description":"Array of results in the same order as the request. Each element is either a transfer result or an error object.","type":"array","items":{"oneOf":[{"description":"Token transfer history for the queried address","type":"object","properties":{"transfers":{"type":"array","description":"List of token transfers sorted by block number.","items":{"type":"object","properties":{"blockchain":{"type":"string","description":"Blockchain where the transfer occurred."},"blockNumber":{"type":"integer","description":"Block number containing the transfer."},"transactionHash":{"type":"string","description":"Hash of the transaction."},"transferIndex":{"type":"integer","description":"Index of the transfer within the transaction."},"token":{"type":"string","description":"Token identifier."},"amount":{"type":"string","description":"Transfer amount as a decimal string."},"timestamp":{"type":"integer","description":"Block timestamp in milliseconds since Unix epoch."},"transactionIndex":{"oneOf":[{"type":"integer"},{"type":"null"}],"description":"Position of the transaction within the block."},"logIndex":{"oneOf":[{"type":"integer"},{"type":"null"}],"description":"Event log index for EVM chains. null for non-EVM chains like Bitcoin."},"from":{"oneOf":[{"type":"string"},{"type":"null"}],"description":"Sender wallet address."},"to":{"oneOf":[{"type":"string"},{"type":"null"}],"description":"The recipient's address"},"label":{"type":"string","description":"A label associated with the transfer, if any"},"metadata":{"oneOf":[{"type":"object","additionalProperties":true},{"type":"null"}],"description":"Chain-specific extra data attached to the transfer, if any."}},"additionalProperties":true}}},"additionalProperties":false},{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"}},"additionalProperties":false}]},"minItems":1}}}},"400":{"description":"Bad Request - invalid parameters, address format, blockchain, or token","content":{"application/json":{"schema":{"description":"Bad Request - invalid parameters, address format, blockchain, or token","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"401":{"description":"Unauthorized - expired API key","content":{"application/json":{"schema":{"description":"Unauthorized - expired API key","type":"object","properties":{"error":{"type":"string","description":"Authentication error type"},"message":{"type":"string","description":"Authentication error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"403":{"description":"Forbidden - missing or invalid API key","content":{"application/json":{"schema":{"description":"Forbidden - missing or invalid API key","type":"object","properties":{"error":{"type":"string","description":"Authorization error type"},"message":{"type":"string","description":"Authorization error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"description":"Too Many Requests - rate limit exceeded","type":"object","properties":{"error":{"type":"string","description":"Rate limit error type"},"message":{"type":"string","description":"Rate limit error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"500":{"description":"Internal Server Error - indexer service unavailable or unexpected failure","content":{"application/json":{"schema":{"description":"Internal Server Error - indexer service unavailable or unexpected failure","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}}}}},"/api/v1/batch/token-balances":{"post":{"summary":"Get token balances for multiple addresses","tags":["Token Balances"],"description":"Retrieve the current token balance for multiple addresses in a single request. Each item in the batch is processed independently - if one item fails (e.g. invalid address), the others still return results. The response array maintains the same order as the request. Maximum 10 items per batch.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","description":"Array of balance query objects. Maximum 10 items.","minItems":1,"maxItems":10,"items":{"type":"object","properties":{"blockchain":{"type":"string","enum":["ethereum","arbitrum","avalanche","polygon","plasma","sepolia","tron","ton","bitcoin","spark"],"description":"Blockchain network identifier."},"token":{"type":"string","enum":["usdt","xaut","usat","btc"],"description":"Token identifier."},"address":{"type":"string","minLength":1,"description":"Wallet address to query."}},"required":["blockchain","token","address"],"additionalProperties":false}}}},"description":"Array of balance query objects. Maximum 10 items."},"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Array of results in the same order as the request. Each element is either a balance result or an error object.","content":{"application/json":{"schema":{"description":"Array of results in the same order as the request. Each element is either a balance result or an error object.","type":"array","items":{"oneOf":[{"description":"Current token balance for the queried address","type":"object","properties":{"tokenBalance":{"type":"object","description":"Balance information.","properties":{"blockchain":{"type":"string","description":"Blockchain queried."},"token":{"type":"string","description":"Token queried."},"amount":{"type":"string","description":"Current balance as a decimal string."}},"additionalProperties":false}},"additionalProperties":false},{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"status":{"type":"number"}},"additionalProperties":false}]}}}}},"400":{"description":"Bad Request - invalid parameters, address format, blockchain, or token","content":{"application/json":{"schema":{"description":"Bad Request - invalid parameters, address format, blockchain, or token","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"401":{"description":"Unauthorized - expired API key","content":{"application/json":{"schema":{"description":"Unauthorized - expired API key","type":"object","properties":{"error":{"type":"string","description":"Authentication error type"},"message":{"type":"string","description":"Authentication error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"403":{"description":"Forbidden - missing or invalid API key","content":{"application/json":{"schema":{"description":"Forbidden - missing or invalid API key","type":"object","properties":{"error":{"type":"string","description":"Authorization error type"},"message":{"type":"string","description":"Authorization error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"description":"Too Many Requests - rate limit exceeded","type":"object","properties":{"error":{"type":"string","description":"Rate limit error type"},"message":{"type":"string","description":"Rate limit error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"500":{"description":"Internal Server Error - indexer service unavailable or unexpected failure","content":{"application/json":{"schema":{"description":"Internal Server Error - indexer service unavailable or unexpected failure","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Error details"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}}}}},"/api/v1/wallets":{"post":{"summary":"Register wallets for automatic transaction syncing","tags":["Wallets"],"description":"Registers one or more wallets for the authenticated owner. Registered wallet addresses are synced automatically - transfers touching them are collected continuously and can be queried via the wallet transfer endpoints without polling the chain endpoints. Each item is processed independently and returns its own status: 201 created, 400 invalid, 429 wallet limit exceeded. Registration is rejected with 409 if an address is already registered.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","description":"Array of wallets to register. Maximum 10 items.","minItems":1,"maxItems":10,"items":{"type":"object","properties":{"type":{"type":"string","enum":["client_wallet"],"description":"Wallet type. Must be the type this gateway registers."},"name":{"type":"string","minLength":1,"maxLength":100,"description":"Optional display name for the wallet."},"addresses":{"type":"object","description":"Addresses to register, keyed by blockchain (e.g. {\"ethereum\": \"0x...\", \"bitcoin\": \"bc1...\"}). Use GET /api/v1/chains for supported blockchains.","minProperties":1,"propertyNames":{"enum":["ethereum","arbitrum","avalanche","polygon","plasma","sepolia","tron","ton","bitcoin","spark"]},"additionalProperties":{"type":"string","minLength":1,"maxLength":200}},"meta":{"type":"object","description":"Optional wallet metadata. Required when registering a spark address.","properties":{"spark":{"type":"object","properties":{"sparkDepositAddress":{"type":"string","minLength":1,"pattern":"^([13][a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[a-z0-9]{39,59})$"},"sparkIdentityKey":{"type":"string","minLength":1}},"required":["sparkDepositAddress","sparkIdentityKey"],"additionalProperties":false}},"additionalProperties":false}},"required":["type","addresses"],"additionalProperties":false}}}},"description":"Array of wallets to register. Maximum 10 items."},"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Per-wallet registration results in request order","content":{"application/json":{"schema":{"description":"Per-wallet registration results in request order","type":"object","properties":{"wallets":{"type":"array","items":{"description":"Per-wallet registration result","type":"object","properties":{"status":{"type":"number","description":"Per-item status code: 201 created, 400 invalid, 429 wallet limit exceeded."},"id":{"type":"string","description":"Wallet identifier (present when created)."},"name":{"type":"string","description":"Wallet display name."},"type":{"type":"string","description":"Wallet type assigned at registration."},"enabled":{"type":"boolean","description":"Whether the wallet is active for transaction syncing."},"addresses":{"type":"object","description":"Registered addresses keyed by blockchain.","additionalProperties":{"type":"string"}},"meta":{"type":"object","description":"Optional wallet metadata. Required when registering a spark address.","properties":{"spark":{"type":"object","properties":{"sparkDepositAddress":{"type":"string","minLength":1,"pattern":"^([13][a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[a-z0-9]{39,59})$"},"sparkIdentityKey":{"type":"string","minLength":1}},"required":["sparkDepositAddress","sparkIdentityKey"],"additionalProperties":false}},"additionalProperties":false},"error":{"type":"string","description":"Error code when the item was rejected."},"limit":{"type":"number","description":"Wallet limit that was exceeded (present on 429)."},"currentCount":{"type":"number","description":"Current wallet count (present on 429)."}},"additionalProperties":false}}},"additionalProperties":false}}}},"400":{"description":"Bad Request - invalid parameters, address format, or blockchain","content":{"application/json":{"schema":{"description":"Bad Request - invalid parameters, address format, or blockchain","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"401":{"description":"Unauthorized - expired API key","content":{"application/json":{"schema":{"description":"Unauthorized - expired API key","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"403":{"description":"Forbidden - missing or invalid API key","content":{"application/json":{"schema":{"description":"Forbidden - missing or invalid API key","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"409":{"description":"Conflict - address already registered","content":{"application/json":{"schema":{"description":"Conflict - address already registered","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"description":"Too Many Requests - rate limit exceeded","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"500":{"description":"Internal Server Error - wallet service unavailable or unexpected failure","content":{"application/json":{"schema":{"description":"Internal Server Error - wallet service unavailable or unexpected failure","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"503":{"description":"Service Unavailable - wallet service temporarily unreachable","content":{"application/json":{"schema":{"description":"Service Unavailable - wallet service temporarily unreachable","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}}}},"get":{"summary":"List registered wallets","tags":["Wallets"],"description":"Returns all active wallets registered by the authenticated owner.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Registered wallets","content":{"application/json":{"schema":{"description":"Registered wallets","type":"object","properties":{"wallets":{"type":"array","items":{"description":"A registered wallet","type":"object","properties":{"id":{"type":"string","description":"Wallet identifier."},"name":{"type":"string","description":"Optional wallet display name."},"type":{"type":"string","description":"Wallet type assigned at registration."},"enabled":{"type":"boolean","description":"Whether the wallet is active for transaction syncing."},"addresses":{"type":"object","description":"Registered addresses keyed by blockchain.","additionalProperties":{"type":"string"}},"meta":{"type":"object","description":"Optional wallet metadata. Required when registering a spark address.","properties":{"spark":{"type":"object","properties":{"sparkDepositAddress":{"type":"string","minLength":1,"pattern":"^([13][a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[a-z0-9]{39,59})$"},"sparkIdentityKey":{"type":"string","minLength":1}},"required":["sparkDepositAddress","sparkIdentityKey"],"additionalProperties":false}},"additionalProperties":false},"createdAt":{"type":"number","description":"Creation timestamp in milliseconds."},"updatedAt":{"type":"number","description":"Last update timestamp in milliseconds."}},"additionalProperties":false}}},"additionalProperties":false}}}},"401":{"description":"Unauthorized - expired API key","content":{"application/json":{"schema":{"description":"Unauthorized - expired API key","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"403":{"description":"Forbidden - missing or invalid API key","content":{"application/json":{"schema":{"description":"Forbidden - missing or invalid API key","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"description":"Too Many Requests - rate limit exceeded","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"500":{"description":"Internal Server Error - wallet service unavailable or unexpected failure","content":{"application/json":{"schema":{"description":"Internal Server Error - wallet service unavailable or unexpected failure","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"503":{"description":"Service Unavailable - wallet service temporarily unreachable","content":{"application/json":{"schema":{"description":"Service Unavailable - wallet service temporarily unreachable","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}}}}},"/api/v1/wallets/{walletId}":{"get":{"summary":"Get a registered wallet","tags":["Wallets"],"description":"Returns a single wallet registered by the authenticated owner.","parameters":[{"schema":{"type":"string","minLength":1},"in":"path","name":"walletId","required":true,"description":"Wallet identifier from POST /api/v1/wallets."}],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"A registered wallet","content":{"application/json":{"schema":{"description":"A registered wallet","type":"object","properties":{"id":{"type":"string","description":"Wallet identifier."},"name":{"type":"string","description":"Optional wallet display name."},"type":{"type":"string","description":"Wallet type assigned at registration."},"enabled":{"type":"boolean","description":"Whether the wallet is active for transaction syncing."},"addresses":{"type":"object","description":"Registered addresses keyed by blockchain.","additionalProperties":{"type":"string"}},"meta":{"type":"object","description":"Optional wallet metadata. Required when registering a spark address.","properties":{"spark":{"type":"object","properties":{"sparkDepositAddress":{"type":"string","minLength":1,"pattern":"^([13][a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[a-z0-9]{39,59})$"},"sparkIdentityKey":{"type":"string","minLength":1}},"required":["sparkDepositAddress","sparkIdentityKey"],"additionalProperties":false}},"additionalProperties":false},"createdAt":{"type":"number","description":"Creation timestamp in milliseconds."},"updatedAt":{"type":"number","description":"Last update timestamp in milliseconds."}},"additionalProperties":false}}}},"401":{"description":"Unauthorized - expired API key","content":{"application/json":{"schema":{"description":"Unauthorized - expired API key","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"403":{"description":"Forbidden - missing or invalid API key","content":{"application/json":{"schema":{"description":"Forbidden - missing or invalid API key","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"404":{"description":"Not Found - wallet not found or access denied","content":{"application/json":{"schema":{"description":"Not Found - wallet not found or access denied","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"description":"Too Many Requests - rate limit exceeded","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"500":{"description":"Internal Server Error - wallet service unavailable or unexpected failure","content":{"application/json":{"schema":{"description":"Internal Server Error - wallet service unavailable or unexpected failure","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"503":{"description":"Service Unavailable - wallet service temporarily unreachable","content":{"application/json":{"schema":{"description":"Service Unavailable - wallet service temporarily unreachable","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}}}},"patch":{"summary":"Update a registered wallet","tags":["Wallets"],"description":"Updates the display name of a wallet or enables/disables its transaction syncing.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"New display name for the wallet."},"enabled":{"type":"boolean","description":"Whether the wallet is active for transaction syncing."}},"minProperties":1,"additionalProperties":false}}}},"parameters":[{"schema":{"type":"string","minLength":1},"in":"path","name":"walletId","required":true,"description":"Wallet identifier from POST /api/v1/wallets."}],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"A registered wallet","content":{"application/json":{"schema":{"description":"A registered wallet","type":"object","properties":{"id":{"type":"string","description":"Wallet identifier."},"name":{"type":"string","description":"Optional wallet display name."},"type":{"type":"string","description":"Wallet type assigned at registration."},"enabled":{"type":"boolean","description":"Whether the wallet is active for transaction syncing."},"addresses":{"type":"object","description":"Registered addresses keyed by blockchain.","additionalProperties":{"type":"string"}},"meta":{"type":"object","description":"Optional wallet metadata. Required when registering a spark address.","properties":{"spark":{"type":"object","properties":{"sparkDepositAddress":{"type":"string","minLength":1,"pattern":"^([13][a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[a-z0-9]{39,59})$"},"sparkIdentityKey":{"type":"string","minLength":1}},"required":["sparkDepositAddress","sparkIdentityKey"],"additionalProperties":false}},"additionalProperties":false},"createdAt":{"type":"number","description":"Creation timestamp in milliseconds."},"updatedAt":{"type":"number","description":"Last update timestamp in milliseconds."}},"additionalProperties":false}}}},"400":{"description":"Bad Request - invalid parameters, address format, or blockchain","content":{"application/json":{"schema":{"description":"Bad Request - invalid parameters, address format, or blockchain","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"401":{"description":"Unauthorized - expired API key","content":{"application/json":{"schema":{"description":"Unauthorized - expired API key","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"403":{"description":"Forbidden - missing or invalid API key","content":{"application/json":{"schema":{"description":"Forbidden - missing or invalid API key","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"404":{"description":"Not Found - wallet not found or access denied","content":{"application/json":{"schema":{"description":"Not Found - wallet not found or access denied","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"description":"Too Many Requests - rate limit exceeded","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"500":{"description":"Internal Server Error - wallet service unavailable or unexpected failure","content":{"application/json":{"schema":{"description":"Internal Server Error - wallet service unavailable or unexpected failure","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"503":{"description":"Service Unavailable - wallet service temporarily unreachable","content":{"application/json":{"schema":{"description":"Service Unavailable - wallet service temporarily unreachable","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}}}},"delete":{"summary":"Delete a registered wallet","tags":["Wallets"],"description":"Deletes a wallet registered by the authenticated owner and stops syncing its transactions. Its addresses can be registered again afterwards.","parameters":[{"schema":{"type":"string","minLength":1},"in":"path","name":"walletId","required":true,"description":"Wallet identifier from POST /api/v1/wallets."}],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Wallet deleted","content":{"application/json":{"schema":{"description":"Wallet deleted","type":"object","properties":{"success":{"type":"boolean"}},"additionalProperties":false}}}},"401":{"description":"Unauthorized - expired API key","content":{"application/json":{"schema":{"description":"Unauthorized - expired API key","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"403":{"description":"Forbidden - missing or invalid API key","content":{"application/json":{"schema":{"description":"Forbidden - missing or invalid API key","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"404":{"description":"Not Found - wallet not found or access denied","content":{"application/json":{"schema":{"description":"Not Found - wallet not found or access denied","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"description":"Too Many Requests - rate limit exceeded","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"500":{"description":"Internal Server Error - wallet service unavailable or unexpected failure","content":{"application/json":{"schema":{"description":"Internal Server Error - wallet service unavailable or unexpected failure","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"503":{"description":"Service Unavailable - wallet service temporarily unreachable","content":{"application/json":{"schema":{"description":"Service Unavailable - wallet service temporarily unreachable","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}}}}},"/api/v1/wallets/{walletId}/transfers":{"get":{"summary":"Get synced transfers for a wallet","tags":["Wallet Transfers"],"description":"Returns the automatically synced transfer log for a single registered wallet, newest first by default.","parameters":[{"schema":{"type":"string","enum":["ethereum","arbitrum","avalanche","polygon","plasma","sepolia","tron","ton","bitcoin","spark"]},"in":"query","name":"blockchain","required":false,"description":"Filter transfers by blockchain."},{"schema":{"type":"string","enum":["usdt","xaut","usat","btc"]},"in":"query","name":"token","required":false,"description":"Filter transfers by token."},{"schema":{"type":"string","enum":["sent","received"]},"in":"query","name":"type","required":false,"description":"Filter by transfer direction relative to the wallet."},{"schema":{"oneOf":[{"type":"integer","minimum":0},{"type":"string","format":"date-time"}]},"in":"query","name":"from","required":false,"description":"Start of the time range - timestamp in milliseconds or ISO 8601 date."},{"schema":{"oneOf":[{"type":"integer","minimum":0},{"type":"string","format":"date-time"}]},"in":"query","name":"to","required":false,"description":"End of the time range - timestamp in milliseconds or ISO 8601 date."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"in":"query","name":"limit","required":false,"description":"Maximum number of transfers to return."},{"schema":{"type":"integer","minimum":0,"default":0},"in":"query","name":"skip","required":false,"description":"Number of matching transfers to skip (pagination offset)."},{"schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"in":"query","name":"sort","required":false,"description":"Sort order by timestamp."},{"schema":{"type":"string","minLength":1},"in":"path","name":"walletId","required":true,"description":"Wallet identifier from POST /api/v1/wallets."}],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Raw transfer log entries for registered wallets","content":{"application/json":{"schema":{"description":"Raw transfer log entries for registered wallets","type":"object","properties":{"transfers":{"type":"array","description":"List of transfers sorted by timestamp.","items":{"type":"object","properties":{"walletId":{"type":"string","description":"Wallet the transfer belongs to."},"blockchain":{"type":"string","description":"Blockchain where the transfer occurred."},"token":{"type":"string","description":"Token identifier."},"transactionHash":{"type":"string","description":"Hash of the transaction."},"transferIndex":{"type":"integer","description":"Index of the transfer within the transaction."},"blockNumber":{"type":"integer","description":"Block number containing the transfer."},"amount":{"type":"string","description":"Transfer amount as a decimal string."},"from":{"oneOf":[{"type":"string"},{"type":"null"}],"description":"Sender address."},"to":{"oneOf":[{"type":"string"},{"type":"null"}],"description":"Recipient address."},"ts":{"type":"integer","description":"Block timestamp in milliseconds since Unix epoch."},"transactionIndex":{"oneOf":[{"type":"integer"},{"type":"null"}],"description":"Position of the transaction within the block."},"logIndex":{"oneOf":[{"type":"integer"},{"type":"null"}],"description":"Event log index for EVM chains. null for non-EVM chains."},"label":{"type":"string","description":"A label associated with the transfer, if any."},"type":{"type":"string","enum":["sent","received"],"description":"Direction of the transfer relative to the wallet."}},"additionalProperties":false}}},"additionalProperties":false}}}},"400":{"description":"Bad Request - invalid parameters, address format, or blockchain","content":{"application/json":{"schema":{"description":"Bad Request - invalid parameters, address format, or blockchain","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"401":{"description":"Unauthorized - expired API key","content":{"application/json":{"schema":{"description":"Unauthorized - expired API key","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"403":{"description":"Forbidden - missing or invalid API key","content":{"application/json":{"schema":{"description":"Forbidden - missing or invalid API key","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"404":{"description":"Not Found - wallet not found or access denied","content":{"application/json":{"schema":{"description":"Not Found - wallet not found or access denied","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"description":"Too Many Requests - rate limit exceeded","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"500":{"description":"Internal Server Error - wallet service unavailable or unexpected failure","content":{"application/json":{"schema":{"description":"Internal Server Error - wallet service unavailable or unexpected failure","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"503":{"description":"Service Unavailable - wallet service temporarily unreachable","content":{"application/json":{"schema":{"description":"Service Unavailable - wallet service temporarily unreachable","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}}}}},"/api/v1/transfers":{"get":{"summary":"Get synced transfers across all registered wallets","tags":["Wallet Transfers"],"description":"Returns the automatically synced transfer log across all the owner's registered wallets, merged and sorted by timestamp.","parameters":[{"schema":{"type":"string","enum":["ethereum","arbitrum","avalanche","polygon","plasma","sepolia","tron","ton","bitcoin","spark"]},"in":"query","name":"blockchain","required":false,"description":"Filter transfers by blockchain."},{"schema":{"type":"string","enum":["usdt","xaut","usat","btc"]},"in":"query","name":"token","required":false,"description":"Filter transfers by token."},{"schema":{"type":"string","enum":["sent","received"]},"in":"query","name":"type","required":false,"description":"Filter by transfer direction relative to the wallet."},{"schema":{"oneOf":[{"type":"integer","minimum":0},{"type":"string","format":"date-time"}]},"in":"query","name":"from","required":false,"description":"Start of the time range - timestamp in milliseconds or ISO 8601 date."},{"schema":{"oneOf":[{"type":"integer","minimum":0},{"type":"string","format":"date-time"}]},"in":"query","name":"to","required":false,"description":"End of the time range - timestamp in milliseconds or ISO 8601 date."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"in":"query","name":"limit","required":false,"description":"Maximum number of transfers to return."},{"schema":{"type":"integer","minimum":0,"default":0},"in":"query","name":"skip","required":false,"description":"Number of matching transfers to skip (pagination offset)."},{"schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"in":"query","name":"sort","required":false,"description":"Sort order by timestamp."}],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Raw transfer log entries for registered wallets","content":{"application/json":{"schema":{"description":"Raw transfer log entries for registered wallets","type":"object","properties":{"transfers":{"type":"array","description":"List of transfers sorted by timestamp.","items":{"type":"object","properties":{"walletId":{"type":"string","description":"Wallet the transfer belongs to."},"blockchain":{"type":"string","description":"Blockchain where the transfer occurred."},"token":{"type":"string","description":"Token identifier."},"transactionHash":{"type":"string","description":"Hash of the transaction."},"transferIndex":{"type":"integer","description":"Index of the transfer within the transaction."},"blockNumber":{"type":"integer","description":"Block number containing the transfer."},"amount":{"type":"string","description":"Transfer amount as a decimal string."},"from":{"oneOf":[{"type":"string"},{"type":"null"}],"description":"Sender address."},"to":{"oneOf":[{"type":"string"},{"type":"null"}],"description":"Recipient address."},"ts":{"type":"integer","description":"Block timestamp in milliseconds since Unix epoch."},"transactionIndex":{"oneOf":[{"type":"integer"},{"type":"null"}],"description":"Position of the transaction within the block."},"logIndex":{"oneOf":[{"type":"integer"},{"type":"null"}],"description":"Event log index for EVM chains. null for non-EVM chains."},"label":{"type":"string","description":"A label associated with the transfer, if any."},"type":{"type":"string","enum":["sent","received"],"description":"Direction of the transfer relative to the wallet."}},"additionalProperties":false}}},"additionalProperties":false}}}},"400":{"description":"Bad Request - invalid parameters, address format, or blockchain","content":{"application/json":{"schema":{"description":"Bad Request - invalid parameters, address format, or blockchain","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"401":{"description":"Unauthorized - expired API key","content":{"application/json":{"schema":{"description":"Unauthorized - expired API key","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"403":{"description":"Forbidden - missing or invalid API key","content":{"application/json":{"schema":{"description":"Forbidden - missing or invalid API key","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"429":{"description":"Too Many Requests - rate limit exceeded","content":{"application/json":{"schema":{"description":"Too Many Requests - rate limit exceeded","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"500":{"description":"Internal Server Error - wallet service unavailable or unexpected failure","content":{"application/json":{"schema":{"description":"Internal Server Error - wallet service unavailable or unexpected failure","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}},"503":{"description":"Service Unavailable - wallet service temporarily unreachable","content":{"application/json":{"schema":{"description":"Service Unavailable - wallet service temporarily unreachable","type":"object","properties":{"error":{"type":"string","description":"Error type"},"message":{"type":"string","description":"Human-readable error description"},"status":{"type":"number","description":"HTTP status code"}},"additionalProperties":false}}}}}}}},"tags":[{"name":"Health","description":"Server health and status checks"},{"name":"Chains","description":"Supported blockchains and token discovery"},{"name":"Token Transfers","description":"Query token transfer history for addresses and transactions"},{"name":"Token Balances","description":"Query current token balances for addresses"},{"name":"Wallets","description":"Register and manage wallets for automatic transaction syncing"},{"name":"Wallet Transfers","description":"Query automatically synced transfers for registered wallets"}]}