Cut.ProDocs
Guias

Quickstart: seu primeiro clipe

Do link do vídeo ao MP4 renderizado, com requisições reais

Sete requisições separam um link do YouTube de um clipe vertical renderizado. Este guia mostra as sete, na ordem, com a resposta de cada uma.

Antes de começar, gere uma chave de API e exporte-a no seu terminal:

export CUTPRO_API_KEY="sua_chave"

Todos os exemplos usam a URL base https://api.cut.pro/api/v1 e enviam a chave no header X-Api-Key. Se a sua chave for multi-workspace, adicione também X-Workspace-Id.

1. Analise o vídeo

POST /clips/info lê os metadados do link e calcula o custo. Analisar não consome créditos.

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" }'
Resposta
{
  "id": "7412908365112823",
  "title": "Entrevista completa: 2 horas sobre carreira",
  "author": "Canal Exemplo",
  "platform": "youtube",
  "duration": 7245,
  "credits_cost": 121,
  "current_balance": 480,
  "credits_unlimited": false,
  "force_watermark": false
}

Guarde esse id: é o video_id de todas as chamadas seguintes.

Quer clipar um arquivo do seu computador em vez de uma URL? Veja Enviando um vídeo para o fluxo de upload.

2. Envie para clipagem

POST /clips cria a submissão. Os créditos são debitados aqui, no valor que o passo anterior mostrou.

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 }
  }'
Resposta 201
{
  "id": "7412908371004912",
  "video_id": "7412908365112823",
  "status": "queued",
  "credits_charged": 30
}

O timeframe é opcional: omita para processar o vídeo inteiro, ou restrinja a um trecho (em segundos) para gastar menos. Acima, a primeira meia hora custou 30 créditos em vez de 121.

strategy_id, template_id e source_language (auto, en, pt) também são opcionais. Liste seus templates com GET /templates para obter os IDs.

3. Acompanhe até concluir

Faça polling na submissão a cada 10 ou 15 segundos. O status passa por queued, downloading, transcribing, video_analysis, analyzing e finalizing até chegar em completed (ou failed).

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

Enquanto o vídeo está na fila, queue_position e estimated_time (em segundos) dizem quanto falta. Quando o status vira completed, clips_count traz quantos clipes a IA gerou.

4. Busque os clipes gerados

curl https://api.cut.pro/api/v1/clips/7412908365112823/submissions/7412908371004912/clips \
  -H "X-Api-Key: $CUTPRO_API_KEY"
Resposta
{
  "clips": [
    {
      "id": "7412908412887301",
      "title": "O erro que custou a primeira empresa",
      "rating": 9.2,
      "start_time": 412.5,
      "end_time": 461.8,
      "language": "pt",
      "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 }
}

O rating é a nota da IA de 0 a 10: quanto maior, maior o potencial do corte. Ordene por ele para pegar os melhores primeiro.

5. Renderize um clipe

POST .../render gera o MP4 final. Para aplicar um dos seus visuais antes, chame POST .../apply_template na submissão.

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

Quando from_cache for true, a resposta vem com 200 e o download_url já preenchido: esse clipe já tinha sido renderizado com as mesmas configurações e você pode pular os dois passos seguintes.

6. Acompanhe o render

curl https://api.cut.pro/api/v1/renders/7412908490112774 \
  -H "X-Api-Key: $CUTPRO_API_KEY"
Resposta
{
  "id": "7412908490112774",
  "edit_id": "7412908490112775",
  "status": "active",
  "progress": 64,
  "output_resolution": "1080p"
}

O status passa por queued, active e completed, e progress vai de 0 a 100.

7. Baixe o MP4

curl https://api.cut.pro/api/v1/renders/7412908490112774/download \
  -H "X-Api-Key: $CUTPRO_API_KEY"
Resposta
{
  "url": "https://media.cut.pro/render/7412908490112774.mp4?signature=...",
  "filename": "o-erro-que-custou-a-primeira-empresa.mp4"
}

A url é assinada e vale por uma hora. Baixe o arquivo dentro desse prazo ou peça outra.

O fluxo inteiro em um arquivo

Os sete passos encadeados, com o polling já resolvido. Troque a URL do vídeo e rode.

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.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(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.id}`);
	if (job.status !== "completed") {
		if (job.status === "queued" || job.status === "active") continue;
		throw new Error(job.status);
	}
	download = (await call(`/renders/${render.id}/download`)).url;
}

console.log(best.title, download);

E agora?

Nesta página