
picassoia / Seedance 2.5 Lite
Text and image to video with audio, clips of 5, 10 or 15 seconds and 480p or 720p output.
From nothing to a generated image in a few minutes.
Paste it into ChatGPT, Claude, Gemini or your coding agent: it has everything needed to add the API to your project.
Add the PicassoIA API to my project, to generate images and videos from my own code.
How the API works:
- Base URL: https://api.picassoia.com/v1. JSON requests and responses.
- Auth: send `Authorization: Bearer <key>`, reading the key from the PICASSOIA_API_KEY environment variable. Keep it server-side: the API sends no CORS headers, so never call it from a browser or put the key in an app.
- Create a prediction: `POST /v1/models/{owner}/{name}/predictions` with the body `{"input": {...}}`. It answers `201` with the prediction in the `starting` state and never waits for the result.
- Poll `prediction.urls.get`, waiting `eta.next_poll_in_seconds` between calls, until `status` is `succeeded`, `failed` or `canceled`. Then read `output`, or `error` when it failed.
- `GET /v1/models` lists every model with its input schema (JSON Schema). Unknown fields are refused with `422 invalid_input`.
- Images go as public https URLs or data URLs (PNG, JPEG or WebP, up to 5 MB each); the request body is limited to 10 MB.
- Up to 5 predictions queued or running per account; the next one answers `429 concurrency_limit` with a `Retry-After` header.
- Output URLs are hosted by PicassoIA: download the files you want to keep.
- Docs: https://picassoia.com/en/api
Models:
- `picassoia/seedance-2.5-lite` (Seedance 2.5 Lite): text or image to video with synchronized audio: 5, 10 or 15 s at 480p, up to 10 s at 720p; optional closing frame (last_frame_image, needs image). Output: one MP4 URL (a string).
- `picassoia/picassoia-video` (PicassoIA Video): text or image to video: 480p up to 20 s, 720p up to 10 s, 1080p up to 5 s. Output: one MP4 URL (a string).
- `picassoia/picassoia-image` (PicassoIA Image): text to image: 1 or 2 images from a prompt. Output: a list of image URLs.
- `picassoia/picassoia-image-editor-pro` (PicassoIA Image Editor Pro): edits or combines 1 to 4 images following a prompt (refer to them as "image 1", "image 2"…). Output: a list of image URLs.
- `picassoia/picassoia-reference-to-video` (PicassoIA Reference To Video): reference to video with synchronized audio: up to 9 reference images, an optional reference video and an optional reference audio (a voice a character lip-syncs, or music), named in the prompt as "Image 1", "Video 1", "Audio 1". At least one image or the video is required; the video and the audio go as public https URLs only. 480p or 720p, 1 to 15 s. Output: one MP4 URL (a string).Create a key in your account and keep it on your server in the PICASSOIA_API_KEY environment variable. Creating keys and predictions needs an active Infinite plan.
export PICASSOIA_API_KEY="pia_sk_…"Create a prediction with one POST. The API usually answers within seconds, without waiting for the result.
curl -s -X POST https://api.picassoia.com/v1/models/picassoia/picassoia-image/predictions \
-H "Authorization: Bearer $PICASSOIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"input":{"prompt":"a lighthouse at sunset, oil painting"}}'const API = 'https://api.picassoia.com/v1'
const headers = {
Authorization: `Bearer ${process.env.PICASSOIA_API_KEY}`,
'Content-Type': 'application/json',
}
const input = {
prompt: "a lighthouse at sunset, oil painting"
}
const created = await fetch(`${API}/models/picassoia/picassoia-image/predictions`, {
method: 'POST',
headers,
body: JSON.stringify({ input }),
})
let prediction = await created.json()
if (!created.ok) throw new Error(`${prediction.code}: ${prediction.detail}`)
console.log(prediction.id, prediction.status) // api_…, startingimport os, requests
API = "https://api.picassoia.com/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['PICASSOIA_API_KEY']}"}
payload = {"input": {
"prompt": "a lighthouse at sunset, oil painting",
}}
response = requests.post(f"{API}/models/picassoia/picassoia-image/predictions", json=payload, headers=HEADERS)
prediction = response.json()
if not response.ok:
raise RuntimeError(f"{prediction['code']}: {prediction['detail']}")
print(prediction["id"], prediction["status"]) # api_…, starting{
"id": "api_3f9c2b7e8d1a4c6f9e0b1a2c3d4e5f60",
"model": "picassoia/picassoia-image",
"input": {
"prompt": "a lighthouse at sunset, oil painting",
"aspect_ratio": "1:1",
"num_outputs": 1,
"output_format": "jpg",
"output_quality": 80
},
"output": null,
"error": null,
"status": "starting",
"created_at": "2026-10-01T09:30:00.000Z",
"started_at": null,
"completed_at": null,
"metrics": {
"predict_time": null
},
"urls": {
"get": "https://api.picassoia.com/v1/predictions/api_3f9c2b7e8d1a4c6f9e0b1a2c3d4e5f60",
"cancel": "https://api.picassoia.com/v1/predictions/api_3f9c2b7e8d1a4c6f9e0b1a2c3d4e5f60/cancel"
},
"eta": {
"seconds": 12,
"next_poll_in_seconds": 6
}
}Poll the prediction's urls.get, waiting eta.next_poll_in_seconds between calls, until its status is succeeded, failed or canceled. If it succeeded, download the output.
# Repeat after eta.next_poll_in_seconds until status is
# succeeded, failed or canceled.
curl -s https://api.picassoia.com/v1/predictions/api_3f9c2b7e8d1a4c6f9e0b1a2c3d4e5f60 \
-H "Authorization: Bearer $PICASSOIA_API_KEY"
# The last poll holds the result: "output" when "status" is succeeded,
# "error" when it is failed. With jq, just those three fields:
curl -s https://api.picassoia.com/v1/predictions/api_3f9c2b7e8d1a4c6f9e0b1a2c3d4e5f60 \
-H "Authorization: Bearer $PICASSOIA_API_KEY" | jq '.status, .output, .error'const sleep = (s) => new Promise((resolve) => setTimeout(resolve, s * 1000))
while (!['succeeded', 'failed', 'canceled'].includes(prediction.status)) {
await sleep(prediction.eta?.next_poll_in_seconds ?? 2)
prediction = await (await fetch(prediction.urls.get, { headers })).json()
}
if (prediction.status !== 'succeeded') throw new Error(prediction.error ?? prediction.status)
console.log(prediction.output)import time
while prediction["status"] not in ("succeeded", "failed", "canceled"):
time.sleep((prediction.get("eta") or {}).get("next_poll_in_seconds", 2))
prediction = requests.get(prediction["urls"]["get"], headers=HEADERS).json()
if prediction["status"] != "succeeded":
raise RuntimeError(prediction["error"] or prediction["status"])
print(prediction["output"]){
"id": "api_3f9c2b7e8d1a4c6f9e0b1a2c3d4e5f60",
"status": "succeeded",
"output": [
"https://…/output-1.jpg"
],
"error": null,
"completed_at": "2026-10-01T09:30:08.000Z",
"metrics": {
"predict_time": 6.4
},
"eta": null
}Every model with its playground, its code and its parameters

Text and image to video with audio, clips of 5, 10 or 15 seconds and 480p or 720p output.

Text and image to video with audio, clips of 1 to 20 seconds and 480p, 720p or 1080p output.
Text to image with 1 or 2 images per request and 7 aspect ratios.

AI image editing with up to 4 input images, 1 or 2 images per request and 7 aspect ratios.