# Crea personas e intercambia a la persona del video

> Crea una persona realista a partir de características, fotos del rostro o un personaje listo, y colócala en cualquier video o foto de producto.

Una **persona** es una persona realista hecha a partir de características (edad, cabello, ropa), de fotos del rostro de quien la usa o de un personaje listo. Una vez guardada, reemplaza a la persona de un video de la biblioteca y mantiene la escena, la cámara, el movimiento y el sonido. También aparece en fotos con un producto en la mano.

Foto y video corren en segundo plano: tú creas y consultas. `GET /personas` trae, por persona, `image_status` (`generating`, `ready` o `failed`) y `video_generating`, así que una llamada muestra todo lo que aún está en curso.

> Las personas siempre cobran, incluso en uso liberado. Solo son gratis crear desde un personaje listo, restaurar una versión, leer un producto por el enlace y evaluar. Lee los precios de `GET /personas/catalog` y `GET /personas/swap/quote` en el momento, nunca los fijes en el código. Si una generación falla, los créditos vuelven solos.

### Lee el catálogo

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

| Campo | Para qué sirve |
|---|---|
| `chip_options`, `default_chips` | Todas las opciones de cada característica y el valor predeterminado. Arma el formulario a partir de aquí. |
| `face_photo_groups`, `max_face_photos` | Las características que aún valen cuando la persona viene de fotos del rostro, y cuántas fotos caben. |
| `video_styles` | Los estilos de animación o ilustración que puede recibir un video. |
| `pricing` | Precio de cada foto y de cada segundo de video por calidad. |
| `video_limits` | Duración, tamaño y resolución aceptados en el video de origen, por calidad. |

### Crea la persona

Envía una opción por característica en `chips`. La foto empieza a generarse y la respuesta es `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"
    }
  }'
```

**Con el rostro de quien la usa.** Envía las fotos antes y pasa los ids en `face_ids`, dentro de 24 horas y hasta `max_face_photos` (6). JPEG, PNG, WebP o HEIC de hasta 10 MB. `own_face_adult: true` confirma que la foto es de quien la usa y que esa persona tiene 18 años o más.

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

Con `face_ids`, solo las características de `face_photo_groups` siguen valiendo, y en ellas la opción `photo` mantiene el rasgo tal como está en las fotos.

**Desde un personaje listo, gratis.** `GET /personas/presets` lista personajes con la foto ya hecha (`category`: `weird`, `cartoon`, `creator` o `influencers`). Crear desde uno de ellos no genera nada y nace con `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" }'
```

Con `name`, la persona sale ya guardada. Sin `name`, es un borrador para guardar después. Sigue siendo ese personaje: en un `regenerate`, los `chips` se ignoran y solo la `note` edita. `PUT /personas/presets/{presetId}/favorite` con `{ "favorite": true }` marca favoritos.

### Ajusta y guarda

Consulta `GET /personas/{id}` cada 5 segundos hasta que `image_status` pase a `ready`, o a `failed` con el motivo en `error_code`.

Para cambiar la foto, genera de nuevo con otros `chips` o edita con una `note` de una línea, que mantiene a la misma persona:

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

Una edición con `note` cuesta `pricing.photo_with_references_credits`. Si ya se está generando otra foto, la respuesta es `409 CARD_LOCKED`.

Cuando la foto esté bien, guarda. En una persona guardada, la misma llamada solo cambia el nombre.

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

### Envía el video de origen

Un video que ya está en la biblioteca no necesita este paso: usa su id como `media_id`. Para un archivo nuevo, pide la URL, envía y confirma. Solo MP4 y 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" }'
```

### Pide el precio

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

No se cobra nada. Muéstrale el precio a la persona y espera el sí.

| Parámetro | Valores |
|---|---|
| `quality` | `economy` es la `standard` en resolución menor, ampliada a 1080p, y la más barata. `standard` (predeterminada) sigue las características de la persona. `high` también sigue las fotos, deja el rostro más fiel y acepta videos más largos, por más. Prefiere `high` en una persona hecha de fotos del rostro. |
| `replace` | `person` (predeterminado) cambia a la persona completa, con cuerpo y ropa. `head` cambia solo la cabeza y el cabello. `none` no cambia a nadie y solo aplica el `style`. |
| `style` | Redibuja todo el video en un estilo visual, como `cel` (animación 2D), `felt` (stop motion de fieltro), `pixel` o `silent` (cine mudo), manteniendo cámara y movimiento. Con estilo, se cambia a la persona completa, salvo en `replace: none`. Lista completa en `video_styles`. |

El precio depende solo de la calidad, de la duración y del estilo. `head` y `person` cuestan lo mismo. Un video rechazado en `standard` puede caber en `high`.

### Genera el video

Envía los `credits` del precio, con la misma `quality`, `replace` y `style`. La respuesta es `202` con `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 }'
```

Si el precio cambió, no se cobra nada y la respuesta es `409 PRICE_CHANGED` con el valor correcto en `extra.credits`.

De forma predeterminada, quien se convierte en la persona es la persona principal del video. Para elegir a otra, envía `target`:

- una persona vista en el video: `{ "seconds": 2.5, "x": 0.62, "y": 0.48 }`, con el momento y el centro de ella de 0 a 1. `box` es opcional y ayuda cuando hay gente cerca.
- quien está filmando: `{ "camera": true }`.

Elegir a la persona nunca aumenta el precio confirmado. Si no hay nadie en ese punto, el video termina en `failed` con `TARGET_NOT_A_PERSON` y los créditos vuelven.

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

- `ready`: `download_url` tiene el MP4, válido por 6 horas. Para publicar o renderizar, `POST /generations/{videoId}/edit` devuelve el `edit_id` que va en [`POST /posts`](/es/publishing) o [`POST /renders`](/es/rendering).
- `failed`: el motivo está en `error_code` y los créditos ya volvieron.

## Versiones y evaluaciones

Cada foto que termina se convierte en una versión y pasa a ser la actual. Las anteriores quedan en `versions`, en `GET /personas/{id}`. Volver a una de ellas es gratis:

```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 video guarda la versión de la que salió en `version_id`. Los videos nuevos usan la actual, a menos que envíes `version_id` en `POST /personas/{id}/videos`. `GET /personas/{id}/videos?version_id=...` filtra por versión. Los videos ya hechos no cambian.

