Ir al contenido

Quickstart: tu primer clip

Siete peticiones separan un enlace de YouTube de un clip vertical renderizado. Esta guía recorre las siete, en orden, con la respuesta de cada una.

Antes de empezar, genera una clave de API y expórtala en tu terminal:

Ventana de terminal
export CUTPRO_API_KEY="tu_clave"

POST /clips/info lee los metadatos del enlace y calcula el coste. Analizar no consume créditos.

Ventana de terminal
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" }'
Respuesta
{
"video_id": "7412908365112823",
"title": "Entrevista completa: 2 horas sobre carrera",
"author": "Canal de ejemplo",
"platform": "youtube",
"duration": 7245,
"credits_cost": 121,
"current_balance": 480,
"credits_unlimited": false,
"force_watermark": false
}

Guarda el video_id: es lo que identifica el vídeo en todas las llamadas siguientes.

POST /clips crea el envío. Los créditos se cobran aquí, por el importe que mostró el paso anterior.

Ventana de terminal
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",
"timeframe": { "start": 0, "end": 1800 }
}'
Respuesta 201
{
"submission_id": "7412908371004912",
"video_id": "7412908365112823",
"status": "queued",
"credits_charged": 30
}

El timeframe es opcional: omítelo para procesar el vídeo entero, o redúcelo a un tramo (en segundos) para gastar menos. Arriba, la primera media hora costó 30 créditos en vez de 121.

Haz polling del envío cada 10 o 15 segundos. El status pasa por queued, downloading, transcribing, video_analysis, analyzing y finalizing hasta llegar a completed (o failed).

Ventana de terminal
curl https://api.cut.pro/api/v1/clips/7412908365112823/submissions/7412908371004912 \
-H "X-Api-Key: $CUTPRO_API_KEY"
Respuesta
{
"submission_id": "7412908371004912",
"video_id": "7412908365112823",
"status": "analyzing",
"error_code": null,
"clips_count": 0,
"queue_position": 2,
"estimated_time": 340
}

Mientras el vídeo espera en la cola, queue_position y estimated_time (en segundos) dicen cuánto falta. Cuando el status pasa a completed, clips_count trae cuántos clips generó la IA.

Ventana de terminal
curl https://api.cut.pro/api/v1/clips/7412908365112823/submissions/7412908371004912/clips \
-H "X-Api-Key: $CUTPRO_API_KEY"
Respuesta
{
"clips": [
{
"id": "7412908412887301",
"title": "El error que le costó su primera empresa",
"rating": 9.2,
"start_time": 412.5,
"end_time": 461.8,
"language": "es",
"play_url": "https://media.cut.pro/preview/...",
"download_url": "https://media.cut.pro/clip/...",
"has_template_applied": false
}
],
"pagination": { "current_page": 1, "total_pages": 1, "total_count": 12, "has_next_page": false }
}

El rating es la nota de la IA de 0 a 10: cuanto más alta, más potencial tiene el corte. Ordena por ella para quedarte con los mejores primero.

POST .../render genera el MP4 final. Para aplicar antes uno de tus estilos, llama a POST .../apply_template en el envío.

Ventana de terminal
curl -X POST \
https://api.cut.pro/api/v1/clips/7412908365112823/submissions/7412908371004912/clips/7412908412887301/render \
-H "X-Api-Key: $CUTPRO_API_KEY"
Respuesta 202
{
"render_id": "7412908490112774",
"edit_setting_id": "7412908490112775",
"status": "queued",
"output_resolution": "1080p",
"has_watermark": false,
"from_cache": false,
"download_url": null
}

Cuando from_cache llega como true, la respuesta es un 200 con el download_url ya rellenado: ese clip ya se había renderizado con la misma configuración y puedes saltarte los dos pasos siguientes.

Ventana de terminal
curl https://api.cut.pro/api/v1/renders/7412908490112774 \
-H "X-Api-Key: $CUTPRO_API_KEY"
Respuesta
{
"render_id": "7412908490112774",
"edit_setting_id": "7412908490112775",
"status": "active",
"progress": 64,
"output_resolution": "1080p"
}

El status pasa por queued, active y completed, y progress va de 0 a 100.

Ventana de terminal
curl https://api.cut.pro/api/v1/renders/7412908490112774/download \
-H "X-Api-Key: $CUTPRO_API_KEY"
Respuesta
{
"url": "https://media.cut.pro/render/7412908490112774.mp4?signature=...",
"filename": "el-error-que-le-costo-su-primera-empresa.mp4"
}

La url está firmada y vale una hora. Descarga el archivo dentro de ese plazo o pide otra.

Los siete pasos encadenados, con el polling ya resuelto. Cambia la URL del vídeo y ejecútalo.

const API = "https://api.cut.pro/api/v1";
const headers = {
"X-Api-Key": process.env.CUTPRO_API_KEY,
"Content-Type": "application/json",
};
async function call(path, init) {
const response = await fetch(`${API}${path}`, { ...init, headers });
const body = await response.json();
if (!response.ok) throw new Error(`${response.status} ${body.code}`);
return body;
}
const wait = (seconds) => new Promise((resolve) => setTimeout(resolve, seconds * 1000));
const video = await call("/clips/info", {
method: "POST",
body: JSON.stringify({ url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }),
});
console.log(`${video.title}: ${video.credits_cost} créditos`);
const submission = await call("/clips", {
method: "POST",
body: JSON.stringify({ video_id: video.video_id }),
});
const base = `/clips/${video.video_id}/submissions/${submission.submission_id}`;
let state = submission;
while (state.status !== "completed") {
if (state.status === "failed") throw new Error(state.error_code);
await wait(15);
state = await call(base);
}
const { clips } = await call(`${base}/clips`);
const best = [...clips].sort((a, b) => b.rating - a.rating)[0];
const render = await call(`${base}/clips/${best.id}/render`, { method: "POST" });
let download = render.from_cache ? render.download_url : null;
while (!download) {
await wait(10);
const job = await call(`/renders/${render.render_id}`);
if (job.status !== "completed") {
if (job.status === "queued" || job.status === "active") continue;
throw new Error(job.status);
}
download = (await call(`/renders/${render.render_id}/download`)).url;
}
console.log(best.title, download);

Publica en redes

Lleva los clips renderizados a TikTok, Instagram, YouTube y más