Getting Started
Access powerful onchain data curated by the Zapper Protocol with a GraphQL API.
Portfolio Data
A set of portfolio queries to fetch Tokens, NFTs, App Balances, Portfolio Totals, and Claimables.
Human-Readable Transactions
Simplify onchain transactions with human-friendly descriptions.
Onchain Identity
Surface identity primitives such as avatars, ENS, Farcaster, Lens and more.
Onchain Prices
A price for every token that has an onchain market, including historical data.
NFTs
Rich NFT metadata with media, traits, holders, valuations and more.
Quickstart
1) Get an API key
2) Start building
Below are examples for working with the Zapper API across different languages and frameworks. Each example shows how to fetch portfolio data for provided addresses, across the chosen chains. Additionally, our API Sandbox lets you try our endpoints in one click.
If you are working with an AI agent, we also recommend providing our customized prompt to start building efficiently.
The API key must be base64 encoded for all requests.
- React
- Node.js
- cURL
- Python
- Ruby
Setup
- Create new React project:
npm create vite@latest my-app -- --template react-ts
- Install dependencies:
npm install @apollo/client graphql
- Replace
src/App.tsx
with code below - Replace YOUR_API_KEY with your actual key
- Run:
npm start
New to React? Get started with Create React App or Next.js.
import { ApolloClient, InMemoryCache, createHttpLink, gql, useQuery, ApolloProvider } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';
// Types for the GraphQL response
interface BaseToken {
name: string;
symbol: string;
}
interface Token {
balance: string;
balanceUSD: number;
baseToken: BaseToken;
}
interface TokenBalance {
address: string;
network: string;
token: Token;
}
interface PortfolioData {
portfolio: {
tokenBalances: TokenBalance[];
};
}
// Set up Apollo Client
const httpLink = createHttpLink({
uri: 'https://public.zapper.xyz/graphql',
});
const API_KEY = 'YOUR_API_KEY';
const encodedKey = btoa(API_KEY);
const authLink = setContext((_, { headers }) => {
return {
headers: {
...headers,
authorization: `Basic ${encodedKey}`,
},
};
});
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache(),
});
const PortfolioQuery = gql`
query providerPorfolioQuery($addresses: [Address!]!, $networks: [Network!]!) {
portfolio(addresses: $addresses, networks: $networks) {
tokenBalances {
address
network
token {
balance
balanceUSD
baseToken {
name
symbol
}
}
}
}
}
`;
function Portfolio() {
const { loading, error, data } = useQuery<PortfolioData>(PortfolioQuery, {
variables: {
addresses: ['0x3d280fde2ddb59323c891cf30995e1862510342f'],
networks: ['ETHEREUM_MAINNET'],
},
});
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
if (!data) return <div>No data found</div>;
return (
<div className="p-4">
{data.portfolio.tokenBalances.map((balance, index) => (
<div key={`${balance.address}-${index}`} className="mb-4 p-4 border rounded">
<p>Token: {balance.token.baseToken.name}</p>
<p>Symbol: {balance.token.baseToken.symbol}</p>
<p>Balance: {balance.token.balance}</p>
<p>Value (USD): ${balance.token.balanceUSD.toFixed(2)}</p>
<p>Network: {balance.network}</p>
</div>
))}
</div>
);
}
function App() {
return (
<ApolloProvider client={client}>
<Portfolio />
</ApolloProvider>
);
}
export default App;
Setup
- Create new directory and enter it
- Run
npm init -y
- Install axios:
npm install axios
- Create
index.js
with code below - Replace YOUR_API_KEY
- Run:
node index.js
New to Node.js? Get started with the official guide.
const axios = require('axios');
const API_KEY = 'YOUR_API_KEY';
const encodedKey = Buffer.from(API_KEY).toString('base64');
const query = `
query providerPorfolioQuery($addresses: [Address!]!, $networks: [Network!]!) {
portfolio(addresses: $addresses, networks: $networks) {
tokenBalances {
address
network
token {
balance
balanceUSD
baseToken {
name
symbol
}
}
}
}
}
`;
async function fetchPortfolio() {
try {
const response = await axios({
url: 'https://public.zapper.xyz/graphql',
method: 'post',
headers: {
'Content-Type': 'application/json',
Authorization: `Basic ${encodedKey}`,
},
data: {
query,
variables: {
addresses: ['0x3d280fde2ddb59323c891cf30995e1862510342f'],
networks: ['ETHEREUM_MAINNET'],
},
},
});
if (response.data.errors) {
throw new Error(`GraphQL Errors: ${JSON.stringify(response.data.errors)}`);
}
return response.data.data;
} catch (error) {
console.error('Error fetching portfolio:', error.message);
if (error.response) {
console.error('Response data:', error.response.data);
}
throw error;
}
}
// Example usage
(async () => {
try {
const portfolio = await fetchPortfolio();
console.log(JSON.stringify(portfolio, null, 2));
} catch (error) {
console.error('Failed to fetch portfolio:', error.message);
process.exit(1);
}
})();
Setup
cURL is usually pre-installed on Unix-based systems. For Windows, download it here.
# Encode your API key
API_KEY="YOUR_API_KEY"
ENCODED_KEY=$(echo -n $API_KEY | base64)
Then, run the cURL command using your encoded key :
curl --location 'https://public.zapper.xyz/graphql' --header 'Content-Type: application/json' --header "Authorization: Basic $ENCODED_KEY" --data '{"query":"query providerPorfolioQuery($addresses: [Address!]!, $networks: [Network!]!) { portfolio(addresses: $addresses, networks: $networks) { tokenBalances { address network token { balance balanceUSD baseToken { name symbol } } } } }","variables":{"addresses":["0x3d280fde2ddb59323c891cf30995e1862510342f"],"networks":["ETHEREUM_MAINNET"]}}'
Setup
- Create new directory:
mkdir python-portfolio && cd python-portfolio
- Create virtual environment:
python3 -m venv venv
- Activate virtual environment:
source venv/bin/activate
- Install requests:
pip install requests
- Create
portfolio.py
with code below - Replace YOUR_API_KEY
- Run:
python portfolio.py
New to Python? Get started with the official tutorial.
import requests
import base64
from typing import Dict, Any
API_KEY = 'YOUR_API_KEY'
encoded_key = base64.b64encode(API_KEY.encode()).decode()
query = """
query providerPorfolioQuery($addresses: [Address!]!, $networks: [Network!]!) {
portfolio(addresses: $addresses, networks: $networks) {
tokenBalances {
address
network
token {
balance
balanceUSD
baseToken {
name
symbol
}
}
}
}
}
"""
def fetch_portfolio() -> Dict[str, Any]:
try:
response = requests.post(
'https://public.zapper.xyz/graphql',
headers={
'Content-Type': 'application/json',
'Authorization': f'Basic {encoded_key}'
},
json={
'query': query,
'variables': {
'addresses': ['0x3d280fde2ddb59323c891cf30995e1862510342f'],
'networks': ['ETHEREUM_MAINNET']
}
},
timeout=30
)
response.raise_for_status()
data = response.json()
if 'errors' in data:
raise ValueError(f"GraphQL Errors: {data['errors']}")
return data['data']
except requests.RequestException as e:
print(f"Request failed: {e}")
raise
except ValueError as e:
print(f"Data validation failed: {e}")
raise
except Exception as e:
print(f"Unexpected error: {e}")
raise
if __name__ == "__main__":
try:
portfolio_data = fetch_portfolio()
print("Portfolio data:")
for balance in portfolio_data['portfolio']['tokenBalances']:
print(f"\nToken: {balance['token']['baseToken']['name']}")
print(f"Symbol: {balance['token']['baseToken']['symbol']}")
print(f"Balance: {balance['token']['balance']}")
print(f"Value (USD): ${balance['token']['balanceUSD']}")
print(f"Network: {balance['network']}")
except Exception as e:
print(f"Failed to fetch portfolio: {e}")
Setup
- Install Ruby if not installed:
brew install ruby
(macOS) or follow Ruby installation guide - Create new directory:
mkdir ruby-portfolio && cd ruby-portfolio
- Create
portfolio.rb
with code below - Replace YOUR_API_KEY
- Run:
ruby portfolio.rb
New to Ruby? Get started with Ruby in 20 minutes.
require 'net/http'
require 'uri'
require 'json'
require 'base64'
API_KEY = 'YOUR_API_KEY'
encoded_key = Base64.strict_encode64(API_KEY)
query = <<-GRAPHQL
query providerPorfolioQuery($addresses: [Address!]!, $networks: [Network!]!) {
portfolio(addresses: $addresses, networks: $networks) {
tokenBalances {
address
network
token {
balance
balanceUSD
baseToken {
name
symbol
}
}
}
}
}
GRAPHQL
def fetch_portfolio
uri = URI('https://public.zapper.xyz/graphql')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.read_timeout = 30
http.open_timeout = 30
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request['Authorization'] = "Basic #{encoded_key}"
request.body = {
query: query,
variables: {
addresses: ['0x3d280fde2ddb59323c891cf30995e1862510342f'],
networks: ['ETHEREUM_MAINNET']
}
}.to_json
response = http.request(request)
unless response.is_a?(Net::HTTPSuccess)
raise "HTTP Request failed: #{response.code} - #{response.message}"
end
data = JSON.parse(response.body)
if data['errors']
raise "GraphQL Errors: #{data['errors']}"
end
data['data']
rescue JSON::ParserError => e
raise "Failed to parse JSON response: #{e.message}"
rescue StandardError => e
raise "Error fetching portfolio: #{e.message}"
end
begin
portfolio = fetch_portfolio
puts "Portfolio data:"
portfolio['portfolio']['tokenBalances'].each do |balance|
puts "\nToken: #{balance['token']['baseToken']['name']}"
puts "Symbol: #{balance['token']['baseToken']['symbol']}"
puts "Balance: #{balance['token']['balance']}"
puts "Value (USD): $#{balance['token']['balanceUSD']}"
puts "Network: #{balance['network']}"
end
rescue StandardError => e
puts "Failed to fetch portfolio: #{e.message}"
exit 1
end
3) Buy Credits
Zapper API uses a credit system to manage how many queries an API key can perform. Each query made costs a certain amount of credits which can be found by visiting Pricing.
Track API usage and purchase additional credits via the API Dashboard.
If you are a client of the legacy REST API, you have access to the new GraphQL endpoints with your existing API key, after signing in to the new Dashboard with the email associated with your existing account. Please contact us at [email protected] to get your purchased points migrated to the new GraphQL API.