Quickstart
Create an asynchronous Task and handle polling, completion, failure, and callbacks.
RunAPI uses Tasks for asynchronous image, video, audio, and music generation. A create request returns quickly; your application then polls the Task or receives the callback events listed in that endpoint’s API Reference.
Create a Task
Choose a model and endpoint in the Catalog, then send the endpoint’s required inputs. This example starts a Flux 2 text-to-image Task:
curl -X POST "https://runapi.ai/api/v1/flux_2/text_to_image" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Idempotency-Key: 8c8ba3c9-0ce0-4bbd-a9a7-bf59ab639286" \
-H "Content-Type: application/json" \
-d '{
"model": "flux-2-pro-text-to-image",
"prompt": "A product photograph on a clean studio background"
}'
An accepted asynchronous request returns 202 Accepted with a Task identifier:
{
"id": "task_id",
"status": "processing"
}
Store id with your application record. It is the stable identifier used for polling, support, and callback reconciliation.
Send media inputs
Media Input Fields are the request fields that carry media URLs: top-level fields whose names end in _url or _urls, such as image_url or image_urls, the url of each video_list item, and the element_input_urls, element_input_video_urls, and element_input_audio_urls of each kling_elements item. callback_url is a delivery endpoint, not a Media Input Field. Each Media Input Field value can be a public HTTPS URL or a data URI in the form data:<mime>;base64,<data>, up to 10 MB per data URI. RunAPI stores each data URI as a temporary File Upload that expires after one hour and uses that upload for the Task. A data URI that cannot be stored returns 422 with the error code invalid_media_input.
GPT Image edit endpoints accept only HTTPS URLs in source_image_urls. To send a local image to these endpoints, create a File Upload first and pass its returned URL.
To send a file larger than 10 MB, call POST /api/v1/files to create a File Upload, then pass its returned URL. A multipart or URL-source File Upload accepts files up to 50 MB. File Upload URLs also expire after one hour, so create a new File Upload for each Task that starts after that window.
# For this model, non-PNG/JPEG input may return 409 depending on the selected service.
# If rejected, convert WebP/BMP/TIFF/GIF to PNG/JPEG or select a compatible service.
# Actual MIME determines support, even for a .png URL. Rejection happens before task creation or charging.
# This is not a format limit for every service. Existing Task queries remain available.
curl -X POST "https://runapi.ai/api/v1/seedream/decompose_layers" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"model":"seedream-5-pro-layer-decomposition","image_url":"https://cdn.runapi.ai/public/samples/image.png"}'
Prevent duplicate Task creation
Task-creation endpoints accept an optional Idempotency-Key header with an opaque value of up to 512 characters. Generate one value for each logical Task and keep it with the request until you know whether it was accepted.
If a timeout or connection failure leaves the result unknown, retry the exact same Task creation request with the same key. RunAPI returns the original Task instead of creating and charging for a second one. Reusing a key with a different Task creation request returns 409 Conflict. Generate a new key for an intentionally new Task, and do not use X-Client-Request-Id as this key.
Recover an interrupted synchronous request
Slow synchronous endpoints normally keep the connection open and return the same terminal response as before. No polling changes are required for existing integrations.
For an intentionally shorter connection budget, send Prefer: wait=N. If the Task is still running after that explicit budget, RunAPI returns 202 Accepted with the same Task id, an opaque Location URL for recovery, and Retry-After for the suggested query delay. Follow Location exactly rather than constructing a result URL. A completed Task Result preserves the terminal HTTP status, allowed headers, content type, and body; decode response.body according to response.content_type, which is not always JSON.
Poll a Task
Append the Task identifier to the same endpoint path:
curl "https://runapi.ai/api/v1/flux_2/text_to_image/task_id" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Continue while status is processing. Use bounded backoff between requests instead of polling continuously. A Task becomes terminal when its status is completed or failed.
Handle completion
A completed response includes the Task id, terminal status, endpoint-specific result fields, and usage.cost as a float USD amount for that Task. Persist the result you need and stop polling. Consult the endpoint’s API Reference for the exact result shape rather than assuming every media endpoint returns the same fields.
Create, processing, and failed Task envelopes omit usage.
Tasks that require media-based final settlement remain processing until their final charge is recorded. The completed callback is sent only after that settlement; its usage.cost matches subsequent Task queries. Missing accounting facts are not reported as zero: the Task remains processing while they are reconciled. A confirmed zero charge is returned as usage.cost: 0.
Handle failure
A failed response includes the Task id, terminal status, and a RunAPI-authored error when one is available. Stop polling, record the identifier and error, and retry only when your application has classified the failure as transient. A retry creates a new Task identifier.
Receive a callback
Add a public HTTPS callback_url to the create request when you want RunAPI to send the callback events documented for that endpoint:
{
"model": "flux-2-pro-text-to-image",
"prompt": "A product photograph on a clean studio background",
"callback_url": "https://your-domain.com/webhooks/runapi"
}
Each callback body matches one lifecycle event in the endpoint’s API Reference. A completed callback shares usage.cost with the completed polling response; create, processing, and failed callbacks omit usage. Terminal callbacks include the same result fields as terminal polling responses; some endpoints also send documented processing callbacks. Return a successful HTTP response quickly and keep polling available for reconciliation when delivery is delayed or your callback handler is unavailable.
Read Callbacks to create a Callback Secret, verify signatures, and handle retries safely.
Generate Vidu Q4 videos
Use POST /api/v1/vidu/image_to_video with model: "vidu-q4-image-to-video" and first_frame_image_url. Use POST /api/v1/vidu/reference_to_video with model: "vidu-q4-reference-to-video", a nonblank prompt, and 1–15 ordered reference_image_urls. Retrieve each task with GET on its creation path followed by /:id. Completed tasks contain a videos array of result URLs. You can also provide callback_url for completion notifications.
Both endpoints accept integer duration_seconds from 3 to 16, default 5, and output_resolution of 540p, 720p, 1080p, 2k, or 4k, default 720p. audio is a JSON boolean, default true; explicit false disables generated audio. Prompts accept up to 20,000 characters. The image-to-video prompt is optional and the first frame determines its aspect ratio. Reference-to-video accepts aspect_ratio of 16:9, 9:16, 1:1, 4:3, or 3:4, default 16:9, and up to 3 reference_audio_urls.
Use public HTTP(S) media URLs. Images must be JPG/JPEG, PNG, or WEBP; the first-frame image must be no larger than 50 MB. Each reference audio file must be MP3, 3–12 seconds long, and no larger than 50 MB. RunAPI checks field types, URL schemes, and reference counts. The generation provider checks remote media format, size, and audio duration asynchronously. Invalid media can cause the task to fail through the normal failure and refund flow.