# Monitorea canales y transmisiones en vivo

> Sigue un canal de YouTube, Twitch o Kick y recibe clips de cada transmisión en vivo o video nuevo, sin enviar enlace.

Un monitor observa un canal y genera clips solo. Hay dos tipos:

| `type` | Qué procesa | Dónde aparecen los clips | Cobro |
|---|---|---|---|
| `live` | Cada transmisión, mientras está al aire, en bloques de 10 minutos | `GET /monitors/{id}/broadcasts/{broadcastId}/clips` | Por bloque de 10 minutos que generó clips, solo con el monitor encendido |
| `video` | Cada video nuevo publicado en el canal | Envíos comunes en `GET /clips` | Como un clipping normal |

Plataformas: YouTube, Twitch y Kick.

## Crea el monitor

```bash
curl -X POST https://api.cut.pro/api/v1/monitors \
  -H "X-Api-Key: $CUTPRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "https://www.twitch.tv/gaules",
    "type": "live",
    "template_id": "7398110254410021"
  }'
```

```json title="201 Created"
{
  "id": "7413020011876610",
  "type": "live",
  "platform": "twitch",
  "username": "gaules",
  "display_name": "Gaules",
  "avatar_url": "https://...",
  "enabled": true,
  "enabled_at": "2026-10-29T19:00:00.000Z",
  "strategy_id": "7398110000000001",
  "template_id": "7398110254410021",
  "video_min_duration": null,
  "video_max_duration": null,
  "days_of_week": [],
  "hours_of_day": []
}
```

| Campo | Descripción |
|---|---|
| `channel` | URL del canal: `https://www.youtube.com/@handle`, `https://www.twitch.tv/login` o `https://kick.com/slug`. |
| `type` | `live` o `video`. |
| `enabled` | Empieza encendido (`true`, predeterminado). Envía `false` para configurar ahora y encender después. |
| `template_id` | Plantilla aplicada a todo clip. Con ella, cada clip ya llega con `edit_id`, listo para renderizar o publicar. |
| `strategy_id` | Estrategia de clipping. Sin ella, la configuración predeterminada. |

Solo para `video`:

| Campo | Descripción |
|---|---|
| `video_min_duration`, `video_max_duration` | Ignora videos más cortos o más largos, en segundos (1 a 3600). |
| `days_of_week` | Días aceptados, 0 es domingo. Vacío acepta todos. |
| `hours_of_day` | Franjas `[desde, hasta]` de hora aceptadas, en la zona horaria del dueño del workspace. |

`POST /monitors` acepta 10 llamadas por minuto, porque consulta el canal en la plataforma. Monitorear el mismo canal con el mismo `type` dos veces responde `409 ALREADY_MONITORING`.

## Enciende y apaga

```bash
curl -X POST https://api.cut.pro/api/v1/monitors/7413020011876610/start \
  -H "X-Api-Key: $CUTPRO_API_KEY"
```

- **Encender** (`/start`): en un canal que ya está en vivo, la grabación empieza en cerca de un minuto. Solo lo que sale al aire desde ahí se procesa.
- **Apagar** (`/stop`): no se procesa ni se cobra ningún bloque nuevo, y la grabación en curso se detiene en cerca de un minuto.
- Llamar a `/start` en un monitor encendido, o a `/stop` en uno apagado, no cambia nada y responde `200`.

> El monitor debe permanecer encendido al menos 10 minutos antes de apagarse. Antes de eso, `/stop` responde `409 MINIMUM_MONITORING_TIME` con `extra.remaining_seconds`. El monitor también se apaga solo cuando se acaba el saldo.

Para un canal que transmite las 24 horas, créalo con `enabled: false` y usa `/start` y `/stop` en los horarios que te interesen.

## Obtén los clips de una transmisión en vivo

Lista las transmisiones del canal:

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

```json title="200 OK"
{
  "broadcasts": [
    {
      "id": "318274651093",
      "title": "Final del campeonato",
      "category": "Counter-Strike",
      "language": "pt",
      "is_mature": false,
      "tags": ["Português"],
      "started_at": "2026-10-29T19:02:11.000Z",
      "ended_at": null,
      "clips_count": 14,
      "thumbnail_url": "https://...",
      "recording_expired": false
    }
  ],
  "pagination": { "current_page": 1, "total_pages": 1, "total_count": 1, "has_next_page": false, "has_previous_page": false, "limit": 20 }
}
```

`ended_at: null` significa que la transmisión está al aire y sigue generando clips cada 10 minutos. No esperes a que termine: consulta los clips a medida que llegan.

```bash
curl "https://api.cut.pro/api/v1/monitors/7413020011876610/broadcasts/318274651093/clips?min_rating=7" \
  -H "X-Api-Key: $CUTPRO_API_KEY"
```

Cada clip trae `rating`, `duration`, `started_at` y `ended_at` (cuándo el momento salió al aire), `play_url` y:

| Campo | Significa |
|---|---|
| `edit_id` | El clip ya tiene edición. Envíalo a `POST /renders` o `POST /posts`. |
| `render_id` | Ya existe un MP4 listo de esa edición. Descárgalo en `GET /renders/{renderId}/download`. |
| `rendering` | Un render de este clip está en la cola o corriendo. |

Un clip sin `edit_id` se renderiza con el diseño predeterminado:

```bash
curl -X POST https://api.cut.pro/api/v1/monitors/7413020011876610/broadcasts/318274651093/clips/7413020199001234/render \
  -H "X-Api-Key: $CUTPRO_API_KEY"
```

Para editar en lote los clips que ya llegaron, usa `POST /monitors/{id}/broadcasts/{broadcastId}/clips/apply_template`. Para todo clip futuro, pon `template_id` en el monitor.

Cuando la grabación expira, `recording_expired` pasa a `true` y los clips de esa transmisión responden `410 RECORDING_EXPIRED`.

## Administra

| Ruta | Qué hace |
|---|---|
| `GET /monitors` | Lista los monitores, filtrando por `type`. |
| `GET /monitors/{id}` | Muestra un monitor y si está encendido. |
| `PATCH /monitors/{id}` | Cambia solo los campos enviados. `null` limpia `template_id` y los límites de duración. |
| `DELETE /monitors/{id}` | Deja de observar. Los clips quedan. Crear de nuevo el mismo canal y `type` trae el monitor de vuelta, con el mismo `id` y el historial. |

## Errores

| Code | Cuándo |
|---|---|
| `INVALID_CHANNEL_URL` | La URL no es de un canal de YouTube, Twitch o Kick. |
| `CREATOR_NOT_FOUND` | El canal no existe. |
| `LIVE_CLIPS_NOT_AVAILABLE` | El plan no incluye clips de transmisiones en vivo. |
| `INVALID_OBSERVING_TYPE` | Pidió transmisiones de un monitor `video`. |
| `MINIMUM_MONITORING_TIME` | Intentó apagar antes de 10 minutos. |
