◈   ⌘ api · Intermediate

Moralis NFT Endpoints: The Complete Developer Guide

Learn how to use Moralis NFT API endpoints to fetch NFT data, ownership, metadata, and transfers with real code examples for crypto developers.

Uncle Solieditor · voc · 06.05.2026 ·views 15
◈   Contents
  1. → What Moralis NFT API Actually Gives You
  2. → Authentication and SDK Setup
  3. → Core NFT Endpoints: Ownership and Metadata
  4. → NFT Transfer History and On-Chain Activity
  5. → NFT Prices, Floor Data, and Collection Stats
  6. → Frequently Asked Questions
  7. → Building Real Tools with Moralis NFT Data

If you've ever tried to build an NFT tracker, portfolio tool, or trading bot that needs on-chain NFT data, you've probably hit the same wall: querying NFT ownership and metadata directly from an RPC node is slow, expensive, and painful. Moralis solves this by indexing the blockchain and exposing clean REST and SDK endpoints so you can pull NFT data in milliseconds instead of hours. This guide walks through the most important Moralis NFT endpoints with real code you can copy and run today.

What Moralis NFT API Actually Gives You

Moralis NFT API is a suite of endpoints built on top of their multi-chain indexer. Instead of subscribing to raw node events and parsing logs yourself, you hit a single HTTPS endpoint and get structured JSON back. The API covers Ethereum, Polygon, BNB Chain, Avalanche, Solana, and a dozen other networks. For a trader or developer building tools around NFT markets — whether that's tracking floor prices, watching whale wallets, or building a collection analytics dashboard — this saves weeks of infrastructure work.

Authentication and SDK Setup

Every request to Moralis requires an API key. Get yours free at moralis.io — the free tier allows 40,000 compute units per day, which is plenty for development and small projects. You can call endpoints directly via REST or use their Python and JavaScript SDKs. The SDK is cleaner for complex workflows; raw REST is better if you're integrating into an existing system.

# Install SDK
# pip install moralis

from moralis import evm_api
import os

# Set your API key — store this in an environment variable, never hardcode
API_KEY = os.environ.get("MORALIS_API_KEY")

# Quick connectivity check — get native balance to confirm key works
def check_auth():
    params = {
        "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",  # vitalik.eth
        "chain": "eth"
    }
    try:
        result = evm_api.balance.get_native_balance(api_key=API_KEY, params=params)
        print(f"Auth OK — balance: {result['balance']} wei")
        return True
    except Exception as e:
        print(f"Auth failed: {e}")
        return False

check_auth()
// npm install moralis

import Moralis from 'moralis';

const API_KEY = process.env.MORALIS_API_KEY;

async function initMoralis() {
  await Moralis.start({ apiKey: API_KEY });
  console.log('Moralis initialized');
}

initMoralis();
Never commit your Moralis API key to Git. Use environment variables or a secrets manager. A leaked key means someone else burns through your compute units — or worse, your paid quota.

Core NFT Endpoints: Ownership and Metadata

The two most commonly used endpoints are wallet NFT lookup and token metadata fetch. The wallet endpoint tells you every NFT a given address holds — useful if you're building a portfolio tracker or monitoring a whale wallet for positions. The metadata endpoint gives you the token's image URI, traits, description, and any custom attributes defined by the collection.

from moralis import evm_api
import os
import json

API_KEY = os.environ.get("MORALIS_API_KEY")

def get_wallet_nfts(wallet_address: str, chain: str = "eth", limit: int = 10):
    """
    Fetch all NFTs owned by a wallet.
    Returns list of NFT objects with metadata.
    """
    params = {
        "address": wallet_address,
        "chain": chain,
        "limit": limit,
        "media_items": False  # Set True if you need image CDN URLs
    }
    try:
        result = evm_api.nft.get_wallet_nfts(api_key=API_KEY, params=params)
        nfts = result.get("result", [])
        print(f"Found {len(nfts)} NFTs for {wallet_address}")
        return nfts
    except Exception as e:
        print(f"Error fetching wallet NFTs: {e}")
        return []

def get_nft_metadata(contract_address: str, token_id: str, chain: str = "eth"):
    """
    Fetch full metadata for a specific NFT token.
    """
    params = {
        "address": contract_address,
        "token_id": token_id,
        "chain": chain,
        "normalizeMetadata": True  # Normalize IPFS URIs automatically
    }
    try:
        result = evm_api.nft.get_nft_metadata(api_key=API_KEY, params=params)
        # Parse the nested metadata JSON string
        if result.get("metadata"):
            metadata = json.loads(result["metadata"])
            print(f"Name: {metadata.get('name')}")
            print(f"Traits: {metadata.get('attributes', [])}")
        return result
    except Exception as e:
        print(f"Error fetching NFT metadata: {e}")
        return None

