Quickstart
Haz tu primera solicitud y sal con un clip vertical en MP4.
En esta guía verificas la clave con una llamada que no cobra nada, analizas un video, generas los clips y descargas el mejor ya renderizado.
Vas a necesitar: una cuenta en Cut.Pro, una clave de API y curl. Los ejemplos completos del final usan Node.js 18+ o Python 3.9+.
1. Crea la clave
Abre Claves de API, haz clic en Nueva clave y copia el valor. Aparece una sola vez.
export CUTPRO_API_KEY="pega_tu_clave_aqui"2. Verifica la clave
GET /workspace no cobra créditos y muestra en qué workspace opera la clave.
curl https://api.cut.pro/api/v1/workspace \
-H "X-Api-Key: $CUTPRO_API_KEY"{
"id": "7401220118845503",
"name": "Estudio Ana",
"is_personal": true,
"status": "active",
"role": "admin",
"plan_name": "Pro",
"plan_is_free": false,
"credits": 120,
"credits_unlimited": false,
"created_at": "2026-03-02T14:11:09.000Z"
}¿Recibiste 401 UNAUTHORIZED? La clave es incorrecta o fue revocada. ¿Recibiste 400 MISSING_WORKSPACE_ID? La clave alcanza más de un workspace: ve Autenticación.
3. Analiza el video
Analizar es gratis. La respuesta trae el costo del clipping y tu saldo.
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" }'{
"id": "7412908365112823",
"title": "Rick Astley - Never Gonna Give You Up",
"platform": "youtube",
"duration": 213,
"credits_cost": 4,
"current_balance": 120
}Guarda el id: es el video_id de los próximos pasos.
4. Genera los clips
Este es el paso que cobra. El valor de credits_cost sale del saldo al instante, y vuelve si cancelas antes de que termine.
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" }'{
"id": "7412908371004912",
"video_id": "7412908365112823",
"status": "queued",
"credits_charged": 4
}5. Espera a que termine
Consulta el envío cada 5 a 10 segundos hasta que status pase a completed o failed.
curl https://api.cut.pro/api/v1/clips/7412908365112823/submissions/7412908371004912 \
-H "X-Api-Key: $CUTPRO_API_KEY"{
"id": "7412908371004912",
"video_id": "7412908365112823",
"status": "completed",
"error_code": null,
"clips_count": 9,
"completed_at": "2026-10-29T18:04:51.000Z"
}6. Obtén el mejor clip
Cada clip tiene una nota de 0 a 10. Ordena por ella y pide solo uno.
curl "https://api.cut.pro/api/v1/clips/7412908365112823/submissions/7412908371004912/clips?sort=rating&order=desc&limit=1" \
-H "X-Api-Key: $CUTPRO_API_KEY"{
"clips": [
{
"id": "7412908412887301",
"title": "El estribillo que todo el mundo conoce",
"rating": 9.2,
"start_time": 42.5,
"end_time": 71.0,
"language": "en",
"has_template_applied": false,
"edit_id": null
}
],
"pagination": { "current_page": 1, "total_pages": 9, "total_count": 9, "has_next_page": true, "has_previous_page": false, "limit": 1 }
}7. Renderiza y descarga
Pide el render del clip. Sin plantilla, sale con la configuración predeterminada.
curl -X POST https://api.cut.pro/api/v1/clips/7412908365112823/submissions/7412908371004912/clips/7412908412887301/render \
-H "X-Api-Key: $CUTPRO_API_KEY"{
"id": "7412908490112774",
"edit_id": "7412908488820131",
"status": "queued",
"output_resolution": "1080p",
"from_cache": false,
"download_url": null
}Consulta GET /renders/7412908490112774 hasta que status pase a completed y pide el enlace:
curl https://api.cut.pro/api/v1/renders/7412908490112774/download \
-H "X-Api-Key: $CUTPRO_API_KEY"{
"url": "https://...",
"filename": "el-estribillo-que-todo-el-mundo-conoce.mp4"
}El enlace vale 1 hora. Listo: ese es tu clip.
Todo el flujo en un archivo
Los pasos 3 a 7 encadenados, con la espera resuelta. Cambia la URL y ejecuta.
const API = "https://api.cut.pro/api/v1";
const headers = { "X-Api-Key": process.env.CUTPRO_API_KEY, "Content-Type": "application/json" };
const PENDING = ["queued", "active", "waiting_quality"];
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.id }) });
const base = `/clips/${video.id}/submissions/${submission.id}`;
let state = submission;
while (state.status !== "completed") {
if (state.status === "failed") throw new Error(state.error_code);
await wait(10);
state = await call(base);
}
const { clips: [best] } = await call(`${base}/clips?sort=rating&order=desc&limit=1`);
const render = await call(`${base}/clips/${best.id}/render`, { method: "POST" });
let url = render.download_url;
while (!url) {
await wait(10);
const job = await call(`/renders/${render.id}`);
if (job.status === "completed") url = (await call(`/renders/${render.id}/download`)).url;
else if (!PENDING.includes(job.status)) throw new Error(job.status);
}
console.log(best.title, url);Ajusta el código
- Corta solo un tramo: envía
timeframe: { "start": 600, "end": 1800 }enPOST /clipspara generar clips del minuto 10 al 30. - Aplica tu estilo: pasa un
template_iddeGET /templatesenPOST /clipsy todo clip sale con tus subtítulos y tu encuadre. - Traduce los subtítulos:
translate_to: "es"enPOST /clipsgenera los subtítulos en español. Cuesta más que el clipping simple, ycredits_chargedmuestra cuánto se cobró. - Usa un archivo tuyo: cambia el paso 3 por la subida, que devuelve el mismo
video_id.