Prerequisites
- An API key with
content_editoraccess or higher — see Create an API key - A website — see the Quickstart
Kinds and limits
Upload SVG as an
image. It is checked at finalize: scripts, event handlers, foreignObject, DTD entities, and external references are rejected with the reason, and an accepted SVG gets a rasterized PNG previewUrl that agents and the favicon fallback use. See Assets.
image assets get responsive variants and dimension metadata on the CDN. file assets are delivered as-is. Font, Lottie, and Rive uploads can use mimeType: "application/octet-stream"; Cactal normalizes it from the filename extension. Legacy font MIME aliases are also stored as the canonical font/* type.
1
Begin the upload
POST /v1/websiteAssets registers the asset as pending and returns a presigned upload URL. Include a one-line description and, for images, a category (logo, icon, photo, illustration, screenshot, graphic, background, or other) so the asset can be found later by search instead of by filename. Both are optional and editable afterwards.Begin an upload
Response
byteSize must match the exact size of the bytes you upload. The upload URL expires 900 seconds (15 minutes) after issue; begin again for a fresh URL.2
PUT the bytes to the presigned URL
Send the raw bytes with No
PUT to upload.url, including every header from upload.headers. The signature binds the content type and length, so different values fail.Authorization header is needed here — the signature in the URL authorizes this single upload.3
Finalize the asset
POST /v1/websiteAssets/{assetId}/finalize verifies the uploaded object and flips the asset to ready. For images, Cactal also records the intrinsic width and height. A PNG, JPEG, WebP, GIF, AVIF, or BMP image finalized without a description gets one, plus a category, written in the background, within a monthly allowance per organization.Finalize
Response
4
Use the asset
Reference the asset id from CMS The favicon changes immediately on every host and does not require a source lease or publish. Send
image, gallery, and file fields when you create or update items:Attach to a CMS item
image takes one value, gallery takes an array of up to 25, file takes one. Image values also accept a bare asset-id string. On reads, image fields hydrate into objects with url, originalUrl, srcSet, and variants served from the CDN; file fields hydrate with a url, filename, mimeType, and byteSize.In source code, read those hydrated URLs from your page’s CMS queries instead of hard-coding asset ids.To use a ready PNG, SVG, or ICO image as the website favicon, set its asset id directly (an SVG favicon also links its PNG preview for browsers that ignore SVG icons):Set the website favicon
{"assetId":null} to clear it and restore the Cactal fallback.5
Find, update, and manage
Search the library instead of paging through it:Fix a description, category, or filename at any time:
Find the hero photo
You should see your asset in
items with its description, category, and stable CDN url. Add type=image|video|audio|font|document to narrow by the broad MIME family, for example type=video for every clip regardless of container; it combines with kind, category, and search. List rows are compact; GET /v1/websiteAssets/{assetId} returns the full delivery shape plus status (pending or ready).Update an asset
DELETE /v1/websiteAssets/{assetId} archives the asset ({ "deleted": true }); it disappears from lists and stops resolving in CMS reads.Import from a public URL
When the file already lives on the public web, skip the three-step upload.POST /v1/websiteAssets/import fetches up to ten URLs server-side and returns ready assets in one call:
assets, each the same shape as a finalized upload plus sourceUrl, and errors for items that failed with a type of invalid_url, non_public_address, unreachable, too_large, unsupported_type, signature_expired (a signed link, such as a Meta CDN URL, that has already expired; read the page again for a fresh one), or rights_reserved (a photo on a review platform such as Yelp, Tripadvisor, or Google Maps place photos, owned by whoever posted it). Each item takes the same optional description and image category as an upload. Import is for media only: images, fonts, PDF, audio, video, dotLottie, and Rive. Text, data, documents, and archives are refused, images, fonts, and PDFs must parse as what they claim, and hosts that resolve to private or reserved addresses are rejected. Items are fetched one at a time and the upload kind and MIME rules apply. Each download is capped at 31,457,280 bytes (30 MiB) because the file is buffered in memory before it is stored; larger files, such as most hero videos, must go through the three-step upload, which accepts up to the kind’s limit. Import only files you have the right to use.
Troubleshooting
Next steps
- Manage CMS content to build items around your assets
- Assets concepts for CDN delivery and responsive image variants