See also: REST intro,
Networks,
Pools
Installation
# Using Composer
composer require coinpaprika/dexpaprika-sdk-php
# From source
git clone https://github.com/coinpaprika/dexpaprika-sdk-php
cd dexpaprika-sdk-php
composer install
Prerequisites
- PHP 7.4 or higher
- Composer
ext-jsonPHP extension- Connection to the internet to access the DexPaprika API
- No API key needed to start
PHP SDK Quickstart
<?php
require_once 'vendor/autoload.php';
use DexPaprika\Client;
// Create client and get WETH price on Ethereum
$client = new Client();
$weth = $client->tokens->getTokenDetails('ethereum', '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2');
echo "{$weth['name']}: \${$weth['price_usd']}";
// Output: Wrapped Ether: $3245.67
API Methods Reference
Parameters marked with an asterisk (*) are required.
category
Show methods
Show methods
client->networks->getNetworks()
Endpoint: GET/networksGets all supported blockchain networks including Ethereum, Solana, etc.Parameters: NoneReturns: Network IDs, names, and related information. Response Structure.// Get all networks
$networks = $client->networks->getNetworks();
echo "Found {$networks['networks']} networks";
client->networks->findNetwork(networkId)
Gets a network by its ID.Parameters:networkId* - ID of the network to find (e.g., ‘ethereum’)
// Find Ethereum network
$ethereum = $client->networks->findNetwork('ethereum');
if ($ethereum) {
echo "Found network: {$ethereum['display_name']}";
}
category
Show methods
Show methods
client->networks->getNetworkDexes(networkId, options)
Endpoint: GET/networks/{network}/dexesGets all DEXes on a specific network.Parameters:networkId* - ID of the network (e.g., ‘ethereum’, ‘solana’)options- Additional options:page- Page number for pagination (starts at 0)limit- Number of results per page
// Get all DEXes on Ethereum
$dexes = $client->networks->getNetworkDexes('ethereum', ['limit' => 10]);
echo "Found {$dexes['dexes']} DEXes on Ethereum";
client->networks->findDex(networkId, dexId)
Finds a specific DEX on a network by its ID.Parameters:networkId* - ID of the networkdexId* - ID of the DEX to find
// Find Uniswap V3 on Ethereum
$dex = $client->networks->findDex('ethereum', 'uniswap-v3');
if ($dex) {
echo "Found DEX: {$dex['name']}";
}
category
Show methods
Show methods
client->pools->getTopPools(options)
The
GET /pools endpoint was removed and returns 410 Gone. Whatever this
method does locally, the request cannot succeed. Use the network-scoped method
below and pass a network, or call GET /pools/search with a chains filter
directly. See pool filtering./pools (removed, 410 Gone)Gets top pools across all networks with pagination.Parameters:options- Additional options:page- Page number for pagination (starts at 0)limit- Number of results per pageorderBy- Field to sort by (‘volume_usd’, ‘liquidity_usd’, etc.)sort- Sort direction (‘asc’ or ‘desc’)
// Get top 10 pools by volume
$topPools = $client->pools->getTopPools([
'limit' => 10,
'orderBy' => 'volume_usd',
'sort' => 'desc'
]);
echo "Top pool: {$topPools['pools'][0]['dex_name']}";
client->pools->getNetworkPools(networkId, options)
Endpoint: GET/networks/{network}/pools/searchGets pools on a specific network with pagination and sorting options.Parameters:networkId* - ID of the networkoptions- Additional options:limit- Number of results per pageorderBy- Field to sort by (‘volume_usd_24h’, ‘liquidity_usd’, ‘txns_24h’, and the rest of the canonical list). Legacy values are mapped, sovolume_usdis sent asorder_by=volume_usd_24h, and REST rejects the legacy spelling with400sort- Sort direction (‘asc’ or ‘desc’)cursor- Cursor for the next page, taken fromnext_cursoron the previous response. There is nopageoption: the endpoint is cursor-paginated
results array plus has_next_page and next_cursor. Response Structure.// Get top 5 pools on Ethereum by volume
$pools = $client->pools->getNetworkPools('ethereum', [
'limit' => 5,
'orderBy' => 'volume_usd_24h',
'sort' => 'desc'
]);
echo "Found " . count($pools['results']) . " pools on Ethereum";
client->pools->getDexPools(networkId, dexId, options)
GET /networks/{network}/dexes/{dex}/pools was removed and returns 410 Gone.
This method now calls GET /networks/{network}/pools/search?dex_name=... instead. The DEX id
moved out of the path and into a filter, so page is gone and the response shape changed.
See pool filtering./networks/{network}/pools/search?dex_name=...Gets pools on a specific DEX within a network.Parameters:networkId* - ID of the networkdexId* - ID of the DEX, thedex_idfield fromgetNetworkDexes, case-insensitive (a display name likeUniswap V3returns no rows instead of an error)options- Additional options:limit- Number of results per page (max 100)orderBy- Field to sort by (‘volume_usd_24h’, ‘liquidity_usd’, ‘txns_24h’, and the rest of the canonical list)sort- Sort direction (‘asc’ or ‘desc’)cursor- Cursor for the next page, taken fromnext_cursoron the previous response
There is no
page option any more. The SDK normalizes legacy sort values, so volume_usd is
sent as order_by=volume_usd_24h; REST rejects the legacy spelling with a 400 that lists the
values it will take.results array plus has_next_page and next_cursor for cursor pagination. Response Structure.// Get the busiest Uniswap V3 pools on Ethereum
$uniswapPools = $client->pools->getDexPools('ethereum', 'uniswap_v3', [
'limit' => 10,
'orderBy' => 'volume_usd_24h',
'sort' => 'desc'
]);
foreach ($uniswapPools['results'] as $pool) {
echo "{$pool['dex_name']}: $" . number_format($pool['volume_usd_24h'], 2) . " 24h volume\n";
}
client->pools->getPoolDetails(networkId, poolAddress, options)
Endpoint: GET/networks/{network}/pools/{pool_address}Gets detailed information about a specific pool.Parameters:networkId* - ID of the networkpoolAddress* - On-chain address of the pooloptions- Additional options:inversed- Whether to invert the price ratio (boolean)
// Get details for a specific pool (WETH/USDC on Uniswap V2)
$pool = $client->pools->getPoolDetails(
'ethereum',
'0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc',
['inversed' => false]
);
echo "Pool: {$pool['tokens'][0]['symbol']}/{$pool['tokens'][1]['symbol']}";
client->pools->getPoolTransactions(networkId, poolAddress, options)
Endpoint: GET/networks/{network}/pools/{pool_address}/transactionsGets transaction history for a specific pool with pagination.Parameters:networkId* - ID of the networkpoolAddress* - On-chain address of the pooloptions- Additional options:page- Page number for paginationlimit- Number of transactions per pagecursor- Transaction ID used for cursor-based pagination
// Get the latest 20 transactions for a pool
$transactions = $client->pools->getPoolTransactions(
'ethereum',
'0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc',
['limit' => 20]
);
$latestTxTime = date('Y-m-d H:i:s', $transactions['transactions'][0]['block_timestamp']);
echo "Latest transaction: {$latestTxTime}";
client->pools->getPoolOHLCV(networkId, poolAddress, start, options)
Endpoint: GET/networks/{network}/pools/{pool_address}/ohlcvGets OHLCV (Open, High, Low, Close, Volume) chart data for a pool.Parameters:networkId* - ID of the networkpoolAddress* - On-chain address of the poolstart* - Start time (ISO date string, YYYY-MM-DD, or Unix timestamp)options- Additional options:end- End time (optional)limit- Number of data points to returninterval- Time interval (‘1m’, ‘5m’, ‘15m’, ‘30m’, ‘1h’, ‘6h’, ‘12h’, ‘24h’)inversed- Whether to invert the price ratio (boolean)
// Get OHLCV data for the past 7 days with 1-hour intervals
$endDate = date('Y-m-d');
$startDate = date('Y-m-d', strtotime('-7 days'));
$ohlcv = $client->pools->getPoolOHLCV(
'ethereum',
'0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc',
$startDate,
[
'end' => $endDate,
'interval' => '1h',
'limit' => 168 // 24 * 7 hours
]
);
echo "Received {$ohlcv} OHLCV data points";
category
Show methods
Show methods
client->tokens->getTokenDetails(networkId, tokenAddress)
Endpoint: GET/networks/{network}/tokens/{token_address}Gets comprehensive token information.Parameters:networkId* - ID of the networktokenAddress* - Token contract address
// Get WETH token details
$weth = $client->tokens->getTokenDetails(
'ethereum',
'0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'
);
echo "{$weth['name']} price: \${$weth['price_usd']}";
client->tokens->getTokenPools(networkId, tokenAddress, options)
GET /networks/{network}/tokens/{token_address}/pools was removed and returns 410 Gone.
This method now calls GET /networks/{network}/pools/search?token_address=... instead. The old
second-token address pair filter and the reorder flag have no replacement and are not sent.
See pool filtering./networks/{network}/pools/search?token_address=...Gets pools containing a specific token.Parameters:networkId* - ID of the networktokenAddress* - Token contract addressoptions- Additional options:limit- Number of results per page (max 100)sort- Sort direction (‘asc’ or ‘desc’)orderBy- Field to sort by (‘volume_usd_24h’, ‘liquidity_usd’, ‘txns_24h’, and the rest of the canonical list)cursor- Cursor for the next page, taken fromnext_cursoron the previous response
There is no
page option and no second-token address option. The endpoint is cursor-paginated,
and GET /networks/{network}/pools/search has no pair filter, so anything you pass under those
names is dropped before the request goes out. Filter results[].tokens yourself to match a pair.
The SDK also normalizes legacy sort values, so volume_usd is sent as order_by=volume_usd_24h;
REST rejects the legacy spelling with 400.results array plus has_next_page and next_cursor for cursor pagination. Response Structure.// Get the busiest WETH pools on Ethereum
$pools = $client->tokens->getTokenPools(
'ethereum',
'0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // WETH
[
'limit' => 5,
'orderBy' => 'volume_usd_24h',
'sort' => 'desc'
]
);
foreach ($pools['results'] as $pool) {
echo "{$pool['dex_name']}: $" . number_format($pool['volume_usd_24h'], 2) . " 24h volume\n";
}
client->tokens->findToken(networkId, tokenAddress)
Endpoint: GET/networks/{network}/tokens/{token_address}Same call as getTokenDetails, wrapped so a missing token raises
NotFoundException instead of handing you an empty payload to check.Parameters:networkId* - ID of the networktokenAddress* - Contract address of the tokenasObject- Return an object instead of an array (default:false)
getTokenDetails.// Find WETH by its contract address
try {
$token = $client->tokens->findToken(
'ethereum',
'0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'
);
echo "Found {$token['name']} at {$token['id']}";
} catch (DexPaprika\Exception\NotFoundException $e) {
echo "Token not found";
}
category
Show methods
Show methods
client->search->search(query)
Endpoint: GET/searchSearches across tokens, pools, and DEXes using a query string.Parameters:query* - Search query string
// Search for "ethereum" across all entities
$results = $client->search->search("ethereum");
echo "Found {$results['summary']['total_tokens']} tokens\n";
echo "Found {$results['summary']['total_pools']} pools\n";
echo "Found {$results['summary']['total_dexes']} dexes\n";
category
Show methods
Show methods
client->stats->getStats()
Endpoint: GET/statsGets platform-wide statistics.Parameters: NoneReturns: Counts of chains, DEXes, pools, and tokens indexed. Response Structure.// Get platform statistics
$stats = $client->stats->getStats();
echo "Total chains: {$stats['chains']}\n";
echo "Total DEXes: {$stats['dexes']}\n";
echo "Total pools: {$stats['pools']}\n";
echo "Total tokens: {$stats['tokens']}\n";
Complete Example
Show example
Show example
<?php
require_once __DIR__ . '/vendor/autoload.php';
use DexPaprika\Client;
use DexPaprika\Exception\DexPaprikaApiException;
function main() {
try {
// Initialize client
$client = new Client();
// Get Ethereum network details
$networks = $client->networks->getNetworks();
$ethereum = null;
foreach ($networks['networks'] as $network) {
if ($network['id'] === 'ethereum') {
$ethereum = $network;
break;
}
}
echo "Found {$ethereum['display_name']} with {$ethereum['dexes_count']} DEXes\n";
// Get WETH token details
$weth = $client->tokens->getTokenDetails(
'ethereum',
'0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'
);
echo "{$weth['name']} price: \${$weth['price_usd']}\n";
// Find the busiest WETH pools
$pools = $client->tokens->getTokenPools(
'ethereum',
'0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // WETH
[
'limit' => 5,
'orderBy' => 'volume_usd_24h',
'sort' => 'desc'
]
);
// Show top pools
echo "Top WETH pools:\n";
foreach ($pools['results'] as $pool) {
echo "{$pool['dex_name']}: $" . number_format($pool['volume_usd_24h'], 2) . " 24h volume\n";
}
} catch (DexPaprikaApiException $e) {
echo "API Error: {$e->getMessage()}\n";
} catch (Exception $e) {
echo "Error: {$e->getMessage()}\n";
}
}
main();
Advanced Features
Error Handling
Show error handling
Show error handling
<?php
require_once __DIR__ . '/vendor/autoload.php';
use DexPaprika\Client;
use DexPaprika\Exception\DexPaprikaApiException;
use DexPaprika\Exception\NotFoundException;
use DexPaprika\Exception\RateLimitException;
use DexPaprika\Exception\ServerException;
use DexPaprika\Exception\NetworkException;
// Basic error handling
try {
$client = new Client();
$token = $client->tokens->getTokenDetails('ethereum', '0xinvalidaddress');
} catch (NotFoundException $e) {
echo "Token not found: {$e->getMessage()}\n";
} catch (RateLimitException $e) {
echo "Rate limit exceeded. Try again in: {$e->getRetryAfter()} seconds\n";
} catch (ServerException $e) {
echo "Server error occurred: {$e->getMessage()}\n";
} catch (NetworkException $e) {
echo "Network error: {$e->getMessage()}\n";
} catch (DexPaprikaApiException $e) {
echo "API error: {$e->getMessage()} (Code: {$e->getCode()})\n";
} catch (Exception $e) {
echo "General error: {$e->getMessage()}\n";
}
// The SDK automatically retries on these status codes:
// 408 (Request Timeout), 429 (Too Many Requests),
// 500, 502, 503, 504 (Server Errors)
// Custom retry configuration
use DexPaprika\Config;
$config = new Config();
$config->setMaxRetries(4); // Number of retry attempts (default: 3)
$config->setRetryDelays([100, 500, 1000, 5000]); // Delay in milliseconds
$client = new Client(null, null, false, $config);
// All API requests will now use these retry settings
try {
$networks = $client->networks->getNetworks();
} catch (Exception $e) {
echo "Failed after multiple retries: {$e->getMessage()}\n";
}
Caching System
Show caching
Show caching
<?php
require_once __DIR__ . '/vendor/autoload.php';
use DexPaprika\Client;
use DexPaprika\Cache\FilesystemCache;
// The SDK includes built-in caching capabilities
// Demonstration of cache behavior
// Create a client with default cache (1 hour TTL)
$client = new Client();
$client->setupCache();
// First call - hits the API
$startTime = microtime(true);
$networks = $client->networks->getNetworks();
$firstCallTime = microtime(true) - $startTime;
echo "First call (API): {$networks['networks']} networks, took {$firstCallTime} s\n";
// Second call - served from cache (much faster)
$startTime = microtime(true);
$networks = $client->networks->getNetworks();
$secondCallTime = microtime(true) - $startTime;
echo "Second call (cached): {$networks['networks']} networks, took {$secondCallTime} s\n";
echo "Cache speedup: " . ($firstCallTime / $secondCallTime) . "x\n";
// You can skip the cache when you need fresh data
$client->getConfig()->setCacheEnabled(false);
$freshNetworks = $client->networks->getNetworks();
$client->getConfig()->setCacheEnabled(true);
// Custom cache configuration
$cache = new FilesystemCache('/path/to/custom/cache');
$client->setupCache($cache, 300); // 5 minutes TTL
// Clear the entire cache
$client->getConfig()->getCache()->clear();
Pagination Helper
Show pagination
Show pagination
<?php
require_once __DIR__ . '/vendor/autoload.php';
use DexPaprika\Client;
function fetchAllPools($networkId) {
$client = new Client();
$allPools = [];
$limit = 50;
$cursor = null;
while (true) {
$options = [
'limit' => $limit,
'sort' => 'desc',
'orderBy' => 'volume_usd_24h'
];
if ($cursor !== null) {
$options['cursor'] = $cursor;
}
$response = $client->pools->getNetworkPools($networkId, $options);
$allPools = array_merge($allPools, $response['results']);
// The search endpoint is cursor-paginated, not page-numbered
if (empty($response['has_next_page']) || empty($response['next_cursor'])) {
break;
}
$cursor = $response['next_cursor'];
// Free allows 30 requests a minute, so pause 2 seconds between pages
sleep(2);
}
echo "Fetched a total of " . count($allPools) . " pools on {$networkId}\n";
return $allPools;
}
// Alternative approach using built-in paginator
function fetchAllPoolsWithPaginator($networkId) {
$client = new Client();
$allPools = [];
// Create a paginator for network pools
$paginator = $client->createPaginator(
$client->pools,
'getNetworkPools',
[
$networkId,
[
'limit' => 50,
'orderBy' => 'volume_usd_24h',
'sort' => 'desc'
]
]
);
// Iterate through all pages (or up to a maximum)
$paginator->setMaxPages(10); // Optional: limit to 10 pages
foreach ($paginator as $page => $response) {
$allPools = array_merge($allPools, $response['pools']);
echo "Processed page {$page}, got {$response['pools']} pools\n";
}
echo "Fetched a total of {$allPools} pools on {$networkId}\n";
return $allPools;
}
// Usage example
$ethereumPools = fetchAllPools('ethereum');
// or
$ethereumPools = fetchAllPoolsWithPaginator('ethereum');
Working with Objects
Show objects
Show objects
<?php
require_once __DIR__ . '/vendor/autoload.php';
use DexPaprika\Client;
use DexPaprika\Config;
// Create a client that returns objects instead of arrays
$config = new Config();
$config->setResponseFormat('object');
$client = new Client(null, null, true, $config);
// Get pool details
$pool = $client->pools->getPoolDetails(
'ethereum',
'0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640' // USDC/WETH Uniswap v3 pool
);
// Access pool properties as object properties
echo "Pool: {$pool->tokens[0]->symbol}/{$pool->tokens[1]->symbol}\n";
echo "Volume (24h): \${$pool->day->volume_usd}\n";
echo "Transactions (24h): {$pool->day->txns}\n";
echo "Price: \${$pool->last_price_usd}\n";
// Time interval data is available for multiple timeframes
echo "1h price change: {$pool->hour1->last_price_usd_change}%\n";
echo "24h price change: {$pool->day->last_price_usd_change}%\n";
// Combining with array-based response for specific API calls
$client->getConfig()->setResponseFormat('array');
$networks = $client->networks->getNetworks();
// Back to object mode
$client->getConfig()->setResponseFormat('object');
$token = $client->tokens->getTokenDetails('ethereum', '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2');
echo "{$token->name} price: \${$token->price_usd}\n";
Resources
API Status
The DexPaprika API provides consistent data with stable endpoints. No API key is currently required to access the service. We aim to maintain backward compatibility and provide notice of any significant changes.FAQs
Do I need an API key with this SDK?
Do I need an API key with this SDK?
Not to start. Keyless requests work at 50,000 credits a month per IP, and a free registered key raises that to 300,000 with no card.
How do I find identifiers?
How do I find identifiers?
Use Coverage Checker or list Networks and query Tokens/Pools to discover addresses.
How do I get historical or transactions data?
How do I get historical or transactions data?
Use pools/transactions endpoints with
pool_address, network, and time/paging params as documented.What about rate limiting?
What about rate limiting?
30 requests a minute on the free tier, 300 on Pro, against a monthly allowance of 50,000 credits keyless, 300,000 with a free key, or 5,000,000 on Pro. Retry transient HTTP errors with backoff. See rate limits for how the counters work, and Pro pricing for what the 5,000,000 credit tier costs.