Skip to content

Carpetas

Las carpetas organizan tus archivos subidos en el dashboard. Por defecto son solo metadatos — los archivos conservan sus propios CIDs y no se mueven en IPFS — pero también puedes crear una instantánea (snapshot) de una carpeta para materializarla como un directorio UnixFS real y obtener un único CID para todo el conjunto.

Cuándo crear una instantánea de una carpeta

Una instantánea de carpeta es un único CID de directorio IPFS que contiene todos los archivos de la carpeta, direccionables por nombre. Con ella puedes:

  • Compartir toda la carpeta mediante una sola URL: https://ipfs.ninja/ipfs/{dirCid}/
  • Resolver https://ipfs.ninja/ipfs/{dirCid}/photo.jpg (o cualquier otro gateway) directamente
  • Colocar el CID en un contenthash de ENS para alojar un sitio estático
  • Usarlo como el CID base de una colección NFT, de modo que cada token referencie ipfs://{dirCid}/<id>.json
  • Fijar el directorio en cualquier otro lugar — todos los gateways IPFS del mundo saben resolver un CID de directorio UnixFS

Las instantáneas están direccionadas por contenido: contenidos de carpeta idénticos siempre producen el mismo CID. Volver a crear una instantánea de una carpeta que no has cambiado devuelve el mismo CID que devolvió antes. Añadir, quitar o renombrar un archivo produce un nuevo CID; el CID anterior sigue fijado y resoluble mientras no elimines sus archivos.

Crear carpeta

POST /folders

ParámetroTipoRequeridoDescripción
namestringNombre visible.
parentFolderIdstring | nullNoID de la carpeta padre para carpetas anidadas. Omítelo para una carpeta de nivel raíz.

Ejemplo

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

Devuelve:

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

Las carpetas recién creadas no tienen instantánea. El campo latestSnapshot aparece en la carpeta una vez que llamas a POST /folders/{id}/snapshot (ver abajo) y en las respuestas posteriores de GET /folders.

Listar carpetas

GET /folders

Devuelve todas las carpetas de tu cuenta, de nivel raíz y anidadas, con el CID de la última instantánea de cada una (si existe).

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

fileCount refleja el contenido actual de la carpeta; latestSnapshot.fileCount refleja el contenido en el momento de la última instantánea. Si difieren, el CID de la instantánea sigue resolviendo pero está desactualizado — vuelve a crear la instantánea para actualizarlo.

Mover un archivo a una carpeta

PUT /files/{cid}/move

ParámetroTipoRequeridoDescripción
folderIdstring | nullID de la carpeta destino, o null para mover el archivo a la raíz.
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-…" }'

Crear una instantánea de una carpeta (obtener un CID de directorio UnixFS)

POST /folders/{folderId}/snapshot

Materializa la carpeta como un directorio UnixFS real en el cluster IPFS y fija el resultado. Devuelve un único CID para toda la carpeta. Los nombres de los hijos provienen del fileName de cada archivo; los duplicados se resuelven automáticamente.

No se necesita cuerpo de solicitud; el parámetro de ruta identifica la carpeta.

Ejemplo

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

Devuelve:

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

El CID también se persiste en el registro de la carpeta, así que las siguientes llamadas a GET /folders lo devuelven como latestSnapshot.cid sin necesidad de otra instantánea.

Resolver una instantánea

Una vez fijada la instantánea, el CID de directorio resuelve a través de cualquier gateway IPFS. El patrón de URL más simple:

https://ipfs.ninja/ipfs/{dirCid}/         → listado del directorio
https://ipfs.ninja/ipfs/{dirCid}/photo.jpg → ese archivo concreto

El cluster fija de forma recursiva, así que los hijos también son resolubles — incluso si más tarde eliminas el archivo original de tu cuenta, la copia de la instantánea sobrevive porque es un pin independiente que recorre el directorio.

Volver a crear la instantánea

Volver a crear la instantánea de una carpeta sin cambios devuelve el mismo CID — los CIDs de directorio están direccionados por contenido, así que contenidos idénticos siempre producen el mismo hash, y la llamada de fijación del cluster reconoce el duplicado y no hace nada en su extremo.

