AI generation
Generate images, videos and voices with the best models, and use the result
Generate an image, a video or a voice from a prompt, from images, or from a first and last frame. Generations run in the background: you create one, then poll it. Every charge is given back on its own when a generation fails.
Prices follow what each model costs and can change at any time. Read them from GET /generations/models right before generating, and send the total you agreed to in credits: if the price moved, nothing is charged and you get PRICE_CHANGED with the new total.
Read the models
GET /generations/models lists every image, video and voice model with the modes, resolutions, durations, aspect ratios and voices each one accepts, and its price in credits.
curl https://api.cut.pro/api/v1/generations/models \
-H "X-Api-Key: $CUTPRO_API_KEY"Each model also tells you what to expect from it, so you can pick without trying:
maker,description,released_atandtags: what the maker says about it. They arenullor empty where the maker says nothing.typical_seconds: how long a generation usually takes, from request toready, over the last two weeks.success_rate: the share of generations that came out, from 0 to 1. A request the model refuses for its content is not counted against it.
Both are null until enough generations ran. When the user names no model, use presets: the recommended model for each level (fast, balanced, best) and kind. prompt_max is the longest prompt, max_running how many generations one workspace may have running at once, and improve_credits what rewriting a prompt costs.
Prices are in credits: per second for a video, per image for an image, and per 1,000 characters for a voice (unrounded: the charge is that price times the characters of prompt, divided by 1,000, rounded up). silent_credits is the price of a video without sound, where the model can leave it out.
Add images, if the request needs them
A first frame, a last frame or references go in image_ids. Upload a file with POST /generations/images (multipart/form-data), or reuse an image CutPro generated: its output.image_id works the same.
curl -X POST https://api.cut.pro/api/v1/generations/images \
-H "X-Api-Key: $CUTPRO_API_KEY" \
-F "image=@product.jpg"The mode says how the images are used: text takes none, image one (animate it), frames two (first and last) and references up to the model's max_images (borrow a person, product or style, or edit them).
Rewrite a short request (optional)
POST /generations/improve turns a short request into a clearer, more detailed one, written the way the chosen model reads best and in the language of the request. Nothing is generated. It charges improve_credits, and gives them back if the rewrite fails. Show the result to the user before generating with it.
curl -X POST https://api.cut.pro/api/v1/generations/improve \
-H "X-Api-Key: $CUTPRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "model": "google/veo-3.1-lite", "mode": "text", "prompt": "a dog surfing at sunset", "seconds": 8 }'Generate
curl -X POST https://api.cut.pro/api/v1/generations \
-H "X-Api-Key: $CUTPRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "kind": "video", "model": "google/veo-3.1-lite", "mode": "text", "resolution": "720p", "prompt": "a dog surfing at sunset", "seconds": 8, "aspect_ratio": "9:16", "credits": 96 }'The call answers 201 with the id and charges the credits at once. A few rules by kind:
- A video needs
seconds, one of the model'sseconds.audio: falseleaves the sound out of a model withaudio: optional, usually for less. - An image needs no
seconds. A model drawn in one resolution needs none in the request. - A voice (
kind: speech,mode: text) readspromptword for word in one of the model'svoices, passed asvoice. It takes noaspect_ratio, and the result is an MP3. Each voice has apreview_url(a sample line) and aportrait_url, both signed links valid for 6 hours.
Errors worth handling: INSUFFICIENT_CREDITS (402, with a top_up_url), PRICE_CHANGED (409, with the new total in extra.credits), TOO_MANY_RUNNING (429) and MODEL_UNAVAILABLE, MODE_UNSUPPORTED, RESOLUTION_INVALID, SECONDS_INVALID, RATIO_INVALID, IMAGES_INVALID or VOICE_INVALID (400).
Follow it
Poll GET /generations/{id} every 10 seconds while status is processing. expected_seconds says how long this model usually takes. It ends ready, with output.url (a signed preview link valid for 6 hours, an MP3 for a voice) and output.thumbnail_url, or failed, with the reason in error_code, and the credits already given back.
curl https://api.cut.pro/api/v1/generations/GENERATION_ID \
-H "X-Api-Key: $CUTPRO_API_KEY"GET /generations?kind=video&page=1&limit=20 lists the workspace's generations, newest first. Besides the request (model, mode, resolution, seconds, aspect_ratio, voice, audio, prompt, image_ids), each one shows credits_charged, feedback, feedback_reason, refund_status, downloaded and removed (the file was deleted from the library).
Use the result
- Download it with
GET /generations/{id}/download: a signed link to the full-quality file, valid for 6 hours. Once it was downloaded, its credits can no longer be asked back. - Edit or post a ready video with
POST /generations/{id}/edit. It makes the editor project on the first call and returns the sameedit_idafter. Pass it toPOST /poststo publish or schedule the video, or toPOST /renders. - Delete it with
DELETE /generations/{id}. It leaves the list and the library. One stillprocessingcannot be deleted.
Rate it, or ask for the credits back
Tell us what worked with POST /generations/{id}/feedback. Send { "vote": "up" }, or { "vote": "down", "reason": "defects" }, or { "vote": null } to clear it. The reasons are prompt_ignored, defects, bad_motion, not_realistic, speech_wrong (a word, name or number said wrong) and other. A down also cancels the posts of the result that are still scheduled. Rating is free.
curl -X POST https://api.cut.pro/api/v1/generations/GENERATION_ID/feedback \
-H "X-Api-Key: $CUTPRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "vote": "down", "reason": "bad_motion" }'If a result is not usable, ask for its credits back with POST /generations/{id}/refund, with a reason (the same list) and a note of a sentence or two. The team reviews it. It works once per generation, only when it is ready, and not after it was downloaded or posted (REFUND_AFTER_DOWNLOAD, REFUND_AFTER_POST; asking twice answers REFUND_ALREADY_REQUESTED). Follow it in refund_status of GET /generations/{id}: requested, then approved or denied.
curl -X POST https://api.cut.pro/api/v1/generations/GENERATION_ID/refund \
-H "X-Api-Key: $CUTPRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "reason": "defects", "note": "The hands are deformed in every shot." }'