# Genera clips de un video

> Analiza el enlace, crea el envío, sigue los estados y trabaja con los clips que generó la IA.

El clipping tiene tres recursos: el **video** (la fuente), el **envío** (un procesamiento de ese video) y los **clips** (los cortes que generó el envío). Un video puede tener varios envíos, por ejemplo con tramos o plantillas distintos.

```text
POST /clips/info  →  POST /clips  →  GET .../submissions/{id}  →  GET .../clips
    análisis            envío           hasta completed             los cortes
```

## Analiza el enlace

```bash
curl -X POST https://api.cut.pro/api/v1/clips/info \
  -H "X-Api-Key: $CUTPRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }'
```

La respuesta trae título, autor, plataforma, duración en segundos, miniatura y el costo en créditos. Analizar no cobra, pero tiene un límite propio de 10 por minuto. Si el archivo lo tienes tú, usa la [subida](/es/uploads) en lugar de este paso.

Cuando el enlace no sirve, el `code` dice por qué:

| Status | Codes | Significa |
|---|---|---|
| `400` | `VIDEO_TOO_LONG` | Supera la duración máxima del plan. `extra.duration` y `extra.max_duration` dicen cuánto. |
| `403` | `PRIVATE_VIDEO`, `AGE_RESTRICTED`, `ACCESS_DENIED`, `REGION_BLOCKED`, `COPYRIGHT_BLOCKED`, `PLATFORM_NOT_SUPPORTED` | La plataforma no entrega este video. |
| `404` | `VIDEO_ID_NOT_FOUND`, `UNAVAILABLE`, `METADATA_UNAVAILABLE` | El video no existe o salió del aire. |
| `422` | `PLAYLIST_URL`, `CHANNEL_URL`, `SHORTS_NOT_SUPPORTED`, `LIVE_STREAM`, `PREMIUM_ONLY`, `AUDIO_ONLY`, `INVALID_URL`, `INVALID_DURATION`, `INVALID_DIMENSIONS` | El enlace es válido, pero no es un video del que se puedan generar clips. |

## Crea el envío

```bash
curl -X POST https://api.cut.pro/api/v1/clips \
  -H "X-Api-Key: $CUTPRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "video_id": "7412908365112823",
    "source_language": "pt",
    "timeframe": { "start": 600, "end": 1800 },
    "template_id": "7398110254410021"
  }'
```

| Campo | Obligatorio | Descripción |
|---|---|---|
| `video_id` | sí | El `id` de `POST /clips/info` o de la subida. |
| `source_language` | no | `auto` (predeterminado), `pt` o `en`. Fíjalo cuando lo sepas: acierta más. |
| `timeframe` | no | `{ start, end }` en segundos. Genera clips solo de ese tramo. |
| `template_id` | no | Una plantilla de `GET /templates`. Todo clip sale editado con ella, listo para renderizar. |
| `translate_to` | no | Código ISO 639-1 (`en`, `es`). Traduce los subtítulos de los clips y cuesta más. |
| `strategy_id` | no | Una estrategia de clipping guardada en Cut.Pro. Sin ella, la IA usa la configuración predeterminada. |

> Los créditos salen al crear. `credits_charged` en la respuesta dice cuánto salió.

Errores comunes al crear: `402 INSUFFICIENT_CREDITS`, `409 VIDEO_ALREADY_PROCESSING` (el mismo video ya se está procesando), `429 TOO_MANY_PENDING_CLIPS` (cola del workspace llena), `400 TIMEFRAME_OUT_OF_BOUNDS` y `400 TIMEFRAME_TOO_SHORT`.

## Sigue el envío

```bash
curl https://api.cut.pro/api/v1/clips/7412908365112823/submissions/7412908371004912 \
  -H "X-Api-Key: $CUTPRO_API_KEY"
```

Consulta cada 5 a 10 segundos. Los estados siguen este orden:

| `status` | Qué está pasando |
|---|---|
| `queued` | En la cola. `queue_position` y `estimated_time` (en segundos) dicen cuánto falta. |
| `downloading` | Descargando la fuente. |
| `transcribing` | Transcribiendo el audio. |
| `video_analysis` | Analizando la imagen. |
| `analyzing` | La IA eligiendo los momentos. |
| `finalizing` | Generando los clips. |
| `completed` | Listo. `clips_count` dice cuántos clips salieron. |
| `failed` | Falló. El motivo está en `error_code`. |

### Fuente que aún no está en el aire

Un envío puede quedar detenido en `downloading` porque la fuente todavía no existe completa: un estreno programado, una transmisión en vivo aún al aire o una grabación que la plataforma todavía procesa. En ese caso `waiting_reason` viene completo:

