Uploading Files

Upload a local image, video, or audio file and get back a public https URL you can pass to image_urls, reference_image_urls, or reference_video_urls.

Every media input in the VicSee API — image_urls, reference_image_urls, reference_video_urls, reference_audio_urls — takes a public https URL that our provider fetches on your behalf. It cannot read a file from your machine.

If your file is already reachable at a public URL, pass it directly and skip this page. If it is on disk, upload it here first.

The two steps

Uploading is two requests. This is the step most often missed: POST /api/v1/upload does not receive your file — it returns a URL you then send the bytes to.

  1. Ask for an upload URL. Tell us the content type; you get back a short-lived uploadUrl and the publicUrl the file will have.
  2. PUT the bytes to uploadUrl. The file goes straight to storage and never passes through our servers, so there is no request-size ceiling to work around.
  3. Use publicUrl as your model input.

Step 1 — Request an upload URL

POST /api/v1/upload

Requires an API key. No credits are charged, and uploads do not count against your daily generation quota.

curl -X POST https://vicsee.com/api/v1/upload \
  -H "Authorization: Bearer $VICSEE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "contentType": "image/png", "sizeBytes": 402721 }'
FieldTypeRequiredNotes
contentTypestringYesMust be one of the supported types below
sizeBytesnumberNoChecked against the cap for that media kind
{
  "success": true,
  "data": {
    "uploadUrl": "https://<storage-host>/...&X-Amz-Signature=...",
    "publicUrl": "https://cdn.vicsee.com/uploads/mist/<id>/<uuid>.png",
    "key": "mist/<id>/<uuid>.png",
    "expiresAt": "2026-08-24T15:25:03.104Z"
  }
}

uploadUrl and publicUrl are not interchangeable. uploadUrl is signed for a single PUT; fetching it with GET returns 403. Only publicUrl is readable, and only after step 2 has completed.

Step 2 — Send the bytes

PUT the raw file to uploadUrl. Send no Authorization header — the signature in the URL is the authorization. Match the Content-Type you declared in step 1.

curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: image/png" \
  --data-binary @./character.png

A 200 means the file is stored and publicUrl is live.

Step 3 — Use the public URL

curl -X POST https://vicsee.com/api/v1/generate \
  -H "Authorization: Bearer $VICSEE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2-5-reference-to-video",
    "input": {
      "prompt": "the character walks through a neon-lit market at night",
      "reference_image_urls": ["https://cdn.vicsee.com/uploads/mist/<id>/<uuid>.png"],
      "duration": 5,
      "resolution": "480p"
    }
  }'

Supported types and size caps

KindContent typesMax size
Imageimage/jpeg, image/png, image/webp, image/gif, image/avif, image/heic, image/heif20 MB
Videovideo/mp4, video/quicktime, video/webm100 MB
Audioaudio/mpeg, audio/wav, audio/aac, audio/mp4, audio/ogg20 MB

Uploaded inputs are retained for 7 days. Generated outputs follow your plan's retention, described in Credits.

A note on base64 data URIs

The API also accepts an inline data: URI, and for a small image it works. We recommend uploading instead. A base64 payload inflates the file by roughly a third, and past a few tens of kilobytes providers commonly reject it — the failure arrives as a file-type or invalid-image error rather than a size error, which makes it hard to diagnose. Agent frameworks also truncate long strings in tool-call arguments, silently corrupting the image.

Upload has no such ceiling, so prefer it for anything beyond a thumbnail.

Troubleshooting

What you seeWhat it means
GET publicUrl403You fetched the uploadUrl by mistake. It is signed for PUT only.
GET publicUrl404Step 2 never completed. The object does not exist yet.
Generation fails to fetch your imageThe URL is not publicly readable. Cloud-drive "share links" usually return an HTML page, not the image — open it in a private browser window to confirm you get the file itself.
403 from POST /api/v1/uploadAPI access requires an active subscription or a credit pack.
INVALID_CONTENT_TYPEThe contentType is not in the table above.
The uploadUrl stopped workingIt expires at expiresAt. Request a new one; nothing else is lost.