ApiframeDocs

Uploads

Upload a local image, video, or audio file to short-lived CDN storage and use the returned URL as a generation input.

POST /v2/uploads accepts a single multipart file and returns a public CDN URL you can drop into any image, video, or audio input field. Files live about 1–2 hours before they are deleted.

For media you will reuse across many jobs, use the Assets API instead — assets do not expire.

Upload a file

POST /v2/uploads

Send multipart/form-data with one file part. The API sniffs magic bytes and ignores the declared Content-Type.

Limits

KindMax sizeAllowed types
Image25 MBPNG, JPEG, WebP, GIF
Audio25 MBMP3, WAV, OGG, M4A
Video50 MBMP4, WebM, MOV

Response

Status: 201 Created

{
  "id": "3f9d2a71-58f0-4f4e-9c6b-2f1f7d0a8b34",
  "url": "https://cdn2.apiframe.ai/uploads/...",
  "kind": "audio",
  "contentType": "audio/mpeg",
  "byteSize": 245123,
  "expiresAt": "2026-08-14T16:00:00.000Z"
}

Pass url as audioUrl, start_image, reference_images, or any other media URL field. After expiresAt the file is gone.

Code examples

curl -X POST https://api.apiframe.ai/v2/uploads \
  -H "X-API-Key: afk_your_api_key_here" \
  -F "file=@./demo.mp3"
import requests

resp = requests.post(
    "https://api.apiframe.ai/v2/uploads",
    headers={"X-API-Key": "afk_your_api_key_here"},
    files={"file": open("demo.mp3", "rb")},
)
url = resp.json()["url"]
import { readFile } from "node:fs/promises";

const form = new FormData();
form.append("file", new Blob([await readFile("demo.mp3")]), "demo.mp3");

const resp = await fetch("https://api.apiframe.ai/v2/uploads", {
  method: "POST",
  headers: { "X-API-Key": "afk_your_api_key_here" },
  body: form,
});
const { url } = await resp.json();

On this page