A API do KolWrite para agentes de IA
Como deixar um agente de IA (Claude Code, Codex, Cursor ou um script seu) transformar gravações em transcrições, legendas SRT e tempos por palavra com a API da plataforma KolWrite em https://api.kolwrite.com. Uma pessoa cria um token uma única vez; o agente o lê de uma variável de ambiente e chama HTTPS puro. Não é preciso nenhum SDK.
Esta é a API da plataforma, com tokens kol_. A API de créditos em https://app.kolwrite.com (cabeçalho x-api-key) é outra API, descrita (em inglês) em https://console.kolwrite.com/llms.txt para quem a procura.
1. Dê um token ao agente
- O acesso à API é ativado por conta; sem ele, criar ou usar um token é recusado.
- Uma pessoa cria o token no app KolWrite (Configurações → Conta → Acesso à API → Criar token) e escolhe o menor conjunto de escopos. O segredo (
kol_...) aparece uma única vez. - Guarde-o em uma variável de ambiente, longe de prompts, logs e git.
| Tarefa | Escopos |
|---|---|
| Transcrever e exportar | files:write, jobs:write, jobs:read, transcripts:read |
| Consultar também o saldo de créditos | acrescente billing:read |
| Endpoints compatíveis com OpenAI | ai:use (gasta créditos; não faz parte da predefinição Automação do app) |
| Criar links de compartilhamento | acrescente shares:write |
Cole isto em AGENTS.md, CLAUDE.md ou .cursorrules:
## KolWrite platform API
- Base URL https://api.kolwrite.com. The token is in the environment variable KOLWRITE_TOKEN: send it as "Authorization: Bearer $KOLWRITE_TOKEN" and never print it.
- Flow: POST /api/v1/media/upload-session, PUT the bytes to data.upload_url, POST /api/v1/media/complete, POST /api/v1/jobs, poll GET /api/v1/jobs/{job_id} until status is succeeded, then GET /api/v1/jobs/{job_id}/export?format=json
- Spec: https://kolwrite-docs.pages.dev/openapi.json. Guide: https://kolwrite-docs.pages.dev/agents.md
2. Qual chamada usar
| Você quer | Chamada |
|---|---|
| A transcrição de um arquivo, com tempos por palavra e falantes | sessão de upload, depois POST /api/v1/jobs (type: transcription), depois GET /api/v1/jobs/{job_id}/export?format=json |
| Legendas SRT ou VTT | GET /api/v1/jobs/{job_id}/export?format=srt ou format=vtt (plano Plus ou superior) |
| Legendas em outro idioma | options.target_language na tarefa e depois exportar |
| Texto simples | export?format=text |
| O texto de um clipe de voz curto, sem tarefa | POST /api/v1/ai/openai/audio/transcriptions |
| Chat, respostas, embeddings | /api/v1/ai/openai/* (endpoints compatíveis com OpenAI) |
| A transcrição salva, com versões | GET /api/v1/jobs/{job_id}/artifacts |
| O saldo de créditos | GET /api/v1/billing/balance |
| Um link público para uma transcrição | POST /api/v1/shares |
| Quais perfis de modelo existem | GET /api/v1/models |
3. Transcrever um arquivo em Python
import json, mimetypes, os, time
import requests
BASE = "https://api.kolwrite.com"
TOKEN = os.environ["KOLWRITE_TOKEN"]
def call(method, path, **kw):
headers = {"Authorization": f"Bearer {TOKEN}", **kw.pop("headers", {})}
r = requests.request(method, BASE + path, headers=headers, timeout=120, **kw)
r.raise_for_status()
return r
def transcribe(path, profile="oracle", language="auto"):
name, size = os.path.basename(path), os.path.getsize(path)
ctype = mimetypes.guess_type(name)[0] or "application/octet-stream"
session = call("POST", "/api/v1/media/upload-session",
json={"filename": name, "file_size_bytes": size,
"content_type": ctype}).json()["data"]
with open(path, "rb") as f:
requests.put(session["upload_url"], data=f, headers=session["headers"],
timeout=3600).raise_for_status()
media = call("POST", "/api/v1/media/complete",
json={"finalize_token": session["finalize_token"]}).json()["data"]
job = call("POST", "/api/v1/jobs",
headers={"Idempotency-Key": f"{name}-{size}-{profile}-{language}"},
json={"type": "transcription",
"input": {"type": "media_ref", "media_id": media["media_id"]},
"profile": profile,
"options": {"language": language,
"diarization": {"mode": "regular"}}}).json()["data"]
while True:
status = call("GET", f"/api/v1/jobs/{job['job_id']}").json()["data"]["status"]
if status in ("succeeded", "failed", "cancelled"):
break
time.sleep(5)
if status != "succeeded":
raise RuntimeError(f"job {job['job_id']} {status}")
export = call("GET", f"/api/v1/jobs/{job['job_id']}/export",
params={"format": "json"}).json()
return job["job_id"], json.loads(export["data"]) # data is a JSON string
job_id, transcript = transcribe("interview.wav")
for seg in transcript["segments"]:
print(f"{seg['start']:.2f}-{seg['end']:.2f} {seg.get('speaker', '')} {seg['text']}")
Arquivos grandes são enviados em partes: a sessão devolve então data.upload_url como null e uma URL para cada parte em data.multipart_part_urls (veja o início rápido).
4. Usar os tempos
A exportação JSON traz segments, cada um com start e end em segundos, text, um speaker quando a separação de falantes foi executada e words (text, start, end). Deixe o agente escolher segmentos pelo índice e ler os tempos na transcrição; nunca deixe um modelo digitar marcas de tempo por conta própria.
import subprocess
keep = [s for s in transcript["segments"] if "pricing" in s["text"].lower()]
for i, seg in enumerate(keep):
subprocess.run(["ffmpeg", "-y", "-i", "talk.mp4", "-ss", str(seg["start"]),
"-to", str(seg["end"]), f"clip{i}.mp4"], check=True)
As legendas vêm direto da API. include_speakers=false omite os nomes dos falantes e max_chars_per_entry define o tamanho de cada entrada de legenda:
curl -H "Authorization: Bearer $KOLWRITE_TOKEN" -o talk.srt \
"https://api.kolwrite.com/api/v1/jobs/JOB_ID/export?format=srt&include_speakers=false&max_chars_per_entry=42"
Baixar SRT e VTT exige o plano Plus ou superior. Os outros planos recebem HTTP 403 com o código subtitle_export_requires_plus; as exportações em JSON e em texto não são afetadas.
5. Regras para agentes
- Envie um
Idempotency-Keyao criar uma tarefa, para que uma nova tentativa não inicie uma segunda. - Tente de novo após
429,502,503e504com espera exponencial; em429, aguardeRetry-After. Não tente de novo após401,403nem erros de validação. Veja erros. - Leia
detail.code, não o texto da mensagem. - Uma tarefa reserva créditos ao ser criada e acerta o valor ao terminar; consulte
GET /api/v1/billing/balanceantes de um lote grande. - O arquivo OpenAPI é o contrato: cada operação indica o escopo exigido em
x-required-scope.
Perguntas
Como faço legendas SRT de um vídeo com um agente de IA?
Envie o arquivo, crie uma tarefa de transcrição, espere succeeded e chame o endpoint de exportação com format=srt. Legendas exigem o plano Plus ou superior.
O Claude Code ou o Codex podem chamar a API do KolWrite?
Podem. Eles a chamam por HTTPS com um token de acesso pessoal lido de uma variável de ambiente. Não há SDK nem servidor MCP para instalar.
Como um agente obtém o carimbo de tempo de cada palavra?
Exporte a tarefa como JSON. Cada segmento traz words com start e end em segundos.