Skip to main content

Upload Storefront Media

Host a file for a storefront (Creator page) and return a URL. The saved draft is not changed — PATCH the returned file_url into header, settings, or a widget.

The path is nested under the storefront UUID. A missing storefront is 404 before the file is hosted.

The body is multipart/form-data, not JSON. Use curl -F (or equivalent) and do not send Content-Type: application/json — the client must set the multipart boundary.

Skip this endpoint when the URL is already a public http:// or https:// link. Storefront PATCHes store that URL as given; they do not fetch and rehost it the way product image_url does.

type=image is a photo or a video. Raster stills come back with a .webp file_url — use the returned value, not the original extension. Video bytes return type=video; PATCH that file_url into header.photo.video_src_url (or a widget video_src_url), not src_url.

type=file returns a private locator for config.file, not a public download. PATCH config.file = { name, url, external: false }. Do not GET url. There is no download_url (unlike product files).

There is no preview_url.

This endpoint also allows 60 uploads per 60 seconds per store, in addition to the API-wide 100 requests per 60 seconds. The 60-upload budget is shared with Upload Product Media and completing an upload. See Rate limiting.

Request​

POST /storefronts/{id}/media

Path Parameters​

ParameterTypeRequiredDescription
idstringYesStorefront UUID

Request Body​

multipart/form-data. file and type are required; there is no default for type. Size is limited by the store's upload limit (default 100 MB).

ParameterTypeRequiredDescription
filefileYesThe file to host.
typestringYesimage or file. image hosts a photo or video. file hosts a private locator for config.file.

Example Requests​

Host a PNG as type=image. Raster stills come back .webp; the response file_url ends in .webp even when name keeps the original filename:

curl -X POST "https://cart.easy.tools/api/v1/storefronts/b10f5980-d653-4494-ad1c-6a9d68c96d19/media" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-F "type=image" \
-F "file=@storefront-upload.png"

Host a PDF as type=file:

curl -X POST "https://cart.easy.tools/api/v1/storefronts/b10f5980-d653-4494-ad1c-6a9d68c96d19/media" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-F "type=file" \
-F "file=@storefront-upload.pdf"

Response​

Success Response (201)​

Returns the hosted file. name is the original filename. type is detected from the file contents (image, video, or file) and can differ from the request type.

PNG uploaded with type=image:

{
"name": "storefront-upload.png",
"file_url": "https://cdn.example.com/storefront-media/4yTMGS7pzSNHGW68Q97zpBNR0z0cVHJg.webp",
"type": "image"
}

PDF uploaded with type=file:

{
"name": "storefront-upload.pdf",
"file_url": "https://cdn.example.com/storefront-files/ZwK3vCSQZDImaBsXu1qdXQ5c61Nc6A4o.pdf",
"type": "file"
}

Response Fields​

See Media Upload Object.

Error Responses​

Bad Request (400)​

Returned when {id} is not a UUID.

{
"message": "Invalid storefront ID"
}

Not Found Error (404)​

Returned when the UUID does not exist, belongs to another store, or points at a deleted storefront. The storefront is checked before the file is hosted.

{
"message": "Storefront not found"
}

Validation Error (422 Unprocessable Entity)​

Returned when file or type is missing, type is not image or file, the file is over the store's upload limit, the file is HEIC/HEIF or AVIF, or type=image is used with bytes that are not an image or a video.

{
"message": "HEIC/HEIF is not supported. Please convert to JPG or PNG before uploading.",
"errors": {
"file": [
"HEIC/HEIF is not supported. Please convert to JPG or PNG before uploading."
]
}
}

Unauthorized (401)​

{
"message": "Unauthenticated."
}

Forbidden (403)​

Returned when your API key has not been granted access to the requested store.

{
"message": "You do not have API access to the requested store."
}

Too Many Requests (429)​

Returned when you exceed the API-wide rate limit or the shared 60 uploads per 60 seconds. The Retry-After response header gives the number of seconds to wait.

{
"message": "Too many requests. Please retry after 60 seconds."
}