Vodič za API

Tri usluge sajta – transkripcija sa prepoznavanjem govornika, sinhronizacija videa i pretvaranje teksta u govor – dostupne su i iz vaših programa. Zahtev sa linkom ka snimku ili tekstom, odgovor sa rezultatom. Jedan nalog, jedan saldo kredita.

Sadržaj

Kako početi

  1. Registrujte se ili se prijavite na sajtu cujem.rs i potvrdite e-mail adresu.
  2. Kupite kredite (API koristi iste kredite kao sajt).
  3. U korisničkom meniju otvorite odeljak „API“ i napravite ključ. Ključ se prikazuje samo jednom – odmah ga kopirajte.

Cena i ograničenja

  • Transkripcija – 1 kredit za svaki započeti minut snimka. Sinhronizacija – 10 kredita za započeti minut. Tekst u govor – 2 kredita za svakih započetih 1000 znakova. Preko API-ja nema besplatnih minuta ni znakova.
  • Saldo se proverava pri kreiranju zadatka, krediti se skidaju tek kada je zadatak završen. Neuspeli zadaci se ne naplaćuju.
  • Jedan snimak – do 3 sata; veličina fajla nije ograničena (i video od više GB). Fajl mora biti dostupan na javnoj https:// adresi.
  • Za fajlove do 200 MB trajanje i cena se određuju odmah; za veće – tokom obrade, pa je u odgovoru estimatedCredits jednako null.
  • Svaki API rezultat pojavljuje se i na listi vaših projekata na sajtu.

Adresa i autentifikacija

Osnovna adresa: https://cujem.rs/api/v1. Uz svaki zahtev dodajte zaglavlje X-API-Key: ak_… (ili Authorization: Bearer ak_…).

Nalog

GET /v1/account

Vraća saldo vaših kredita.

{ "credits": 120, "creditsPerMinute": 1 }

Transkripcija

POST /v1/transcriptions

Kreira zadatak transkripcije. Snimak se preuzima sa navedene adrese, meri se trajanje, proverava saldo. Snimak se transkribuje na jeziku ovog sajta.

{
  "audioUrl": "https://example.com/recordings/call.mp3",
  "fileName": "call.mp3",
  "webhookUrl": "https://example.com/hooks/transcripts"
}
PoljeObaveznoOpis
audioUrldaJavna https:// adresa audio ili video fajla.
fileNameneNaziv na listi projekata. Podrazumevano – poslednji deo adrese.
webhookUrlneJavna https:// adresa na koju se šalje rezultat kada se zadatak završi (isti JSON kao GET). Jedan pokušaj, 10 s čekanja.

Odgovor 202 Accepted:

{
  "id": "k3FgT9bQ2w",
  "status": "queued",
  "languageCode": "sr-RS",
  "fileName": "call.mp3",
  "durationSeconds": 1532,
  "estimatedCredits": 26,
  "pollUrl": "/v1/transcriptions/k3FgT9bQ2w"
}

GET /v1/transcriptions/{id}

Status ili, kada je završeno, cela transkripcija. Statusi: queued, processing, completed, failed.

Dok se obrađuje:

{ "id": "k3FgT9bQ2w", "status": "processing", "progress": 40, "languageCode": "sr-RS", "fileName": "call.mp3", "durationSeconds": 1532 }

Kada je završeno (?format=json, podrazumevano):

{
  "id": "k3FgT9bQ2w",
  "status": "completed",
  "creditsCharged": 26,
  "speakers": ["SPEAKER_00", "SPEAKER_01"],
  "segments": [
    { "speaker": "SPEAKER_00", "start": 0.0, "end": 4.2, "text": "…" },
    { "speaker": "SPEAKER_01", "start": 4.2, "end": 7.9, "text": "…" }
  ],
  "text": "…"
}

start i end – sekunde. ?format=txt vraća običan tekst ([MM:SS] SPEAKER_00: tekst), ?format=srt – titlove u SubRip formatu.

Sinhronizacija videa

POST /v1/dubbings

Kreira zadatak sinhronizacije: snimak se transkribuje, prevodi i izgovara na izabranom jeziku, muzika i efekti se zadržavaju. Link ka snimku i pravila o veličini – isti kao za transkripciju.

{
  "audioUrl": "https://example.com/recordings/talk.mp4",
  "targetLanguage": "en",
  "sourceLanguage": "auto",
  "keepBackground": true,
  "originalVoices": false,
  "fileName": "talk.mp4",
  "webhookUrl": "https://example.com/hooks/dubbing"
}
PoljeObaveznoOpis
audioUrldaJavna https:// adresa audio ili video fajla.
targetLanguagedaJezik sinhronizacije (dvoslovni kod): lt, lv, pl, et, sr, hu, sk, bg, en, de, fr, es, it, pt, nl, sv, da, nb, fi, cs, ro, uk, ru, tr.
sourceLanguageneJezik originala (dvoslovni kod) ili auto (podrazumevano).
keepBackgroundneZadržati muziku i pozadinu (podrazumevano true); false – samo glas.
originalVoicesneSinhronizovani glasovi liče na govornike iz originala (podrazumevano false).
fileNameneNaziv na listi projekata. Podrazumevano – poslednji deo adrese.
webhookUrlneJavna https:// adresa na koju se šalje rezultat kada se zadatak završi (isti JSON kao GET). Jedan pokušaj, 10 s čekanja.

