Documentation Index
Fetch the complete documentation index at: https://docs.moralis.com/llms.txt
Use this file to discover all available pages before exploring further.
Question it answers
“Give me the collection metadata — name, symbol, contract type — for NFT collection 0x….” Mirrors Moralis GET /nft/{address}/metadata.
This is the NFT-collection sibling of Token Metadata. Both read the same per-block deployed-contracts stream, but this recipe keeps only NFT-type contracts (ERC-721 / ERC-1155) and drops ERC-20 tokens. Collection metadata is fixed at deploy time, so there is normally exactly one row per (chain_id, token_address) — the latest deploy by (block_number, transaction_index) is canonical (defensive against a CREATE2 re-deploy at a reused address).
What you get
One row per NFT-type contract deploy, keyed by the collection (token_address):
| Column | Description |
|---|---|
token_address | The NFT collection contract address |
name | On-chain collection name — best-effort; may be empty for many ERC-1155 collections |
symbol | On-chain collection symbol — best-effort; may be empty |
contract_type | ERC721 · ERC1155 · NFT (derived from the EIP-165 interface ids; NFT is the fallback when neither interface is advertised) |
deployer_address | Address that deployed the contract |
block_number, transaction_index | Deploy position — the recency tiebreaker for latest-wins |
block_timestamp | Block time of the deploy |
name/symbol are best-effort on-chain fields, not filter keys. Far fewer rows land than Token Metadata: only a handful of NFT contracts deploy per ~1000 blocks.
Source
The transform reads the per-block deployed-contracts stream and keeps the NFT slice — contracts whosetype contains NFT (ERC-721 / ERC-1155). A contract is kept when its deployer_address is non-empty. contract_type is derived from the contract’s supportedInterfaces (EIP-165 ids): 0xd9b67a26 → ERC1155, else 0x80ac58cd → ERC721, else the NFT fallback.
Destination
| Destination | Table | By-collection access |
|---|---|---|
| ClickHouse (first-class) | fact_nft_collection_metadata | ORDER BY (chain_id, token_address); latest deploy via argMax(…, (block_number, transaction_index)), read with FINAL |
| Postgres | nft_collection_metadata (matview over nft_collection_metadata_observations) | Unique index on (token_address) |
| MySQL | nft_collection_metadata (latest-wins state table over the observations) | Primary key on (token_address) |
argMax(…, (block_number, transaction_index)) rather than assuming a single row. Postgres derives the current-metadata surface as a DISTINCT ON (token_address) materialized view; MySQL maintains it incrementally with a latest-wins trigger.
Full schema
The complete read table this recipe produces. Keep the columns you need —name/symbol/contract_type are usually enough for a metadata lookup (see Schema & flexibility). name and symbol are stored as text; they can contain quotes and odd characters, which are parameter-bound on insert so there is no quoting breakage.
ClickHouse — fact_nft_collection_metadata
ClickHouse — fact_nft_collection_metadata
sign column drives reorg collapsing — read with FINAL or a sign-aware aggregate, never a bare WHERE sign = 1. A single-node setup can use CollapsingMergeTree(sign) without the replication path. The collection-keyed sort order makes a single-collection lookup a tight prefix scan.Postgres — nft_collection_metadata
Postgres — nft_collection_metadata
nft_collection_metadata_observations; refresh the current-metadata view on a schedule with REFRESH MATERIALIZED VIEW CONCURRENTLY nft_collection_metadata;. MySQL mirrors this shape — VARCHAR(255) for name/symbol — with the current-metadata nft_collection_metadata table maintained incrementally by an AFTER INSERT latest-wins trigger.Example reads
Metadata for one collection — latest deploy wins (ClickHouse):REFRESH MATERIALIZED VIEW CONCURRENTLY nft_collection_metadata;):
Modes
Shipped defaults: ClickHousehybrid (backfill → realtime), Postgres / MySQL historical (one-shot backfill). For live/reorg-safe ingestion, use ClickHouse — see the overview.
The realtime reorg path on Postgres / MySQL needs a single-column
UNIQUE on the block-level position, but a single block can deploy several NFT contracts — so the array-expanded rows can only carry a composite unique. Run realtime/hybrid on ClickHouse, where the collapsing log table corrects reorgs per-block. The Postgres / MySQL configs are intended for historical backfill, which is the dominant use of this recipe — a once-off metadata census.EVM only
This recipe is EVM-shaped: it reads EVM contract deploys. Solana NFT (Metaplex) collection metadata does not flow through the deployed-contracts stream the same way EVM contract deploys do, so the recipe targets EVM chains. It is chain-parametrized via thechain setting across any supported EVM chain.
Fidelity gaps
GET /nft/{address}/metadata returns enrichment fields this recipe does not source — all off-chain indexer or editorial state:
collection_logo/collection_banner_image— off-chain CDN assets.collection_category— editorial categorisation.project_url/discord_url/telegram_url/wiki_url— social links.possible_spam/verified_collection— spam & verification heuristics from a separate pipeline.synced_at(wall-clock) — this recipe carries on-chainblock_number/block_timestampinstead.
token_address, name, symbol, contract_type, plus block_number and deployer_address — are fully sourced.
Related
NFT Owners by Contract
Current holders of a collection — pair with this metadata for a complete collection view.
NFT Marketplace
The use case this collection metadata powers.

