Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save eder-projetos-dev/4b7133449a1b0be712019ba79eae8095 to your computer and use it in GitHub Desktop.
Save eder-projetos-dev/4b7133449a1b0be712019ba79eae8095 to your computer and use it in GitHub Desktop.
Python - Using Coinmarketcap API

Using Coinmarketcap API with Python

This is a Gist for anyone looking to learn everything about retrieving cryptocurrency data from Coinmarketcap.com. A handful of information is provided here - Getting started, how to get the API key, what problems I faced, the API limitations and many others...



What is Coinmarketcap?

CoinMarketCap is the world's most-referenced price-tracking website for cryptoassets in the rapidly growing cryptocurrency space. Its mission is to make crypto discoverable and efficient globally by empowering retail users with unbiased, high quality and accurate information for drawing their own informed conclusions.

The CoinMarketCap API is a suite of high-performance RESTful JSON endpoints that are specifically designed to meet the mission-critical demands of application developers, data scientists, and enterprise business platforms.

Source: Google and Coinmarketcap

Getting Started

Note: CMC API can be used with various other languages as well, check the official CMC documentation for more info

This section of the guide will tell you how you can use the API yourself to retrieve data.

Sign up for a free developer account

Before getting an API, you need to make an account on Coinmarketcap.


Getting the API key

In your profile dashboard, you will find a panel at the top-left to copy your API key. Make sure to keep this API key safe and secure.


Receiving the data

Retrieving the data using the API is actually quite simple; your first job is to copy the following code into your favorite text editor -

from requests import Request, Session
import json
import time
import webbrowser
import pprint

def getInfo (): # Function to get the info

    url = 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest' # Coinmarketcap API url

    parameters = { 'slug': 'bitcoin', 'convert': 'USD' } # API parameters to pass in for retrieving specific cryptocurrency data

    headers = {
        'Accepts': 'application/json',
        'X-CMC_PRO_API_KEY': 'YOUR_API_KEY'
    } # Replace 'YOUR_API_KEY' with the API key you have recieved in the previous step

    session = Session()
    session.headers.update(headers)

    response = session.get(url, params=parameters)

    info = json.loads(response.text)

    pprint.pprint(info)
        
getInfo() # Calling the function to get the statistics

On running the code, you shall get the following message in your terminal:

{'data': {'1': {'circulating_supply': 18738693,
               'cmc_rank': 1,
               'date_added': '2013-04-28T00:00:00.000Z',
               'id': 1,
               'is_active': 1,
               'is_fiat': 0,
               'last_updated': '2021-06-19T17:54:02.000Z',
               'max_supply': 21000000,
               'name': 'Bitcoin',
               'num_market_pairs': 9098,
               'platform': None,
               'quote': {'USD': {'last_updated': '2021-06-19T17:54:02.000Z',
                                 'market_cap': 671015752371.1693,
                                 'percent_change_1h': -0.50165606,
                                 'percent_change_24h': -1.43407449,
                                 'percent_change_30d': -10.47602652,
                                 'percent_change_60d': -35.96305551,
                                 'percent_change_7d': 0.22327229,
                                 'percent_change_90d': -37.57395358,
                                 'price': 35809.101113464494,
                                 'volume_24h': 33429254119.029865}},
               'slug': 'bitcoin',
               'symbol': 'BTC',
               'tags': ['mineable',
                        'pow',
                        'sha-256',
                        'store-of-value',
                        'state-channels',
                        'coinbase-ventures-portfolio',
                        'three-arrows-capital-portfolio',
                        'polychain-capital-portfolio',
                        'binance-labs-portfolio',
                        'arrington-xrp-capital',
                        'blockchain-capital-portfolio',
                        'boostvc-portfolio',
                        'cms-holdings-portfolio',
                        'dcg-portfolio',
                        'dragonfly-capital-portfolio',
                        'electric-capital-portfolio',
                        'fabric-ventures-portfolio',
                        'framework-ventures',
                        'galaxy-digital-portfolio',
                        'huobi-capital',
                        'alameda-research-portfolio',
                        'a16z-portfolio',
                        '1confirmation-portfolio',
                        'winklevoss-capital',
                        'usv-portfolio',
                        'placeholder-ventures-portfolio',
                        'pantera-capital-portfolio',
                        'multicoin-capital-portfolio',
                        'paradigm-xzy-screener'],
               'total_supply': 18738693}},
'status': {'credit_count': 1,
           'elapsed': 25,
           'error_code': 0,
           'error_message': None,
           'notice': None,>
           'timestamp': '2021-06-19T17:54:42.974Z'}}