Odgovor 202 Accepted:

{ "id": "p8Dk2Qa1Lm", "kind": "dubbing", "status": "queued", "fileName": "talk.mp4", "durationSeconds": 184, "estimatedCredits": 40, "targetLanguage": "en", "sourceLanguage": "auto", "pollUrl": "/v1/dubbings/p8Dk2Qa1Lm" }

GET /v1/dubbings/{id}

Kada je završeno, downloadUrl je sinhronizovani video (ili audio fajl ako je otpremljen audio); outputKind je video ili audio.

{ "id": "p8Dk2Qa1Lm", "kind": "dubbing", "status": "completed", "targetLanguage": "en", "durationSeconds": 184, "creditsCharged": 40, "downloadUrl": "https://…/dubbed.mp4", "outputKind": "video", "segments": 42, "flaggedSegments": 0 }

Tekst u govor

POST /v1/speech

Izgovara tekst prirodnim glasom i vraća MP3. Do 2 000 000 znakova; dugi tekstovi se izgovaraju u delovima i spajaju. Jezik teksta se prepoznaje automatski.

{ "text": "…", "voice": "female", "fileName": "intro", "webhookUrl": "https://example.com/hooks/speech" }
PoljeObaveznoOpis
textdaTekst za izgovaranje (1–2 000 000 znakova).
voicenefemale (podrazumevano) ili male.
fileNameneNaziv na listi projekata. Podrazumevano – poslednji deo adrese.
webhookUrlneJavna https:// adresa na koju se šalje rezultat kada se zadatak završi (isti JSON kao GET). Jedan pokušaj, 10 s čekanja.

Odgovor 202 Accepted:

{ "id": "s4Hn7Rt9Wq", "kind": "speech", "status": "queued", "characters": 1840, "voice": "female", "estimatedCredits": 4, "pollUrl": "/v1/speech/s4Hn7Rt9Wq" }

GET /v1/speech/{id}

Kada je završeno, downloadUrl je MP3 fajl; durationSeconds – trajanje snimka, characters – broj izgovorenih znakova.

{ "id": "s4Hn7Rt9Wq", "kind": "speech", "status": "completed", "characters": 1840, "durationSeconds": 131.4, "creditsCharged": 4, "downloadUrl": "https://…/full.mp3" }

Greške

KodZnačenje
missing_api_keyNema zaglavlja sa ključem (401).
invalid_api_keyKljuč nije pronađen ili je pogrešan (401).
api_key_revokedKljuč je obrisan (403).
invalid_audio_urlAdresa nije https:// ili nije dostupna (400).
unsupported_mediaU fajlu nije pronađen zvuk (400).
max_duration_exceededSnimak je duži od 3 h (400).
insufficient_creditsNema dovoljno kredita (402). U odgovoru: required, available, balance.
not_foundZadatak nije pronađen ili pripada drugom nalogu (404).
invalid_target_languageNedostaje ili nije podržan jezik sinhronizacije (400).
invalid_source_languagePogrešan jezik originala (400).
invalid_textNedostaje tekst ili je duži od 2 000 000 znakova (400).
invalid_voiceGlas mora biti female ili male (400).

Primeri

BASE=https://cujem.rs/api/v1
KEY=ak_...

curl -s $BASE/account -H "X-API-Key: $KEY"

curl -s -X POST $BASE/transcriptions -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
  -d '{"audioUrl":"https://example.com/call.mp3"}'

curl -s $BASE/transcriptions/JOB_ID -H "X-API-Key: $KEY"
curl -s "$BASE/transcriptions/JOB_ID?format=srt" -H "X-API-Key: $KEY" -o call.srt

Proveravajte status na svakih 10–30 s dok status ne postane completed ili failed.

import requests, time

BASE = "https://cujem.rs/api/v1"
H = {"X-API-Key": "ak_..."}

job = requests.post(f"{BASE}/transcriptions", headers=H,
                    json={"audioUrl": "https://example.com/call.mp3"}).json()
while True:
    r = requests.get(f"{BASE}/transcriptions/{job['id']}", headers=H).json()
    if r["status"] in ("completed", "failed"):
        break
    time.sleep(15)
print(r.get("text") or r.get("error"))

Pomoć

Pitanja – pomoc@cujem.rs.