KolWrite API для ИИ-агентов
Как позволить ИИ-агенту (Claude Code, Codex, Cursor или вашему собственному скрипту) превращать записи в расшифровки, субтитры SRT и тайминги слов через API платформы KolWrite по адресу https://api.kolwrite.com. Человек один раз создаёт токен; агент читает его из переменной окружения и вызывает обычный HTTPS. SDK не нужен.
Это API платформы с токенами kol_. API кредитов на https://app.kolwrite.com (заголовок x-api-key) — другое API, оно описано (по-английски) на https://console.kolwrite.com/llms.txt для тех, кто ищет его.
1. Выдайте агенту токен
- Доступ к API включается для каждого аккаунта отдельно; без него создание и использование токена отклоняются.
- Человек создаёт токен в приложении KolWrite (Настройки → Аккаунт → Доступ к API → Создать токен) и выбирает минимальный набор областей доступа. Секрет (
kol_...) показывается один раз. - Храните его в переменной окружения, вдали от промптов, журналов и git.
| Задача | Области доступа |
|---|---|
| Расшифровка и экспорт | files:write, jobs:write, jobs:read, transcripts:read |
| Плюс проверка баланса кредитов | добавьте billing:read |
| Эндпоинты, совместимые с OpenAI | ai:use (тратит кредиты; не входит в набор Automation в приложении) |
| Создание ссылок для общего доступа | добавьте shares:write |
Вставьте это в AGENTS.md, CLAUDE.md или .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. Какой вызов использовать
| Вам нужно | Вызов |
|---|---|
| Расшифровка файла с таймингами слов и говорящими | сессия загрузки, затем POST /api/v1/jobs (type: transcription), затем GET /api/v1/jobs/{job_id}/export?format=json |
| Субтитры SRT или VTT | GET /api/v1/jobs/{job_id}/export?format=srt или format=vtt (тариф Plus или выше) |
| Субтитры на другом языке | options.target_language в задаче, затем экспорт |
| Обычный текст | export?format=text |
| Текст короткой голосовой записи без задачи | POST /api/v1/ai/openai/audio/transcriptions |
| Чат, ответы, эмбеддинги | /api/v1/ai/openai/* (эндпоинты, совместимые с OpenAI) |
| Сохранённая расшифровка с версиями | GET /api/v1/jobs/{job_id}/artifacts |
| Баланс кредитов | GET /api/v1/billing/balance |
| Публичная ссылка на расшифровку | POST /api/v1/shares |
| Какие профили моделей существуют | GET /api/v1/models |
3. Расшифровка файла на 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']}")
Большие файлы загружаются частями: тогда сессия возвращает data.upload_url со значением null и по одному URL на каждую часть в data.multipart_part_urls (см. быстрый старт).
4. Используйте тайминги
В JSON-экспорте есть segments; у каждого сегмента start и end в секундах, text, speaker, если выполнялось разделение по говорящим, и words (text, start, end). Пусть агент выбирает сегменты по номеру и берёт время из расшифровки; никогда не позволяйте модели вписывать временные метки самой.
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)
Субтитры приходят прямо из API. include_speakers=false убирает имена говорящих, а max_chars_per_entry задаёт длину каждой строки субтитров:
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"
Скачивание SRT и VTT требует тарифа Plus или выше. На других тарифах возвращается HTTP 403 с кодом subtitle_export_requires_plus; экспорт в JSON и текст это не затрагивает.
5. Правила для агентов
- Передавайте
Idempotency-Keyпри создании задачи, чтобы повторный запрос не запустил вторую. - Повторяйте запрос после
429,502,503и504с экспоненциальной задержкой; при429дождитесьRetry-After. Не повторяйте после401,403и ошибок валидации. См. ошибки. - Читайте
detail.code, а не текст сообщения. - Задача резервирует кредиты при создании и рассчитывается по завершении; проверьте
GET /api/v1/billing/balanceперед большой партией. - Файл OpenAPI — это контракт: каждая операция указывает нужную область доступа в
x-required-scope.
Вопросы
Как сделать субтитры SRT из видео с помощью ИИ-агента?
Загрузите файл, создайте задачу расшифровки, дождитесь succeeded и вызовите эндпоинт экспорта с format=srt. Для субтитров нужен тариф Plus или выше.
Могут ли Claude Code или Codex вызывать API KolWrite?
Да. Они вызывают его по HTTPS с персональным токеном доступа из переменной окружения. Устанавливать SDK или MCP-сервер не нужно.
Как агент получает временные метки каждого слова?
Экспортируйте задачу в JSON. У каждого сегмента есть words с start и end в секундах.