Greita pradžia
Nuo rakto sukūrimo iki pirmos nuskaitytos transkripcijos per kelias minutes.
Šiame vadove sukursite raktą, atliksite pirmą užklausą, kuri nuskaito jūsų pačių duomenis, importuosite viešą YouTube vaizdo įrašą ir nuskaitysite jo transkripciją. Visi pavyzdžiai naudoja bazinį URL https://api.diko.app/api/v1.
1. Sukurkite API raktą
- Prisijunkite prie Diko ir atidarykite Nustatymai → API, tai yra API raktų puslapį (
/settings/api). Senoji nuoroda/kurejamsnukreipia čia. Reikia „Verslas“ plano. - Pasirinkite Sukurti raktą, įveskite pavadinimą ir leidimų šabloną Skaitymas ir importas (
meetings:read,library:write). Numatytasis galiojimas – 90 dienų. - Patvirtinkite veiksmą pakartotiniu prisijungimu, jei Diko to paprašys.
- Nukopijuokite raktą. Jis rodomas tik vieną kartą, o paskui matysite tik užuominą, pavyzdžiui,
dk_live_Ab12…9xYz.
Raktą laikykite aplinkos kintamajame, o ne kode:
export DIKO_API_KEY="dk_live_..."2. Atlikite pirmą užklausą
Pradėkite nuo užklausos, kuri grąžina jūsų pačių duomenis. Šablonas Skaitymas ir importas apima abu žemiau pateiktus sąrašus. library:write apima library:read, o meetings:read nurodytas atskirai. Bazinį URL ir antraštes nustatykite vieną kartą: vėlesni žingsniai jais naudojasi.
Bibliotekos transkripcijos
GET /library/transcripts?limit=1 grąžina naujausią jūsų bibliotekoje pridėtą transkripciją. Reikia leidimo library:read (arba library:write, kuris jį apima).
curl "https://api.diko.app/api/v1/library/transcripts?limit=1" \
-H "Authorization: Bearer $DIKO_API_KEY"import os
import requests
BASE = "https://api.diko.app/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['DIKO_API_KEY']}"}
first = requests.get(f"{BASE}/library/transcripts", headers=HEADERS, params={"limit": 1}, timeout=30)
first.raise_for_status()
print(first.json()["data"])const BASE = "https://api.diko.app/api/v1"
const headers = { Authorization: `Bearer ${process.env.DIKO_API_KEY}` }
const first = await fetch(`${BASE}/library/transcripts?limit=1`, { headers })
if (!first.ok) throw new Error(`${first.status} ${await first.text()}`)
console.log((await first.json()).data)Atsakymas yra sąrašas. data laiko elementus (tuščias masyvas, jei bibliotekoje dar nėra transkripcijų). has_more parodo, ar yra kitas puslapis. next_cursor leidžia gauti kitą puslapį (Puslapiavimas):
{
"object": "list",
"data": [
{
"id": "trn_ZFF3NHc5V2dYY1E",
"object": "library_transcript",
"title": "Kaip veikia transkribavimas",
"source_type": "youtube",
"youtube_video_id": "dQw4w9WgXcQ",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"channel": "Diko",
"language": "lt",
"duration_ms": 212000,
"transcription_method": "captions",
"summary": { "status": "ready", "text": null },
"categories": ["Technologijos"],
"added_at": "2026-10-11T09:30:00.000Z",
"archived": false,
"segment_count": 120,
"revision": "r_6f6f4bb9762915b561878fd1e1fa7f56",
"web_url": "https://studio.diko.app/library/dQw4w9WgXcQ"
}
],
"has_more": false,
"next_cursor": null
}Susitikimai
Jei raktas turi meetings:read, GET /meetings?limit=1 tokiu pat sąrašo formatu grąžina naujausią jūsų susitikimą:
curl "https://api.diko.app/api/v1/meetings?limit=1" \
-H "Authorization: Bearer $DIKO_API_KEY"meetings = requests.get(f"{BASE}/meetings", headers=HEADERS, params={"limit": 1}, timeout=30)
meetings.raise_for_status()
print(meetings.json()["data"])const meetings = await fetch(`${BASE}/meetings?limit=1`, { headers })
if (!meetings.ok) throw new Error(`${meetings.status} ${await meetings.text()}`)
console.log((await meetings.json()).data)Susitikimo elementas turi id (mtg_...), title, status, processing, transcript ir minutes. Dalyvių sąrašą, įraše atpažintus dalyvius ir kiekius (pvz., segmentų skaičių) grąžina tik GET /meetings/{meeting_id}.
Jei pirma užklausa nepavyksta
- 401 reiškia, kad pats raktas nepriimtas:
missing_api_key,invalid_api_key,api_key_expired,api_key_revokedarbaapi_key_disabled. Patikrinkite, ar nustatytasDIKO_API_KEYir ar raktas dar aktyvus. - 403
insufficient_scopereiškia, kad raktas galioja, bet neturi šiam endpointui reikalingo leidimo. Pavyzdžiui, raktas tik sulibrary:readkviečiaGET /meetings:
HTTP/1.1 403 Forbidden
WWW-Authenticate: Bearer realm="diko", error="insufficient_scope", scope="meetings:read"{
"type": "error",
"error": {
"type": "permission_error",
"code": "insufficient_scope",
"message": "API raktas neturi šiam endpointui reikalingo leidimo.",
"doc_url": "https://diko.app/api-docs/klaidos#insufficient_scope",
"details": {
"required_scopes": ["meetings:read"],
"granted_scopes": ["library:read"]
}
},
"request_id": "req_QBPIQ5QTIWAUYTMDNCLD7CMKBE"
}details.required_scopes yra tai, ko reikia endpointui, o details.granted_scopes – ką turi jūsų raktas. Sukūrus raktą leidimų pakeisti negalima, todėl sukurkite naują raktą su reikiamu leidimu (Leidimai). Kiti 403 kodai (plan_required, ip_not_allowed ir kiti) aprašyti klaidų kataloge.
3. Importuokite YouTube vaizdo įrašą
POST /library/imports reikalingas leidimas library:write (šablonas Skaitymas ir importas jį turi). Jis pradeda asinchroninį importą ir niekada nelaukia atsisiuntimo. Visada siųskite Idempotency-Key. Jei užklausa nutrūks, tą pačią užklausą su tuo pačiu raktu galėsite saugiai pakartoti. Importas nebus sukurtas du kartus.
curl -X POST "https://api.diko.app/api/v1/library/imports" \
-H "Authorization: Bearer $DIKO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"}'import uuid
# BASE ir HEADERS paimti iš 2 žingsnio. Vienas raktas vienam importui; kartodami užklausą naudokite tą patį.
idempotency_key = str(uuid.uuid4())
response = requests.post(
f"{BASE}/library/imports",
headers={**HEADERS, "Idempotency-Key": idempotency_key},
json={"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"},
timeout=30,
)
response.raise_for_status()
job = response.json()
print(job["id"], job["status"])// BASE ir headers paimti iš 2 žingsnio. Vienas raktas vienam importui; kartodami užklausą naudokite tą patį.
const idempotencyKey = crypto.randomUUID()
const response = await fetch(`${BASE}/library/imports`, {
method: "POST",
headers: { ...headers, "Content-Type": "application/json", "Idempotency-Key": idempotencyKey },
body: JSON.stringify({ url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }),
})
if (!response.ok) throw new Error(`${response.status} ${await response.text()}`)
let job = await response.json()
console.log(job.id, job.status)Atsakymas yra 201 Created su antrašte Location. Pirmą kartą importuojamas vaizdo įrašas pradeda nuo queued:
{
"id": "imp_6Mfj7Oxm4MfxGGmZRhiUQf",
"object": "library_import",
"status": "queued",
"stage": null,
"queue_position": 1,
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"youtube_video_id": "dQw4w9WgXcQ",
"language": null,
"reused": false,
"transcript_id": null,
"error": null,
"created_at": "2026-10-11T09:30:00.000Z",
"updated_at": "2026-10-11T09:30:00.100Z",
"completed_at": null
}Jei transkripcija jau yra jūsų bibliotekoje arba bendroje talpykloje, importas iškart tampa succeeded su reused: true ir kreditai nenaudojami.
4. Palaukite rezultato
Importo būseną galite periodiškai tikrinti arba gauti pranešimą per webhooks.
Periodinis tikrinimas
GET /library/imports/{import_id}, kol importas nepasiekė galutinės būsenos, grąžina antraštę Retry-After: 3. Tikrinkite ne dažniau nei tai ir nustatykite bendrą laukimo laiką:
curl "https://api.diko.app/api/v1/library/imports/imp_6Mfj7Oxm4MfxGGmZRhiUQf" \
-H "Authorization: Bearer $DIKO_API_KEY"import time
deadline = time.monotonic() + 15 * 60
while job["status"] not in ("succeeded", "failed", "canceled"):
if time.monotonic() > deadline:
raise TimeoutError("Importas dar vyksta: naudokite webhooks arba patikrinkite vėliau")
time.sleep(3)
response = requests.get(f"{BASE}/library/imports/{job['id']}", headers=HEADERS, timeout=30)
response.raise_for_status()
job = response.json()
if job["status"] != "succeeded":
raise RuntimeError(job["error"] or job["status"])
print(job["transcript_id"])const deadline = Date.now() + 15 * 60_000
while (!["succeeded", "failed", "canceled"].includes(job.status)) {
if (Date.now() > deadline) throw new Error("Importas dar vyksta: naudokite webhooks arba patikrinkite vėliau")
await new Promise(resolve => setTimeout(resolve, 3000))
const poll = await fetch(`${BASE}/library/imports/${job.id}`, { headers })
if (!poll.ok) throw new Error(`${poll.status} ${await poll.text()}`)
job = await poll.json()
}
if (job.status !== "succeeded") throw new Error(JSON.stringify(job.error ?? job.status))
console.log(job.transcript_id)Ilgi vaizdo įrašai gali užtrukti ilgiau, nei numatėte laukti. Tada nutraukite ciklą ir patikrinkite vėliau arba naudokite webhooks.
Importo būsenos ir klaidos
Importas turi vieną iš šių status reikšmių. Galutinės yra succeeded, failed ir canceled.
status |
Reikšmė |
|---|---|
queued |
laukia eilėje; queue_position rodo jūsų vietą |
processing |
vykdomas; stage nurodo žingsnį |
canceling |
paprašėte atšaukti vykdomą importą; sustojus darbui jis tampa canceled |
succeeded |
baigtas; nustatytas transcript_id |
failed |
sustojo dėl klaidos; error.code nurodo priežastį |
canceled |
atšaukė jūs arba sistema. Sistema atšaukia importą, kai jo raktas atšauktas, išjungtas, ištrintas ar rotuotas be persidengimo, kai raktas atšaukiamas dėl nutekėjimo ir kai sustabdoma API prieiga. Importas eilėje iškart tampa canceled, vykdomas pereina per canceling. Jau atliktas darbas apmokestinamas kaip įprasta. Rotacija su persidengimu importo neatšaukia |
Kol importas processing, stage yra viena iš šių reikšmių: captions (Diko ieško YouTube subtitrų), waiting (laukia laisvos kalbos atpažinimo vietos), downloading, transcribing arba summarizing. Kitose būsenose stage yra null.
Nepavykusio (failed) importo error.code gali būti:
error.code |
Reikšmė |
|---|---|
video_unavailable, video_private, age_restricted |
vaizdo įrašo gauti neįmanoma; pakartojimas nepadės |
video_too_long |
vaizdo įrašas ilgesnis už kalbos atpažinimo ribą (šiuo metu 4 valandos) |
video_duration_unknown |
Diko nepavyko nustatyti vaizdo įrašo trukmės |
captions_unavailable |
nepavyko gauti subtitrų |
download_failed, transcription_failed |
nepavyko atsisiųsti arba transkribuoti; bandykite vėliau |
transcription_timeout |
importas queued būsenoje užsibuvo ilgiau nei 24 valandas arba processing ilgiau nei 6 valandas |
provider_limit |
pasiekta subtitrų tiekėjo riba; bandykite vėliau |
insufficient_credits |
importui užbaigti nepakako kreditų |
internal_error |
klaida Diko pusėje; bandykite vėliau |
Norėdami bandyti iš naujo, sukurkite naują importą su nauju Idempotency-Key.
Kreditai. Transkripcija, kuri jau yra jūsų bibliotekoje ar bendroje talpykloje, nekainuoja nieko (reused: true). Kitu atveju Diko tikrina kreditų likutį kuriant importą ir dar kartą prieš mokamą darbą. Likutį raktui su library:write rodo GET /me. Kreditų įkainiai ir planų apimtys pateikti kainų puslapyje.
Webhooks
Sukurkite endpointą skiltyje Nustatymai → API → Webhooks (/settings/api/webhooks) ir pasirinkite įvykius library.import.succeeded, library.import.failed ir library.import.canceled. Diko atsiųs POST užklausą jūsų adresu, kai importas baigsis. Parašo tikrinimas ir pakartojimai aprašyti puslapyje Įvykiai ir webhooks.
5. Nuskaitykite transkripciją
Kai importas succeeded, transcript_id yra transkripcijos trn_... ID: ji jau jūsų bibliotekoje (matysite ją ir 2 žingsnio sąraše GET /library/transcripts). Nuskaitykite jos tekstą:
# Visas tekstas su laiko žymomis (naudokite importo transcript_id)
curl "https://api.diko.app/api/v1/library/transcripts/trn_ZFF3NHc5V2dYY1E/transcript?format=text" \
-H "Authorization: Bearer $DIKO_API_KEY"transcript_id = job["transcript_id"]
text = requests.get(
f"{BASE}/library/transcripts/{transcript_id}/transcript",
headers=HEADERS,
params={"format": "text"},
timeout=30,
)
text.raise_for_status()
print(text.text)const transcriptId = job.transcript_id
const text = await fetch(`${BASE}/library/transcripts/${transcriptId}/transcript?format=text`, { headers })
if (!text.ok) throw new Error(`${text.status} ${await text.text()}`)
console.log(await text.text())Tekstas pateikiamas eilutėmis [HH:MM:SS] Vardas: tekstas. Norite segmentų JSON formatu, SRT ar VTT? Žr. getLibraryTranscriptTranscript.
Patikrinkite, ką gali jūsų raktas (GET /me)
GET /me yra paskyros metaduomenys, o ne jūsų duomenys. Jis veikia su bet kuriuo galiojančiu raktu. Todėl greitai parodo, kurį raktą naudojate ir ar paskyra gali naudoti API. Raktui su leidimu library:write jis parodo ir kreditų likutį. Naudokite jį, kai kas nors neveikia kaip tikėtasi, o ne kaip pirmą užklausą.
curl "https://api.diko.app/api/v1/me" \
-H "Authorization: Bearer $DIKO_API_KEY"me = requests.get(f"{BASE}/me", headers=HEADERS, timeout=30)
me.raise_for_status()
print(me.json()["access"])const me = await fetch(`${BASE}/me`, { headers })
if (!me.ok) throw new Error(`${me.status} ${await me.text()}`)
console.log((await me.json()).access)Sėkmingo atsakymo access dalis atrodo taip:
{ "allowed": true, "reason": "subscription", "plan": "verslas" }Jei allowed yra false, reason pasako kodėl (pavyzdžiui, plan_required). Klaidų kodų prasmė aprašyta klaidų kataloge.
GET /me laikosi mažiausių privilegijų principo, todėl siauro leidimo raktas neatskleidžia daugiau, nei reikia. user.email visada paslėptas, o credits užpildomas tik raktui su library:write, vieninteliu leidimu, kuris naudoja kreditus:
{
"user": { "id": "usr_4iAD1dYhdAEJIkMN5GPczR", "object": "user", "email": "j***@example.com", "display_name": "Jonas" },
"credits": { "scope": "user", "available": "123.5000", "as_of": "2026-10-11T09:30:00.000Z" }
}Tik skaitymo raktui (meetings:read, library:read) tame pačiame atsakyme bus "credits": null. GET /me turi savo, griežtesnę užklausų ribą (Ribos), todėl nekvieskite jo cikle.
Kas toliau
- Klaidos: kaip elgtis su kiekvienu kodu ir kada kartoti užklausą.
- Ribos: užklausų ir importų ribos.
- Susitikimai: su
meetings:readnuskaitykite susitikimų transkripcijas, protokolus ir veiksmų punktus.