API-reference
Hvert kald herunder har et eksempel på en anmodning og et svar, efterfulgt af jobtilstande, fejlkoder, grænser og opbevaringstider. Ny her? Start med udviklerguiden.
Overblik
- Basis-URL:
https://api.video-to-notes.com. Alle stier begynder med/api/v1. - Anmodninger og svar er JSON over HTTPS. Send
Content-Type: application/jsonmed hver anmodningstekst. - Tidspunkter er Unix-tidsstempler i sekunder (UTC). Positioner i en optagelse er sekunder fra filens begyndelse.
- Id’er og cursorer er uigennemsigtige strenge. Gem dem præcis, som du modtager dem.
- Hvert fejlsvar indeholder et
request_id. Angiv det, når du kontakter support. - Svar sendes med
Cache-Control: no-store; gem dem ikke i delte caches. - Den maskinlæsbare kontrakt findes i openapi.json (OpenAPI 3.1) og paid-api.schema.json (JSON Schema).
Godkendelse
Send din API-nøgle som bearer-token med hver API-anmodning. Nøgler begynder med vtn_prod_. Du opretter og tilbagekalder nøgler, mens du er logget ind på webstedet; en API-nøgle kan ikke administrere nøgler, betalinger eller kontoen.
Authorization: Bearer vtn_prod_...En nøgle, der mangler, er forkert formateret, er udløbet eller er tilbagekaldt, giver 401 UNAUTHORIZED. Send aldrig nøglen til de signerede lager-URL’er: de har deres egen godkendelse. Curl-eksemplerne på denne side bruger denne lille hjælpefunktion, som giver nøglen til curl via standard input:
# Sends the key through stdin, so it never appears in the process list.
vtn() {
printf 'header = "Authorization: Bearer %s"\n' "$VTN_API_KEY" |
curl -s --config - "$@"
}Konto
GET /api/v1/account
Returnerer abonnementet, de resterende abonnementssekunder, slutningen af den aktuelle tildeling samt de funktioner og grænser, der gælder for kontoen lige nu. Læs det, før du uploader: hvis eligible eller capabilities.api_admission_enabled er false, afvises nye job.
vtn "$VTN_API_BASE/api/v1/account"{
"plan": "basic",
"eligible": true,
"remaining_seconds": 64800,
"allowance_expires_at": 1792886400,
"capabilities": {
"api_admission_enabled": true,
"key_creation_enabled": true,
"server_upload_enabled": true,
"long_jobs": true,
"formats": [
"mp4", "m4v", "mov", "webm", "mkv", "ogv", "avi", "wmv", "asf",
"flv", "mpg", "mpeg", "vob", "ts", "mts", "m2ts", "3gp", "3g2",
"mxf", "mp3", "m4a", "aac", "wav", "flac", "ogg", "oga", "opus",
"wma", "amr", "aiff", "aif", "caf", "ac3"
],
"audio_languages": [
"auto", "af", "am", "ar", "hy", "az", "be", "bn", "bs", "bg", "my",
"ca", "zh", "hr", "cs", "da", "nl", "en", "et", "tl", "fi", "fr",
"gl", "ka", "de", "el", "gu", "ha", "he", "hi", "hu", "is", "id",
"it", "ja", "kn", "kk", "km", "ko", "lv", "lt", "mk", "ms", "ml",
"mt", "mr", "mn", "ne", "no", "fa", "pl", "pt", "pa", "ro", "ru",
"sr", "sk", "sl", "es", "sw", "sv", "ta", "te", "th", "tr", "uk",
"uz", "vi"
],
"notes_languages": [
"auto", "af", "am", "ar", "hy", "az", "be", "bn", "bs", "bg", "my",
"ca", "zh", "hr", "cs", "da", "nl", "en", "et", "tl", "fi", "fr",
"gl", "ka", "de", "el", "gu", "ha", "he", "hi", "hu", "is", "id",
"it", "ja", "kn", "kk", "km", "ko", "lv", "lt", "mk", "ms", "ml",
"mt", "mr", "mn", "ne", "no", "fa", "pl", "pt", "pa", "ro", "ru",
"sr", "sk", "sl", "es", "sw", "sv", "ta", "te", "th", "tr", "uk",
"uz", "vi"
],
"download_formats": ["transcript_txt", "notes_md", "notes_html", "notes_pdf"],
"email_opt_in": false,
"limits": {
"max_upload_bytes": 8589934592,
"max_selection_seconds": null,
"active_jobs": 1,
"active_uploads": 1,
"daily_uploads": 10,
"daily_upload_bytes": 21474836480,
"new_requests_per_minute": 12,
"read_requests_per_minute": 60,
"poll_after_seconds": 5,
"result_page_bytes": 1000000,
"result_page_items": 32,
"upload_url_seconds": 900,
"download_url_seconds": 600,
"result_retention_seconds": 86400,
"recovery_retention_seconds": 172800,
"idempotency_retention_seconds": 34560000
}
}
}Uploads
Filer uploades i dele direkte til lageret via signerede URL’er. En konto kan have én aktiv upload ad gangen.
POST /api/v1/uploads
Starter en upload. Send den nøjagtige filstørrelse i byte og filtypenavnet. Svaret angiver part_size og part_count: del filen op i dele på part_size byte; den sidste del må være mindre.
vtn -X POST "$VTN_API_BASE/api/v1/uploads" \
-H "Content-Type: application/json" \
-d '{
"byte_size": 1048576,
"extension": "mp4"
}'{
"upload_id": "upload-1",
"state": "created",
"expires_at": 1792807200,
"part_size": 16777216,
"part_count": 1,
"error": null
}POST /api/v1/uploads/{upload_id}/parts
Returnerer signerede upload-URL’er for 1 til 100 delnumre. Hver URL er gyldig i op til 15 minutter; anmod om en ny, når den udløber, eller når en del skal sendes igen.
vtn -X POST "$VTN_API_BASE/api/v1/uploads/upload-1/parts" \
-H "Content-Type: application/json" \
-d '{
"part_numbers": [1]
}'{
"upload_id": "upload-1",
"targets": [
{
"part_number": 1,
"url": "https://example.invalid/signed",
"expires_at": 1792800900
}
]
}PUT {signed part URL}
Send hver del som rå byte i en HTTP-PUT til dens signerede URL uden Authorization-header. Gem svarheaderen ETag præcis, som den returneres, inklusive anførselstegnene. Hver URL accepterer kun sin dels nøjagtige størrelse: part_size for hver del undtagen den sidste, som indeholder de resterende byte. En body med en anden længde afvises med HTTP 403.
# PART_URL comes from the parts response; send no Authorization header.
curl -s --upload-file part-0001.bin --dump-header - --output /dev/null \
"$PART_URL" | grep -i '^etag:'POST /api/v1/uploads/{upload_id}/complete
Afslutter uploaden. Send hvert delnummer med dets ETag. At afslutte en upload starter ikke behandlingen; opret derefter et job.
vtn -X POST "$VTN_API_BASE/api/v1/uploads/upload-1/complete" \
-H "Content-Type: application/json" \
-d '{
"parts": [
{
"part_number": 1,
"etag": "opaque-etag"
}
]
}'{
"upload_id": "upload-1",
"state": "uploaded",
"expires_at": 1792807200,
"part_size": 16777216,
"part_count": 1,
"error": null
}GET /api/v1/uploads/{upload_id}
Returnerer tilstanden for en upload: created, uploading, uploaded, probing, probed, failed, aborted eller expired.
vtn "$VTN_API_BASE/api/v1/uploads/upload-1"{
"upload_id": "upload-1",
"state": "uploaded",
"expires_at": 1792807200,
"part_size": 16777216,
"part_count": 1,
"error": null
}POST /api/v1/uploads/{upload_id}/abort
Afbryder en upload, du ikke vil bruge, og frigør kontoens uploadplads. Det er sikkert at kalde den igen.
vtn -X POST "$VTN_API_BASE/api/v1/uploads/upload-1/abort" \
-H "Content-Type: application/json" \
-d '{}'Job
Et job behandler én uploadet fil til en transskription og noter. En konto kan køre ét job ad gangen.
POST /api/v1/jobs
Starter behandlingen af en uploadet fil. Headeren Idempotency-Key er påkrævet: 1 til 128 udskrivbare ASCII-tegn uden mellemrum, ny for hvert job. Valgfrie felter er range (start_seconds og end_seconds, begge påkrævet, hvis feltet er med), audio_language og notes_language. Returnerer 202 med jobbet i tilstanden preparing. Den samme nøgle med det samme indhold returnerer det samme job; den samme nøgle med andet indhold returnerer 409.
vtn -X POST "$VTN_API_BASE/api/v1/jobs" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $IDEMPOTENCY_KEY" \
-d '{
"upload_id": "upload-1",
"range": {
"start_seconds": 5,
"end_seconds": 60
},
"audio_language": null,
"notes_language": "en"
}'{
"job_id": "job-1",
"state": "preparing",
"stage": "probe",
"created_at": 1792800000,
"expires_at": 1792807200,
"result_expires_at": null,
"idempotency_expires_at": 1827360000,
"poll_after_seconds": 5,
"status_url": "/api/v1/jobs/job-1",
"result_url": "/api/v1/jobs/job-1/result",
"completed_units": 0,
"total_units": null,
"charged_seconds": 0,
"result_available": false,
"can_resume": false,
"warnings": [],
"error": null
}GET /api/v1/jobs/{job_id}
Returnerer tilstanden, den aktuelle fase, fremskridtet (completed_units af total_units), charged_seconds, advarsler og en eventuel fejl. Et mislykket job returnerer stadig 200; læs dets error.
vtn "$VTN_API_BASE/api/v1/jobs/job-1"{
"job_id": "job-1",
"state": "completed",
"stage": "terminal",
"created_at": 1792800000,
"expires_at": 1792807200,
"result_expires_at": 1792886400,
"idempotency_expires_at": 1827360000,
"poll_after_seconds": 5,
"status_url": "/api/v1/jobs/job-1",
"result_url": "/api/v1/jobs/job-1/result",
"completed_units": 8,
"total_units": 8,
"charged_seconds": 1140,
"result_available": true,
"can_resume": false,
"warnings": [],
"error": null
}POST /api/v1/jobs/{job_id}/cancel
Stopper et job. Færdige dele forbliver tilgængelige, og reserveret tid, der ikke blev brugt, gives tilbage. Det er sikkert at kalde den igen.
vtn -X POST "$VTN_API_BASE/api/v1/jobs/job-1/cancel" \
-H "Content-Type: application/json" \
-d '{}'POST /api/v1/jobs/{job_id}/resume
Genoptager et afbrudt job, når dets status angiver can_resume: true. Det kræver et aktivt abonnement og tjekker din resterende tid igen. Dele, der allerede er behandlet, opkræves ikke igen.
vtn -X POST "$VTN_API_BASE/api/v1/jobs/job-1/resume" \
-H "Content-Type: application/json" \
-d '{}'Resultater
GET /api/v1/jobs/{job_id}/result
Returnerer én resultatside med op til 32 elementer og 1 MB. Elementerne er ordnede og har en kind: transcript (tekst med tidsangivne segmenter), notes (Markdown), gap (lyd, der ikke kunne behandles) eller warning. Send next_cursor som forespørgselsparameteren cursor for at hente den næste side, indtil den er null. Hver side kan angive op til fire downloadlinks i artifacts, gyldige i op til 10 minutter. Hvis jobbet genoptages, mens du læser, returnerer API’et 409 JOB_CONFLICT; start da forfra fra første side.
vtn --get "$VTN_API_BASE/api/v1/jobs/job-1/result" \
--data-urlencode "cursor=$NEXT_CURSOR" # omit for the first page{
"job_id": "job-1",
"snapshot": "generation-1",
"items": [
{
"index": 0,
"kind": "transcript",
"text": "Welcome to the weekly planning meeting.",
"segments": [
{
"text": "Welcome to the weekly planning meeting.",
"start_seconds": 0,
"end_seconds": 4.2,
"timing_quality": "approximate",
"timing_method": "provider_segment"
}
]
},
{
"index": 0,
"kind": "notes",
"text": "## Summary\n\nThe team agreed on the launch plan.\n\n## Key points\n\n- Launch moves to Monday."
}
],
"next_cursor": "opaque-account-bound-cursor",
"artifacts": [
{
"format": "notes_md",
"url": "https://example.invalid/signed-notes",
"expires_at": 1792800600
}
],
"charged_seconds": 1140,
"partial": false,
"expires_at": 1792886400
}Hvert transskriptionssegment angiver sin timing_quality: aligned, approximate eller unavailable. Omtrentlige tider ligger tæt på talen, men er ikke præcise ned til ordet.
Downloadformaterne er transcript_txt (TXT), notes_md (Markdown), notes_html (HTML) og notes_pdf (PDF). Lange noter kan være fordelt på flere filer; download dem i rækkefølge. Kontokaldet viser de formater, der er tilgængelige lige nu.
Jobtilstande
| Tilstand | Betydning |
|---|---|
preparing | Serveren tjekker filen og planlægger arbejdet. |
queued | Jobbet venter på at starte. |
processing | Lyden udtrækkes, transskriberes og omdannes til noter. |
completed | Færdigt. Den fulde transskription og noterne er tilgængelige. |
completed_with_gaps | Færdigt, men en del af lyden kunne ikke behandles. Se gap-elementerne. |
interrupted | Stoppet før slutningen. Tjek can_resume. |
cancelled | Stoppet på din anmodning. Færdige dele forbliver tilgængelige. |
failed | Jobbet kunne ikke behandles. Se error. |
expired | Indholdet opbevares ikke længere. |
stage viser det trin, der er i gang: probe, planning, admission, extraction, transcription, notes, publication og til sidst terminal.
Fejl
Alle fejl har det samme JSON-indhold. retryable fortæller, om den samme anmodning kan lykkes senere, og retry_after_seconds, hvor længe du skal vente.
{
"error": {
"code": "RATE_LIMITED",
"message": "Request refused.",
"retryable": true,
"retry_after_seconds": 5
},
"request_id": "request-1"
}| Kode | HTTP | Betydning | Hvad du gør |
|---|---|---|---|
UNAUTHORIZED | 401 | Nøglen mangler, er forkert formateret, udløbet, tilbagekaldt eller hører til et andet miljø. | Tjek nøglen, eller opret en ny. |
FORBIDDEN | 403 | Nøglen kan ikke bruges til denne anmodning. | Administrer nøgler og betalinger på webstedet. |
NOT_FOUND | 404 | Uploaden eller jobbet findes ikke eller tilhører en anden konto. | Tjek id’et. |
VALIDATION_ERROR | 400 | Indholdet, en header eller en forespørgselsparameter er ugyldig. | Ret anmodningen; gentag den ikke uændret. |
PLAN_REQUIRED | 403 | Kontoen har ikke et aktivt Basic- eller Plus-abonnement. | Vælg et abonnement, og prøv igen. |
INSUFFICIENT_BALANCE | 403 | Den resterende abonnementstid dækker ikke den valgte lyd. | Vælg et kortere interval, eller vent, til dine timer fornyes. |
CAPABILITY_DISABLED | 503 | Nye job er sat på pause, eller en funktion er slået fra. | Prøv igen senere; kontokaldet viser den aktuelle status. |
UNSUPPORTED_MEDIA | 400 | Formatet understøttes ikke, eller den uploadede størrelse afviger fra den angivne. | Upload en understøttet fil med dens nøjagtige størrelse. |
MEDIA_TOO_LARGE | 413 | Filen er større end grænsen. | Upload en fil på højst 8 GiB. |
PROBE_FAILED | 400 | Filen har intet lydspor, der kan afkodes, eller intervallet ligger uden for filen. | Tjek filen og intervallet. Der opkræves ingen tid. |
IDEMPOTENCY_CONFLICT | 409 | Idempotency-Key er allerede brugt med andre inddata. | Brug en ny nøgle til et nyt job. |
IDEMPOTENCY_EXPIRED | 410 | Det oprindelige job for denne nøgle er udløbet. | Gentag det ikke; start et nyt job med en ny nøgle. |
JOB_CONFLICT | 409 | En anden upload eller et andet job er aktivt, tilstanden tillader ikke handlingen, eller resultatet ændrede sig, mens du bladrede. | Vent på det aktuelle job, eller start bladringen forfra fra første side. |
RESULT_EXPIRED | 410 | Resultatet opbevares ikke længere. | Gem resultaterne, før de udløber. |
RATE_LIMITED | 429 | For mange anmodninger, eller den daglige uploadgrænse er nået. | Vent som angivet i Retry-After, og prøv derefter igen. |
UNAVAILABLE | 503 | En tjeneste er midlertidigt utilgængelig. | Prøv igen med stadig længere pauser. |
Grænser
Dette er standardværdierne. Kontokaldet returnerer de værdier, der gælder for din konto; gå ud fra dem.
| Grænse | Standard | Felt i capabilities.limits |
|---|---|---|
| Filstørrelse | 8 GiB | max_upload_bytes |
| Valgt lyd pr. job | Din resterende abonnementstid (null betyder intet andet loft) | max_selection_seconds |
| Aktive uploads og job | Én af hver pr. konto | active_uploads, active_jobs |
| Uploads pr. UTC-døgn | 10 uploads, i alt 20 GiB | daily_uploads, daily_upload_bytes |
| Nye job og genoptagelser | 12 pr. minut | new_requests_per_minute |
| Andre anmodninger | 60 pr. minut for alle nøgler tilsammen | read_requests_per_minute |
| Statusforespørgsler | Højst hvert 5. sekund | poll_after_seconds |
| Resultatside | 32 elementer og 1 MB | result_page_items, result_page_bytes |
| Signeret upload-URL | Gyldig i op til 15 minutter | upload_url_seconds |
| Downloadlink | Gyldigt i op til 10 minutter | download_url_seconds |
| Mislykket godkendelse | 30 pr. minut pr. IP-adresse; derefter får alle anmodninger fra den adresse 429, også med en gyldig nøgle, indtil minuttet er gået | — |
Opbevaring
| Data | Opbevares i |
|---|---|
| Upload uden job | Cirka 2 timer |
| Resultatsider og downloadfiler | Cirka 24 timer efter, at jobbet er færdigt |
| Gendannelse af transskriptionen | Cirka 48 timer |
| Idempotenspost, uden indhold | 400 dage |
Værdierne i expires_at i hvert svar er gældende; brug dem i stedet for disse standardværdier.
Ændringslog
API-versionen er en del af stien. Ændringer i v1 står her med deres dato.
- 2026-10-24: API v1 tilgængeligt for abonnementerne Basic og Plus.