Upload Resource
Uploads an asset (image, video, document, …) to your project’s storage. The endpoint supports two upload modes: simple upload for files up to 400 MB, and chunked upload for larger files or unreliable networks.
Endpoint
curl -X POST https://api.contentisland.net/api/1.0/resource/upload \--header 'Authorization: Bearer YOUR_WRITE_TOKEN' \--form 'file=@/path/to/your-asset.png'The request must be multipart/form-data. The field name and the optional X-Chunk-Upload header determine which mode is used.
Simple upload (≤ 400 MB)
Use this mode for any file up to 400 MB. The whole file travels in a single request.
| Field | Required | Description |
|---|---|---|
file | yes | The binary contents of the asset (multipart field). |
Example
curl -X POST https://api.contentisland.net/api/1.0/resource/upload \--header 'Authorization: Bearer YOUR_WRITE_TOKEN' \--form 'file=@/path/to/cover-image.png'Response
201 Created:
interface UploadedResource { name: string; // the final file name in storage (prefixed and sanitized) url: string; // public URL of the uploaded asset}{ "name": "ab12cd34-cover-image.png", "url": "https://storage.contentisland.net/your-project/ab12cd34-cover-image.png"}Chunked upload (large files or resumable uploads)
For files larger than 400 MB, or whenever you need a resumable upload, split the file into smaller chunks (each one still must be ≤ 400 MB) and send one request per chunk to the same endpoint, setting the header X-Chunk-Upload: true.
| Field | Required | Description |
|---|---|---|
chunk | yes | Binary contents of this chunk (multipart field — not file). |
chunkOptions | yes | JSON string with the metadata of the chunk. See the ChunkOptions interface below. |
Required header: X-Chunk-Upload: true.
interface ChunkOptions { chunkIndex: number; // 0-based index of this chunk chunkSize: number; // size of this chunk, in bytes totalChunks: number; // total number of chunks for the whole file uploadId?: string; // returned by the first chunk; resend it for every subsequent chunk multiPartUpload?: { // returned by the first chunk; resend it for every subsequent chunk Parts: { ETag: string; PartNumber: number }[]; }; filePrefix?: string; // returned by the first chunk; resend it for every subsequent chunk}The flow
- First chunk (
chunkIndex: 0): omituploadId,multiPartUploadandfilePrefix. The server initializes the multipart upload and returns those three fields. - Intermediate chunks: copy
uploadId,multiPartUploadandfilePrefixfrom the previous response into the nextchunkOptions. The server keeps appending parts and returns the updated values. - Last chunk (
chunkIndex + 1 === totalChunks): the server finalizes the upload automatically and the response is the final{ name, url }object — there is no separate finalize endpoint to call.
Example — first chunk
curl -X POST https://api.contentisland.net/api/1.0/resource/upload \--header 'Authorization: Bearer YOUR_WRITE_TOKEN' \--header 'X-Chunk-Upload: true' \--form 'chunkOptions={"chunkIndex":0,"chunkSize":5242880,"totalChunks":4}' \--form 'chunk=@/path/to/part-0.bin'Response (chunk in progress):
{ "uploadId": "abcd1234EXAMPLEUPLOADID", "multiPartUpload": { "Parts": [{ "ETag": "\"e1d2c3...\"", "PartNumber": 1 }] }, "filePrefix": "ab12cd34"}Example — subsequent chunk
Reuse the values returned by the previous response:
curl -X POST https://api.contentisland.net/api/1.0/resource/upload \--header 'Authorization: Bearer YOUR_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=@/path/to/part-1.bin'Final chunk response
When you send the last chunk (chunkIndex + 1 === totalChunks), the server completes the multipart upload and replies with the same { name, url } shape as the simple upload.
Status Codes
| Code | Description |
|---|---|
| 201 | The chunk (or the whole file) was processed successfully. Body shape depends on whether this is the final chunk ({ name, url }) or not (chunk-progress object). |
| 400 | Invalid request. Most commonly: the project’s organization does not have storage configured, or the multipart payload is malformed. |
| 401 | Unauthorized. The token is missing, malformed or expired. |
| 403 | Forbidden. The token does not have write permissions — use a Write Token. |
| 500 | Internal server error. An error occurred while processing the request. |