Skip to main content

CoinGecko API

CoinGecko provides token metadata and pricing across all major chains. The CoinGeckoApiService wraps CoinGecko's REST API with built-in caching and rate-limit management, so you can query asset platforms, token lists, and prices from C# without managing HTTP calls or worrying about throttling.

The Token Portfolio guide uses CoinGecko pricing through the higher-level Erc20TokenService. This guide covers the lower-level CoinGeckoApiService directly — use it when you need raw platform metadata, token lists, or prices outside the balance pipeline.

When you need this guide:

  • Mapping chain IDs to CoinGecko platform identifiers
  • Fetching token lists with names, symbols, logos, and addresses for a chain
  • Getting token prices by contract address or CoinGecko ID
  • Building price feeds or portfolio views with direct API control
  • Configuring cache behavior for your application's needs

Prerequisites

Install the package:

dotnet add package Nethereum.DataServices

CoinGecko's free API is keyless but has strict rate limits (10-30 calls/minute). The built-in cache helps stay within limits.

Creating the Service

using Nethereum.DataServices.CoinGecko;

var coingecko = new CoinGeckoApiService();

Asset Platforms: Mapping Chain IDs

CoinGecko identifies blockchains by platform IDs (e.g., "ethereum", "polygon-pos") rather than numeric chain IDs. The first step is mapping between them.

GetPlatformIdForChainAsync translates a numeric chain ID to CoinGecko's platform string:

string platformId = await coingecko.GetPlatformIdForChainAsync(chainId: 137);
Console.WriteLine(platformId); // "polygon-pos"

If you need the full list of platforms CoinGecko supports:

var platforms = await coingecko.GetAssetPlatformsAsync();

foreach (var p in platforms.Where(x => x.ChainIdentifier.HasValue).Take(10))
Console.WriteLine($" Chain {p.ChainIdentifier}: {p.Id} ({p.Name})");

This is useful for building a mapping table once at startup and caching it.

Token Lists

Once you have a platform ID (or a chain ID), you can fetch the complete token list for that chain. Each token entry includes address, symbol, name, decimals, and a logo URL:

var tokenList = await coingecko.GetTokenListForChainAsync(chainId: 1);
Console.WriteLine($"Ethereum tokens: {tokenList.Tokens.Count}");

foreach (var token in tokenList.Tokens.Take(5))
Console.WriteLine($" {token.Symbol}: {token.Name} ({token.Address})");

You can also fetch by platform ID directly if you already have it:

var polygonTokens = await coingecko.GetTokenListForPlatformAsync("polygon-pos");

Or get the list of tokens as a flat collection:

var tokens = await coingecko.GetTokensForChainAsync(chainId: 1);

Full Coins List

For cross-chain lookups, GetCoinsListAsync returns every coin CoinGecko tracks, along with the platforms (chains) each coin is deployed on:

var coins = await coingecko.GetCoinsListAsync();
Console.WriteLine($"Total coins tracked: {coins.Count}");

Each coin object has a Platforms dictionary mapping platform IDs to contract addresses, which is how FindCoinGeckoIdAsync works internally.

Token Prices

Price by CoinGecko ID

If you know the CoinGecko ID for a token (e.g., "ethereum", "usd-coin"), fetch prices directly:

var prices = await coingecko.GetPricesAsync(
new[] { "ethereum", "usd-coin", "matic-network" },
vsCurrency: "usd");

Console.WriteLine($"ETH: ${prices["ethereum"]["usd"]}");
Console.WriteLine($"USDC: ${prices["usd-coin"]["usd"]}");
Console.WriteLine($"MATIC: ${prices["matic-network"]["usd"]}");

The method batches requests automatically (250 IDs per batch) and respects the configured rate-limit delay between batches.

Price by Contract Address

More commonly, you have a contract address and want the price without knowing the CoinGecko ID. Use GetTokenPriceByContractAsync with the platform ID and contract address:

decimal? usdcPrice = await coingecko.GetTokenPriceByContractAsync(
"ethereum",
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"usd");

if (usdcPrice.HasValue)
Console.WriteLine($"USDC: ${usdcPrice.Value}");
else
Console.WriteLine("Price not available");

The method returns null if the token is not found or CoinGecko does not have pricing data for it.

Mapping Contract Addresses to CoinGecko IDs

Sometimes you need the CoinGecko ID itself (e.g., to build a detail page URL). FindCoinGeckoIdAsync searches the coins list:

string geckoId = await coingecko.FindCoinGeckoIdAsync(
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", chainId: 1);
Console.WriteLine(geckoId); // "usd-coin"

For batch lookups, use FindCoinGeckoIdsAsync to resolve multiple addresses in one pass:

var ids = await coingecko.FindCoinGeckoIdsAsync(
new[] {
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
"0xdAC17F958D2ee523a2206206994597C13D831ec7", // USDT
"0x6B175474E89094C44Da98b954EedeAC495271d0F" // DAI
},
chainId: 1);

foreach (var kvp in ids)
Console.WriteLine($" {kvp.Key} => {kvp.Value}");

Cache Configuration

CoinGecko's free API has aggressive rate limits. The service caches responses by default to avoid hitting them. You can tune the cache durations:

var config = new CoinGeckoCacheConfiguration
{
Enabled = true,
PlatformsCacheDuration = TimeSpan.FromHours(24),
CoinsListCacheDuration = TimeSpan.FromHours(1),
TokenListCacheDuration = TimeSpan.FromHours(1),
RateLimitDelay = TimeSpan.FromMilliseconds(1500)
};

var coingecko = new CoinGeckoApiService(config);
CacheDefault DurationWhy
Asset platforms24 hoursNew chains are added rarely
Coins list1 hourNew tokens appear frequently
Token lists1 hourToken metadata can change
Rate limit delay1.5 secondsBetween batched API calls

To disable caching entirely (useful in tests):

var testService = new CoinGeckoApiService(CoinGeckoCacheConfiguration.Disabled);

To force a refresh of a specific cache, pass forceRefresh: true to any method that supports it:

var freshPlatforms = await coingecko.GetAssetPlatformsAsync(forceRefresh: true);

To clear all cached data:

coingecko.ClearCache();

Relationship to TokenServices

Nethereum.TokenServices wraps CoinGeckoApiService inside CoinGeckoPriceProvider for the portfolio pipeline. Use CoinGeckoApiService directly when you need:

  • Raw platform metadata or token lists for display
  • Prices without the full balance pipeline
  • Fine-grained cache control
  • CoinGecko ID lookups for building URLs or cross-referencing data

Use Erc20TokenService (via Token Portfolio guide) when you need balances + prices together, as it handles the full pipeline including multicall batching, discovery, and price resolution.

Common Gotchas

Rate limits are strict. The free tier allows roughly 10-30 calls per minute. The built-in cache and rate-limit delay help, but if you make many different queries in quick succession, you will get HTTP 429 errors. Increase RateLimitDelay if needed.

Platform IDs are not chain IDs. Ethereum mainnet is "ethereum", not "1". Polygon is "polygon-pos", not "137". Always use GetPlatformIdForChainAsync to translate.

Not all tokens have prices. CoinGecko tracks major tokens, but obscure or newly launched tokens may not be listed. GetTokenPriceByContractAsync returns null for untracked tokens.

The coins list is large. GetCoinsListAsync returns tens of thousands of entries. Cache the result and avoid calling it repeatedly. The built-in cache handles this with a 1-hour default expiry.

Address casing matters for lookups. Contract addresses passed to FindCoinGeckoIdAsync are matched case-insensitively internally, but the CoinGecko API itself may require lowercase. The service normalizes addresses for you.

Batch pricing has implicit limits. GetPricesAsync batches at 250 IDs per request. For very large token sets, multiple API calls are made with rate-limit delays between them.

Next Steps