Working with the data

The data you receive can be be narrowed down to be more specific, ie - giving you the price, market cap, etc.

Narrowing down the data is simple, we just need to add the parent elements before each data type. If we want to get the price of bitcoin, we need to change the following line

info = json.loads(response.text)

to this

info = json.loads(response.text)['data']['1']['quote']['USD']['price'] # Output : 35809.101113464494

parent-element-referencing

Referencing parent elements to get to specific information

Another example is if we want to know the symbol of Bitcoin -

info = json.loads(response.text)['data']['1']['symbol'] # Output : BTC

parent-element-referencing

Referencing parent elements to get to specific information

Changing the currency

If we want to change the currency data we get, we would edit the code to -

parameters = { 'slug': 'bitcoin', 'convert': 'USD' }

For example - If we want to get the price of Ethereum in Indian Rupee, we change the code to -
parameters = { 'slug': 'ethereum', 'convert': 'INR' }
Note: Name of cryptocurrency has to be in lowercase while currency has to be in locale uppercase

In addition to modifying the parameters variable, we will also need to update the info variable. The change that we need to do in the latter is to change the ID at which is the second parent element. Everytime you change the currency, you will need to put in the correct ID. We can get the ID of any cryptocurrency with the following steps -

  • Change the slug value in the parameters to the cryptocurrency name you want (in lowercase).
parameters = { 'slug': 'dogecoin', 'convert': 'USD' }

  • Change the info variable to
