Skip to content

Dossiers

Les dossiers organisent vos fichiers téléversés dans le tableau de bord. Ils ne contiennent que des métadonnées par défaut — les fichiers gardent leurs propres CID et ne sont pas déplacés sur IPFS — mais vous pouvez aussi créer un instantané d'un dossier pour le matérialiser en un véritable répertoire UnixFS et obtenir un seul CID pour l'ensemble.

Quand créer un instantané de dossier

Un instantané de dossier est un unique CID de répertoire IPFS qui contient tous les fichiers du dossier, adressables par nom. Il vous permet de :

  • Partager le dossier entier via une seule URL : https://ipfs.ninja/ipfs/{dirCid}/
  • Résoudre https://ipfs.ninja/ipfs/{dirCid}/photo.jpg (ou tout autre gateway) directement
  • Déposer le CID dans un contenthash ENS pour héberger un site statique
  • L'utiliser comme CID de base d'une collection de NFT afin que chaque token référence ipfs://{dirCid}/<id>.json
  • Épingler le répertoire ailleurs — chaque gateway IPFS au monde sait résoudre un CID de répertoire UnixFS

Les instantanés sont adressés par contenu : un contenu de dossier identique produit toujours le même CID. Recréer un instantané d'un dossier que vous n'avez pas modifié renvoie le même CID que précédemment. Ajouter/supprimer/renommer un fichier produit un nouveau CID ; le CID précédent reste épinglé et résoluble tant que vous ne supprimez pas ses fichiers.

Créer un dossier

POST /folders

ParamètreTypeRequisDescription
namestringOuiNom d'affichage.
parentFolderIdstring | nullNonID du dossier parent pour les dossiers imbriqués. Omettre pour un dossier de premier niveau.

Exemple

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" }'

Renvoie :

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

Les dossiers nouvellement créés n'ont pas d'instantané. Le champ latestSnapshot apparaît sur le dossier une fois que vous appelez POST /folders/{id}/snapshot (voir ci-dessous), et sur les réponses ultérieures de GET /folders.

Lister les dossiers

GET /folders

Renvoie tous les dossiers de votre compte, de premier niveau et imbriqués, avec le CID du dernier instantané pour chacun (le cas échéant).

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

fileCount reflète le contenu actuel du dossier ; latestSnapshot.fileCount reflète le contenu au moment du dernier instantané. S'ils diffèrent, le CID de l'instantané se résout toujours mais est obsolète — recréez un instantané pour le rafraîchir.

Déplacer un fichier dans un dossier

PUT /files/{cid}/move

ParamètreTypeRequisDescription
folderIdstring | nullOuiID du dossier cible, ou null pour déplacer le fichier vers la racine.
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-…" }'

Créer un instantané d'un dossier (obtenir un CID de répertoire UnixFS)

POST /folders/{folderId}/snapshot

Matérialise le dossier sous forme d'un véritable répertoire UnixFS sur le cluster IPFS et épingle le résultat. Renvoie un seul CID pour l'ensemble du dossier. Les noms des enfants proviennent du fileName de chaque fichier ; les doublons sont automatiquement dédupliqués.

Aucun corps de requête n'est nécessaire ; le paramètre de chemin identifie le dossier.

Exemple

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

Renvoie :

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

Le CID est également persisté sur la ligne du dossier, de sorte que les appels ultérieurs à GET /folders le renvoient sous forme de latestSnapshot.cid sans nécessiter un nouvel instantané.

Résoudre un instantané

Une fois qu'un instantané est épinglé, le CID de répertoire se résout via n'importe quel gateway IPFS. Le modèle d'URL le plus simple :

https://ipfs.ninja/ipfs/{dirCid}/         → listing du répertoire
https://ipfs.ninja/ipfs/{dirCid}/photo.jpg → ce fichier précis

Le cluster épingle de manière récursive, donc les enfants sont eux aussi résolubles — même si vous supprimez plus tard le fichier original de votre compte, la copie de l'instantané survit car il s'agit d'un épinglage distinct qui parcourt récursivement le répertoire.

Recréer un instantané

Recréer un instantané d'un dossier inchangé renvoie le même CID — les CID de répertoire sont adressés par contenu, donc un contenu identique produit toujours le même hash, et l'appel d'épinglage du cluster reconnaît le doublon et devient un no-op de son côté.

Remarque : le chemin d'instantané lui-même n'est pas gratuit même quand le résultat est le même CID. Chaque appel relit les octets de chaque fichier depuis IPFS et les retéléverse en multipart vers l'endpoint /add du cluster — c'est là que se produit l'enveloppement dans le répertoire. Pour des dossiers classiques (≤100 petits fichiers), cela reste rapide (quelques secondes) ; pour de très grands dossiers, préférez n'appeler l'instantané que lorsque le contenu a réellement changé.

Appeler l'instantané après avoir ajouté ou supprimé des fichiers produit un CID différent ; le précédent continue de se résoudre tant que vous ne supprimez pas ses fichiers sous-jacents.

