# Zerion API Docs Documentation ## API Reference - [Building with AI](https://developers.zerion.io/reference/building-with-ai.md) - [Featured Partners](https://developers.zerion.io/reference/featured-partners.md): Explore how other web3 teams use Zerion's API to power their amazing applications - [Zerion API Designed for Developers](https://developers.zerion.io/reference/getting-started.md): This page will help you get the most out of Zerion API. You'll be up and running in a jiffy! - [Supported Blockchains](https://developers.zerion.io/reference/supported-blockchains.md): Across all major blockchains, you can access wallets, assets, and chain data for web3 portfolios through Zerion's infrastructure! - [Spam Filtering](https://developers.zerion.io/reference/token-spam-filtering.md) - [Support & Feedback](https://developers.zerion.io/reference/feedback.md) - [Authentication](https://developers.zerion.io/reference/authentication.md): API keys are used for authenticating your Zerion API Access. Generate your key below 👇 - [Get chain by ID](https://developers.zerion.io/reference/getchainbyid.md): This endpoint returns chain by unique chain identifier. This endpoint supports testnets. To get data for testnets use `X-Env` header. - [chains](https://developers.zerion.io/reference/chains.md) - [Get list of all chains](https://developers.zerion.io/reference/listchains.md): This endpoint returns list of all chains supported by Zerion. This endpoint supports testnets. To get data for testnets use `X-Env` header. - [Get DApp by ID](https://developers.zerion.io/reference/getdappbyid.md): This endpoint returns single DApp by its unique identifier. - [Get list of DApps](https://developers.zerion.io/reference/listdapps.md): This endpoint returns list of DApps by using different parameters. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. - [Endpoints and Schema Details](https://developers.zerion.io/reference/endpoints-and-schema-details.md) - [Error Codes](https://developers.zerion.io/reference/error-codes.md) - [Get fungible asset by ID](https://developers.zerion.io/reference/getfungiblebyid.md): This endpoint returns a fungible asset by unique identifier - [Get a chart for a fungible asset](https://developers.zerion.io/reference/getfungiblechart.md): This endpoint returns the chart for the fungible asset for a selected period - [fungibles](https://developers.zerion.io/reference/fungibles.md) - [Get list of fungible assets](https://developers.zerion.io/reference/listfungibles.md): This endpoint returns a paginated list of fungible assets supported by Zerion. It also provides the ability to search for fungibles. If no fungible assets are found for given filters, the empty list with 200 status is returned. > NOTE: This endpoint supports a lot of filters, sorting, and pagination parameters. Ensure your request URL length is within a safe range for your platform. Usually, 2000 characters are the safe limit in virtually any combination of client and server software. > NOTE: The `filter[implementation_address]` parameter ignores `filter[search_query]`. It may be changed in the future. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. - [Get list of all available gas prices](https://developers.zerion.io/reference/listgasprices.md): This endpoint provides real-time information on the current gas prices across all supported blockchain networks. Gas prices play a crucial role in the speed and cost of executing transactions on a blockchain, and fluctuate frequently based on network demand and usage. By using this endpoint, developers can stay up-to-date with the latest gas prices and adjust their application's transaction parameters accordingly to ensure optimal speed and cost efficiency. - [Get single NFT by ID](https://developers.zerion.io/reference/getnftbyid.md): This endpoint returns single NFT by its unique identifier. This endpoint supports testnets. To get data for testnets use `X-Env` header. - [Get list of NFTs](https://developers.zerion.io/reference/listnfts.md): This endpoint returns list of NFTs by using different parameters. It returns NFTs of both types - ERC721 and ERC1155. This endpoint supports testnets. To get data for testnets use `X-Env` header. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. - [Create subscription](https://developers.zerion.io/reference/createsubscriptionwallettransactions.md): This endpoint subscribes to new transactions associated with the wallets. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. ### Use Case The main use case for the webhooks system is to send notifications, similar to push notifications in the Zerion App. ### Setup Callback URL If you want to use this endpoint to test how it works, you might use your dev key to start. It has limits: one subscription & maximum 5 wallets per subscription. You may use callback URL from webhook.site to start from. If want use your custom - contact us at api@zerion.io, and we will whitelist your URL. If you want to use this endpoint in your production environment, you should contact us and provide the following details: - Your email associated with the API key - The URL that you prefer using as the callback (or host). After we've whitelisted your callback URL (or host), you may start using this endpoint. ### Note - **Subscription Validity**: Every subscription is valid for unlimited amount of time for production key, and one week for `dev` keys. - **Transaction Prices**: Prices are not attached to webhook notifications and will always be `null`. Prices are added to transactions in the backend after some time. To get prices, query the transactions endpoint by hash. - **Delivery Guarantees**: Webhook delivery is not guaranteed. If delivery fails three times, no further attempts will be made. - **Order of Dispatch**: The order of webhook dispatch is not guaranteed and may not correspond to the order of transactions occurring on the blockchain. ### Callback Format and Signature Verification Approved clients will receive notifications via POST requests to their provided URL. These notifications will include a signed notification object in the body (specified below in the `Callback` section) and a signature in the headers. Clients should verify the signature provided in the headers of the webhook request to ensure the authenticity of the data. The following headers will be included: - `X-Signature`: The signature of the request. - `X-Timestamp`: The timestamp of the request. - `X-Certificate-URL`: The URL to download the public certificate used to verify the signature. **To verify the signature:** 1. Concatenate the `X-Timestamp` header value, the request body, and a newline character: `$timestamp + "\n" + $request.body + "\n"` 2. Use the public certificate downloaded from the `X-Certificate-URL` header to verify the signature in the `X-Signature` header. Example code in go for message verification: ```go package signature import ( "crypto" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/base64" "encoding/pem" "errors" "github.com/stretchr/testify/assert" "testing" ) // FetchCertificate fetches the certificate from the given URL func FetchCertificate() (*x509.Certificate, error) { certBytes := certificate() block, _ := pem.Decode(certBytes) if block == nil || block.Type != "CERTIFICATE" { return nil, errors.New("failed to decode PEM block containing the certificate") } return x509.ParseCertificate(block.Bytes) } func certificate() []byte { return []byte(`-----BEGIN CERTIFICATE----- MIIDMTCCAhmgAwIBAgIUDd3dFMswamyJ5A1bqF0nzS8v2wgwDQYJKoZIhvcNAQEL BQAwQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC1plcmlvbiBJbmMuMRwwGgYJKoZI hvcNAQkBFg1hcGlAemVyaW9uLmlvMB4XDTI0MDYyNzE1MzUzM1oXDTI1MDYyNzE1 MzUzM1owQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC1plcmlvbiBJbmMuMRwwGgYJ KoZIhvcNAQkBFg1hcGlAemVyaW9uLmlvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEAwcPVCPLDhS9dLA8s5J6GJ3t0+jWuUCFwI+q6c03xZnhCaz45FepN MTiApbvPw1Zm8F8JQB4BRp/F5anokNcDSl/qmNtj3M/z/FrsVvGnSH2FOkZu9TLU LTW5i8Q0LAYrpgiBHrTa2qrRXd2DiMrEs3QZVoylFYc9QIGet3SULPrlSsYEKxfB iBZDoFw619NnV6/kBO8FS34Lc+WH5SNNHNnItRrxMv4DMAFyFajSn1IwV6LSWSNK aPJHCzP/Omu95550HQKcXaJYNE/d99NrcLaFI2fCuEVd00nApFo5knKs0FiXpGca l3cLOQG5SCOzUOjQb6X5CynEV+0QiyYxDwIDAQABoyEwHzAdBgNVHQ4EFgQUVL4m u0PcI4nJGUS8syLi5DNL44YwDQYJKoZIhvcNAQELBQADggEBAKaA1oqW0D6KxvIp IZxWf02XK/YFYwxKV55Vas0VWlzNemE2IjlIj0tknZt0EiM9um2FC27U9n3u0ApS UDrk96dQ+/RY3T3fiuXysa3ZL05OpreRk0aPuFU9rB4iLTgFiv1G/X5XXJ8O7OQb 48u0vQnYXjT/nt72TMUoakjZ68QsP64FkG8mcK62Tg+FVWB9YWTFc0wOjsOt9RzJ muKCQ7qx7L1GhkxKX4ZhrYItsH1DzXjeP5aniZgLBSPbxt01tUrSjOGN5CLOpdG8 iOnAFP+Nz8S0h2C7hppOHgC+uxY285UrzAZQoMbCREMV+0Mq/aqdF1B6qoKGNGqL kFbUhvo= -----END CERTIFICATE----- `) } func VerifySignature(cert *x509.Certificate, message, signature string) error { pubKey := cert.PublicKey.(*rsa.PublicKey) hashed := sha256.Sum256([]byte(message)) sigBytes, err := base64.StdEncoding.DecodeString(signature) if err != nil { return err } return rsa.VerifyPKCS1v15(pubKey, crypto.SHA256, hashed[:], sigBytes) } func TestVerifySignature(t *testing.T) { // Example usage x509Cert, err := FetchCertificate() assert.NoError(t, err) xTimestamp := "2024-07-31T00:17:36Z" xSignature := "t65gdR8z3NGh/OQRPzGMFmw36JhDNvOe6LxL6K2hCd3SdYQoTGr76dAy1CpsX2G8XVOIYUIctUQvgICQvtDctVjkRZmXuQDvXHOmiJE0ZknORgjVLFoo5JRYKvwt3EPp6SMN7RtedIX17rH1s2Vp3GRQWSjzN7C/cNgInhCQOP0UDjYlaeNT/yW4B2Qt4uY01yK0YhvQJaFHN+NNr7DZAt4FJuDppItqjaYbHTaFNqLlpI1IX7YvQWVhEYTJY6M4T9IdcGYPJKDljckjvmj9mDHZeh/Y6w8eXjLziMSFvlhJeSn1kBIR3nS7lTcwFNv1CPxD3MM7VB++te3mBbFubg==" messageBody := `{"data":{"attributes":{"timestamp":"2024-07-31T00:17:36.661896043Z"},"id":"15daee90-5028-4b4c-bd49-b4d43fa1a89e","type":"callback"},"included":[{"attributes":{"application_metadata":{"contract_address":"0x8286d601a0ed6cf75e067e0614f73a5b9f024151","method":{"id":"0x7859bb8d","name":""}},"approvals":[],"fee":{"fungible_info":{"flags":{"verified":true},"icon":{"url":"https://cdn.zerion.io/eth.png"},"implementations":[{"address":"","chain_id":"redstone","decimals":18},{"address":"","chain_id":"polygon-zkevm","decimals":18},{"address":"","chain_id":"optimism","decimals":18},{"address":"","chain_id":"zksync-era","decimals":18},{"address":"","chain_id":"mode","decimals":18},{"address":"","chain_id":"base","decimals":18},{"address":"","chain_id":"ethereum","decimals":18},{"address":"","chain_id":"aurora","decimals":18},{"address":"","chain_id":"scroll","decimals":18},{"address":"","chain_id":"rari","decimals":18},{"address":"","chain_id":"astar-zkevm","decimals":18},{"address":"","chain_id":"arbitrum","decimals":18},{"address":"","chain_id":"zora","decimals":18},{"address":"","chain_id":"blast","decimals":18},{"address":"","chain_id":"linea","decimals":18},{"address":"","chain_id":"manta-pacific","decimals":18}],"name":"Ethereum","symbol":"ETH"},"price":null,"quantity":{"decimals":18,"float":0.0000016785001958,"int":"1678500195825","numeric":"0.000001678500195825"},"value":null},"flags":{"is_trash":false},"hash":"0xbbcfb0ac5e466ded168794a162da334634fee3f95adfdb55392999f91b4c6d41","mined_at":"2024-07-31T00:17:35Z","mined_at_block":7490818,"nonce":250,"operation_type":"execute","sent_from":"0xfc0f1b3fb88c5ab19e77a6f7d4d637272e71e684","sent_to":"0x8286d601a0ed6cf75e067e0614f73a5b9f024151","status":"confirmed","transfers":[]},"id":"a65b2541c58a5908a7333480f0ac6792","relationships":{"chain":{"id":"linea","type":"chains"},"dapp":{"id":"","type":"dapps"}},"type":"transactions"}]}` message := xTimestamp + "\n" + messageBody + "\n" err = VerifySignature(x509Cert, message, xSignature) assert.NoError(t, err) } ``` - [Delete subscription by ID](https://developers.zerion.io/reference/deletewallettransactionssubscription.md): This endpoint deletes existing subscription > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. - [Disable a specific subscription](https://developers.zerion.io/reference/disablesubscription.md): This endpoint sets the status of a specific subscription to "disabled". > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. This ensures flexibility and future-proofing against ID format changes. - [Enable a specific subscription](https://developers.zerion.io/reference/enablesubscription.md): This endpoint sets the status of a specific subscription to "enabled". > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. This ensures flexibility and future-proofing against ID format changes. - [Find subscriptions](https://developers.zerion.io/reference/findwallettransactionssubscription.md): This endpoint finds subscriptions to new transactions associated with the wallets and chains. Currently response is limited to 1000 subscriptions in the response. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. - [Find wallets within subscription](https://developers.zerion.io/reference/getsubscribedwalletsinsubscription.md): This endpoint by subscription ID returns wallets within specific subscription. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. - [Find subscription by ID](https://developers.zerion.io/reference/getwallettransactionssubscription.md): This endpoint by ID returns subscription to new transactions associated with the wallets and chains. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. - [Patch wallets within subscription](https://developers.zerion.io/reference/patchsubscribedwalletsinsubscription.md): This endpoint works by subscription ID. It patches wallets list within specific subscription. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. - [Replace wallets within subscription](https://developers.zerion.io/reference/replacesubscribedwalletsinsubscription.md): This endpoint works by subscription ID. It replaces wallets list within specific subscription. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. - [Update callback URL within subscription](https://developers.zerion.io/reference/updatecallbackurlinsubscription.md): This endpoint updates the callback URL for a specific subscription. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. - [Update chain IDs within subscription](https://developers.zerion.io/reference/updatechainidsinsubscription.md): This endpoint updates the list of chain IDs associated with a specific subscription. > NOTE: > - Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. > - The chain IDs provided will replace the existing chain IDs associated with the subscription. - [Get fungibles available for bridge.](https://developers.zerion.io/reference/swapfungibles.md): The endpoint provides a list of fungibles available for bridge exchange. This endpoint is specifically designed for situations where the input and output chains are different. - [Get available swap offers](https://developers.zerion.io/reference/swapoffers.md): The endpoint offers a comprehensive overview of relevant trades and bridge exchanges. A bridge exchange refers to the transfer of cryptocurrencies between different blockchain networks, while a trade pertains to an exchange of cryptocurrencies within the same network. In an effort to secure the optimal exchange rate for our users, our system sends requests to multiple exchange providers. Zerion only charges a commission fee of 0.5% on L2 and alternative L1 trades, which can be waived by obtaining our Genesis NFT. Our platform has the advantage of being an aggregator of various exchanges, ensuring that users will always get the best exchange rates available. Please note that due to the nature of the multiple requests and calculations involved, it is normal for this endpoint to have a relatively long timeout. You can expect a response time of around 5-10 seconds. - [Get wallet's balance chart](https://developers.zerion.io/reference/getwalletchart.md): This endpoint returns a portfolio balance chart for a wallet. This is over a specified time period, based on the provided start and end timestamps. Results can be filtered by blockchain and asset type, offering flexible and detailed visualizations of wallet performance, similar to what you see in the Zerion interface. Note: We do not support historical protocol positions data. - [Get wallet's NFT portfolio](https://developers.zerion.io/reference/getwalletnftportfolio.md): This endpoint returns the NFT portfolio overview of a web3 wallet. This endpoint supports testnets. To get data for testnets use `X-Env` header. If the address was not added before it is possible that this endpoint will return `202` status. It means that portfolio for the wallet is not prepared yet, but will be available soon. In that case the client have to request this endpoint periodically, while `200` status wasn't returned. > NOTE: Don't forget to stop retries after some reasonable period of time. If the `200` status is not returned within 2 minutes it most probably means that some unexpected error occurred and the client should stop the polling. - [Get wallet's PnL](https://developers.zerion.io/reference/getwalletpnl.md): This endpoint returns the Profit and Loss (PnL) details of a web3 wallet. This includes Unrealized PnL, Realized PnL, Net Invested amounts and filters for asset categories like Non Fungible Tokens (NFTs). It uses the FIFO (First In, First Out) standard for calculations, providing accurate insights into wallet performance. Ideal for tracking and analyzing financial outcomes of wallet activity. - [Get wallet's portfolio](https://developers.zerion.io/reference/getwalletportfolio.md): This endpoint returns the portfolio overview of a web3 wallet. **Temporary limitations for Solana addresses:** - Doesn't support protocol positions > NOTE: Don't forget to stop retries after some reasonable period of time. If the `200` status is not returned within 2 minutes it most probably means that some unexpected error occurred and the client should stop the polling. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. - [wallets](https://developers.zerion.io/reference/wallets.md) - [Get a list of NFT collections held by a wallet](https://developers.zerion.io/reference/listwalletnftcollections.md): This endpoint returns a list of the NFT collections held by a specific wallet. This endpoint supports testnets. To get data for testnets use `X-Env` header. If the wallet address has not been previously added, this endpoint may return a `202` status code. This indicates that the wallet's collections are not yet available, but will be in the near future. In this case, the client should periodically request this endpoint until a `200` status code is returned. > NOTE: It is important to stop retrying after a reasonable period of time. If a `200` status code is not returned within 2 minutes, it is likely that an unexpected error has occurred, and the client should stop polling. > NOTE: This endpoint provides support for filters, sorting. Ensure that the length of the request URL falls within a safe range for your platform. Typically, a length of 2000 characters is a safe limit for most combinations of client and server software. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. - [Get a list of a wallet's NFT positions](https://developers.zerion.io/reference/listwalletnftpositions.md): This endpoint returns a list of the NFT positions held by a specific wallet. This endpoint supports testnets. To get data for testnets use `X-Env` header. If the wallet address has not been previously added, this endpoint may return a `202` status code. This indicates that the wallet's positions are not yet available, but will be in the near future. In this case, the client should periodically request this endpoint until a `200` status code is returned. > NOTE: It is important to stop retrying after a reasonable period of time. If a `200` status code is not returned within 2 minutes, it is likely that an unexpected error has occurred and the client should stop polling. > NOTE: This endpoint provides support for filters, sorting, and pagination parameters. Ensure that the length of the request URL falls within a safe range for your platform. Typically, a length of 2000 characters is a safe limit for most combinations of client and server software. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. - [Get list of wallet's fungible positions](https://developers.zerion.io/reference/listwalletpositions.md): This endpoint returns a list of wallet positions. This endpoint supports testnets. To get data for testnets use `X-Env` header. **Temporary limitations for Solana addresses:** - Doesn't support protocol positions - Some tokens require a few seconds to bootstrap. In this case, there may be no position in the first query, but it will already be displayed in the next query > NOTE: Don't forget to stop retries after some reasonable period of time. If the `200` status is not returned within 2 minutes it most probably means that some unexpected error occurred and the client should stop the polling. > NOTE: This endpoint supports a lot of filters, sorting and pagination parameters. Make sure that a request URL length is in a safe range for your platform. Usually, 2000 characters are the safe limit in virtually any combination of client and server software. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. - [Get list of wallet's transactions](https://developers.zerion.io/reference/listwallettransactions.md): This endpoint returns a list of transactions associated with the wallet. This endpoint supports testnets. To get data for testnets use `X-Env` header. **Temporary limitations for Solana addresses:** - Doesn't support NFT transactions - Some specific transaction types are lacking - Getting data for some specific wallet addresses takes much more time than for others - Doesn't include some incoming transfers > NOTE: This endpoint supports a lot of filters, sorting, and pagination parameters. Make sure that your request URL length is safe for your platform. Usually, 2000 characters are the safe limit in virtually any combination of client and server software. > NOTE: Consider all IDs as abstract strings, without making any assumptions about their format or relying on such assumptions. There is a non-zero probability that IDs may change in the future, and this should not result in any breaking changes. - [Zerion Wallet – Mobile Dapp developers](https://developers.zerion.io/reference/zerion-wallet-docs-for-mobile-dapp-developers.md) ## Recipes - [Building a Real-time Asset Tracker with Zerion's API](https://developers.zerion.io/recipes/building-a-real-time-asset-tracker-with-zerions-api.md) - [How to build a Meta DEX aggregator – 0x, 1inch, Uniswap & more price sources](https://developers.zerion.io/recipes/how-to-build-a-meta-dex-aggregator-0x-1inch-uniswap-more-price-sources-1.md) - [How to Build a Multichain Transaction History (Like Zerion)](https://developers.zerion.io/recipes/how-to-build-a-multichain-transaction-history-like-zerion.md) ## Changelog - [07.10.2025 - Extended Solana Support](https://developers.zerion.io/changelog/07102025-extended-solana-support.md) - [02.10.2025 - `Delegate` & `Revoke Delegation` Support in Transactions API](https://developers.zerion.io/changelog/delegate-revoke-delegation-support-in-transactions-api.md) - [14.02.2025 - Enhanced Portfolio Filtering with Protocol Position Categories](https://developers.zerion.io/changelog/08032024-enhanced-portfolio-filtering-with-protocol-position-categories.md) - [07.05.2024 - Application metadata is now attached to every protocol position](https://developers.zerion.io/changelog/07052024-application-metadata-is-now-attached-to-every-protocol-position.md) - [27.03.2024 - Last Sale Data Integration in Wallet NFT Positions](https://developers.zerion.io/changelog/27032024-last-sale-data-integration-in-wallet-nft-positions.md)