Uploading Files
At the core of Pinata is file uploads through our File API. It’s fast and easy to use, whether you’re using the SDK or the API. Something unique about the Files API is that all files are given a unique Content Identifier or CID
. These are not like normal IDs in that they are content addressable hashes based on the contents of the file. You can upload the same file over and over and it will always return the same CID. This has multiple benefits including:
- Deduplication: Since a duplicate file would have the same CID, it is not included upon upload and reduces the amount of files in your account. This keeps things organized and reduces your total costs.
- Versioning: Tracking the history of a file requires proprietary solutions built on top of the data storage provider and does not expose that history and provenance in a meaningful way to everyone who needs to access it.
Let’s look at the multiple ways you can upload files!
Using the SDK
The Pinata SDK is able to handle mutliple kinds of uploads, whether its file objects, base64 strings, or even content from remote URLs.
import { PinataSDK } from "pinata";
const pinata = new PinataSDK({
pinataJwt: process.env.PINATA_JWT!,
pinataGateway: "example-gateway.mypinata.cloud",
});
const file = new File(["hello"], "Testing.txt", { type: "text/plain" });
const upload = await pinata.upload.file(file);
The SDK is also equipped to handle an array of file objects.
import { PinataSDK } from "pinata";
const pinata = new PinataSDK({
pinataJwt: process.env.PINATA_JWT!,
pinataGateway: "example-gateway.mypinata.cloud",
});
const file1 = new File(["hello world!"], "hello.txt", { type: "text/plain" })
const file2 = new File(["hello world again!"], "hello2.txt", { type: "text/plain" })
const upload = await pinata.upload.fileArray([file1, file2])
Using the API
The API is a bit more flexible, as it can be used in multiple languages or environments, and is sometimes preferred for client side uploads. With that, we should express warning in that client side applications will expose API keys.
Using your API Keys in a client side application will expose them! Consider using a signed JWT approach.
The API accepts File
objects (and blobs in the right environment) through a multipart form data request, where the object has a key of file
.
const JWT = "YOUR_PINATA_JWT";
async function pinFileToIPFS() {
try {
const formData = new FormData();
const file = new File(["hello"], "Testing.txt", { type: "text/plain" });
formData.append("file", file);
const request = await fetch("https://uploads.pinata.cloud/v3/files", {
method: "POST",
headers: {
Authorization: `Bearer ${JWT}`
},
body: formData,
});
const response = await request.json();
console.log(response);
} catch (error) {
console.log(error);
}
}
Common File Recipes
Below are some common recipes for uploading a file.
Blob
Usually you can pass a Blob directly into the request but to help guarantee success we recommend passing it into a File
object.
import { PinataSDK } from "pinata";
const pinata = new PinataSDK({
pinataJwt: process.env.PINATA_JWT!,
pinataGateway: "example-gateway.mypinata.cloud",
});
const text = "Hello World!";
const blob = new Blob([text], { type: "text/plain" });
const file = new File(["hello world!"], "hello.txt", { type: "text/plain" })
const upload = await pinata.upload.file(file)
JSON
Pinata makes it easy to upload JSON objects using the json method.
import { PinataSDK } from "pinata";
const pinata = new PinataSDK({
pinataJwt: process.env.PINATA_JWT!,
pinataGateway: "example-gateway.mypinata.cloud",
});
const upload = await pinata.upload.json({
id: 2,
name: "Bob Smith",
email: "[email protected]",
age: 34,
isActive: false,
roles: ["user"]
})
Local Files
If you need to upload files from a local file source you can use fs
to feed a file into a blob
, then turn that blob
into a File
.
const { PinataSDK } = require("pinata")
const fs = require("fs")
const { Blob } = require("buffer")
const pinata = new PinataSDK({
pinataJwt: process.env.PINATA_JWT!,
pinataGateway: "example-gateway.mypinata.cloud"
})
const blob = new Blob([fs.readFileSync("./hello-world.txt")]);
const file = new File([blob], "hello-world.txt", { type: "text/plain"})
const upload = await pinata.upload.file(file);
URL
To upload a file from an external URL you can stream the contents into an arrayBuffer
, which then gets passed into a new Blob
that can then be uploaded to Pinata. This has been abstracted in the SDK using the url method.
import { PinataSDK } from "pinata";
const pinata = new PinataSDK({
pinataJwt: process.env.PINATA_JWT!,
pinataGateway: "example-gateway.mypinata.cloud",
});
const upload = await pinata.upload.url("https://i.imgur.com/u4mGk5b.gif")
base64
To upload a file in base64 simply turn the contents into a buffer
that is passed into a Blob
. Alternatively you can use the SDK for this as well using the base64 method.
import { PinataSDK } from "pinata";
const pinata = new PinataSDK({
pinataJwt: process.env.PINATA_JWT!,
pinataGateway: "example-gateway.mypinata.cloud",
});
const upload = await pinata.upload.base64("SGVsbG8gV29ybGQh")
Folders
The SDK can accept an array of files using the fileArray method. Folders can also be uploaded via the API by creating an array of files and mapping over them to add them to the form data. This is different then having a single file
entry and having multiple files for that one entry, which does not work.
We also have other tools like the Pinata CLI or Next.js Starter which can be used to upload using API Keys!
Web App
If you’re non-technical, you can use Pinata App to upload files, perfect if you just want to get started with NFTs and IPFS! It’s as simple as clicking the “Upload” button in the top right corner of the files page. Select your file, give it a name, then upload. Once it’s complete you’ll see it listed in the files page.
Start uploading by signing up for a free account!