Cut.ProDocs

Create personas and swap the person in the video

Create a realistic person from traits, face photos or a ready-made character, and put them in any video or product photo.

A persona is a realistic person made from traits (age, hair, outfit), from the face photos of whoever uses it or from a ready-made character. Once saved, it replaces the person in a library video and keeps the scene, the camera, the movement and the sound. It also appears in photos holding a product.

Photo and video run in the background: you create and poll. GET /personas returns, per persona, image_status (generating, ready or failed) and video_generating, so a single call shows everything still in progress.

Personas always charge, even on unlimited usage. Only creating from a ready-made character, restoring a version, reading a product from its link and rating are free. Read the prices from GET /personas/catalog and GET /personas/swap/quote on the spot, never hardcode them. If a generation fails, the credits come back on their own.

Read the catalog

curl https://api.cut.pro/api/v1/personas/catalog \
  -H "X-Api-Key: $CUTPRO_API_KEY"
FieldWhat it is for
chip_options, default_chipsAll the options for each trait and the default. Build the form from here.
face_photo_groups, max_face_photosThe traits that still apply when the persona comes from face photos, and how many photos fit.
video_stylesThe animation or illustration styles a video can receive.
pricingPrice of each photo and of each second of video per quality.
video_limitsAccepted duration, size and resolution of the source video, per quality.

Create the persona

Send one option per trait in chips. The photo starts generating and the response is 202.

curl -X POST https://api.cut.pro/api/v1/personas \
  -H "X-Api-Key: $CUTPRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "chips": {
      "vibe": "natural", "gender": "female", "age": "25_34", "origin": "latin",
      "skin": "medium", "eyes": "brown", "hair_style": "long_wavy", "hair_color": "brown",
      "facial_hair": "none", "face": "none", "body": "average", "outfit": "basic",
      "accessory": "none", "mark": "freckles"
    }
  }'

With the face of whoever uses it. Upload the photos first and pass the ids in face_ids, within 24 hours and up to max_face_photos (6). JPEG, PNG, WebP or HEIC up to 10 MB. own_face_adult: true confirms the photo is of whoever uses it and that this person is 18 or older.

curl -X POST https://api.cut.pro/api/v1/personas/faces \
  -H "X-Api-Key: $CUTPRO_API_KEY" \
  -F "photo=@selfie.jpg" \
  -F "own_face_adult=true"

With face_ids, only the traits in face_photo_groups still apply, and for those the photo option keeps the feature as it is in the photos.

From a ready-made character, for free. GET /personas/presets lists characters with the photo already made (category: weird, cartoon, creator or influencers). Creating from one generates nothing and is born with image_status: ready:

curl -X POST https://api.cut.pro/api/v1/personas/presets/$PRESET_ID \
  -H "X-Api-Key: $CUTPRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Ana" }'

With name, the persona comes out already saved. Without name, it is a draft to save later. It remains that character: on a regenerate, the chips are ignored and only the note edits. PUT /personas/presets/{presetId}/favorite with { "favorite": true } marks favorites.

Adjust and save

Poll GET /personas/{id} every 5 seconds until image_status becomes ready, or failed with the reason in error_code.

To change the photo, generate again with other chips or edit with a one-line note, which keeps the same person:

curl -X POST https://api.cut.pro/api/v1/personas/$PERSONA_ID/regenerate \
  -H "X-Api-Key: $CUTPRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "note": "make the jacket red" }'

An edit with note costs pricing.photo_with_references_credits. If another photo is already being generated, the response is 409 CARD_LOCKED.

When the photo is good, save it. On a saved persona, the same call only renames it.

curl -X POST https://api.cut.pro/api/v1/personas/$PERSONA_ID/save \
  -H "X-Api-Key: $CUTPRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Ana" }'

Upload the source video

A video that is already in the library skips this step: use its id as media_id. For a new file, request the URL, upload and confirm. MP4 and MOV only, within video_limits.

curl -X POST https://api.cut.pro/api/v1/personas/sources/upload \
  -H "X-Api-Key: $CUTPRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "file_name": "video.mp4", "file_size": 8421337, "content_type": "video/mp4" }'

