Managed Assets
Upload images, video, and audio so you can reference them by URL in edit and generation calls.
The edit and video endpoints accept public URLs, not raw bytes. If a file only exists on your device or a private server, upload it here first — the returned url is immediately usable as an image_urls entry on /v1/images/edit or as image_url on /v1/videos/generate.
Every upload gets a durable id, so you can list what you've uploaded, re-fetch a URL, and delete assets you no longer need.
Creating and deleting an asset requires the
uploads:writescope. Listing and fetching your assets require a valid API key. Grant the scope when creating or updating the key from the API Keys dashboard.
POST /v1/assets
Upload a file and receive a managed asset record with a CDN URL.
Auth: API Key (uploads:write scope)
Content-Type: multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
file |
binary | Yes | Image, video, or audio file. |
metadata |
string (JSON) |
No | An arbitrary JSON object of your own labels, stored alongside the asset. |
Size limits
| Kind | Max size |
|---|---|
Image (image/*) |
20 MB |
Video (video/*) |
50 MB |
Audio (audio/*) |
15 MB |
Response 201 Created
{
"id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"url": "https://cdn.picxstudio.com/uploads/api/portrait.jpg",
"kind": "image",
"filename": "portrait.jpg",
"content_type": "image/jpeg",
"bytes": 245120,
"metadata": { "source": "onboarding" },
"created_at": "2026-08-20T09:15:00Z"
}
The kind field is inferred from the MIME type: image, video, or audio. Files with any other content type are rejected with 400.
Upload, then edit
JavaScript SDK
import { PicX } from "picx-ai";
const picx = new PicX(process.env.PICX_API_KEY);
// 1. Upload the source image
const asset = await picx.assets.create({
file: new Blob([bytes], { type: "image/jpeg" }),
filename: "portrait.jpg",
});
// 2. Pass the URL to an edit call
const edited = await picx.images.edit({
instruction: "turn this into a naive doodle avatar",
image_urls: [asset.url],
});
console.log(edited.url);
Python SDK
import os
from picx import PicX
picx = PicX(os.environ["PICX_API_KEY"])
# 1. Upload the source image
with open("portrait.jpg", "rb") as source:
asset = picx.assets.create(file=source)
# 2. Pass the URL to an edit call
edited = picx.images.edit(
instruction="turn this into a naive doodle avatar",
image_urls=[asset.url],
)
print(edited.url)
curl
# Upload
curl -X POST https://api.picxstudio.com/v1/assets \
-H "Authorization: Bearer pxsk_your_key" \
-F "file=@portrait.jpg" \
-F 'metadata={"source":"onboarding"}'
# Use the returned URL in an edit
curl -X POST https://api.picxstudio.com/v1/images/edit \
-H "Authorization: Bearer pxsk_your_key" \
-H "Content-Type: application/json" \
-d '{"instruction":"turn this into a doodle avatar","image_urls":["https://cdn.picxstudio.com/uploads/api/portrait.jpg"]}'
Upload, then generate video
const ref = await picx.assets.create({ file: keyframeBlob, filename: "keyframe.png" });
const video = await picx.video.create({
prompt: "smooth camera push-in on this scene",
model: "seedance-2.5",
image_url: ref.url, // first-frame reference
});
List assets
curl https://api.picxstudio.com/v1/assets?kind=image&limit=10 \
-H "Authorization: Bearer pxsk_your_key"
Response:
{
"assets": [ /* AssetResponse[] */ ],
"total": 42,
"limit": 10,
"offset": 0
}
Filter by kind (image, video, audio) and paginate with limit (1–100, default 20) and offset.
Delete an asset
curl -X DELETE https://api.picxstudio.com/v1/assets/d290f1ee-6c54-4b01-90e6-d701748f0851 \
-H "Authorization: Bearer pxsk_your_key"
Deletion is soft: the CDN URL remains valid so existing generations that reference it keep working, but the asset no longer appears in your list.
If you only need a throwaway URL for one generation (no listing, no re-use), you can skip managed assets and host the file anywhere publicly accessible. Managed assets are for files you plan to reference across multiple calls or need to audit later.
FAQ
Does uploading cost credits?
No. Only generation and editing endpoints consume credits.
Can I use data URIs instead of uploading?
No. The edit and video endpoints require HTTPS URLs — data: URIs are rejected. Upload the file first, then pass the returned url.
What happens if I delete an asset that a generation references?
The CDN URL stays live. Deletion only removes the asset from your list; it does not purge the underlying object.
Do I need uploads:write to list or fetch assets?
No. Any valid API key can list and fetch your assets. Only create and delete require the uploads:write scope.