How to surface newly-minted and trending NFT collections

Did you know that there are over 10,000 new NFT collections minted every month on Ethereum alone? That averages out to about 14 new collections per hour. 🤯

Surfacing freshly minted, or currently minting NFT collections can be valuable for many applications including but not limited to trading insights tools, marketplaces, and general NFT discovery experiences. However, given the quantity of new collections appearing on chain, manually surfacing and tracking newly-minted collections would be extremely time-consuming and tedious work. Keeping up with new collections in real-time could easily be a full time job, but it doesn't have to be.

Mnemonic's NFT analytics APIs make it extremely easy to surface new collections in real-time so you can build discovery, tracking, and analytics experiences with ease.

Mnemonic indexes contracts not just at the metadata and standards implementation level, but at the byte-code level too. This allows us to more accurately detect various contract types and other properties of the contracts.

Read more about the contract types and standards Mnemonic currently supports here.

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.

Newly minted NFT collections

This data is updated every 2 minutes on average, or as soon as the data is validated on the blockchain, meaning we can provide instant access to all historical and new collections on the blockchain. Since our data encompasses the entire blockchain, we can surface all collections regardless of which marketplace they are listed on.

To get newly-minted collections we will use the Contracts List endpoint.

This endpoint, by default, returns all contract types, including ERC20 contracts. So, we'll need to reduce our result to include only NFT collections. We can do this by specifying one of the following types:

  • TYPE_ERC721
  • TYPE_ERC1155
  • TYPE_ERC721_LEGACY
  • TYPE_CRYPTOPUNKS

The default sorting key for collections is mint timestamp. By using sortDirection you can specify the direction of the sorting to get the most recent or the oldest collections.

curl -i -X GET \
  'https://ethereum-rest.api.mnemonichq.com/foundational/v1beta2/contracts?limit=10&sortDirection=SORT_DIRECTION_DESC&contractTypes=TYPE_ERC721' \
  -H 'X-API-Key: YOUR_API_KEY_HERE'

We can use the blockTimestampGt request parameter to get collections minted after a certain timestamp. This is especially useful for continuous tracking by using exclusive greater comparison.

The result will look something like this:

{
    "contracts": [
        {
            "mintEvent": {
                "blockTimestamp": "2022-07-10T23:15:16Z",
                "txHash": "0x0d81248958c7d7c803cec3b7809bacfdf3cf86872dcbae6b34b26511b80f38e2",
                "minterAddress": "0xc5c0f482b561cf2ff5e2206b4e21ec749111ab63"
            },
            "name": "SAUDIBIRDS",
            "symbol": "SB",
            "decimals": 0,
            "address": "0xc07f748b65456b37d5fb3cebcfbd4bcd42589565",
            "types": [
                "TYPE_ERC721"
            ]
        },
        {
            "mintEvent": {
                "blockTimestamp": "2022-07-10T23:14:55Z",
                "txHash": "0xcdf5fb45b678d3e991f6ef4ee7dc2db2bf1703129e4e7e5462f3426add0360c3",
                "minterAddress": "0x4ecbac578acd7f9928a3d0f7e0b7ec0d54a7e3b5"
            },
            "name": "RamenDAO by CNC",
            "symbol": "RAMEN",
            "decimals": 0,
            "address": "0x9fda027e32446fc9eba720446efa98beba62d9dc",
            "types": [
                "TYPE_ERC721"
            ]
        },
        {
            "mintEvent": {
                "blockTimestamp": "2022-07-10T23:14:16Z",
                "txHash": "0x309e554c39287b01f854c7859f3d0058cd452552fe52f89038554b73faf0d3f4",
                "minterAddress": "0x8636fa411113d1b40b5d76f6766d16b3aa829d30"
            },
            "name": "Gregs (ETH)",
            "symbol": "GREG",
            "decimals": 0,
            "address": "0x7ffe2672c100bfb0094ad0b4d592dd9f9416f1ac",
            "types": [
                "TYPE_ERC721"
            ]
        },
        {
            "mintEvent": {
                "blockTimestamp": "2022-07-10T22:58:10Z",
                "txHash": "0xe13ba35cf8e197fce4406d27f26d4f161819249d01f6d8677cfdca85ef1e146f",
                "minterAddress": "0x4db337964306805972a7dfef9a4ccc24206c5311"
            },
            "name": "Influencer Punks",
            "symbol": "IPKS",
            "decimals": 0,
            "address": "0xda2287704b1f1be690fbe5bf33bf13dc2af1ace4",
            "types": [
                "TYPE_ERC721"
            ]
        },
        {
            "mintEvent": {
                "blockTimestamp": "2022-07-10T22:58:10Z",
                "txHash": "0x3ebca0a6822a568e35553bb6682391586378784b80905901424f67e86d84df12",
                "minterAddress": "0xbc8f7b371f64fee0186c6ee4a838940365b69609"
            },
            "name": "HomelessFriends",
            "symbol": "HomelessFriends",
            "decimals": 0,
            "address": "0x47de46c0d4d178ded8eda96927405dad26d11ba1",
            "types": [
                "TYPE_ERC721"
            ]
        },
        {
            "mintEvent": {
                "blockTimestamp": "2022-07-10T22:55:49Z",
                "txHash": "0xf2e477ea92908153c56fb53219986c9915b9ed8124b49fbcb8ff19736de6e6ec",
                "minterAddress": "0x70b71dc811b55e0c914cc326e025ef159da211ab"
            },
            "name": "EMRE2'S",
            "symbol": "EMRE2",
            "decimals": 0,
            "address": "0x836954e67e3b3c7d2d7f00c82313e0dec80c52f3",
            "types": [
                "TYPE_ERC721"
            ]
        },
        {
            "mintEvent": {
                "blockTimestamp": "2022-07-10T22:52:38Z",
                "txHash": "0x4c3c379de84944cdf35c22a455cd42a5c6f267d1d8fc1df22df5acc55b7c5eb2",
                "minterAddress": "0x263ec9e189d5e15b806670203e3914780d2cadbf"
            },
            "name": "RektPepeRenaissance",
            "symbol": "RPR",
            "decimals": 0,
            "address": "0xc507e905f71605488c506f5c4b531d6db7fb0862",
            "types": [
                "TYPE_ERC721"
            ]
        },
        {
            "mintEvent": {
                "blockTimestamp": "2022-07-10T22:48:44Z",
                "txHash": "0xc9f35ea6206e26325e40c4c21515b9f595f8c049beef235f76ece1f874ca6487",
                "minterAddress": "0x24bcda4af1321ce993bb11832c5a17872a5ccf24"
            },
            "name": "MONSTERS",
            "symbol": "MONSTERS",
            "decimals": 0,
            "address": "0x90005f3155fd9df3fefd9c397d5af3adda7aa371",
            "types": [
                "TYPE_ERC721"
            ]
        },
        {
            "mintEvent": {
                "blockTimestamp": "2022-07-10T22:31:13Z",
                "txHash": "0x912e130ddeb676406795a0679011007de01a071f619310af467470f210a006ca",
                "minterAddress": "0xb473055711531843b20badc43a00563879333080"
            },
            "name": "BoredSword",
            "symbol": "BRSD",
            "decimals": 0,
            "address": "0x3a835b59ce2bd13ef7251901dce23dc95c86e492",
            "types": [
                "TYPE_ERC721"
            ]
        },
        {
            "mintEvent": {
                "blockTimestamp": "2022-07-10T22:30:30Z",
                "txHash": "0x7c92023e471655dba8e64cb51e374db15756e6d647887f895e6ab6c562030d53",
                "minterAddress": "0xe354127e1b7fc1b153281a914147991a8b312aab"
            },
            "name": "Pixel Portrait Art",
            "symbol": "PPART",
            "decimals": 0,
            "address": "0xcffd0f354e38f3bfcea7ad9d7d3754aca029414b",
            "types": [
                "TYPE_ERC721"
            ]
        }
    ]
}

