How to get trending NFT collections

Identifying, surfacing, and tracking trending NFT collections across an entire blockchain (or multiple chains) can be a daunting task. First, you'd need to build an indexer, then you'd need to aggregate massive volumes of on-chain data to identify both newly minted and existing collections, then you'd need to ingest and make sense of real-time and historical trades across the blockchain. Once you'd done that, you'd need to tackle the complexities of blockchain transaction taxonomy to properly calculate price attribution per each NFT sale. From there, you could begin determining which NFT collections are trending based on trading volume and/or historical prices and use this data within your product or experience.

Or, you could use Mnemonic's API to bypass all of those steps and surface trending collections with just a few simple lines of code.

Mnemonic ingests historical and real-time data on NFT transfers and sales across the blockchain (across all marketplaces and protocols from genesis block) and uses state of the art algorithms to aggregate billions of transactions and compute pricing attribution per each NFT sale, making it possible to discover trending NFT collections with a single API call and sub-second latency.

The data is updated every 15 minutes, which means every 15 minutes you get the most up to date time-series data for every collection across the entire blockchain.

Note: Mnemonic is committed to producing the most accurate representation of sales activity and prices. This is why we track all sales across the entire blockchain, not just a particular marketplace. We also compute price attribution based on various ERC20 token payments and internal transactions. As a result, you may see larger volume numbers and slightly different prices for a collection than what you see on OpenSea, for example.

Below we'll explore various ways you can find trending collections based on different time periods and properties.

Get trending collections by trading volume

To get collections that are trending based on their trading volumes over a given period of time (down to one hour and up to a year) we will use Top collections by trading volume endpoint.

Use the duration parameter to control the the time period for which you want to obtain the data.

curlpythongo
Copy
Copied
curl -i -X GET \
https://ethereum.rest.mnemonichq.com/collections/v1beta1/top/by_sales_volume?limit=10&offset=0&duration=DURATION_7_DAYS
-H 'X-API-Key: YOUR_API_KEY_HERE'
Copy
Copied
import requests # requires `pip install requests`

result = requests.get(
    'https://ethereum.rest.mnemonichq.com/collections/v1beta1/top/by_sales_volume?limit=10&offset=0&duration=DURATION_7_DAYS',
    headers={'x-api-key': 'YOUR_API_KEY_HERE'}
).json()
Copy
Copied
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {
  reqUrl := "https://ethereum.rest.mnemonichq.com/collections/v1beta1/top/by_sales_volume"
  req, _ := http.NewRequest("GET", reqUrl, nil)

  query := req.URL.Query()
  query.Add("limit", "10")
  query.Add("offset", "0")
  query.Add("duration", "DURATION_7_DAYS")
  req.URL.RawQuery = query.Encode()

  req.Header.Add("X-API-Key", "YOUR_API_KEY_HERE")
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}

The result should look something like this:

Copy
Copied
{
    "collections": [
        {
            "contractAddress": "0x1dfe7ca09e99d10835bf73044a23b73fc20623df",
            "salesVolume": "63848.139",
            "contractName": "More Loot"
        },
        {
            "contractAddress": "0x7bd29408f11d2bfc23c34f18275bbf23bb716bc7",
            "salesVolume": "31585.0626108723816516908834733",
            "contractName": "Meebits"
        },
        {
            "contractAddress": "0x81ae0be3a8044772d04f32398bac1e1b4b215aa8",
            "salesVolume": "23501.173970129205544585",
            "contractName": "Dreadfulz"
        },
        {
            "contractAddress": "0x4e1f41613c9084fdb9e34e11fae9412427480e56",
            "salesVolume": "17595.682447743215225221262",
            "contractName": "Terraforms"
        },
        {
            "contractAddress": "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d",
            "salesVolume": "12385.780385742554366993",
            "contractName": "BoredApeYachtClub"
        },
        {
            "contractAddress": "0xa5d37c0364b9e6d96ee37e03964e7ad2b33a93f4",
            "salesVolume": "10369.48074220104508421572056951598095",
            "contractName": "CATGIRL ACADEMIA"
        },
        {
            "contractAddress": "0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb",
            "salesVolume": "8389.2253890386715242",
            "contractName": "CRYPTOPUNKS"
        },
        {
            "contractAddress": "0xe21ebcd28d37a67757b9bc7b290f4c4928a430b1",
            "salesVolume": "6612.0747436382485710937388202",
            "contractName": ""
        },
        {
            "contractAddress": "0x60e4d786628fea6478f785a6d7e704777c86a7c6",
            "salesVolume": "5740.40219485438910476311199964186864",
            "contractName": "MutantApeYachtClub"
        },
        {
            "contractAddress": "0x34d85c9cdeb23fa97cb08333b511ac86e1c4e258",
            "salesVolume": "5530.8290236948666284541504700985274",
            "contractName": "Otherdeed"
        }
    ]
}

