Scripting to the CoinMarketCap API

  • More Supported Coins – Coinbase Pro only provided quotes for the coins tradable on Coinbase, which is vast, but still limited. CoinMarketCap supports many more.
  • More efficient API – Perhaps this doesn’t matter too much since I am using Airtable resources at no additional cost to me, but I still liked the idea of being able to make 1 fetch() call for all coins rather than 1 per coin. Should fetch() limits from Airtable come some day or API rate limits hit with more coins being used, I was able to simplify everything with 1 fetch() for all coins.
  • More Information – CoinMarketCap provides a lot more information in a quote. I am using the Quotes Latest call and you can see all the info provided in their docs.

Available Data

The Quotes Latest call provides a lot of good data. This is from their docs and provides a good overview of what’s available.

Base Setup

We will use the same Base table from the previous post, but with a few additions.

  • Price % Change (24h) is a percent field with 2 decimal point precision that allows negative numbers.
  • Price % Change (7d) is a percent field with 2 decimal point precision that allows negative numbers.
  • Rank is an integer field. This will hold CoinMarketCap’s rank for the coin/token.
  • The Market field does not matter for this integration. I used it for the Coinbase Pro example. If you prefer CoinMarketCap, you don’t really need it.

Here’s a look at the Coins table.

API Key

To use the CoinMarketCap API, you need to get an API key. There is a free plan and the free plan includes calls to the Quotes Latest method, so there is no cost to getting an API key. Getting the key also gives you access to a nice API dashboard to track your usage and errors.

Code

I have this setup in an Automation scheduled once per day that runs a script. In my previous post, I went into more detail on setting up and debugging the automation. If you are not familiar with setting up an Automation, check out that post.

The code is below. You should be able to just plop this right into your automation. Look for the text that says “YOUR_KEY_HERE”. Replace that text with your API key. I have examples of pulling data from the first level (rank) as well as information from the quote (price, % change)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
let cmcTickerArray = []; // array of ticker symbols for quotes from CoinMarketCap
let recordIdArray = []; // array of record IDs
let updateArray = []; // final array to update Airtable records
let table = base.getTable( "Coins" );
let query = await table.selectRecordsAsync({
     sorts: [ {field: "Latest Price (As Of)" , direction: "asc" } ],
     fields: [ "Ticker" , "Name" , "Latest Price (As Of)" , "Latest Price" , "Price % Change (24h)" , "Price % Change (7d)" , "Rank" ]
});
 
// Loop through records
for ( let record of query.records) {
     cmcTickerArray.push(record.getCellValueAsString( "Ticker" ));
     recordIdArray.push(record.id);
}
 
if (cmcTickerArray.length > 0){
 
     // Make 1 call for all tickers
     let response = await fetch( 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol=' + cmcTickerArray.join() + '&skip_invalid=true' ,{
         headers: {
             "X-CMC_PRO_API_KEY" : "YOUR_KEY_HERE"
         }
     });
     console.log(response);
 
     if (response.status === 200) {
         let data = await response.json();
         console.log(data);
         for ( let i = 0; i < cmcTickerArray.length; i++) {
             let coinData = data.data[cmcTickerArray[i]]; // data for this specific coin
             if (coinData && coinData.quote && coinData.quote.USD){
                 if (coinData.quote.USD.price && isNaN(Number(coinData.quote.USD.price)) == false ){
                     let updateObject = {};
                     updateObject[ "id" ] = recordIdArray[i];
                     updateObject[ "fields" ] = {};
                     updateObject[ "fields" ][ "Latest Price" ] = Number(coinData.quote.USD.price);
                     if (coinData.quote.USD.percent_change_24h && isNaN(Number(coinData.quote.USD.percent_change_24h)) == false ){
                         updateObject[ "fields" ][ "Price % Change (24h)" ] = Number(coinData.quote.USD.percent_change_24h) / 100;
                     }
                     if (coinData.quote.USD.percent_change_7d && isNaN(Number(coinData.quote.USD.percent_change_7d)) == false ){
                         updateObject[ "fields" ][ "Price % Change (7d)" ] = Number(coinData.quote.USD.percent_change_7d) / 100;
                     }
                     if (coinData.cmc_rank && isNaN(Number(coinData.cmc_rank)) == false ){
                         updateObject[ "fields" ][ "Rank" ] = Number(coinData.cmc_rank);
                     }
                     updateObject[ "fields" ][ "Latest Price (As Of)" ] = new Date();
                     updateArray.push(updateObject);
                 }
             }
         }
     }
     
}
 
if (updateArray.length > 0){
     await table.updateRecordsAsync(updateArray);
}

Results

The code has now run and has populated the Price, % change over 24 hours, % change over 7 days, the rank, and a timestamp for when it received the data.

For my personal use, I have moved over to this API and run it every 3 hours.

Scott Hemmeter

Comments

Related posts

Search Quick Method to Setup Single Select & Multi Select Field Value Lists
Airtable: Creating a CRM (Part 5) – Task Management Search