Pin File to IPFS
Upload a file to Pinata to be pinned to IPFS
curl --request POST \
--url https://api.pinata.cloud/pinning/pinFileToIPFS \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form file=readstream \
--form 'pinataMetadata={
"name": "Pinnie.json"
}' \
--form 'pinataOptions={
"cidVersion": 1
}'
{
"IpfsHash": "<string>",
"PinSize": 123,
"Timestamp": "<string>",
"isDuplicate": true
}
Guides
Usually you can pass a Blob directly into the request but to help guarantee success we recommend passing it into a File
object.
const JWT = 'YOUR_PINATA_JWT';
async function pinFileToIPFS() {
try {
const text = "Hello World!";
const blob = new Blob([text], { type: "text/plain" });
const file = new File([blob], "hello-world.txt")
const data = new FormData();
data.append("file", file);
const res = await fetch("https://api.pinata.cloud/pinning/pinFileToIPFS", {
method: "POST",
headers: {
Authorization: `Bearer ${JWT}`,
},
body: data,
});
const resData = await res.json();
console.log(resData);
} catch (error) {
console.log(error);
}
};
await pinFileToIPFS()
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.
const JWT = "YOUR_PINATA_JWT";
async function uploadByURL(url) {
try {
const urlStream = await fetch(url);
const arrayBuffer = await urlStream.arrayBuffer();
const blob = new Blob([arrayBuffer]);
const file = new File([blob], "file")
const data = new FormData();
data.append("file", file);
const upload = await fetch(
"https://api.pinata.cloud/pinning/pinFileToIPFS",
{
method: "POST",
headers: {
Authorization: `Bearer ${JWT}`,
},
body: data,
}
);
const uploadRes = await upload.json();
console.log(uploadRes);
} catch (error) {
console.log(error);
}
}
await uploadByURL("https://pocketcast.cloud/og.png");
To upload a file in base64 simply turn the contents into a buffer
that is passed into a Blob
.
const JWT = "YOUR_PINATA_JWT";
async function uploadBase64(base64String) {
try {
const buffer = Buffer.from(base64String, "base64");
const blob = new Blob([buffer]);
const file = new File([blob], "file");
const data = new FormData();
data.append("file", file);
const upload = await fetch(
"https://api.pinata.cloud/pinning/pinFileToIPFS",
{
method: "POST",
headers: {
Authorization: `Bearer ${JWT}`,
},
body: data,
},
);
const uploadRes = await upload.json();
console.log(uploadRes);
} catch (error) {
console.log(error);
}
}
await uploadBase64("SGVsbG8gZnJvbSBQaW5hdGEhIDop");
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.
import fs from "fs"
import FormData from "form-data"
import rfs from "recursive-fs"
import basePathConverter from "base-path-converter"
import got from 'got'
const pinDirectoryToPinata = async () => {
const url = `https://api.pinata.cloud/pinning/pinFileToIPFS`;
const src = "PATH_TO_FOLDER";
var status = 0;
try {
const { dirs, files } = await rfs.read(src);
let data = new FormData();
for (const file of files) {
data.append(`file`, fs.createReadStream(file), {
filepath: basePathConverter(src, file),
});
}
const response = await got(url, {
method: 'POST',
headers: {
"Authorization": "Bearer PINATA_API_JWT"
},
body: data
})
.on('uploadProgress', progress => {
console.log(progress);
});
console.log(JSON.parse(response.body));
} catch (error) {
console.log(error);
}
};
pinDirectoryToPinata()
Authorizations
Bearer authentication header of the form Bearer <token>
, where <token>
is your auth token.
Body
Response
curl --request POST \
--url https://api.pinata.cloud/pinning/pinFileToIPFS \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form file=readstream \
--form 'pinataMetadata={
"name": "Pinnie.json"
}' \
--form 'pinataOptions={
"cidVersion": 1
}'
{
"IpfsHash": "<string>",
"PinSize": 123,
"Timestamp": "<string>",
"isDuplicate": true
}