TIP: Use offset and limit parameters to control pagination.

Get trending collections by sales count

Another way to find trending collections could be by looking at sales counts. A rapidly increasing sales count could be an indicator for an up and coming or trending collection.

To do this, we will use the Top collections by sales count endpoint.

You can use the duration parameter to control the the time period for which you want to obtain the data.

curlpythongo
Copy
Copied
curl -i -X GET \
https://ethereum.rest.mnemonichq.com/collections/v1beta1/top/by_sales_count?limit=10&offset=0&duration=DURATION_7_DAYS
-H 'X-API-Key: YOUR_API_KEY_HERE'
Copy
Copied
import requests # requires `pip install requests`

result = requests.get(
    'https://ethereum.rest.mnemonichq.com/collections/v1beta1/top/by_sales_count?limit=10&offset=0&duration=DURATION_7_DAYS',
    headers={'x-api-key': 'YOUR_API_KEY_HERE'}
).json()
Copy
Copied
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {
  reqUrl := "https://ethereum.rest.mnemonichq.com/collections/v1beta1/top/by_sales_count"
  req, _ := http.NewRequest("GET", reqUrl, nil)

  query := req.URL.Query()
  query.Add("limit", "10")
  query.Add("offset", "0")
  query.Add("duration", "DURATION_7_DAYS")
  req.URL.RawQuery = query.Encode()

  req.Header.Add("X-API-Key", "YOUR_API_KEY_HERE")
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}

The result should look something like this:

Copy
Copied
{
    "collections": [
        {
            "contractAddress": "0x145b250cce77604209e52f9cabbb408721f01f9c",
            "salesCount": "1000000",
            "contractName": ""
        },
        {
            "contractAddress": "0xb2469a7dd9e154c97b99b33e88196f7024f2979e",
            "salesCount": "112805",
            "contractName": ""
        },
        {
            "contractAddress": "0x495f947276749ce646f68ac8c248420045cb7b5e",
            "salesCount": "111995",
            "contractName": "OpenSea Shared Storefront"
        },
        {
            "contractAddress": "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85",
            "salesCount": "13893",
            "contractName": ""
        },
        {
            "contractAddress": "0xc86664e7d2608f881f796ee8e24fa9d4d7598406",
            "salesCount": "11555",
            "contractName": "WAGMI ARMY"
        },
        {
            "contractAddress": "0x011c77fa577c500deedad364b8af9e8540b808c0",
            "salesCount": "10549",
            "contractName": "ImmortalPlayerCharacter"
        },
        {
            "contractAddress": "0xc907ddb25a926d51784aedd4cf9c04e3eb5da12c",
            "salesCount": "9439",
            "contractName": "Dirt Birds"
        },
        {
            "contractAddress": "0x1e4afe0c027d4f14fdba4254efc1a3ac2f7d49b5",
            "salesCount": "8802",
            "contractName": "CopeBears"
        },
        {
            "contractAddress": "0x211838a8a587b02de8a02a6edafbfd7277c317d4",
            "salesCount": "8000",
            "contractName": "IDZ"
        },
        {
            "contractAddress": "0x99e51171f4e9fc035a8ca6803d4a19a2669fc6c3",
            "salesCount": "6500",
            "contractName": "FAMECollectible"
        }
    ]
}