curl -X PUT "$UPLOAD_URL" -H "Content-Type: video/mp4" --upload-file video.mp4

curl -X POST https://api.cut.pro/api/v1/personas/sources/upload/complete \
  -H "X-Api-Key: $CUTPRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "media_id": "7412908365112823", "file_name": "video.mp4" }'

Ask for the price

curl "https://api.cut.pro/api/v1/personas/swap/quote?media_id=7412908365112823&quality=standard&replace=head" \
  -H "X-Api-Key: $CUTPRO_API_KEY"
200 OK
{ "media_id": "7412908365112823", "quality": "standard", "replace": "head", "style": null, "seconds": 8.4, "credits": 81 }

Nothing is charged. Show the price to the person and wait for a yes.

ParameterValues
qualityeconomy is standard at a lower resolution, upscaled to 1080p, and the cheapest. standard (default) follows the persona's traits. high also follows the photos, makes the face more faithful and accepts longer videos, for more. Prefer high on a persona made from face photos.
replaceperson (default) swaps the whole person, with body and outfit. head swaps only the head and hair. none swaps nobody and only applies the style.
styleRedraws the whole video in a look, like cel (2D animation), felt (felt stop motion), pixel or silent (silent film), keeping camera and movement. With a style, the whole person is swapped, except with replace: none. Full list in video_styles.

The price depends only on quality, duration and style. head and person cost the same. A video refused in standard may fit in high.

Generate the video

Send the price's credits, with the same quality, replace and style. The response is 202 with status: processing.

curl -X POST https://api.cut.pro/api/v1/personas/$PERSONA_ID/videos \
  -H "X-Api-Key: $CUTPRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "type": "swap", "media_id": "7412908365112823", "quality": "standard", "replace": "head", "credits": 81 }'

If the price changed, nothing is charged and the response is 409 PRICE_CHANGED with the right value in extra.credits.

By default, whoever becomes the persona is the main person in the video. To choose another, send target:

  • a person seen in the video: { "seconds": 2.5, "x": 0.62, "y": 0.48 }, with the moment and their center from 0 to 1. box is optional and helps when there are people nearby.
  • whoever is filming: { "camera": true }.

Choosing the person never raises the confirmed price. If nobody is at that point, the video ends in failed with TARGET_NOT_A_PERSON and the credits come back.

Poll GET /personas/{id}/videos/{videoId} every 10 seconds.

  • ready: download_url has the MP4, valid for 6 hours. To post or render, POST /generations/{videoId}/edit returns the edit_id that goes in POST /posts or POST /renders.
  • failed: the reason is in error_code and the credits have already come back.

Versions and ratings

Each photo that finishes becomes a version and becomes the current one. The previous ones stay in versions, in GET /personas/{id}. Going back to one of them is free:

curl -X POST https://api.cut.pro/api/v1/personas/$PERSONA_ID/versions/$VERSION_ID/restore \
  -H "X-Api-Key: $CUTPRO_API_KEY"

Every video stores the version it came from in version_id. New videos use the current one, unless you send version_id in POST /personas/{id}/videos. GET /personas/{id}/videos?version_id=... filters by version. Videos already made do not change.

Rating is free and improves results:

curl -X POST https://api.cut.pro/api/v1/personas/$PERSONA_ID/versions/$VERSION_ID/feedback \
  -H "X-Api-Key: $CUTPRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "vote": "down", "reason": "not_like_me" }'
RateRouteReasons for down
PhotoPOST /personas/{id}/versions/{versionId}/feedbacknot_realistic, wrong_traits, not_like_me, defects, other
VideoPOST /personas/{id}/videos/{videoId}/feedbackdifferent_person, scene_changed, defects, bad_motion, other

vote is up, down or null (clears). A down on a video cancels its posts that are still scheduled.

DELETE /personas/{id} deletes the persona. The edits made with its videos remain.

Photos with a product

A saved persona poses in a ready-made scene or one you write, holding a product. Start with the product.

From the store link, for free. Reads the name, description, price and brand, and stores up to 3 photos:

curl -X POST https://api.cut.pro/api/v1/personas/$PERSONA_ID/shots/product \
  -H "X-Api-Key: $CUTPRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://loja.exemplo.com.br/serum-vitamina-c" }'
