> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dexpaprika.com/llms.txt
> Use this file to discover all available pages before exploring further.

# DexPaprika DEX API Go SDK: on-chain liquidity and swap data client

> The official Go client library for the DexPaprika API, providing easy access to decentralized exchange data across multiple blockchain networks

> [!TIP]
>
> See also: [REST intro](https://docs.dexpaprika.com/api-reference/introduction.md),
> [Networks](https://docs.dexpaprika.com/api-reference/networks/get-a-list-of-available-blockchain-networks.md),
> [Pools](https://docs.dexpaprika.com/api-reference/pools/get-a-pool-on-a-network.md)

## Installation

```bash theme={null}
go get github.com/coinpaprika/dexpaprika-sdk-go
```

## Prerequisites

* Go 1.24 or higher
* Connection to the internet to access the DexPaprika API
* No API key needed to start

## Quick example: get token price

```go theme={null}
package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/coinpaprika/dexpaprika-sdk-go/dexpaprika"
)

func main() {
    // Create client
    client := dexpaprika.NewClient()
    
    // Create context with timeout
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    
    // Get WETH token details on Ethereum
    token, err := client.Tokens.GetDetails(ctx, "ethereum", "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2")
    if err != nil {
        log.Fatalf("Error getting token details: %v", err)
    }
    
    if token.Summary != nil {
        fmt.Printf("%s: $%.2f\n", token.Name, token.Summary.PriceUSD)
    }
    // Output: Wrapped Ether: $3245.67
}
```

## Using an API key (optional)

The SDK works without a key, and that is the default. A [free key](https://console.dexpaprika.com)
raises both the per-minute request limit and the credit allowance. Current figures are on the [rate limits page](https://docs.dexpaprika.com/knowledge-base/rate-limits.md).

Requires v1.8.0 or later.

```go theme={null}
// Explicit
client := dexpaprika.NewClient(dexpaprika.WithAPIKey("api_your_key_here"))

// Or leave it out and set DEXPAPRIKA_API_KEY in the environment
client := dexpaprika.NewClient()
```

An explicit key beats the environment variable, and no key at all keeps the keyless behaviour
unchanged. The host is never inferred from the key: free keys are served from the default base URL,
and [Dev, Pro and Enterprise](https://docs.dexpaprika.com/api-pro/introduction.md) keys move to `api-pro.dexpaprika.com`.

> [!WARNING]
>
> The key is sent as the entire `Authorization` header value. **Nothing goes in front of it**,
> no scheme word of any kind. The SDK writes the header for you, so this matters when you are
> debugging what went out or calling the API directly. See
> [401 Unauthorized](https://docs.dexpaprika.com/knowledge-base/error-handling.md#401-unauthorized).

## API methods reference

> [!NOTE]
>
> Parameters marked with an asterisk (\*) are required.

**Networks** `category`

**methods**

### client.Networks.List(ctx)

**Endpoint:** [GET `/networks`](https://docs.dexpaprika.com/api-reference/networks/get-a-list-of-available-blockchain-networks)

Gets all supported blockchain networks including Ethereum, Solana, etc.

**Parameters:**

* `ctx`\* - Context for API request

**Returns:** Network IDs, names, and related information. [Response Structure](https://docs.dexpaprika.com/api-reference/networks/get-a-list-of-available-blockchain-networks.md).

```go theme={null}
networks, err := client.Networks.List(ctx)
```

**DEXes** `category`

**methods**

### client.Networks.ListDexes(ctx, networkId, page, limit)

**Endpoint:** [GET `/networks/{network}/dexes`](https://docs.dexpaprika.com/api-reference/dexes/get-a-list-of-available-dexes-on-a-network)

Gets all DEXes on a specific network.

**Parameters:**

* `ctx`\* - Context for API request
* `networkId`\* - ID of the network (e.g., 'ethereum', 'solana')
* `page` - Page number for pagination (0 leaves it to the API default)
* `limit` - Number of results per page (0 leaves it to the API default)

**Returns:** DEX IDs, names, pool counts, and volume information. [Response Structure](https://docs.dexpaprika.com/api-reference/dexes/get-a-list-of-available-dexes-on-a-network.md).

```go theme={null}
dexes, err := client.Networks.ListDexes(ctx, "ethereum", 0, 10)
```

**Pools** `category`

**methods**

### client.Pools.List(ctx, options)

> [!WARNING]
>
> **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](https://docs.dexpaprika.com/tutorials/pool-filtering.md).

**Endpoint:** GET `/pools` (removed, `410 Gone`)

Gets top pools across all networks with pagination.

**Parameters:**

* `ctx`\* - Context for API request
* `options` - ListOptions containing pagination and sorting parameters:
  * `Page` - Page number for pagination (starts at 0)
  * `Limit` - Number of results per page
  * `Sort` - Sort direction ('asc' or 'desc')
  * `OrderBy` - Field to sort by ('volume\_usd', 'liquidity\_usd', etc.)

***

### client.Pools.ListByNetwork(ctx, networkId, options)

**Endpoint:** [GET `/networks/{network}/pools/search`](https://docs.dexpaprika.com/api-reference/pools/advanced-pool-filtering-on-a-specific-network)

Gets pools on a specific network with pagination and sorting options.

**Parameters:**

* `ctx`\* - Context for API request
* `networkId`\* - ID of the network
* `options` - `ListOptions`. The endpoint is cursor-paginated, so page forward with `Cursor` taken from the previous response's `NextCursor`; `Page` is not sent. Legacy sort values are mapped, so `OrderBy: "volume_usd"` is sent as `order_by=volume_usd_24h`, and REST rejects the legacy spelling with `400`

**Returns:** Cursor-paginated pools for the given network: a `results` array plus `has_next_page` and `next_cursor`. [Response Structure](https://docs.dexpaprika.com/api-reference/pools/advanced-pool-filtering-on-a-specific-network.md).

```go theme={null}
options := &dexpaprika.ListOptions{
    Limit:   5,
    OrderBy: "volume_usd_24h",
    Sort:    "desc",
}
pools, err := client.Pools.ListByNetwork(ctx, "ethereum", options)
```

***

### client.Pools.ListByDex(ctx, networkId, dexId, options)

> [!WARNING]
>
> **`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](https://docs.dexpaprika.com/tutorials/pool-filtering.md).

**Endpoint:** [GET `/networks/{network}/pools/search?dex_name=...`](https://docs.dexpaprika.com/api-reference/pools/advanced-pool-filtering-on-a-specific-network)

Gets pools on a specific DEX within a network.

**Parameters:**

* `ctx`\* - Context for API request
* `networkId`\* - ID of the network
* `dexId`\* - ID of the DEX, the `dex_id` field from `client.Networks.ListDexes`, case-insensitive (a display name like `Uniswap V3` returns no rows instead of an error)
* `options` - ListOptions containing `Limit`, `OrderBy`, `Sort`, and `Cursor`

> [!NOTE]
>
> `ListOptions.Page` is not sent for this call any more. Page through with `Cursor`, taking the
> value from `NextCursor` on the previous response. The SDK normalizes legacy sort values, so
> `volume_usd` goes out as `order_by=volume_usd_24h`; REST rejects the legacy spelling with a
> `400` that lists the values it will take.

**Returns:** Cursor-paginated pools for the given DEX: a `results` array plus `has_next_page` and `next_cursor`. [Response Structure](https://docs.dexpaprika.com/api-reference/pools/advanced-pool-filtering-on-a-specific-network.md).

```go theme={null}
options := &dexpaprika.ListOptions{
    Limit: 10,
    OrderBy: "volume_usd_24h",
    Sort: "desc",
}
pools, err := client.Pools.ListByDex(ctx, "ethereum", "uniswap_v3", options)
```

***

### client.Pools.GetDetails(ctx, networkId, poolAddress, inversed)

**Endpoint:** [GET `/networks/{network}/pools/{pool_address}`](https://docs.dexpaprika.com/api-reference/pools/get-a-pool-on-a-network)

Gets detailed information about a specific pool.

**Parameters:**

* `ctx`\* - Context for API request
* `networkId`\* - ID of the network
* `poolAddress`\* - On-chain address of the pool
* `inversed` - Whether to invert the price ratio (boolean)

**Returns:** Detailed pool information including tokens, volumes, liquidity, and more. [Response Structure](https://docs.dexpaprika.com/api-reference/pools/get-a-pool-on-a-network.md).

```go theme={null}
poolDetails, err := client.Pools.GetDetails(ctx, "ethereum", "0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc", false)
```

***

### client.Pools.GetTransactions(ctx, networkId, poolAddress, page, limit, cursor, opts...)

**Endpoint:** [GET `/networks/{network}/pools/{pool_address}/transactions`](https://docs.dexpaprika.com/api-reference/pools/get-transactions-of-a-pool-on-a-network-paging-can-be-used-up-to-100-pages)

Gets transaction history for a specific pool with pagination.

Needs a Dev, Pro or Enterprise key and the `https://api-pro.dexpaprika.com` base URL since 30 September 2026; keyless and free keys get `403`. See [pool transactions](https://docs.dexpaprika.com/api-reference/pools/get-transactions-of-a-pool-on-a-network-paging-can-be-used-up-to-100-pages.md).

**Parameters:**

* `ctx`\* - Context for API request
* `networkId`\* - ID of the network
* `poolAddress`\* - On-chain address of the pool
* `page`, `limit` - Pagination
* `cursor` - Transaction ID for cursor-based pagination, or `""`
* `opts` - Optional time window: `dexpaprika.WithFrom("-1h")` and `dexpaprika.WithTo(...)` take a relative offset, Unix seconds, RFC3339 or `YYYY-MM-DD` (1.10.0 and later); `WithFromTimestamp` and `WithToTimestamp` take Unix seconds. `from` is inclusive, `to` exclusive; results go back 7 days at most

**Returns:** List of transactions with details about tokens, amounts, and timestamps. [Response Structure](https://docs.dexpaprika.com/api-reference/pools/get-transactions-of-a-pool-on-a-network-paging-can-be-used-up-to-100-pages.md).

```go theme={null}
// Latest 20 transactions
transactions, err := client.Pools.GetTransactions(ctx, "ethereum", "0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc", 0, 20, "")

// Only the last hour
lastHour, err := client.Pools.GetTransactions(ctx, "ethereum", "0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc", 0, 20, "",
    dexpaprika.WithFrom("-1h"))
```

***

### client.Pools.GetOHLCV(ctx, networkId, poolAddress, options)

**Endpoint:** [GET `/networks/{network}/pools/{pool_address}/ohlcv`](https://docs.dexpaprika.com/api-reference/pools/get-ohlcv-data-for-a-pool-pair)

Gets OHLCV (Open, High, Low, Close, Volume) chart data for a pool.

**Parameters:**

* `ctx`\* - Context for API request
* `networkId`\* - ID of the network
* `poolAddress`\* - On-chain address of the pool
* `options` - OHLCVOptions containing:
  * `Start`\* - Start time as a string (a relative offset such as `-24h`, RFC 3339, `YYYY-MM-DD` or Unix seconds), inside your plan's [history window](https://docs.dexpaprika.com/knowledge-base/rate-limits.md#ohlcv-limits-by-plan)
  * `End` - End time (optional)
  * `Limit` - Number of data points to return
  * `Interval` - Time interval ('1h', '6h', '24h', etc.; finer intervals need a key or a paid plan)
  * `Inversed` - Whether to invert the price ratio (boolean)

**Returns:** Array of OHLCV data points for the specified time range and interval. [Response Structure](https://docs.dexpaprika.com/api-reference/pools/get-ohlcv-data-for-a-pool-pair.md).

```go theme={null}
// Hourly candles for the last 24 hours, which works without a key
options := &dexpaprika.OHLCVOptions{
    Start: "-24h",
    Limit: 24,
    Interval: "1h",
    Inversed: false,
}

ohlcv, err := client.Pools.GetOHLCV(ctx, "ethereum", "0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc", options)
```

***

### client.Pools.GetIndicator(ctx, networkId, poolAddress, options)

**Endpoint:** [GET `/networks/{network}/pools/{pool_address}/indicators`](https://docs.dexpaprika.com/api-reference/pools/get-a-technical-indicator-for-a-pool)

Computes RSI, EMA, MACD, Bollinger Bands or VWAP from a pool's candles. Requires SDK v1.12.0 or later.

**Parameters:**

* `ctx`\* - Context for API request
* `networkId`\* - ID of the network
* `poolAddress`\* - On-chain address of the pool
* `options`\* - IndicatorOptions containing:
  * `Indicator`\* - `dexpaprika.IndicatorRSI`, `IndicatorEMA`, `IndicatorMACD`, `IndicatorBBands` or `IndicatorVWAP`
  * `Interval` - Candle interval (`"1m"` to `"24h"`, or `"1d"`); pass it every time
  * `Start`, `End`, `Limit`, `Cursor` - Range and paging, same formats as OHLCV
  * `Period` - rsi, ema, bbands and vwap
  * `FastPeriod`, `SlowPeriod`, `SignalPeriod` - macd only
  * `StdDev` - bbands only

Only the fields you set are sent. A parameter that belongs to another indicator, such as `FastPeriod` with rsi, returns a 400 whose `APIError.Param` names it.

**Returns:** `*IndicatorResponse`. `Data` is oldest first, one `IndicatorDataPoint` per completed candle with `Value` for rsi, ema and vwap; `MACD`, `Signal` and `Histogram` for macd; `Upper`, `Middle` and `Lower` for bbands (all pointers). `Parameters` echoes the settings used, and `HasNextPage`/`NextCursor` page through longer ranges. [Response Structure](https://docs.dexpaprika.com/api-reference/pools/get-a-technical-indicator-for-a-pool.md).

Works on every plan, keyless included, with the same interval and history limits as pool OHLCV ([limits by plan](https://docs.dexpaprika.com/knowledge-base/rate-limits.md#ohlcv-limits-by-plan)). Tutorial: [technical indicators](https://docs.dexpaprika.com/tutorials/technical-indicators.md).

```go theme={null}
// Hourly RSI over the last 24 hours, which works without a key
rsi, err := client.Pools.GetIndicator(ctx, "ethereum", "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640", &dexpaprika.IndicatorOptions{
    Indicator: dexpaprika.IndicatorRSI,
    Interval:  "1h",
    Start:     "-24h",
})
if err != nil {
    log.Fatal(err)
}
last := rsi.Data[len(rsi.Data)-1]
fmt.Printf("RSI %.1f at %s\n", *last.Value, last.Timestamp)
```

**Tokens** `category`

**methods**

### client.Tokens.GetDetails(ctx, networkId, tokenAddress)

**Endpoint:** [GET `/networks/{network}/tokens/{token_address}`](https://docs.dexpaprika.com/api-reference/tokens/get-a-tokens-latest-data-on-a-network)

Gets comprehensive token information.

**Parameters:**

* `ctx`\* - Context for API request
* `networkId`\* - ID of the network
* `tokenAddress`\* - Token contract address

**Returns:** Token details including price, market cap, volume, and metadata. [Response Structure](https://docs.dexpaprika.com/api-reference/tokens/get-a-tokens-latest-data-on-a-network.md).

```go theme={null}
token, err := client.Tokens.GetDetails(ctx, "ethereum", "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2")
```

***

### client.Tokens.GetPools(ctx, networkId, tokenAddress, options)

**Endpoint:** [GET `/networks/{network}/pools/search?token_address=...`](https://docs.dexpaprika.com/api-reference/pools/advanced-pool-filtering-on-a-specific-network)

Gets pools containing a specific token.

**Parameters:**

* `ctx`\* - Context for API request
* `networkId`\* - ID of the network
* `tokenAddress`\* - Token contract address
* `options` - `*TokenPoolsOptions`, which embeds `*ListOptions` for `Limit`, `Sort`, `OrderBy` and `Cursor`. `Page` is not sent upstream: the endpoint is cursor-paginated, so page forward with `Cursor` taken from the previous response's `NextCursor`
* `options.AdditionalTokenAddress` - deprecated and no longer sent. `GET /networks/{network}/pools/search` accepts one `token_address` only, and repeating it makes the API use a single value rather than filtering for the pair. Filter `results[].tokens` yourself if you need a specific pair
* `options.Reorder` - deprecated and no longer sent; the search endpoint has no equivalent

> [!NOTE]
>
> The SDK normalizes legacy sort values before they go on the wire, so `OrderBy: "volume_usd"` is sent as `order_by=volume_usd_24h`. REST rejects the legacy spelling with `400`, so use the canonical value when you call the API directly.

**Returns:** List of pools where the queried token is found. [Response Structure](https://docs.dexpaprika.com/api-reference/pools/advanced-pool-filtering-on-a-specific-network.md).

```go theme={null}
options := &dexpaprika.TokenPoolsOptions{
    ListOptions: &dexpaprika.ListOptions{
        Limit:   10,
        OrderBy: "volume_usd_24h",
        Sort:    "desc",
    },
}

// Get the busiest WETH pools on Ethereum
pools, err := client.Tokens.GetPools(
    ctx,
    "ethereum",
    "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // WETH
    options,
)
```

***

### client.Tokens.GetIndicator(ctx, networkId, tokenAddress, options)

**Endpoint:** [GET `/networks/{network}/tokens/{token_address}/indicators`](https://docs.dexpaprika.com/api-reference/tokens/get-a-technical-indicator-for-a-token)

The same indicators computed from the token's USD candles across every pool it trades in. Same `IndicatorOptions` and response shape as `client.Pools.GetIndicator`, with `TokenAddress` set instead of `PoolAddress`. Requires SDK v1.12.0 or later.

Needs a Dev, Pro or Enterprise key and the `https://api-pro.dexpaprika.com` base URL; keyless and free keys get `403`, which matches `errors.Is(err, dexpaprika.ErrForbidden)`, with `APIError.RequiredTier` naming the plan.

```go theme={null}
macd, err := client.Tokens.GetIndicator(ctx, "ethereum", "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", &dexpaprika.IndicatorOptions{
    Indicator: dexpaprika.IndicatorMACD,
    Interval:  "1h",
    Start:     "-7d",
})
```

**Search** `category`

**methods**

### client.Search.Search(ctx, query)

**Endpoint:** [GET `/search`](https://docs.dexpaprika.com/api-reference/search/search-for-tokens-pools-and-dexes)

Searches across tokens, pools, and DEXes using a query string.

**Parameters:**

* `ctx`\* - Context for API request
* `query`\* - Search query string

**Returns:** Matching entities from all categories (tokens, pools, DEXes). [Response Structure](https://docs.dexpaprika.com/api-reference/search/search-for-tokens-pools-and-dexes.md).

```go theme={null}
results, err := client.Search.Search(ctx, "ethereum")
```

**Utils** `category`

**methods**

### client.Utils.GetStats(ctx)

**Endpoint:** [GET `/stats`](https://docs.dexpaprika.com/api-reference/utils/retrieve-high-level-asset-statistics)

Gets platform-wide statistics.

**Parameters:**

* `ctx`\* - Context for API request

**Returns:** Counts of chains, DEXes, pools, and tokens indexed. [Response Structure](https://docs.dexpaprika.com/api-reference/utils/retrieve-high-level-asset-statistics.md).

```go theme={null}
stats, err := client.Utils.GetStats(ctx)
```

## Complete example

**example**

```go theme={null}
package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/coinpaprika/dexpaprika-sdk-go/dexpaprika"
)

const (
    weth = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
    usdc = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
)

func main() {
    client := dexpaprika.NewClient()

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    // Networks come back as a slice of Network{ID, DisplayName}
    networks, err := client.Networks.List(ctx)
    if err != nil {
        log.Fatalf("Error fetching networks: %v", err)
    }
    for _, network := range networks {
        if network.ID == "ethereum" {
            fmt.Printf("%s is one of %d networks\n", network.DisplayName, len(networks))
        }
    }

    // Price lives under Summary
    token, err := client.Tokens.GetDetails(ctx, "ethereum", weth)
    if err != nil {
        log.Fatalf("Error fetching token details: %v", err)
    }
    fmt.Printf("%s price: $%.2f\n", token.Name, token.Summary.PriceUSD)

    // Pools for a token are served by pool search. The SDK copies the rows
    // into Pools and fills VolumeUSD from volume_usd_24h. There is no pair
    // filter, so match the second token client-side.
    pools, err := client.Tokens.GetPools(ctx, "ethereum", weth, &dexpaprika.TokenPoolsOptions{
        ListOptions: &dexpaprika.ListOptions{Limit: 20, OrderBy: "volume_usd_24h", Sort: "desc"},
    })
    if err != nil {
        log.Fatalf("Error fetching pools: %v", err)
    }

    fmt.Println("Top WETH/USDC pools:")
    shown := 0
    for _, pool := range pools.Pools {
        for _, t := range pool.Tokens {
            if t.ID == usdc && shown < 5 {
                fmt.Printf("%s: $%.2f 24h volume\n", pool.DexName, pool.VolumeUSD)
                shown++
            }
        }
    }
}
```

## Advanced features

### Error handling

**error handling**

```go theme={null}
import (
    "context"
    "errors"
    "fmt"
    "log"
    "time"

    "github.com/coinpaprika/dexpaprika-sdk-go/dexpaprika"
)

func handleAPIErrors() {
    client := dexpaprika.NewClient()
    ctx := context.Background()

    // Attempt to get a token with an invalid address
    _, err := client.Tokens.GetDetails(ctx, "ethereum", "0xinvalidaddress")
    if err != nil {
        // Check for specific error types
        var apiErr *dexpaprika.APIError
        if errors.As(err, &apiErr) {
            switch apiErr.StatusCode {
            case 404:
                fmt.Println("Token not found")
            case 429:
                fmt.Println("Rate limit exceeded, retry after a delay")
            case 500:
                fmt.Println("Server error, retry may succeed")
            default:
                fmt.Printf("API error: %s\n", apiErr.Message)
            }
        } else {
            // Handle non-API errors (like network issues)
            fmt.Printf("Non-API error: %v\n", err)
        }

        // Check if error is retryable
        if dexpaprika.IsRetryable(err) {
            fmt.Println("This error is retryable")
        }
    }
}
```

### Caching

**caching**

```go theme={null}
import (
    "context"
    "fmt"
    "time"

    "github.com/coinpaprika/dexpaprika-sdk-go/dexpaprika"
)

func useCaching() {
    // Create a regular client
    client := dexpaprika.NewClient()

    // Create a cached client with 5-minute TTL
    cachedClient := dexpaprika.NewCachedClient(client, nil, 5*time.Minute)

    // Create context
    ctx := context.Background()

    // First call - hits the API
    startTime := time.Now()
    networks, err := cachedClient.GetNetworks(ctx)
    if err != nil {
        fmt.Printf("Error: %v\n", err)
        return
    }
    fmt.Printf("First call (API): %d networks, took %v\n", len(networks), time.Since(startTime))

    // Second call - served from cache (much faster)
    startTime = time.Now()
    networks, err = cachedClient.GetNetworks(ctx)
    if err != nil {
        fmt.Printf("Error: %v\n", err)
        return
    }
    fmt.Printf("Second call (cached): %d networks, took %v\n", len(networks), time.Since(startTime))
}
```

### Pagination helpers

**pagination**

```go theme={null}
import (
    "context"
    "fmt"
    "time"

    "github.com/coinpaprika/dexpaprika-sdk-go/dexpaprika"
)

func usePagination() {
    client := dexpaprika.NewClient()
    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()

    // Create a paginator for Ethereum pools with 50 items per page
    options := &dexpaprika.ListOptions{
        Limit:   50,
        OrderBy: "volume_usd_24h",
        Sort:    "desc",
    }
    paginator := dexpaprika.NewPoolsPaginator(client, options).ForNetwork("ethereum")

    // Count total pools processed
    totalPools := 0

    // Process first 3 pages (or fewer if there aren't that many)
    for i := 0; i < 3 && paginator.HasNextPage(); i++ {
        // Get next page of results
        if err := paginator.GetNextPage(ctx); err != nil {
            fmt.Printf("Error getting page: %v\n", err)
            break
        }

        // Process current page
        pools := paginator.GetCurrentPage()
        totalPools += len(pools)

        // Process first few pools in each page
        fmt.Printf("=== Page %d ===\n", i+1)
        for j, pool := range pools {
            if j >= 3 {
                fmt.Printf("...and %d more pools\n", len(pools)-3)
                break
            }
            var vol float64
            if pool.VolumeUSD24h != nil {
                vol = *pool.VolumeUSD24h
            }
            fmt.Printf("%s: $%.2f 24h volume\n", pool.DexName, vol)
        }
    }

    fmt.Printf("Processed %d pools total\n", totalPools)
}
```

### Custom configuration

**configuration**

```go theme={null}
import (
    "net/http"
    "time"

    "github.com/coinpaprika/dexpaprika-sdk-go/dexpaprika"
)

func configureClient() *dexpaprika.Client {
    // Create a client with custom configuration
    client := dexpaprika.NewClient(
        // Custom HTTP client with longer timeout
        dexpaprika.WithHTTPClient(&http.Client{
            Timeout: 60 * time.Second,
        }),
        
        // Custom retry configuration (5 retries with backoff)
        dexpaprika.WithRetryConfig(5, 2*time.Second, 30*time.Second),
        
        // Rate limiting to 3 requests per second
        dexpaprika.WithRateLimit(3.0),
        
        // Custom user agent
        dexpaprika.WithUserAgent("MyApp/1.0 DexPaprikaClient"),
    )

    return client
}
```

## Resources

* [GitHub Repository](https://github.com/coinpaprika/dexpaprika-sdk-go)
* [DexPaprika Website](https://dexpaprika.com)
* [API Reference](https://docs.dexpaprika.com/api-reference/introduction.md)

## API status

The DexPaprika API provides consistent data with stable endpoints. Requests are answered without an API key on the free tier, and a free key raises the credit allowance. We aim to maintain backward compatibility and provide notice of any significant changes.

### FAQs

> **Do I need an API key with this SDK?**
>
> Not to start. Keyless requests work at 10,000 credits per rolling 30 days per IP, and a [free registered key](https://console.dexpaprika.com/dashboard) raises that to 100,000 with no card.

> **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?**
>
> Use pools/transactions endpoints with `pool_address`, `network`, and time/paging params as documented. Transactions need a Dev, Pro or Enterprise key on `api-pro.dexpaprika.com`.

> **What about rate limiting?**
>
> 15 requests a minute keyless, 30 with a [free key](https://console.dexpaprika.com) and 500 on Pro, against 10,000 credits keyless and 100,000 with a free key over a rolling 30 days, or 5,000,000 a month on Pro. Retry transient HTTP errors with backoff. See [rate limits](https://docs.dexpaprika.com/knowledge-base/rate-limits.md) for how the counters work, and [Pro pricing](https://dexpaprika.com/api/pricing) for what the 5,000,000 credit tier costs.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.