How to Get All NFTs Owned by an Address
Learn how to get all NFTs (and their metadata) owned by an address using the Alchemy NFT API
If you're building a wallet, an NFT marketplace like OpenSea, or a dApp with an NFT gallery, chances are that you will need to list all NFTs owned by a user as well as information about the NFTs themselves (such as name, description, traits, etc.)
NFT gallery showing multiple NFTs including Degen Apes, Bored Ape Yacht Club (BAYC), Mekaverse, and Degen Trash Pandas.
To get all NFTs owned by a user on a blockchain like Ethereum or Polygon, you would have to parse the entire blockchain since genesis, track all ERC-721 and ERC-1155 contracts, and track the latest ownership status of every NFT.
This requires a massive amount of engineering resources and time.
However, it is possible to bypass this effort by using Alchemy's NFT API.
In this tutorial, you will use the Alchemy NFT API to get all NFTs owned by a wallet address.
If you are new, read the NFT API Quickstart Guide to learn how the NFT API works.

About This Tutorial

You will write a simple script in Node to get the top 100 NFTs owned by a wallet on Ethereum.
This will be achieved using a free Alchemy developer account and the NFT API.

Creating the NFT Ownership Script

Step 1: Install Node and npm

In case you haven't already, install node and npm on your local machine.
Make sure that node is at least v14 or higher by typing the following in your terminal:
1
node -v
Copied!

Step 2: Create a new Alchemy app