200 OK
{
  "product": { "name": "Vitamin C Serum 30 ml", "description": "Facial serum with 10% vitamin C.", "price": "R$ 89,90", "brand": "Example" },
  "photo_ids": ["7413100022003301", "7413100022003302"],
  "partial": false
}

It works on most stores, on Shopee and on Amazon Brazil. partial: true means the price or the photos did not come through. Up to 5 reads per minute; above that, 429 PRODUCT_RATE_LIMITED.

From the photo. When the page does not open (PRODUCT_NOT_READABLE, always on Mercado Livre and TikTok Shop), upload the photos and write the fields. JPEG, PNG, WebP or HEIC up to 10 MB, with the label facing the camera. rights_confirmed: true says the person may use the product and the photo. Use the id within 24 hours.

curl -X POST https://api.cut.pro/api/v1/personas/$PERSONA_ID/shots/photos \
  -H "X-Api-Key: $CUTPRO_API_KEY" \
  -F "photo=@serum.jpg" \
  -F "rights_confirmed=true"

Generate the photo:

curl -X POST https://api.cut.pro/api/v1/personas/$PERSONA_ID/shots \
  -H "X-Api-Key: $CUTPRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "bathroom",
    "aspect_ratio": "9:16",
    "credits": 20,
    "product": { "name": "Vitamin C Serum 30 ml", "photo_ids": ["7413100022003301"] }
  }'
202 Accepted
{ "id": "7413100030004401", "status": "processing", "credits_charged": 20 }
FieldValues
templatemirror (default), kitchen, bathroom, sofa, cafe, gym, street, closeup, story, bedroom. The template decides what the persona does with the product.
sceneA written scene, in any language, from 3 to 500 characters. Replaces the template.
product.actionOnly with scene: show (default, shows it to the camera) or use (uses it with one hand). A scene that requires both hands (applying, serving, opening, eating) is refused with SCENE_ACTION_UNSUPPORTED before charging.
aspect_ratio9:16 (default), 4:5, 1:1, 16:9.
creditsThe catalog's pricing.scene_photo_credits, double with style. A different price responds 409 PRICE_CHANGED.

Poll GET /personas/{id}/shots/{shotId} every 5 seconds. On ready, image_url has the photo. GET /personas/{id}/shots lists them all, from newest to oldest.

Errors

CodeWhen
INSUFFICIENT_CREDITSInsufficient balance. extra.credits_needed says how much is missing, extra.top_up_url leads to the top-up, extra.is_owner says whether the caller can top up.
PRICE_CHANGEDThe price changed. The new one is in extra.credits: show it and ask for a yes again.
CARD_LOCKEDA photo of the persona is already being generated. Wait for it to finish.
CARD_NOT_READYSaved before the photo was ready.
VIDEO_IN_PROGRESSThe persona is already making the same video in the same version.
VIDEO_DURATION_OUT_OF_RANGE, VIDEO_UNSUPPORTEDThe video falls outside video_limits at this quality. Try another.
STYLE_REQUIREDreplace: none without style.
STYLE_UNSUPPORTEDStyle at quality: high on a video longer than video_mid_max_seconds.
TARGET_UNSUPPORTEDtarget after the end of the video, or on a high video longer than video_mid_max_seconds.
INVALID_IMAGEUnreadable photo or outside the accepted formats.
PRODUCT_URL_INVALID, PRODUCT_NOT_READABLEThe link is not a product page, or it does not open. Upload the photos.
PERSONA_NOT_FOUND, VERSION_NOT_FOUND, VIDEO_NOT_FOUND, PRESET_NOT_FOUND, FACE_NOT_FOUND, PHOTO_NOT_FOUND, SHOT_NOT_FOUND, MEDIA_NOT_FOUNDThe id does not exist in this workspace.

When a photo or video ends in failed, error_code says why: SAFETY_BLOCKED, COPYRIGHT_BLOCKED, REAL_FACES_BLOCKED and MEDIA_REJECTED are refusals over the content (change the traits, the photos or the video); MEDIA_FAILED, MEDIA_UNAVAILABLE and TIMEOUT are worth another attempt. The credits have already come back in both cases.

On this page