Trending collections by trading volume

This 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.

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 endpoint by trading volume.

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

curl -i -X GET \
    'https://ethereum-rest.api.mnemonichq.com/collections/v1beta2/top/METRIC_SALES_VOLUME/DURATION_7_DAYS' \
    -H 'X-API-Key: YOUR_API_KEY_HERE'

The result should look something like this:

{
    "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.

Trending collections by NFT sales quantity

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 endpoint and METRIC_SALES_QUANTITY metric parameter.

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

curl --request GET \
     --url https://ethereum-rest.api.mnemonichq.com/collections/v1beta2/top/METRIC_SALES_QUANTITY/DURATION_1_DAY \
     --header 'X-API-Key: <YOUR API KEY>' \
     --header 'accept: application/json'
import requests # requires `pip install requests`

result = requests.get(
    'https://ethereum-rest.api.mnemonichq.com/collections/v1beta2/top/METRIC_SALES_QUANTITY/DURATION_7_DAYS',
    headers={'x-api-key': 'YOUR_API_KEY_HERE'}
).json()
const axios = require('axios');

const reqUrl = 'https://ethereum-rest.api.mnemonichq.com/collections/v1beta2/top/METRIC_SALES_QUANTITY/DURATION_7_DAYS';
const params = { limit: '10', offset: '0' };
const headers = { 'X-API-Key': 'YOUR_API_KEY_HERE' };

axios.get(reqUrl, { params: params, headers: headers })
  .then(response => {
    console.log(response.status);
    console.log(response.headers);
    console.log(response.data);
  })
  .catch(error => {
    console.error(error);
  });
package main

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

func main() {
  reqUrl := "https://ethereum-rest.api.mnemonichq.com/collections/v1beta2/top/METRIC_SALES_QUANTITY/DURATION_7_DAYS"
  req, _ := http.NewRequest("GET", reqUrl, nil)

  query := req.URL.Query()
  query.Add("limit", "10")
  query.Add("offset", "0")
  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:

{
    "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.

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 of the trend.

The Top Collections endpoint Mnemonic provides allows tracking by price:

  • Max Price
  • Average Price

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

curl -i -X GET \
    'https://ethereum-rest.api.mnemonichq.com/collections/v1beta2/top/METRIC_MAX_PRICE/DURATION_7_DAYS' \
    -H 'X-API-Key: YOUR_API_KEY_HERE'

The result should look something like this:

{
    "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 four results together, it is possible to identify trending or up-and-coming collections across the entire blockchain.

After you've 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 [email protected]!