Saltearse al contenido

Subir Recurso

Sube un recurso (imagen, vídeo, documento, …) al almacenamiento de tu proyecto. El endpoint admite dos modos de subida: subida simple para ficheros de hasta 400 MB, y subida por chunks para ficheros más grandes o redes poco fiables.

Endpoint

shell
curl -X POST https://api.contentisland.net/api/1.0/resource/upload \
--header 'Authorization: Bearer TU_WRITE_TOKEN' \
--form 'file=@/ruta/a/tu-recurso.png'

La petición debe ser multipart/form-data. El nombre del campo y la cabecera opcional X-Chunk-Upload determinan qué modo se usa.

Subida simple (≤ 400 MB)

Usa este modo para cualquier fichero de hasta 400 MB. El fichero entero viaja en una única petición.

CampoObligatorioDescripción
fileContenido binario del recurso (campo multipart).

Ejemplo

shell
curl -X POST https://api.contentisland.net/api/1.0/resource/upload \
--header 'Authorization: Bearer TU_WRITE_TOKEN' \
--form 'file=@/ruta/a/portada.png'

Respuesta

201 Created:

interface UploadedResource {
name: string; // nombre final del fichero en almacenamiento (con prefijo y saneado)
url: string; // URL pública del recurso subido
}
{
"name": "ab12cd34-portada.png",
"url": "https://storage.contentisland.net/tu-proyecto/ab12cd34-portada.png"
}

Subida por chunks (ficheros grandes o subidas resumibles)

Para ficheros mayores de 400 MB, o siempre que necesites una subida resumible, divide el fichero en chunks más pequeños (cada uno sigue debiendo ser ≤ 400 MB) y envía una petición por chunk al mismo endpoint, con la cabecera X-Chunk-Upload: true.

CampoObligatorioDescripción
chunkContenido binario de este chunk (campo multipart — no file).
chunkOptionsString JSON con los metadatos del chunk. Ver la interface ChunkOptions más abajo.

Cabecera obligatoria: X-Chunk-Upload: true.

interface ChunkOptions {
chunkIndex: number; // índice 0-based de este chunk
chunkSize: number; // tamaño de este chunk, en bytes
totalChunks: number; // número total de chunks del fichero completo
uploadId?: string; // devuelto por el primer chunk; reenvíalo en cada chunk posterior
multiPartUpload?: {
// devuelto por el primer chunk; reenvíalo en cada chunk posterior
Parts: { ETag: string; PartNumber: number }[];
};
filePrefix?: string; // devuelto por el primer chunk; reenvíalo en cada chunk posterior
}

Flujo

  1. Primer chunk (chunkIndex: 0): omite uploadId, multiPartUpload y filePrefix. El servidor inicializa la subida multipart y devuelve esos tres campos.
  2. Chunks intermedios: copia uploadId, multiPartUpload y filePrefix de la respuesta anterior al siguiente chunkOptions. El servidor va añadiendo partes y devuelve los valores actualizados.
  3. Último chunk (chunkIndex + 1 === totalChunks): el servidor finaliza la subida automáticamente y la respuesta es ya el objeto final { name, url }no hay endpoint separado de finalización.

Ejemplo — primer chunk

shell
curl -X POST https://api.contentisland.net/api/1.0/resource/upload \
--header 'Authorization: Bearer TU_WRITE_TOKEN' \
--header 'X-Chunk-Upload: true' \
--form 'chunkOptions={"chunkIndex":0,"chunkSize":5242880,"totalChunks":4}' \
--form 'chunk=@/ruta/a/parte-0.bin'

Respuesta (chunk en curso):

{
"uploadId": "abcd1234EXAMPLEUPLOADID",
"multiPartUpload": { "Parts": [{ "ETag": "\"e1d2c3...\"", "PartNumber": 1 }] },
"filePrefix": "ab12cd34"
}

Ejemplo — chunk siguiente

Reutiliza los valores devueltos por la respuesta anterior:

shell
curl -X POST https://api.contentisland.net/api/1.0/resource/upload \
--header 'Authorization: Bearer TU_WRITE_TOKEN' \
--header 'X-Chunk-Upload: true' \
--form 'chunkOptions={"chunkIndex":1,"chunkSize":5242880,"totalChunks":4,"uploadId":"abcd1234EXAMPLEUPLOADID","multiPartUpload":{"Parts":[{"ETag":"\"e1d2c3...\"","PartNumber":1}]},"filePrefix":"ab12cd34"}' \
--form 'chunk=@/ruta/a/parte-1.bin'

Respuesta del último chunk

Cuando envías el último chunk (chunkIndex + 1 === totalChunks), el servidor completa la subida multipart y responde con la misma forma { name, url } que la subida simple.

Códigos de estado

CódigoDescripción
201El chunk (o el fichero completo) se procesó correctamente. La forma del body depende de si es el chunk final ({ name, url }) o no (objeto de progreso del chunk).
400Petición inválida. Lo más habitual: la organización del proyecto no tiene almacenamiento configurado, o el payload multipart está malformado.
401No autorizado. El token está ausente, malformado o ha expirado.
403Prohibido. El token no tiene permisos de escritura — usa un Write Token.
500Error interno del servidor. Se produjo un error al procesar la solicitud.