Skip to content

Folders

Folders organise your uploaded files in the dashboard. They're metadata-only by default — files keep their own CIDs and aren't moved on IPFS — but you can also snapshot a folder to materialise it as a real UnixFS directory and get one CID for the whole thing.

When you'd snapshot a folder

A folder snapshot is a single IPFS directory CID that contains every file in the folder, addressable by name. With it you can:

  • Share the whole folder via one URL: https://ipfs.ninja/ipfs/{dirCid}/
  • Resolve https://ipfs.ninja/ipfs/{dirCid}/photo.jpg (or any other gateway) directly
  • Drop the CID into an ENS contenthash to host a static site
  • Use it as the base CID of an NFT collection so each token references ipfs://{dirCid}/<id>.json
  • Pin the directory anywhere else — every IPFS gateway in the world knows how to resolve a UnixFS dir CID

Snapshots are content-addressed: identical folder contents always produce the same CID. Re-snapshotting a folder you haven't changed returns the same CID it returned before. Adding/removing/renaming a file produces a new CID; the previous CID stays pinned and resolvable as long as you don't delete its files.

Create folder

POST /folders

ParameterTypeRequiredDescription
namestringYesDisplay name.
parentFolderIdstring | nullNoParent folder ID for nested folders. Omit for a root-level folder.

Example

bash
curl -X POST https://api.ipfs.ninja/folders \
  -H "X-Api-Key: bws_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "name": "My NFT collection" }'

Returns:

json
{
  "folderId": "1f8e2c3a-…",
  "name": "My NFT collection",
  "parentFolderId": null,
  "createdAt": 1746360000000
}

Newly-created folders have no snapshot. The latestSnapshot field shows up on the folder once you call POST /folders/{id}/snapshot (see below) and on subsequent GET /folders responses.

List folders

GET /folders

Returns every folder in your account, root-level and nested, with the last snapshot CID for each (if any).

json
[
  {
    "folderId": "1f8e2c3a-…",
    "name": "My NFT collection",
    "parentFolderId": null,
    "createdAt": 1746360000000,
    "fileCount": 42,
    "latestSnapshot": {
      "cid": "QmRZx5…",
      "takenAt": 1746421000000,
      "fileCount": 42
    }
  }
]

fileCount reflects the folder's current contents; latestSnapshot.fileCount reflects the contents at the time of the last snapshot. If they differ the snapshot CID still resolves but is stale — re-snapshot to refresh.

Move a file into a folder

PUT /files/{cid}/move

ParameterTypeRequiredDescription
folderIdstring | nullYesTarget folder ID, or null to move the file to the root.
bash
curl -X PUT https://api.ipfs.ninja/files/Qm.../move \
  -H "X-Api-Key: bws_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "folderId": "1f8e2c3a-…" }'

Snapshot a folder (get a UnixFS dir CID)

POST /folders/{folderId}/snapshot

Materialise the folder as a real UnixFS directory on the IPFS cluster and pin the result. Returns one CID for the whole folder. Names of children come from each file's fileName; duplicates are de-collided automatically.

No request body is needed; the path parameter identifies the folder.

Example

bash
curl -X POST https://api.ipfs.ninja/folders/1f8e2c3a-.../snapshot \
  -H "X-Api-Key: bws_your_api_key_here"

Returns:

json
{
  "ok": true,
  "folderId": "1f8e2c3a-…",
  "cid": "QmRZx5VgFHDsG7ECvaKkZBS4ydmkdAkDyaKyF71RYvh8",
  "fileCount": 42,
  "sizeBytes": 8421376,
  "takenAt": 1746421000000,
  "ipfsUrl": "https://ipfs.ninja/ipfs/QmRZx5.../"
}

The CID is also persisted on the folder row, so subsequent GET /folders calls return it as latestSnapshot.cid without needing another snapshot.

Resolving a snapshot

Once a snapshot is pinned, the directory CID resolves via any IPFS gateway. The simplest URL pattern:

https://ipfs.ninja/ipfs/{dirCid}/         → directory listing
https://ipfs.ninja/ipfs/{dirCid}/photo.jpg → that one file

The cluster pins recursively, so children are resolvable too — even if you later delete the original file from your account, the snapshot's copy survives because it's a separate pin recursing through the directory.

Re-snapshotting

Re-snapshotting an unchanged folder returns the same CID — directory CIDs are content-addressed, so identical contents always produce the same hash, and the cluster's pin call recognises the duplicate and is a no-op on its end.

Note: the snapshot path itself is not free even when the result is the same CID. Each call reads every file's bytes back from IPFS and reuploads them as a multipart to the cluster's /add endpoint — that's where the wrap-with-directory wrapping happens. For typical folders (≤100 small files) this still completes in a few seconds; for very large folders prefer to call snapshot only when the contents actually changed.

Calling snapshot after you've added or removed files produces a different CID; the previous one continues to resolve as long as you don't delete its underlying files.

Limits

  • The folder must contain at least one file. Empty folders return 400 — folder is empty.
  • File-name characters are URL-encoded in the multipart upload Kubo accepts; gateway URLs may need percent-encoding for spaces or non-ASCII characters in your filenames.
  • Snapshots count toward your plan's pin total exactly once per unique CID — file blocks are deduplicated, so the snapshot mostly adds a tiny directory node on top of files you already pin.

Update a folder

PUT /folders/{folderId}

ParameterTypeRequiredDescription
namestringNoNew display name.
parentFolderIdstring | nullNoRe-parent the folder. null moves it to the root.

Delete a folder

DELETE /folders/{folderId}

Deletes the folder and recursively cascades through every file and subfolder it contains. Subject to the same shared-CID safety guard as individual file deletes — if other users still pin a CID you uploaded, your unpin doesn't strip it for them.

json
{
  "deleted": true,
  "filesDeleted": 42,
  "foldersDeleted": 3
}