Uploading Files
At the core of Pinata’s services is our IPFS APIs which allow you to upload files to either public or private IPFS. You can read more about the difference between the two here.
Let’s look at the multiple ways you can upload files!
How to Upload Files
Uploading files with Pinata is simple, whether you want to use the SDK or the API. Key things to know:
- Uploads are done through
multipart/form-data
requests - The SDK and API accept File objects per the Web API Standard for Files
- You can add additional info to your upload such as a custom name for the file, keyvalue metadata, and a target group destination for organization
Here is a simple example of how you might upload a file in Typescript
This will return the following response
id
: The ID of the file used for getting info, updating, or deletingname
: The name of the file or the provided name in theaddMetadata
methodcid
: A cryptographic hash based on the contents of the filesize
: The size of the file in bytesnumber_of_files
: The number of files in a referencemime_type
: The mime type of the uploaded filegroup_id
: The group the file was uploaded to if applicable
Metadata
When uploading a file you can add additional metadata using the name
or keyvalues
methods after the selected upload method. This can include an optional name
override or keyvalue
pairs that can be used to searching the file later on
Groups
Pinata offers Private IPFS Groups to organize your content. You can upload a file to a group by using the group
method.
Client Side Uploads
There are situations where you may need to upload a file client side instead of server side. A great example is in Next.js where there is a 4MB file size restriction for files passed through Next’s API routes. To solve this you can create a signed upload URL on the server and then pass it to the client for it to be consumed. This way your admin API key stays safe behind a server. Creating signed upload URLs can be done with either the Files SDK or the API, and you can designate how long the URL is valid for or if there is other infromation you want to include such as metadata or a group ID.
Setting up a server side API endpoint might look something like this:
Then back on the client side code, you can upload using the signed URL instead of the regular upload endpoint.
If you’re using the SDK you can use the .url()
parameter on any of the upload methods and pass in the signed upload URL there. If you are using the API you can simply make the upload request using the signed URL as the endpoint.
Upload Progress
If you happen to use the API as well as local files you can also track the progress of the upload using a library like got
. Better support for upload progress will come in later versions of the SDK!
If your file is larger than 100MB then a better approach is to follow the Resumable Upload Guide
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.
JSON
Pinata makes it easy to upload JSON objects using the json method.
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
. Due to the buffer limit in Node.js you may have issues going beyond 2GB with this approach. Using Resumable Uploads with a client side file picker will help increase this.
Support for file streams will be coming in a later version of the SDK.
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.
Folder uploads are currently only supported on Public IPFS
We also have other tools like the Pinata IPFS CLI which can be used to upload using API Keys!
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.
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.
Resumable Uploads
The upload endpoint https://uploads.pinata.cloud/v3/files
is fully TUS compatible, so it can support larger files with the ability to resume uploads. Any file upload larger than 100MB needs to be uploaded through the TUS method, or through the legacy /pinFileToIPFS endpoint. The SDK handles this automatically when you use pinata.upload.<network>.file()
by checking the file size before uploading.
At this time folder uploads must go through /pinFileToIPFS. Read the Folder Guide for more info!
If you want to take advantage of resumable uploads then we would recommend using one of the TUS clients and taking note of the following:
- Upload chunk size must be smaller than 50MB
- Instead of using the form data fields for
group_id
orkeyvalues
these can be passed directly into the upload metadata (see example below) - Headers must include the Authorization with your Pinata JWT
Here is an example of an upload to Pinata using the tus-js-client
Pin by CID
Another way you can upload content to Pinata is by transferring content that is already on IPFS. This could be CIDs that are on your own local IPFS node or another IPFS pinning service! You can do this with the “Pin by CID” button in the web app, like so:
Or you can pin by CID with the SDK using the cid method.
This will result in a request_id
and Pinata will start looking for the file. Progress can be checked by using the queue method.
All possible filters are included in the API reference below, but these are the possible “status” filters:
Filter by the status of the job in the pinning queue (see potential statuses below)
prechecking
Pinata is running preliminary validations on your pin request.searching
Pinata is actively searching for your content on the IPFS network. This may take some time if your content is isolated.retrieving
Pinata has located your content and is now in the process of retrieving it.expired
Pinata wasn’t able to find your content after a day of searching the IPFS network. Please make sure your content is hosted on the IPFS network before trying to pin again.over_free_limit
Pinning this object would put you over the free tier limit. Please add a credit card to continue pinning content.over_max_size
This object is too large of an item to pin. If you’re seeing this, please contact us for a more custom solution.invalid_object
The object you’re attempting to pin isn’t readable by IPFS nodes. Please contact us if you receive this, as we’d like to better understand what you’re attempting to pin.bad_host_node
You provided a host node that was either invalid or unreachable. Please make sure all provided host nodes are online and reachable.
Predetermining the CID
If you find yourself in a position where you want to pre-determine the CID before uploading you can use a combination of the ipfs-unixfx-importer
and blockstore-core
libraries.
Usage will just require passing in a file object and the version of the CID you want to predict. Here is an example using a local file.
Peering with Pinata
If you run IPFS infrastructure and would like to peer with Pinata’s nodes you can do so with the Kubo commands listed below. Rather than using full multiaddresses for our node IDs we use a DNS setup that is more stable and allows our infrastructure to be flexible.
If you have any issues feel free to reach out!
Web App
You can also use the Pinata App to upload files. 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!