info = json.loads(response.text)['data']

  • Running the code should give an output as so -
{'74': {'circulating_supply': 130091121654.25931,
      'cmc_rank': 6,
      'date_added': '2013-12-15T00:00:00.000Z',
        ...
        ...

  • Copy the parent element at the beginning ('74' in our case) and use it for getting data. For example - we can now use the ID to view the market cap of Dogecoin -
info = json.loads(response.text)['data']['74']['quote']['USD']['market_cap'] # Output : 37912429592.9439
# Make sure to change USD to the currency mentioned in the parameters variable (If changed)

Using the data

We have successfully received cryptocurrency data from Coinmarketcap. You can now use it anywhere in your codes since you now know how to -

  • Get the API key
  • Receive the data
  • Work with the data
  • Change currencies based on your requirements


Endpoint Overview

This section covers the endpoints, i.e. - the types of data that is returned. They can be changed on our url variable, which as default is /cryptocurrency/

The CoinMarketCap API is divided into 8 top-level categories

Endpoint Category Description
/cryptocurrency/* Endpoints that return data around cryptocurrencies such as ordered cryptocurrency lists or price and volume data.
/exchange/* Endpoints that return data around cryptocurrency exchanges such as ordered exchange lists and market pair data.
/global-metrics/* Endpoints that return aggregate market data such as global market cap and Bitcoin dominance.
/tools/* Useful utilities such as cryptocurrency and fiat price conversions.
/blockchain/* Endpoints that return block explorer related data for blockchains.
/flats/* Endpoints that return data around fiats currencies including mapping to CMC IDs.
/partners/* Endpoints for convenient access to 3rd party crypto data.
/key/* API key administration endpoints to review and manage your usage.

Endpoint paths follow a pattern matching the type of data provided

Endpoint Path Endpoint Type Description
*/latest Latest Market Data Latest market ticker quotes and averages for cryptocurrencies and exchanges.
*/historical Historical Market Data Intervals of historic market data like OHLCV data or data for use in charting libraries.
*/info Metadata Cryptocurrency and exchange metadata like block explorer URLs and logos.
*/map ID Maps Utility endpoints to get a map of resources to CoinMarketCap IDs.

Cryptocurrency and exchange endpoints provide 2 different ways of accessing data depending on the purpose

  • Listing endpoints: Flexible paginated */listings/* endpoints allow you to sort and filter lists of data like cryptocurrencies by market cap or exchanges by volume.

  • Item endpoints: Convenient ID-based resource endpoints like */quotes/* and */market-pairs/* allow you to bundle several IDs; for example, this allows you to get latest market quotes for a specific set of cryptocurrencies in one call.


Errors and Rate Limits

API Request Throttling

Use of the CoinMarketCap API is subject to API call rate limiting or "request throttling". This is the number of HTTP calls that can be made simultaneously or within the same minute with your API Key before receiving an HTTP 429 "Too Many Requests" throttling error. This limit scales with the usage tier and resets every 60 seconds. Please review their Best Practices for implementation strategies that work well with rate limiting.

HTTP Status Codes

The API uses standard HTTP status codes to indicate the success or failure of an API call.

  • 400 (Bad Request) The server could not process the request, likely due to an invalid argument.
  • 401 (Unauthorized) Your request lacks valid authentication credentials, likely an issue with your API Key.
  • 402 (Payment Required) Your API request was rejected due to it being a paid subscription plan with an overdue balance. Pay the balance in the Developer Portal billing tab and it will be enabled.
  • 403 (Forbidden) Your request was rejected due to a permission issue, likely a restriction on the API Key's associated service plan. Here is a convenient map of service plans to endpoints.
  • 429 (Too Many Requests) The API Key's rate limit was exceeded; consider slowing down your API Request frequency if this is an HTTP request throttling error. Consider upgrading your service plan if you have reached your monthly API call credit limit for the day/month.
  • 500 (Internal Server Error) An unexpected server issue was encountered.

Error Response Codes

A Status object is always included in the JSON response payload for both successful calls and failures when possible. During error scenarios you may reference the error_code and error_message properties of the Status object. One of the API error codes below will be returned if applicable otherwise the HTTP status code for the general error type is returned.

HTTP Status Error Code Error Message
401 1001 [API_KEY_INVALID] This API Key is invalid.
401 1002 [API_KEY_MISSING] API key missing.
402 1003 [API_KEY_PLAN_REQUIRES_PAYEMENT] Your API Key must be activated. Please go to pro.coinmarketcap.com/account/plan.
402 1004 [API_KEY_PLAN_PAYMENT_EXPIRED] Your API Key's subscription plan has expired.
403 1005 [API_KEY_REQUIRED] An API Key is required for this call.
403 1006 [API_KEY_PLAN_NOT_AUTHORIZED] Your API Key subscription plan doesn't support this endpoint.
403 1007 [API_KEY_DISABLED] This API Key has been disabled. Please contact support.
429 1008 [API_KEY_PLAN_MINUTE_RATE_LIMIT_REACHED] You've exceeded your API Key's HTTP request rate limit. Rate limits reset every minute.
429 1009 [API_KEY_PLAN_DAILY_RATE_LIMIT_REACHED] You've exceeded your API Key's daily rate limit.
429 1010 [API_KEY_PLAN_MONTHLY_RATE_LIMIT_REACHED] You've exceeded your API Key's monthly rate limit.
429 1011 [IP_RATE_LIMIT_REACHED] You've hit an IP rate limit.

Best Practices

This section contains a few recommendations on how to efficiently utilize the CoinMarketCap API for your application, particularly if you already have a large base of users for your application.

Use CoinMarketCap ID Instead of Cryptocurrency Symbol

Utilizing common cryptocurrency symbols to reference cryptocurrencies on the API is easy and convenient but brittle. You should know that many cryptocurrencies have the same symbol, for example, there are currently three cryptocurrencies that commonly refer to themselves by the symbol HOT. Cryptocurrency symbols also often change with cryptocurrency rebrands. When fetching cryptocurrency by a symbol that matches several active cryptocurrencies we return the one with the highest market cap at the time of the query. To ensure you always target the cryptocurrency you expect, use our permanent CoinMarketCap IDs. These IDs are used reliably by numerous mission critical platforms and never change.

We make fetching a map of all active cryptocurrencies' CoinMarketCap IDs very easy. Just call our /cryptocurrency/map endpoint to receive a list of all active currencies mapped to the unique id property. This map also includes other typical identifiying properties like name, symbol and platform token_address that can be cross referenced. In cryptocurrency calls you would then send, for example id=1027, instead of symbol=ETH. It's strongly recommended that any production code utilize these IDs for cryptocurrencies, exchanges, and markets to future-proof your code.

Use the Right Endpoints for the Job

You may have noticed that /cryptocurrency/listings/latest and /cryptocurrency/quotes/latest return the same crypto data but in different formats. This is because the former is for requesting paginated and ordered lists of all cryptocurrencies while the latter is for selectively requesting only the specific cryptocurrencies you require. Many endpoints follow this pattern, allow the design of these endpoints to work for you!

Implement a Caching Strategy If Needed

There are standard legal data safeguards built into the Commercial User Terms that application developers should keep in mind. These Terms help prevent unauthorized scraping and redistributing of CMC data but are intentionally worded to allow legitimate local caching of market data to support the operation of your application. If your application has a significant user base and you are concerned with staying within the call credit and API throttling limits of your subscription plan consider implementing a data caching strategy.

For example instead of making a /cryptocurrency/quotes/latest call every time one of your application's users needs to fetch market rates for specific cryptocurrencies, you could pre-fetch and cache the latest market data for every cryptocurrency in your application's local database every 60 seconds. This would only require 1 API call, /cryptocurrency/listings/latest?limit=5000, every 60 seconds. Then, anytime one of your application's users need to load a custom list of cryptocurrencies you could simply pull this latest market data from your local cache without the overhead of additional calls. This kind of optimization is practical for customers with large, demanding user bases.

Code Defensively to Ensure a Robust REST API Integration

Whenever implementing any high availability REST API service for mission critical operations it's recommended to code defensively. Since the API is versioned, any breaking request or response format change would only be introduced through new versions of each endpoint, however existing endpoints may still introduce new convenience properties over time.

We suggest these best practices:

  • You should parse the API response JSON as JSON and not through a regular expression or other means to avoid brittle parsing logic.

  • Your parsing code should explicitly parse only the response properties you require to guarantee new fields that may be returned in the future are ignored.

  • You should add robust field validation to your response parsing logic. You can wrap complex field parsing, like dates, in try/catch statements to minimize the impact of unexpected parsing issues (like the unlikely return of a null value).

  • Implement a "Retry with exponential backoff" coding pattern for your REST API call logic. This means if your HTTP request happens to get rate limited (HTTP 429) or encounters an unexpected server-side condition (HTTP 5xx) your code would automatically recover and try again using an intelligent recovery scheme. You may use one of the many libraries available; for example, this one for Node or this one for Python.



Ending Note

Dear reader, I just want you to know this Gist was really fun to write. My main goal was to complete this to help others but ended up helping myself too due to the extra information I gained. The output comments used in the Python code are going to be outdated when you read this, and neither of us two can help it. Google has been my best friend and always will be. It was also really fun discovering and gaining knowledge from the Coinmarketcap API documentation, make sure to check it out, this Gist barely scratched the surface.

Regards,
SrNightmare09


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment