Storefront assets
Business-scoped asset surface for storefront media: upload, list, inspect, and delete CDN-hosted files (images, videos, 3D models, fonts, PDFs). The CLI's `cimplify assets` wraps this.
These endpoints back cimplify assets. They're business-scoped (auth via your dk_live_… key) and only ever surface public, confirmed uploads. The customer-runtime path (Uploads) is a separate surface and never appears here.
The flow:
POST /v1/businesses/{business_id}/assets/init: reserve an upload slot, get a presigned PUT URL.- PUT the bytes directly to the presigned URL.
POST /v1/businesses/{business_id}/assets/confirm: finalise; returns the canonical public URL.GET /v1/businesses/{business_id}/assets: list the business's confirmed storefront assets.GET /v1/businesses/{business_id}/assets/{upload_id}: fetch one.DELETE /v1/businesses/{business_id}/assets/{upload_id}: delete the row and best-effort delete the blob.
What you can upload
Content-agnostic up to 50 MB per file. Any MIME accepted: image/*, video/mp4, model/gltf-binary, font/woff2, application/pdf, anything else. The platform stores raw bytes and serves them via the public CDN (storefrontassetscdn.cimplify.io). Transcoding, thumbnailing, and adaptive video streaming are not part of this surface; those live in Drive (Phase 10).
POST /v1/businesses/{business_id}/assets/init
Reserve an upload slot and get a presigned PUT URL.
Body
| Field | Type | Description |
|---|---|---|
folder | string | Top-level folder, max 200 chars. No .., \, or newlines. |
filename | string | Filename, max 500 chars. Same character rules. |
content_type | string | MIME type, max 255 chars. |
size_bytes | integer | Declared size, must be > 0 and ≤ 52,428,800 (50 MB). |
Request
curl -X POST https://api.cimplify.io/v1/businesses/biz_xxx/assets/init \
-H "Authorization: Bearer dk_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"folder": "hero",
"filename": "main.jpg",
"content_type": "image/jpeg",
"size_bytes": 482915
}'Response
{
"data": {
"upload_id": "upl_01H...",
"upload_url": "https://...presigned...",
"expires_in_secs": 600,
"public_url_preview": "https://storefrontassetscdn.cimplify.io/assets/biz_xxx/hero/main.jpg"
}
}PUT the file bytes to upload_url with the same Content-Type you declared. The URL is single-use and expires.
POST /v1/businesses/{business_id}/assets/confirm
Finalise after the PUT lands. The server verifies the blob exists and returns the canonical public URL.
Body
| Field | Type | Description |
|---|---|---|
upload_id | string | The id returned by init. |
Response
{
"id": "upl_01H...",
"url": "https://storefrontassetscdn.cimplify.io/assets/biz_xxx/hero/main.jpg",
"filename": "main.jpg",
"content_type": "image/jpeg",
"size_bytes": 482915
}GET /v1/businesses/{business_id}/assets
List the business's confirmed storefront assets. Paginated; default limit=50, max 100.
Query parameters
| Param | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | 1-indexed page number. |
limit | integer | 50 | Page size; capped at 100. |
folder | string | — | Exact-match filter on the folder_path set at init. |
mime_prefix | string | — | Prefix-match on content_type, e.g. image/, video/, model/. |
Request
curl "https://api.cimplify.io/v1/businesses/biz_xxx/assets?folder=hero&mime_prefix=video/&page=1&limit=50" \
-H "Authorization: Bearer dk_live_your_key"Response
{
"data": {
"assets": [
{
"id": "upl_01H...",
"url": "https://storefrontassetscdn.cimplify.io/assets/biz_xxx/hero/promo.mp4",
"filename": "promo.mp4",
"folder_path": "hero",
"content_type": "video/mp4",
"size_bytes": 12345678,
"created_at": "2026-05-13T12:00:00Z"
}
],
"pagination": { "page": 1, "limit": 50, "total": 1 }
}
}Ordered by created_at DESC. Customer-uploaded files (the private upload surface) are never included.
GET /v1/businesses/{business_id}/assets/{upload_id}
Fetch a single confirmed storefront asset.
curl https://api.cimplify.io/v1/businesses/biz_xxx/assets/upl_01H... \
-H "Authorization: Bearer dk_live_your_key"Returns the same row shape as one entry from the list endpoint. 404 if the id doesn't exist, doesn't belong to the business, or refers to a non-public/non-confirmed upload.
DELETE /v1/businesses/{business_id}/assets/{upload_id}
Hard-delete the row and best-effort delete the underlying blob. Idempotent: 204 No Content whether or not the row existed.
curl -X DELETE https://api.cimplify.io/v1/businesses/biz_xxx/assets/upl_01H... \
-H "Authorization: Bearer dk_live_your_key"The DB delete is the consistency point; the API stops returning the asset immediately. The blob delete is best-effort; an object-storage failure leaves an orphan blob (storage cost only, not user-visible). A future Drive Phase 1 sweeper reclaims orphans.
Errors
400 VALIDATION_ERROR:folder/filename/content_typeviolates the length/character rules, orsize_bytesexceeds 50 MB.404 NOT_FOUND: unknownupload_id, wrong business, or the upload isn't a confirmed public asset.
Related
cimplify assets: the CLI that wraps these endpoints.- Uploads: the customer-runtime path for files uploaded during checkout (private bucket, signed download URLs).
Uploads
Two-step presigned upload flow. `init` returns a short-lived URL the client PUTs the file bytes to directly; `confirm` finalises the upload and returns the canonical CDN URL.
Support
Customer-facing support / chat-widget API. Each session has exactly one widget conversation; the server resolves it from the session identity, so callers never have to track a `conversation_id`.