# Crie personas e troque a pessoa do vídeo

> Crie uma pessoa realista a partir de características, fotos do rosto ou um personagem pronto, e coloque ela em qualquer vídeo ou foto de produto.

Uma **persona** é uma pessoa realista feita a partir de características (idade, cabelo, roupa), de fotos do rosto de quem usa ou de um personagem pronto. Depois de salva, ela substitui a pessoa de um vídeo da biblioteca e mantém a cena, a câmera, o movimento e o som. Também aparece em fotos com um produto na mão.

Foto e vídeo rodam em segundo plano: você cria e consulta. `GET /personas` traz, por persona, `image_status` (`generating`, `ready` ou `failed`) e `video_generating`, então uma chamada mostra tudo o que ainda está andando.

> Personas sempre cobram, mesmo em uso liberado. Só são grátis criar de um personagem pronto, restaurar uma versão, ler um produto pelo link e avaliar. Leia os preços de `GET /personas/catalog` e `GET /personas/swap/quote` na hora, nunca fixe no código. Se uma geração falha, os créditos voltam sozinhos.

### Leia o catálogo

```bash
curl https://api.cut.pro/api/v1/personas/catalog \
  -H "X-Api-Key: $CUTPRO_API_KEY"
```

| Campo | Para que serve |
|---|---|
| `chip_options`, `default_chips` | Todas as opções de cada característica e o padrão. Monte o formulário a partir daqui. |
| `face_photo_groups`, `max_face_photos` | As características que ainda valem quando a persona vem de fotos do rosto, e quantas fotos cabem. |
| `video_styles` | Os estilos de animação ou ilustração que um vídeo pode receber. |
| `pricing` | Preço de cada foto e de cada segundo de vídeo por qualidade. |
| `video_limits` | Duração, tamanho e resolução aceitos no vídeo de origem, por qualidade. |

### Crie a persona

Mande uma opção por característica em `chips`. A foto começa a ser gerada e a resposta é `202`.

```bash
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"
    }
  }'
```

**Com o rosto de quem usa.** Envie as fotos antes e passe os ids em `face_ids`, em até 24 horas e até `max_face_photos` (6). JPEG, PNG, WebP ou HEIC de até 10 MB. `own_face_adult: true` confirma que a foto é de quem usa e que essa pessoa tem 18 anos ou mais.

```bash
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"
```

Com `face_ids`, só as características de `face_photo_groups` continuam valendo, e nelas a opção `photo` mantém o traço como está nas fotos.

**De um personagem pronto, de graça.** `GET /personas/presets` lista personagens com a foto já feita (`category`: `weird`, `cartoon`, `creator` ou `influencers`). Criar de um deles não gera nada e já nasce com `image_status: ready`:

```bash
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" }'
```

Com `name`, a persona já sai salva. Sem `name`, é um rascunho para salvar depois. Ela continua sendo aquele personagem: num `regenerate`, os `chips` são ignorados e só a `note` edita. `PUT /personas/presets/{presetId}/favorite` com `{ "favorite": true }` marca favoritos.

### Ajuste e salve

Consulte `GET /personas/{id}` a cada 5 segundos até `image_status` virar `ready`, ou `failed` com o motivo em `error_code`.

Para mudar a foto, gere de novo com outros `chips` ou edite com uma `note` de uma linha, que mantém a mesma pessoa:

```bash
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" }'
```

Uma edição com `note` custa `pricing.photo_with_references_credits`. Se outra foto já está sendo gerada, a resposta é `409 CARD_LOCKED`.

Quando a foto estiver boa, salve. Numa persona salva, a mesma chamada só renomeia.

```bash
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" }'
```

### Envie o vídeo de origem

Um vídeo que já está na biblioteca dispensa este passo: use o id dele como `media_id`. Para um arquivo novo, peça a URL, envie e confirme. Só MP4 e MOV, dentro de `video_limits`.

```bash
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" }'
```

### Peça o preço

```bash
curl "https://api.cut.pro/api/v1/personas/swap/quote?media_id=7412908365112823&quality=standard&replace=head" \
  -H "X-Api-Key: $CUTPRO_API_KEY"
```

```json title="200 OK"
{ "media_id": "7412908365112823", "quality": "standard", "replace": "head", "style": null, "seconds": 8.4, "credits": 81 }
```