Limites

  • Le dossier doit contenir au moins un fichier. Les dossiers vides renvoient 400 — folder is empty.
  • Les caractères des noms de fichiers sont encodés en URL dans le téléversement multipart accepté par Kubo ; les URL de gateway peuvent nécessiter un encodage pourcent pour les espaces ou les caractères non-ASCII dans vos noms de fichiers.
  • Les instantanés comptent dans le total d'épinglages de votre plan une seule fois par CID unique — les blocs de fichiers sont dédupliqués, donc l'instantané ajoute surtout un petit nœud de répertoire au-dessus de fichiers que vous épinglez déjà.

Mettre à jour un dossier

PUT /folders/{folderId}

ParamètreTypeRequisDescription
namestringNonNouveau nom d'affichage.
parentFolderIdstring | nullNonChange le dossier parent. null déplace le dossier vers la racine.

Supprimer un dossier

DELETE /folders/{folderId}

Supprime le dossier et se propage de manière récursive à travers tous les fichiers et sous-dossiers qu'il contient. Soumis à la même protection de sécurité de CID partagé que les suppressions de fichiers individuelles — si d'autres utilisateurs épinglent toujours un CID que vous avez téléversé, votre désépinglage ne le supprime pas pour eux.

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

Configurer CORS S3 pour un dossier / bucket

Les dossiers exposés via l'API compatible S3 agissent comme des buckets. Si vous pilotez cette API depuis du JavaScript navigateur, vous avez besoin de règles CORS sur le bucket pour que les preflights du navigateur passent. Deux surfaces équivalentes écrivent dans le même magasin :

  • PUT /folders/{folderId}/cors — cet endpoint REST, authentifié par JWT (utilisé par le tableau de bord)
  • Sous-ressource S3 PUT /{bucket}?cors — authentifiée par SigV4 (utilisée par les SDK AWS, voir s3-compatibility.md)

Le PUT sur cet endpoint s'approprie également le nom du dossier comme bucket unique au niveau mondial s'il n'a pas encore été revendiqué.

PUT /folders/{folderId}/cors

Définit les règles CORS pour le bucket S3 du dossier. Jusqu'à 5 règles par bucket, 64 Ko au total.

ParamètreTypeRequisDescription
rulesCorsRule[]OuiTableau de règles CORS au format AWS (voir ci-dessous). Non vide.
bucketNamestringNonNom de bucket S3 explicite. Par défaut, le nom d'affichage du dossier. Si le nom souhaité est déjà revendiqué au niveau mondial, indiquez une alternative ici.

Chaque CorsRule :

ChampTypeRequisDescription
AllowedOriginsstring[]OuiOrigines autorisées à envoyer des requêtes. Prend en charge les jokers (https://*.myapp.com). Utilisez * pour toute origine.
AllowedMethodsstring[]OuiUne ou plusieurs valeurs parmi GET, HEAD, PUT, POST, DELETE.
AllowedHeadersstring[]NonEn-têtes que les navigateurs peuvent inclure dans les requêtes. Par défaut : aucun. Utilisez ["*"] pour tout autoriser (recommandé pour le SDK AWS v3, qui envoie Authorization, x-amz-*, etc.).
ExposeHeadersstring[]NonEn-têtes de réponse rendus lisibles au JavaScript du navigateur. Incluez ETag et x-amz-meta-cid si votre application a besoin du CID renvoyé.
MaxAgeSecondsnumberNonDurée pendant laquelle les navigateurs mettent en cache le preflight. 0-86400. Par défaut 3600.
IDstringNonLibellé libre pour la règle.

Exemple de requête

bash
curl -X PUT https://api.ipfs.ninja/folders/17f6dfd8-519c-4d0e-8f3a-5988a1d34ef2/cors \
  -H "Authorization: Bearer $COGNITO_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "rules": [{
      "AllowedOrigins": ["https://myapp.com", "http://localhost:3000"],
      "AllowedMethods": ["GET", "HEAD", "PUT", "POST", "DELETE"],
      "AllowedHeaders": ["*"],
      "ExposeHeaders": ["ETag", "x-amz-meta-cid", "x-amz-request-id"],
      "MaxAgeSeconds": 3600
    }]
  }'

Réponse 200 OK

json
{ "success": true, "rules": [ { "AllowedOrigins": ["https://myapp.com", "http://localhost:3000"], "AllowedMethods": ["GET", "HEAD", "PUT", "POST", "DELETE"], "AllowedHeaders": ["*"], "ExposeHeaders": ["ETag", "x-amz-meta-cid", "x-amz-request-id"], "MaxAgeSeconds": 3600 } ] }

GET /folders/{folderId}/cors

Renvoie les règles CORS actuelles ainsi que le nom du bucket (s'il a été revendiqué).

json
{
  "rules": [  ],
  "bucketName": "my-project"
}

DELETE /folders/{folderId}/cors

Supprime toutes les règles CORS. Les preflights navigateur contre le bucket échoueront par défaut jusqu'à ce que de nouvelles règles soient définies.

Alternative via le tableau de bord

Sur la page Fichiers, le menu d'actions de chaque dossier propose une entrée S3 CORS qui ouvre un éditeur basé sur un formulaire. Même magasin sous-jacent que cet endpoint REST et que PutBucketCors via l'API S3.