In case you haven't already, sign up for a free Alchemy account.
Alchemy dashboard where NFT developers can easily create a new app on a specific blockchain and network.
Next, navigate to the Alchemy Dashboard and create a new app.
Make sure you set the chain to Ethereum and network to Mainnet.
Once the app is created:
  • click on your app's View Key button on the dashboard
  • take a note of the HTTP URL (e.g.https://eth-mainnet.alchemyapi.io/nft/v2/xxxxxxxxx)
You will need this URL later.

Step 3: Create a Node project

Next, create an empty repository and install all node dependencies.
To make requests to the NFT API, we recommend using the Alchemy web3 library.
Alternative, you can use axios or fetch.
Alchemy Web3 (Recommended)
Axios
Fetch
1
mkdir nft-ownership && cd nft-ownership
2
npm init -y
3
npm install --save @alch/alchemy-web3
4
touch main.js
Copied!
1
mkdir nft-ownership && cd nft-ownership
2
npm init -y
3
npm install --save axios
4
touch main.js
Copied!
1
mkdir nft-ownership && cd nft-ownership
2
npm init -y
3
touch main.js
Copied!
This will create a repository named nft-ownership that holds all the files and dependencies.
Open this repo in your favorite code editor.
You will be writing all your code in the main.js file.

Step 4: Get all NFTs owned by an address

To get all NFTs owned by an address, use the getNFTs method.
The getNFTs method takes in one required argument:
  1. 1.
    owner: The wallet address of which we want to get NFT ownership data.
By default, the getNFTs method returns metadata of the NFTs.
We are going to stick with this default behavior.
You can also restrict the NFT collections by passing in an array of contractAddresses[] and filtering out NFTs that have been classified as spam using the filter argument.
For more information on this, check out the NFT API FAQ.
Add the following code to the main.js file:
Alchemy Web3 (Recommended)
Axios
Fetch
main.js
1
const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
2
​
3
// Using HTTP
4
const web3 = createAlchemyWeb3(
5
"<-- ALCHEMY APP HTTP URL -->",
6
);
7
​
8
const main = async () => {
9
// Wallet address (Supports ENS!)
10
const address =
11
'elanhalpern.eth'
12
​
13
// Get all NFTs
14
const nfts = await
15
web3.alchemy.getNfts({ owner: address })
16
​
17
// Print NFTs
18
console.log(nfts)
19
}
20
​
21
const runMain = async () => {
22
try {
23
await main();
24
process.exit(0);
25
}
26
catch (error) {
27
console.log(error);
28
process.exit(1);
29
}
30
};
31
​
32
runMain();
Copied!
1
const axios = require('axios')
2
​
3
// Wallet address
4
const address = 'elanhalpern.eth'
5
​
6
// Alchemy URL
7
const baseURL = `<-- ALCHEMY APP HTTP URL -->`;
8
const url = `${baseURL}/getNFTs/?owner=${address}`;
9
​
10
const config = {
11
method: 'get',
12
url: url,
13
};
14
​
15
// Make the request and print the formatted response:
16
axios(config)
17
.then(response => console.log(response['data']))
18
.catch(error => console.log('error', error));
Copied!
1
import fetch from 'node-fetch';
2
​
3
const baseURL = "<-- ALCHEMY APP HTTP URL -->";
4
const address = "elanhalpern.eth";
5
const url = `${baseURL}/getNFTs/?owner=${address}`;
6
​
7
var requestOptions = {
8
method: 'get',
9
redirect: 'follow'
10
};
11
​
12
fetch(url, requestOptions)
13
.then(response => console.log)
14
.catch(error => console.log('error', error))
Copied!
Run this script by typing:
1
node main.jsma
Copied!
You should then see an output that looks something like this:
1
{
2
"ownedNfts": [
3
{
4
"contract": {
5
"address": "0x0beed7099af7514ccedf642cfea435731176fb02"
6
},
7
"id": {
8
"tokenId": "28",
9
"tokenMetadata": {
10
"tokenType": "ERC721"
11
}
12
},
13
"title": "DuskBreaker #28",
14
"description": "Breakers have the honor of serving humanity through their work on The Dusk. They are part of a select squad of 10,000 recruits who spend their days exploring a mysterious alien spaceship filled with friends, foes, and otherworldly technology.",
15
"tokenUri": {
16
"raw": "https://duskbreakers.gg/api/breakers/28",
17
"gateway": "https://duskbreakers.gg/api/breakers/28"
18
},
19
"media": [
20
{
21
"raw": "https://duskbreakers.gg/breaker_images/28.png",
22
"gateway": "https://duskbreakers.gg/breaker_images/28.png"
23
}
24
],
25
"metadata": {
26
"name": "DuskBreaker #28",
27
"description": "Breakers have the honor of serving humanity through their work on The Dusk. They are part of a select squad of 10,000 recruits who spend their days exploring a mysterious alien spaceship filled with friends, foes, and otherworldly technology.",
28
"image": "https://duskbreakers.gg/breaker_images/28.png",
29
"external_url": "https://duskbreakers.gg",
30
"attributes": [
31
{
32
"value": "Locust Rider Armor (Red)",
33
"trait_type": "Clothes"
34
},
35
......
36
{
37
"value": "Big Smile (Purple)",
38
"trait_type": "Mouth"
39
},
40
{
41
"value": "Yellow",
42
"trait_type": "Background"
43
}
44
]
45
},
46
"timeLastUpdated": "2022-02-16T22:52:54.719Z"
47
},
48
......
49
],
50
"totalCount": 6,
51
"blockHash": "0xeb2d26af5b6175344a14091777535a2cb21c681665a734a8285f889981987630"
52
}
Copied!
You get all the metadata about the NFTs in the same request.
This data can be parsed and displayed on your web3 frontend with ease.
If the address owns more than 100 NFTs, the response will contain a pageKey key-value pair.
Use this key to issue another request to getNFTs with pageKey as another argument to owner.
This will return the next 100 NFTs owned by the user.
You can repeat this process until you reach the end of the wallet's collection.
For more information, check out the NFT API docs.

Step 5: Parse the NFT API output

The response you received in the previous step is not human-readable. Let's parse the API output to show only the titles of the NFTs owned by a wallet.
Replace the contents of main.js with the following:
Alchemy Web3 (Recommended)
Axios
Fetch
main.js
1
const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
2
​
3
// Using HTTP
4
const web3 = createAlchemyWeb3(
5
"https://eth-mainnet.alchemyapi.io/nft/v2/NQSuAhlOs706-XBHAkbF6rbLJ50InHTj",
6
);
7
​
8
const main = async () => {
9
// Wallet address
10
const address =
11
'elanhalpern.eth'
12
​
13
// Get all NFTs
14
const nfts = await
15
web3.alchemy.getNfts({ owner: address })
16
​
17
// Parse output
18
const numNfts = nfts['totalCount'];
19
const nftList = nfts['ownedNfts'];
20
​
21
console.log(`Total NFTs owned by ${address}: ${numNfts} \n`);
22
23
let i = 1;
24
​
25
for (nft of nftList) {
26
console.log(`${i}. ${nft['metadata']['name']}`)
27
i++;
28
}
29
​
30
}
31
​
32
const runMain = async () => {
33
try {
34
await main();
35
process.exit(0);
36
}
37
catch (error) {
38
console.log(error);
39
process.exit(1);
40
}
41
};
42
​
43
runMain();
Copied!
1
const axios = require('axios')
2
​
3
// Wallet address
4
const address = 'elanhalpern.eth'
5
​
6
// Alchemy URL
7
const baseURL = `<-- ALCHEMY APP HTTP URL -->`;
8
const url = `${baseURL}/getNFTs/?owner=${address}`;
9
​
10
const config = {
11
method: 'get',
12
url: url,
13
};
14
​
15
// Make the request and print the formatted response:
16
axios(config)
17
.then(response => {
18
const nfts = response['data'];
19
​
20
// Parse output
21
const numNfts = nfts['totalCount'];
22
const nftList = nfts['ownedNfts'];
23
​
24
console.log(`Total NFTs owned by ${address}: ${numNfts} \n`);
25
​
26
let i = 1;
27
​
28
for (nft of nftList) {
29
console.log(`${i}. ${nft['metadata']['name']}`)
30
i++;
31
}
32
})
33
.catch(error => console.log('error', error));
Copied!
1
import fetch from 'node-fetch';
2
​
3
const baseURL = "<-- ALCHEMY APP HTTP URL -->";
4
const address = "elanhalpern.eth";
5
const url = `${baseURL}/getNFTs/?owner=${address}`;
6
​
7
var requestOptions = {
8
method: 'get',
9
redirect: 'follow'
10
};
11
​
12
fetch(url, requestOptions)
13
.then(response => {
14
const nfts = response['data'];
15
​
16
// Parse output
17
const numNfts = nfts['totalCount'];
18
const nftList = nfts['ownedNfts'];
19
​
20
console.log(`Total NFTs owned by ${address}: ${numNfts} \n`);
21
​
22
let i = 1;
23
​
24
for (nft of nftList) {
25
console.log(`${i}. ${nft['metadata']['name']}`)
26
i++;
27
}
28
})
29
.catch(error => console.log('error', error))
Copied!
Run the script using:
1
node main.js
Copied!
You should obtain an output that looks like this:
1
Total NFTs owned by elanhalpern.eth: 18
2
​
3
1. DuskBreaker #9
4
2. Dev #6881
5
3. WAW #1878
6
4. You #1546
7
5. Super Fat Ape #570
8
6. Runner #3429
9
7. cryptocreamery.eth
10
8. elanhalpern.eth
11
9. BFF Friendship Bracelet
12
10. BFF Friendship Bracelet
13
11. CityDAO Citizen
14
12. #4842
15
13. MAVION #1002
16
14. Shackled Genesis #622
17
15. Runner #3429
18
16. Squirrelly Squirrel #245
19
17. Founding BFF Friendship Bracelets
20
18. MAVION Gems - The OG
Copied!

Conclusion

Congratulations! You now know how to use the Alchemy NFT API to get all NFTs owned by a user on a blockchain (whether that be Ethereum, Polygon, or Flow).
If you enjoyed this tutorial on how to get all NFTs owned by an address, tweet us at @AlchemyPlatform and give the authors @rounak_banik and @ankg404 a shoutout!
Don't forget to join our Discord server to meet other blockchain devs, builders, and entrepreneurs!
Ready to start using the Alchemy NFT API?
​Create a free Alchemy account and do share your project with us!