Nota: la ruta de instantánea en sí no es gratuita aunque el resultado sea el mismo CID. Cada llamada lee de nuevo los bytes de cada archivo desde IPFS y los vuelve a subir como multipart al endpoint /add del cluster — ahí es donde ocurre el envoltorio de directorio. Para carpetas típicas (≤100 archivos pequeños) esto sigue completándose en pocos segundos; para carpetas muy grandes, es preferible llamar a la instantánea solo cuando el contenido realmente ha cambiado.

Llamar a la instantánea después de haber añadido o eliminado archivos produce un CID diferente; el anterior sigue resolviendo mientras no elimines sus archivos subyacentes.

Límites

  • La carpeta debe contener al menos un archivo. Las carpetas vacías devuelven 400 — folder is empty.
  • Los caracteres del nombre de archivo se codifican como URL en la subida multipart que acepta Kubo; las URLs de gateway pueden necesitar codificación porcentual para espacios o caracteres no ASCII en tus nombres de archivo.
  • Las instantáneas cuentan para el total de pines de tu plan exactamente una vez por CID único — los bloques de archivo se deduplican, así que la instantánea principalmente añade un pequeño nodo de directorio sobre archivos que ya fijas.

Actualizar una carpeta

PUT /folders/{folderId}

ParámetroTipoRequeridoDescripción
namestringNoNuevo nombre visible.
parentFolderIdstring | nullNoCambia la carpeta padre. null la mueve a la raíz.

Eliminar una carpeta

DELETE /folders/{folderId}

Elimina la carpeta y desencadena en cascada la eliminación de todos los archivos y subcarpetas que contiene. Está sujeta a la misma protección de seguridad de CID compartido que las eliminaciones de archivos individuales — si otros usuarios todavía fijan un CID que subiste, tu desfijado no lo elimina para ellos.

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

Configurar CORS de S3 para una carpeta / bucket

Las carpetas expuestas a través de la API compatible con S3 actúan como buckets. Si estás usando esa API desde JavaScript de navegador, necesitas reglas CORS en el bucket para que los preflights del navegador pasen. Dos superficies equivalentes persisten en el mismo almacén:

  • PUT /folders/{folderId}/cors — este endpoint REST, autenticado con JWT (usado por el dashboard)
  • Subrecurso S3 PUT /{bucket}?cors — autenticado con SigV4 (usado por los SDKs de AWS, ver s3-compatibility.md)

El PUT en este endpoint también reclama el nombre de la carpeta como un bucket único a nivel global si aún no ha sido reclamado.

PUT /folders/{folderId}/cors

Establece las reglas CORS para el bucket S3 de la carpeta. Hasta 5 reglas por bucket, 64 KB en total.

ParámetroTipoRequeridoDescripción
rulesCorsRule[]Arreglo de reglas CORS con forma AWS (ver abajo). No puede estar vacío.
bucketNamestringNoNombre de bucket S3 explícito. Por defecto, el nombre visible de la carpeta. Si el nombre deseado ya está reclamado a nivel global, pasa una alternativa aquí.

Cada CorsRule:

CampoTipoRequeridoDescripción
AllowedOriginsstring[]Orígenes autorizados a enviar solicitudes. Admite comodines (https://*.myapp.com). Usa * para cualquier origen.
AllowedMethodsstring[]Uno o más de GET, HEAD, PUT, POST, DELETE.
AllowedHeadersstring[]NoHeaders que los navegadores pueden incluir en las solicitudes. Por defecto: ninguno. Usa ["*"] para permitir todos (recomendado para el AWS SDK v3, que envía Authorization, x-amz-*, etc.).
ExposeHeadersstring[]NoHeaders de respuesta que se hacen legibles para el JavaScript del navegador. Incluye ETag y x-amz-meta-cid si tu app necesita el CID devuelto.
MaxAgeSecondsnumberNoCuánto tiempo almacenan en caché los navegadores el preflight. 0-86400. Por defecto 3600.
IDstringNoEtiqueta de texto libre para la regla.

Ejemplo de solicitud

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

Respuesta 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

Devuelve las reglas CORS actuales más el nombre del bucket (si ha sido reclamado).

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

DELETE /folders/{folderId}/cors

Elimina todas las reglas CORS. Los preflights del navegador contra el bucket fallarán por defecto hasta que se establezcan nuevas reglas.

Alternativa desde el dashboard

En la página Files, el menú de acciones de cada carpeta tiene una entrada S3 CORS que abre un editor basado en formulario. Mismo almacén subyacente que este endpoint REST y que PutBucketCors a través de la API S3.