Upload an image once, then transform it on the fly via URL. This page documents exactly what POST /upload returns so you know which field to store and what each one means.
Request
POST https://<subdomain>.viucraft.com/upload
X-API-Key: vc_live_...
Content-Type: multipart/form-data
| Field | Required | Description |
|---|---|---|
image | yes | The image file. The field may also be named file. |
folder | no | Virtual folder path to organize the image (defaults to /). |
POST /api/upload is an accepted alias for the same endpoint.
Success — 201 Created
{
"image_id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://<subdomain>.viucraft.com/<image_id>.png",
"filename": "original-name.png",
"folder": "/",
"metadata": {
"width": 1200,
"height": 800,
"format": "png",
"file_size": 528421,
"color_space": "srgb",
"has_alpha": false
},
"created_at": "2026-06-16T09:44:35+00:00",
"storage": { "used": 235748582, "limit": 21474836480, "used_percent": 1.1 }
}
| Field | Type | Meaning |
|---|---|---|
image_id | string (UUID) | The permanent, canonical handle for this image. Store this. Every delivery and management URL is built from it. |
url | string | A ready-to-use canonical URL for the original image (already includes the mandatory extension). |
filename | string | The original upload name. Not stable, not unique — never key on it (see below). |
folder | string | The virtual folder the image was stored in. |
metadata.width / height | integer | Pixel dimensions of the source image. |
metadata.format | string | Source format (png, jpeg, webp, …). Combine with image_id to build the mandatory extension. |
metadata.file_size | integer | Stored size in bytes. |
metadata.color_space | string | e.g. srgb. |
metadata.has_alpha | boolean | Whether the image has an alpha channel. |
created_at | string (ISO-8601) | Upload timestamp. |
storage.used / limit | integer | Account storage usage and quota, in bytes. |
storage.used_percent | number | Convenience percentage of quota used. |
image_id vs filename — the one thing that must be clear
image_idis a UUID assigned by VIUCraft. It is permanent and globally unique. It is the only correct handle to persist in your database and to build URLs from.filenameis just the name of the file you uploaded. Two uploads namedlogo.pngproduce two different images with the samefilenamebut differentimage_ids. Treatfilenameas a display label only.
Duplicate upload — 200 OK
If you upload an image that is byte-identical to one you already have, VIUCraft does not create a second copy. Instead you get 200 OK (not 201) with the existing image and a duplicate flag:
{
"image_id": "550e8400-e29b-41d4-a716-446655440000",
"duplicate": true,
"message": "This image already exists.",
"url": "https://<subdomain>.viucraft.com/<image_id>.png",
"filename": "original-name.png",
"folder": "/",
"metadata": { "...": "..." },
"created_at": "2026-06-16T09:44:35+00:00"
}
Branch on the HTTP status (201 = newly stored, 200 = duplicate) or on the duplicate: true field. Either way, the returned image_id is the one to use.
Next steps
- Build delivery and transform URLs: Delivery & Transform URL Grammar
- Understand which host to use: Tenancy & URL Bases
- Full endpoint list: API Endpoint Map