# Example: Check what NFTs Binance's hot wallet holds
binance_hot_wallet = "0x28C6c06298d514Db089934071355E5743bf21d60"
nfts = get_wallet_nfts(binance_hot_wallet, chain="eth", limit=5)
for nft in nfts:
    print(f"{nft['name']} | Contract: {nft['token_address']} | Token ID: {nft['token_id']}")

When you parse the response, each NFT object contains `token_address`, `token_id`, `owner_of`, `token_uri`, `metadata`, `name`, and `symbol`. The `metadata` field is a JSON string — you need to parse it separately to access traits and image URLs. The `normalizeMetadata` flag is worth enabling because it resolves IPFS URIs to gateway URLs automatically, saving you a lookup.

NFT Transfer History and On-Chain Activity

Transfer history is where things get interesting for traders. You can pull every transfer event for a contract or a wallet — mints, sales, and peer-to-peer transfers. This is the raw ingredient for building wash-trade detection, whale tracking, or signals that feed into platforms like VoiceOfChain, which aggregates on-chain activity into real-time trading signals. Knowing when a whale wallet on Ethereum suddenly mints 50 NFTs from a new collection — or dumps an entire position — is actionable intelligence.

from moralis import evm_api
import os
from datetime import datetime

API_KEY = os.environ.get("MORALIS_API_KEY")

def get_nft_transfers(contract_address: str, chain: str = "eth", limit: int = 20):
    """
    Get recent transfer events for an NFT collection.
    Useful for monitoring mint activity or large sales.
    """
    params = {
        "address": contract_address,
        "chain": chain,
        "limit": limit,
        "order": "DESC"  # Most recent first
    }
    try:
        result = evm_api.nft.get_nft_contract_transfers(
            api_key=API_KEY,
            params=params
        )
        transfers = result.get("result", [])
        for tx in transfers:
            ts = tx.get("block_timestamp", "")
            from_addr = tx.get("from_address", "")[:10]
            to_addr = tx.get("to_address", "")[:10]
            token_id = tx.get("token_id")
            value = tx.get("value", "0")
            # Mint detection: from address is zero address
            is_mint = tx["from_address"] == "0x0000000000000000000000000000000000000000"
            label = "MINT" if is_mint else "TRANSFER"
            print(f"[{label}] Token #{token_id} | {from_addr}... -> {to_addr}... | {ts}")
        return transfers
    except Exception as e:
        print(f"Error fetching transfers: {e}")
        return []

# Bored Ape Yacht Club contract
bayc_contract = "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D"
transfers = get_nft_transfers(bayc_contract, chain="eth", limit=10)
Mint detection trick: when `from_address` is the zero address (0x000...000), it's a fresh mint — not a secondary sale. Filter for these to catch early collection launches before they hit secondary markets like OpenSea.

NFT Prices, Floor Data, and Collection Stats

Moralis also exposes price and marketplace data. The NFT floor price endpoint pulls the lowest listed price across major marketplaces. If you're running a trading bot that monitors collections, this endpoint combined with transfer data gives you a two-dimensional view: what's the current floor, and is volume accelerating. Traders on Binance NFT, OKX NFT marketplace, and Bybit often use on-chain APIs like this to time entries before price moves show up in order books.

import Moralis from 'moralis';

const API_KEY = process.env.MORALIS_API_KEY;

async function getNFTFloorPrice(contractAddress, chain = '0x1') {
  await Moralis.start({ apiKey: API_KEY });

  try {
    // Get NFT lowest price endpoint
    const response = await Moralis.EvmApi.nft.getNFTLowestPrice({
      address: contractAddress,
      chain: chain,
      days: 7,        // Look back 7 days
      marketplace: 'opensea'
    });

    const data = response.toJSON();
    const priceEth = parseInt(data.price) / 1e18;
    const tokenId = data.token_id;
    const txHash = data.transaction_hash;

    console.log(`Floor price: ${priceEth.toFixed(4)} ETH`);
    console.log(`Last sale token: #${tokenId}`);
    console.log(`Tx: ${txHash}`);

    return { priceEth, tokenId, txHash };
  } catch (error) {
    if (error.details?.status === 429) {
      console.error('Rate limited — back off and retry');
    } else {
      console.error('Error:', error.message);
    }
    return null;
  }
}