Nada é cobrado. Mostre o preço à pessoa e espere o sim.

| Parâmetro | Valores |
|---|---|
| `quality` | `economy` é a `standard` em resolução menor, ampliada para 1080p, e a mais barata. `standard` (padrão) segue as características da persona. `high` também segue as fotos, deixa o rosto mais fiel e aceita vídeos mais longos, por mais. Prefira `high` numa persona feita de fotos do rosto. |
| `replace` | `person` (padrão) troca a pessoa inteira, com corpo e roupa. `head` troca só a cabeça e o cabelo. `none` não troca ninguém e só aplica o `style`. |
| `style` | Redesenha o vídeo inteiro num visual, como `cel` (animação 2D), `felt` (stop motion de feltro), `pixel` ou `silent` (cinema mudo), mantendo câmera e movimento. Com estilo, a pessoa inteira é trocada, a não ser em `replace: none`. Lista completa em `video_styles`. |

O preço depende só da qualidade, da duração e do estilo. `head` e `person` custam o mesmo. Um vídeo recusado em `standard` pode caber em `high`.

### Gere o vídeo

Mande os `credits` do preço, com a mesma `quality`, `replace` e `style`. A resposta é `202` com `status: processing`.

```bash
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 }'
```

Se o preço mudou, nada é cobrado e a resposta é `409 PRICE_CHANGED` com o valor certo em `extra.credits`.

Por padrão, quem vira a persona é a pessoa principal do vídeo. Para escolher outra, mande `target`:

- uma pessoa vista no vídeo: `{ "seconds": 2.5, "x": 0.62, "y": 0.48 }`, com o momento e o centro dela de 0 a 1. `box` é opcional e ajuda quando há gente perto.
- quem está filmando: `{ "camera": true }`.

Escolher a pessoa nunca aumenta o preço confirmado. Se não há ninguém no ponto, o vídeo termina em `failed` com `TARGET_NOT_A_PERSON` e os créditos voltam.

Consulte `GET /personas/{id}/videos/{videoId}` a cada 10 segundos.

- `ready`: `download_url` tem o MP4, válido por 6 horas. Para postar ou renderizar, `POST /generations/{videoId}/edit` devolve o `edit_id` que vai em [`POST /posts`](/publishing) ou [`POST /renders`](/rendering).
- `failed`: o motivo está em `error_code` e os créditos já voltaram.

## Versões e avaliações

Cada foto que termina vira uma versão e passa a ser a atual. As anteriores ficam em `versions`, no `GET /personas/{id}`. Voltar a uma delas é grátis:

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

Todo vídeo guarda a versão de onde saiu em `version_id`. Vídeos novos usam a atual, a não ser que você mande `version_id` em `POST /personas/{id}/videos`. `GET /personas/{id}/videos?version_id=...` filtra por versão. Vídeos já feitos não mudam.

Avaliar é grátis e melhora os resultados:

```bash
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" }'
```

| Avaliar | Rota | Motivos do `down` |
|---|---|---|
| Foto | `POST /personas/{id}/versions/{versionId}/feedback` | `not_realistic`, `wrong_traits`, `not_like_me`, `defects`, `other` |
| Vídeo | `POST /personas/{id}/videos/{videoId}/feedback` | `different_person`, `scene_changed`, `defects`, `bad_motion`, `other` |

`vote` é `up`, `down` ou `null` (limpa). Um `down` num vídeo cancela os posts dele que ainda estão agendados.

`DELETE /personas/{id}` apaga a persona. As edições feitas com os vídeos dela continuam.

## Fotos com produto

Uma persona salva posa numa cena pronta ou escrita por você, segurando um produto. Comece pelo produto.

**Pelo link da loja, de graça.** Lê nome, descrição, preço e marca, e guarda até 3 fotos:

```bash
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" }'
```

```json title="200 OK"
{
  "product": { "name": "Sérum Vitamina C 30 ml", "description": "Sérum facial com 10% de vitamina C.", "price": "R$ 89,90", "brand": "Exemplo" },
  "photo_ids": ["7413100022003301", "7413100022003302"],
  "partial": false
}
```

