Uploads an array of JSON files containing NFT metadata to IPFS.
The output is an IPFS URI of a directory containing the uploaded JSON files. The IPFS URI of this directory will be used as the base_uri in Collection contract.

IPFS is an industry standard for decentralized storage and guarantees the immutability of your metadata. For the file_url, we also recommend using IPFS with Upload a file to IPFS.
We use nft.storage to pin the files with Filecoin, which ensures that your important data is retained in IPFS.

Supports only files with MIME type as application/json.

Maximum number of files that can be uploaded together is 25,000 and maximum total file size is 50MB


  • All metadata files must be uploaded at once since IPFS creates a unique immutable hash of all files in the directory.
  • To work with Collection contracts, the filenames should be token IDs starting from 0.
  • The file extension will be removed and only the filename will be retained in the IPFS directory (eg: '4521.json' will become '4521' on IPFS).
  • All files will be placed at the base of the directory.

Useful for:

  • Uploading a directory of metadata files to IPFS.


import requests
import os
from os import listdir
from os.path import join

metadata_directory_path = "Metadata" #Replace with your path

files = [f for f in listdir(metadata_directory_path) if str(join(metadata_directory_path, f)).endswith('.json')]
metadata_files = []

for metadata in files:
        ("metadata_files", open(os.path.join(metadata_directory_path, metadata), "rb")))

response = requests.post(
        headers={"Authorization": "Your-API-Key"},
const fs = require('fs');
const path = require('path')
const request = require('request');

API_KEY = "YOUR_API_KEY" // Replace with your API key
METADATA_DIRECTORY_PATH = "Metadata" // Replace with your path to directory folder containing metadata json files

function isJson(filename) {
return filename.split('.').pop() === "json"

function getFileStreamForJSONFiles(directory) {
const jsonArray = []
fs.readdirSync(directory).forEach(file => {
    if(!isJson(file)) {
    const fileData = fs.createReadStream(path.join(directory, file));
return jsonArray

function sendRequest(metadataFileStreams, apiKey) {
    const options = {
        url: 'https://api.nftport.xyz/v0/metadata/directory',
        headers: { "Authorization": apiKey }
    const req = request.post(options, function (err, resp, body) {
        if (err) {
            console.error('Error: ' + err);
        } else {
            console.log('Response: ' + body);
    const form = req.form();
    metadataFileStreams.forEach(file => {
        form.append('metadata_files', file);


metadataFileStreams = getFileStreamForJSONFiles(METADATA_DIRECTORY_PATH)
sendRequest(metadataFileStreams, API_KEY)
Click Try It! to start a request and see the response here!