Upload an asset from a URL
Have Kalpana fetch a public image and store it as an asset.
POST /api/assets/from-urlRequires assets:create. Returns 201 with the asset, including its id.
| Field | Required | Description |
|---|---|---|
workspaceId | Yes | Workspace id or slug. |
url | Yes | A publicly reachable image URL. A value that is not a URL returns 400. |
filename | No | Display name. Defaults to the last segment of the URL path, or asset- and the first 8 characters of the content hash when the path has none. |
curl --request POST "https://app.kalpana.one/api/assets/from-url" \
--header "x-api-key: $KALPANA_API_KEY" \
--header "content-type: application/json" \
--data '{"workspaceId":"acme","url":"https://example.com/products/blue-shirt.jpg"}'Response
{
"id": "0b0f5a3e-5b1c-4d65-9a5e-3f7d2f2f6c11",
"workspaceId": "ws_123",
"contentHash": "…",
"storageKey": "…",
"filename": "blue-shirt.jpg",
"contentType": "image/jpeg",
"sizeBytes": 184233,
"meta": { "width": 1080, "height": 1080 },
"uploadedBy": "user_123",
"status": "ready",
"createdAt": "2026-09-01T10:00:00.000Z",
"updatedAt": "2026-09-01T10:00:00.000Z",
"url": "https://cdn.example/temporary-url"
}The top-level url is a temporary link to the stored copy, not the URL you sent. contentHash is the SHA-256 of the stored bytes, worked out by the server.
Limits
- 5 MB per image. A file larger than 5 MB is refused while it downloads, with
400andThis file is too large. Images can be at most 5 MB.Images are stored as they arrive, without re-encoding. - Domain whitelist. The
urlhost must be on the workspace's domain whitelist. Subdomains match, soexample.comalso allowscdn.example.com. By default the whitelist holdskalpana.one,cdn.kalpana.one,bria.ai,temp.bria.ai, andcdn.shopify.com. An admin adds more under Workspace Settings → Domain Whitelisting. A host that is not listed returns400withDomain "<host>" is not whitelisted. Please add it to Domain Whitelisting in Workspace Settings. - Public hosts only. Only
httpandhttpsURLs that resolve to public addresses are accepted. Private, loopback, and link-local addresses are rejected. - Redirects. At most 3 redirects are followed; more return
400withToo many redirects.Only the first URL is checked against the whitelist; each redirect target must still be a public host. - Timeout. The fetch times out after 15 seconds.
Behaviour
The response's content-type must be PNG, JPEG, WebP, GIF, AVIF or BMP, and the bytes must decode as an image. The server converts AVIF, which the renderer cannot read, to PNG; other formats are stored unchanged. It de-duplicates by content hash. If the same image already exists in the workspace, the existing asset is returned, renamed when you send a filename. A URL that cannot be fetched returns 400 with Could not fetch this URL. A response that is not a supported image returns 400 with URL did not return a supported image type.
If the file is not publicly reachable or its host cannot be whitelisted, use Upload an asset to send the bytes directly.
Updated 4 Nov 2026