| `waiting_reason` | Significa |
|---|---|
| `SOURCE_PREMIERE_SCHEDULED` | Estreno programado. `waiting_until` trae la hora anunciada, cuando la plataforma la informa. |
| `SOURCE_LIVE_IN_PROGRESS` | La transmisión en vivo aún está al aire. |
| `SOURCE_VOD_PROCESSING` | La transmisión terminó y la plataforma todavía prepara la grabación. |

No es un error y no se trabó: el envío continúa solo cuando la fuente queda disponible. Muéstraselo a la persona y ofrece cancelar, porque el `DELETE` en este estado devuelve los créditos.

### Cuando falla

`error_code` dice el motivo. Los que empiezan con `DOWNLOAD_` son de la fuente (`DOWNLOAD_PRIVATE_VIDEO`, `DOWNLOAD_MEMBERS_ONLY`, `DOWNLOAD_GEO_RESTRICTED`, `DOWNLOAD_REMOVED_BY_UPLOADER`): cambiar de video es el camino. `EMPTY_TRANSCRIPT` y `DOWNLOAD_NO_AUDIO` indican que no hay voz de la que generar clips. Los demás son fallas del procesamiento y valen un nuevo intento:

```bash
curl -X POST https://api.cut.pro/api/v1/clips/7412908365112823/submissions/7412908371004912/retry \
  -H "X-Api-Key: $CUTPRO_API_KEY"
```

El reintento crea un envío **nuevo** con la misma configuración y cobra como `POST /clips`. El que falló sigue en el historial. Solo vale para un envío en `failed`: en los demás, la respuesta es `409 SUBMISSION_NOT_FAILED`.

## Lista los clips

```bash
curl "https://api.cut.pro/api/v1/clips/7412908365112823/submissions/7412908371004912/clips?min_rating=7&sort=rating&order=desc" \
  -H "X-Api-Key: $CUTPRO_API_KEY"
```

```json title="200 OK"
{
  "clips": [
    {
      "id": "7412908412887301",
      "title": "El estribillo que todo el mundo conoce",
      "description": "El momento de mayor energía del video, con el público cantando a coro.",
      "rating": 9.2,
      "start_time": 42.5,
      "end_time": 71.0,
      "language": "en",
      "created_at": "2026-10-29T18:04:50.000Z",
      "thumbnail_url": "https://...",
      "download_url": "https://...",
      "play_url": "https://...",
      "has_template_applied": false,
      "edit_id": null
    }
  ],
  "pagination": { "current_page": 1, "total_pages": 1, "total_count": 6, "has_next_page": false, "has_previous_page": false, "limit": 20 }
}
```

- `rating` va de 0 a 10. Filtra con `min_rating` y `max_rating`.
- Ordena por `rating`, `duration`, `title` o `start_time`.
- `download_url` es el corte crudo, sin edición. Para el MP4 con plantilla y subtítulos, [renderiza](/es/rendering).
- Los enlaces están firmados y duran poco. Pide la lista de nuevo cuando vayas a usarlos.

### Subtítulos del clip

```bash
curl "https://api.cut.pro/api/v1/clips/7412908365112823/submissions/7412908371004912/clips/7412908412887301/subtitles?format=srt" \
  -H "X-Api-Key: $CUTPRO_API_KEY"
```

Devuelve SRT o texto plano (`format=txt`), con el tiempo empezando en `00:00` y alineado al clip. Si el clip tiene edición, los subtítulos son los de la edición, con correcciones y traducción.

## Retención

Los clips de un envío no quedan para siempre. Pasada la retención, el envío aparece con `expired: true` y las rutas de clips responden `410 SUBMISSION_EXPIRED`. Es permanente: no repitas, envía el video de nuevo. Lo que ya renderizaste sigue recuperable por el `edit_id`.

## Organiza la biblioteca

| Ruta | Qué hace |
|---|---|
| `GET /clips` | Lista los videos, con contadores de clips, ediciones, exports y posts y el estado del último envío. |
| `GET /clips/{videoId}/submissions` | Lista los envíos de un video, con `credit_cost`, `timeframe` y `expired`. |
| `DELETE /clips/{videoId}/submissions/{submissionId}` | Elimina el envío y los clips. Si aún se procesa, cancela y devuelve los créditos. |
| `DELETE /clips/{videoId}/submissions/{submissionId}/clips/{clipId}` | Elimina un clip. |
| `DELETE /clips/{videoId}` | Elimina el video con todos sus envíos. Los que se procesan se cancelan y se reembolsan. |

Eliminar no tiene vuelta atrás.