As you can see, the top collections by sales volume and sales count are very different, yet both provide useful insight for tracking trends.

TIP: Use offset and limit parameters to control pagination.

Get trending collections by price

Finally, collections can be tracked by increasing sales price over time and then correlated with the collection results from the previous two methods. This will provide a more accurate view on trends.

Mnemonic provides two separate endpoints for tracking top collections by price:

In this example we will use the Top collections by max price endpoint to find the collections with the highest sale price over the last 7 days.

Again, you can use the duration parameter to control the the time period for which you want to obtain the data.

curlpythongo
Copy
Copied
curl -i -X GET \
https://ethereum.rest.mnemonichq.com/collections/v1beta1/top/by_max_price?limit=10&offset=0&duration=DURATION_7_DAYS
-H 'X-API-Key: YOUR_API_KEY_HERE'
Copy
Copied
import requests # requires `pip install requests`

result = requests.get(
    'https://ethereum.rest.mnemonichq.com/collections/v1beta1/top/by_max_price?limit=10&offset=0&duration=DURATION_7_DAYS',
    headers={'x-api-key': 'YOUR_API_KEY_HERE'}
).json()
Copy
Copied
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {
  reqUrl := "https://ethereum.rest.mnemonichq.com/collections/v1beta1/top/by_max_price"
  req, _ := http.NewRequest("GET", reqUrl, nil)

  query := req.URL.Query()
  query.Add("limit", "10")
  query.Add("offset", "0")
  query.Add("duration", "DURATION_7_DAYS")
  req.URL.RawQuery = query.Encode()

  req.Header.Add("X-API-Key", "YOUR_API_KEY_HERE")
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}

The result should look something like this:

Copy
Copied
{
    "collections": [
        {
            "contractAddress": "0x1dfe7ca09e99d10835bf73044a23b73fc20623df",
            "maxPrice": "1524",
            "contractName": "More Loot"
        },
        {
            "contractAddress": "0x4e1f41613c9084fdb9e34e11fae9412427480e56",
            "maxPrice": "1313",
            "contractName": "Terraforms"
        },
        {
            "contractAddress": "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d",
            "maxPrice": "871.173560204201060902",
            "contractName": "BoredApeYachtClub"
        },
        {
            "contractAddress": "0x81ae0be3a8044772d04f32398bac1e1b4b215aa8",
            "maxPrice": "414",
            "contractName": "Dreadfulz"
        },
        {
            "contractAddress": "0xa5d37c0364b9e6d96ee37e03964e7ad2b33a93f4",
            "maxPrice": "396",
            "contractName": "CATGIRL ACADEMIA"
        },
        {
            "contractAddress": "0xff36ca1396d2a9016869274f1017d6c2139f495e",
            "maxPrice": "378.1",
            "contractName": "dementorstownwtf"
        },
        {
            "contractAddress": "0x495f947276749ce646f68ac8c248420045cb7b5e",
            "maxPrice": "300.20317010830404",
            "contractName": "OpenSea Shared Storefront"
        },
        {
            "contractAddress": "0xd4e4078ca3495de5b1d4db434bebc5a986197782",
            "maxPrice": "248.1632",
            "contractName": "Autoglyphs"
        },
        {
            "contractAddress": "0xbc578ecca2115dac0c93c08674edc0c7d01fe09c",
            "maxPrice": "217.6538978629929451671",
            "contractName": "InvisibleSociety"
        },
        {
            "contractAddress": "0x7bd29408f11d2bfc23c34f18275bbf23bb716bc7",
            "maxPrice": "195",
            "contractName": "Meebits"
        }
    ]
}

By combining the three results together, it is possible to identify trending or up-and-coming collections across the entire blockchain.

After you completed this tutorial, let us know about your experience or if you have any feedback by tagging us on Twitter @mnemonichq or reaching out directly to our support@mnemonichq.com!