Funciona na maioria das lojas, na Shopee e na Amazon Brasil. `partial: true` quer dizer que o preço ou as fotos não vieram. Até 5 leituras por minuto; acima disso, `429 PRODUCT_RATE_LIMITED`.

**Pela foto.** Quando a página não abre (`PRODUCT_NOT_READABLE`, sempre no Mercado Livre e no TikTok Shop), envie as fotos e escreva os campos. JPEG, PNG, WebP ou HEIC de até 10 MB, com o rótulo virado para a câmera. `rights_confirmed: true` diz que a pessoa pode usar o produto e a foto. Use o `id` em até 24 horas.

```bash
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"
```

Gere a foto:

```bash
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": "Sérum Vitamina C 30 ml", "photo_ids": ["7413100022003301"] }
  }'
```

```json title="202 Accepted"
{ "id": "7413100030004401", "status": "processing", "credits_charged": 20 }
```

| Campo | Valores |
|---|---|
| `template` | `mirror` (padrão), `kitchen`, `bathroom`, `sofa`, `cafe`, `gym`, `street`, `closeup`, `story`, `bedroom`. O template decide o que a persona faz com o produto. |
| `scene` | Cena escrita, em qualquer idioma, de 3 a 500 caracteres. Substitui o `template`. |
| `product.action` | Só com `scene`: `show` (padrão, mostra para a câmera) ou `use` (usa com uma mão). Uma cena que pede as duas mãos (passar, servir, abrir, comer) é recusada com `SCENE_ACTION_UNSUPPORTED` antes de cobrar. |
| `aspect_ratio` | `9:16` (padrão), `4:5`, `1:1`, `16:9`. |
| `credits` | `pricing.scene_photo_credits` do catálogo, o dobro com `style`. Preço diferente responde `409 PRICE_CHANGED`. |

Consulte `GET /personas/{id}/shots/{shotId}` a cada 5 segundos. Em `ready`, `image_url` tem a foto. `GET /personas/{id}/shots` lista todas, da mais nova à mais antiga.

## Erros

| Code | Quando |
|---|---|
| `INSUFFICIENT_CREDITS` | Saldo insuficiente. `extra.credits_needed` diz quanto falta, `extra.top_up_url` leva à recarga, `extra.is_owner` diz se quem chamou pode recarregar. |
| `PRICE_CHANGED` | O preço mudou. O novo está em `extra.credits`: mostre e peça o sim de novo. |
| `CARD_LOCKED` | Já há uma foto da persona sendo gerada. Espere terminar. |
| `CARD_NOT_READY` | Salvou antes de a foto ficar `ready`. |
| `VIDEO_IN_PROGRESS` | A persona já está fazendo o mesmo vídeo na mesma versão. |
| `VIDEO_DURATION_OUT_OF_RANGE`, `VIDEO_UNSUPPORTED` | O vídeo foge de `video_limits` nessa `quality`. Tente outra. |
| `STYLE_REQUIRED` | `replace: none` sem `style`. |
| `STYLE_UNSUPPORTED` | Estilo em `quality: high` num vídeo mais longo que `video_mid_max_seconds`. |
| `TARGET_UNSUPPORTED` | `target` depois do fim do vídeo, ou num vídeo `high` mais longo que `video_mid_max_seconds`. |
| `INVALID_IMAGE` | Foto ilegível ou fora dos formatos aceitos. |
| `PRODUCT_URL_INVALID`, `PRODUCT_NOT_READABLE` | O link não é de uma página de produto, ou ela não abre. Envie as fotos. |
| `PERSONA_NOT_FOUND`, `VERSION_NOT_FOUND`, `VIDEO_NOT_FOUND`, `PRESET_NOT_FOUND`, `FACE_NOT_FOUND`, `PHOTO_NOT_FOUND`, `SHOT_NOT_FOUND`, `MEDIA_NOT_FOUND` | O id não existe neste workspace. |

Quando uma foto ou vídeo termina em `failed`, `error_code` diz por quê: `SAFETY_BLOCKED`, `COPYRIGHT_BLOCKED`, `REAL_FACES_BLOCKED` e `MEDIA_REJECTED` são recusas pelo conteúdo (mude as características, as fotos ou o vídeo); `MEDIA_FAILED`, `MEDIA_UNAVAILABLE` e `TIMEOUT` valem nova tentativa. Os créditos já voltaram nos dois casos.