Evaluar es gratis y mejora los 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" }'
```

| Evaluar | Ruta | Motivos del `down` |
|---|---|---|
| Foto | `POST /personas/{id}/versions/{versionId}/feedback` | `not_realistic`, `wrong_traits`, `not_like_me`, `defects`, `other` |
| Video | `POST /personas/{id}/videos/{videoId}/feedback` | `different_person`, `scene_changed`, `defects`, `bad_motion`, `other` |

`vote` es `up`, `down` o `null` (limpia). Un `down` en un video cancela los posts de ese video que aún están programados.

`DELETE /personas/{id}` elimina la persona. Las ediciones hechas con sus videos continúan.

## Fotos con producto

Una persona guardada posa en una escena lista o escrita por ti, sosteniendo un producto. Empieza por el producto.

**Por el enlace de la tienda, gratis.** Lee nombre, descripción, precio y marca, y guarda hasta 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 de vitamina C 30 ml", "description": "Sérum facial con 10% de vitamina C.", "price": "R$ 89,90", "brand": "Ejemplo" },
  "photo_ids": ["7413100022003301", "7413100022003302"],
  "partial": false
}
```

Funciona en la mayoría de las tiendas, en Shopee y en Amazon Brasil. `partial: true` significa que el precio o las fotos no llegaron. Hasta 5 lecturas por minuto; por encima de eso, `429 PRODUCT_RATE_LIMITED`.

**Por la foto.** Cuando la página no abre (`PRODUCT_NOT_READABLE`, siempre en Mercado Livre y en TikTok Shop), envía las fotos y escribe los campos. JPEG, PNG, WebP o HEIC de hasta 10 MB, con la etiqueta de cara a la cámara. `rights_confirmed: true` dice que la persona puede usar el producto y la foto. Usa el `id` dentro de 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"
```

Genera la 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 de vitamina C 30 ml", "photo_ids": ["7413100022003301"] }
  }'
```

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

| Campo | Valores |
|---|---|
| `template` | `mirror` (predeterminado), `kitchen`, `bathroom`, `sofa`, `cafe`, `gym`, `street`, `closeup`, `story`, `bedroom`. La plantilla decide qué hace la persona con el producto. |
| `scene` | Escena escrita, en cualquier idioma, de 3 a 500 caracteres. Reemplaza a `template`. |
| `product.action` | Solo con `scene`: `show` (predeterminado, lo muestra a la cámara) o `use` (lo usa con una mano). Una escena que pide las dos manos (untar, servir, abrir, comer) se rechaza con `SCENE_ACTION_UNSUPPORTED` antes de cobrar. |
| `aspect_ratio` | `9:16` (predeterminado), `4:5`, `1:1`, `16:9`. |
| `credits` | `pricing.scene_photo_credits` del catálogo, el doble con `style`. Un precio distinto responde `409 PRICE_CHANGED`. |

Consulta `GET /personas/{id}/shots/{shotId}` cada 5 segundos. En `ready`, `image_url` tiene la foto. `GET /personas/{id}/shots` lista todas, de la más nueva a la más antigua.

## Errores

| Code | Cuándo |
|---|---|
| `INSUFFICIENT_CREDITS` | Saldo insuficiente. `extra.credits_needed` dice cuánto falta, `extra.top_up_url` lleva a la recarga, `extra.is_owner` dice si quien llamó puede recargar. |
| `PRICE_CHANGED` | El precio cambió. El nuevo está en `extra.credits`: muéstralo y pide el sí de nuevo. |
| `CARD_LOCKED` | Ya se está generando una foto de la persona. Espera a que termine. |
| `CARD_NOT_READY` | Guardaste antes de que la foto quedara `ready`. |
| `VIDEO_IN_PROGRESS` | La persona ya está haciendo el mismo video en la misma versión. |
| `VIDEO_DURATION_OUT_OF_RANGE`, `VIDEO_UNSUPPORTED` | El video se sale de `video_limits` en esa `quality`. Prueba otra. |
| `STYLE_REQUIRED` | `replace: none` sin `style`. |
| `STYLE_UNSUPPORTED` | Estilo en `quality: high` en un video más largo que `video_mid_max_seconds`. |
| `TARGET_UNSUPPORTED` | `target` después del fin del video, o en un video `high` más largo que `video_mid_max_seconds`. |
| `INVALID_IMAGE` | Foto ilegible o fuera de los formatos aceptados. |
| `PRODUCT_URL_INVALID`, `PRODUCT_NOT_READABLE` | El enlace no es de una página de producto, o no abre. Envía las 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` | El id no existe en este workspace. |

Cuando una foto o un video termina en `failed`, `error_code` dice por qué: `SAFETY_BLOCKED`, `COPYRIGHT_BLOCKED`, `REAL_FACES_BLOCKED` y `MEDIA_REJECTED` son rechazos por el contenido (cambia las características, las fotos o el video); `MEDIA_FAILED`, `MEDIA_UNAVAILABLE` y `TIMEOUT` valen un nuevo intento. En ambos casos los créditos ya volvieron.