// Azuki collection
getNFTFloorPrice('0xED5AF388653567Af2F388E6224dC7C4b3241C544');

The rate limiting behavior deserves attention — a 429 response from Moralis means you've hit your compute unit ceiling. Implement exponential backoff in production code. Each endpoint costs a different number of compute units: basic wallet lookups are cheap, but searching by metadata or pulling large transfer histories can run expensive fast. Check the Moralis pricing docs for the compute unit cost table before building anything at scale.

Common Moralis NFT Endpoints and Use Cases
EndpointMethodUse CaseApprox. CU Cost
getWalletNFTsGET /nft/{address}Portfolio tracking, whale watching5 CU per call
getNFTMetadataGET /nft/{address}/{id}Trait lookup, rarity checks5 CU per call
getNFTContractTransfersGET /nft/{address}/transfersVolume monitoring, mint detection10 CU per call
getNFTLowestPriceGET /nft/{address}/lowestpriceFloor price feeds, bots10 CU per call
getNFTOwnersGET /nft/{address}/ownersHolder distribution analysis15 CU per call
searchNFTsGET /nft/searchMetadata trait search20 CU per call

Frequently Asked Questions

Is the Moralis NFT API free to use?
Yes, Moralis has a free tier that includes 40,000 compute units per day, which covers most development and small-scale production use cases. Paid plans unlock higher limits, more chains, and priority support. For serious production workloads you'll likely need a paid plan, but the free tier is generous enough to build and test with.
Which blockchains does the Moralis NFT API support?
Moralis supports Ethereum, Polygon, BNB Chain, Avalanche, Fantom, Cronos, Arbitrum, Optimism, Solana, and several testnets. Most endpoints work cross-chain by simply changing the `chain` parameter. Solana has a separate SDK namespace (`sol_api` instead of `evm_api`) since it uses a different account model.
How do I handle pagination when fetching large NFT collections?
Moralis uses cursor-based pagination. Every response that has more results includes a `cursor` field. Pass that cursor value as a parameter in your next request to get the next page. Keep looping until `cursor` is null or the result array is empty. Don't use offset pagination — it's not supported and can miss records on actively-indexed collections.
Can I use Moralis NFT API to build a trading bot?
Absolutely — Moralis is commonly used as the data layer for NFT bots that track floor prices, detect new mints, or monitor whale activity. You'd combine Moralis endpoints for on-chain data with marketplace APIs (OpenSea, Blur) for listing actions. Platforms like VoiceOfChain use similar on-chain data pipelines to generate real-time crypto trading signals.
What's the difference between getNFTMetadata and getTokenIdMetadata?
They're actually the same endpoint in the current Moralis SDK — `getNFTMetadata` fetches the metadata for a specific token ID within a contract. The confusion usually comes from older SDK versions where the naming differed. Always use the latest SDK version and refer to the current docs, as endpoint names have changed across major versions.
Does Moralis support real-time NFT event streaming?
Yes, via Moralis Streams (a separate product from the REST API). Streams use webhooks to push real-time on-chain events — mints, transfers, sales — to your server as they happen on-chain. This is far more efficient than polling endpoints for time-sensitive applications like sniper bots or alert systems.

Building Real Tools with Moralis NFT Data

The real value of Moralis NFT endpoints isn't any single API call — it's how they combine. A practical whale tracker, for instance, pulls wallet NFT holdings once per block, diffs the result against the previous state, and fires an alert when a known large holder drops or acquires a significant position. Pair that with price data from Coinbase or OKX APIs and you have a system that can flag when a top-10 holder of a collection sells out at the same time floor price starts dropping. That's the kind of intelligence that gives you an edge on platforms like Binance NFT or Bybit's marketplace before it shows up in the charts.

VoiceOfChain integrates on-chain signals like NFT whale movements alongside DeFi and token trading signals, making it easier to see the full picture without building every data pipeline yourself. For developers who want to go deeper, Moralis is the right foundation — it eliminates the indexing problem so you can focus on the logic that actually generates alpha. Start with the wallet NFT endpoint and transfer history, get comfortable with pagination and error handling, then layer in Streams when you need real-time push rather than polling. That progression — from REST polling to event-driven streaming — mirrors how most serious NFT tool builders evolve their architecture.

◈   more on this topic
◉ basics Mastering the ccxt library documentation for crypto traders ⌂ exchanges Mastering the Binance CCXT Library for Crypto Traders ⌬ bots Best Crypto Trading Bots 2025: Profitable AI-Powered Strategies