API-referens
Slutpunkter, fält, svar, krediter, gränser och fel.
Uppdaterad
Så fungerar det#
Varje transkript skapas via ett jobb. Du skickar in en källa, jobbet körs i bakgrunden, och när det lyckas pekar det på ett transkript som du kan läsa eller exportera så ofta du vill. Bas-URL: https://www.transcriptdock.com. Alla förfrågningar och svar är JSON.
# 1. Submitcurl -X POST https://www.transcriptdock.com/v1/jobs \-H "Authorization: Bearer td_live_YOUR_KEY" \-H "Idempotency-Key: video-7680721699171601694" \-H "Content-Type: application/json" \-d '{ "source": { "url": "https://www.tiktok.com/@tiktok/video/7680721699171601694" }, "mode": "captions_only" }'# 2. Wait (returns as soon as the job finishes, up to 25 s per call)curl "https://www.transcriptdock.com/v1/jobs/11111111-1111-4111-8111-111111111111?wait=25" \-H "Authorization: Bearer td_live_YOUR_KEY"# 3. Exportcurl "https://www.transcriptdock.com/v1/transcripts/22222222-2222-4222-8222-222222222222/export?format=srt" \-H "Authorization: Bearer td_live_YOUR_KEY"
Autentisering#
Skapa nycklar på sidan API-nycklar. En nyckel visas en gång, ser ut som td_live_... och läggs i Authorization-headern i varje förfrågan. Nycklar har behörigheter som väljs när de skapas: jobs:read, jobs:write, transcripts:read, uploads:write. Skapa en nyckel per integration så att du kan återkalla den var för sig.
Authorization: Bearer td_live_YOUR_KEY
Idempotency-Key#
Krävs på POST /v1/jobs, /v1/batches, /v1/jobs/{id}/retry, /v1/video-discoveries och /v1/language-discoveries: en valfri sträng på 8 till 128 utskrivbara ASCII-tecken. Om du skickar samma nyckel med samma innehåll inom 48 timmar returneras det ursprungliga objektet, så att en upprepad förfrågan aldrig skapar eller debiterar två gånger. Samma nyckel med annat innehåll returnerar 409 IDEMPOTENCY_CONFLICT. En bra nyckel är ditt eget id för det du transkriberar.
X-Request-Id#
Varje svar har ett. Ange det när du kontaktar supporten.
Slutpunkter#
| Metod | Sökväg | Vad den gör | Krediter |
|---|---|---|---|
| POST | /v1/jobs | Transkribera en video, fil eller länk | 1 per transkript från undertexter, 2 per minut AI-transkribering |
| GET | /v1/jobs/{id} | Jobbets status, väntar upp till 25 s | Gratis |
| GET | /v1/jobs | Jobbhistorik | Gratis |
| POST | /v1/jobs/{id}/cancel | Avbryt ett köat jobb | Gratis |
| POST | /v1/jobs/{id}/retry | Försök igen med ett misslyckat jobb | Som ett nytt jobb |
| POST | /v1/batches | Transkribera många videor (batchstorlek enligt abonnemanget) | Per post, enligt ovan |
| GET | /v1/batches/{id} | Batchstatus | Gratis |
| GET | /v1/transcripts/{id} | Transkript som JSON | Gratis |
| GET | /v1/transcripts/{id}/export | Fil i txt, srt, vtt eller json | Gratis |
| DELETE | /v1/transcripts/{id} | Radera ett transkript | Gratis |
| POST | /v1/uploads | Hämta en URL att ladda upp en fil till | Gratis |
| POST | /v1/uploads/{id}/complete | Markera uppladdningen som klar | Gratis |
| POST | /v1/video-discoveries | Sök på YouTube, lista en kanal, spellista eller TikTok-profil | 1 per sida |
| GET | /v1/video-discoveries/{id} | Resultat av en videosökning | Gratis |
| POST | /v1/language-discoveries | Lista en YouTube-videos undertextspråk | 1 |
| GET | /v1/language-discoveries/{id} | Språklista | Gratis |
| POST | /v1/webhook-endpoints | Registrera en webhook-URL (med inloggad session) | Gratis |
| GET | /v1/webhook-endpoints | Lista webhook-URL:er | Gratis |
| DELETE | /v1/webhook-endpoints/{id} | Inaktivera en webhook-URL (med inloggad session) | Gratis |
| GET | /v1/usage | Krediter och abonnemang | Gratis |
| GET | /v1/capabilities | Vad din nyckel kan göra | Gratis |
Skapa ett jobb#
/v1/jobsSvarar 202 med jobbet. Om din arbetsyta redan har ett transkript för samma video och samma alternativ returneras 200 med ett lyckat jobb gratis (billing.kind: "cached").
{"id": "11111111-1111-4111-8111-111111111111","status": "queued","stage": "resolve","result_id": null,"error": null,"billing": { "credits_reserved": 2, "credits_charged": 0, "kind": "captions" },"source": { "platform": "tiktok", "media_id": "7680721699171601694", "canonical_url": "https://www.tiktok.com/@tiktok/video/7680721699171601694", "title": null, "upload_id": null },"options": { "mode": "auto", "language": null, "caption_preference": "prefer_creator" },"created_at": "2026-09-16T10:00:00.000Z"}
Jobbobjektet#
Hämta ett jobb#
/v1/jobs/{id}?wait=25Returnerar jobbet. Med wait (0 till 25 sekunder) hålls förfrågan öppen och returnerar så snart jobbet är slutligt, så ett anrop ersätter en pollingloop. Läsningar har en egen gräns på 120 per minut.
Lista jobb#
/v1/jobs?limit=20&cursor=Nyast först, limit 1 till 100. Skicka tillbaka svarets next_cursor som cursor för nästa sida. Lägg till platform och source_id (jobbets source.media_id) tillsammans för att bara se jobben för en video, i valfritt läge. Så kontrollerar en klient om arbetsytan redan har ett transkript innan den skickar in igen.
Avbryt ett jobb#
/v1/jobs/{id}/cancelAvbryter ett jobb som ännu inte har startat AI-transkribering; reservationen släpps. Senare än så returneras 409 CANCELLATION_NOT_ALLOWED och jobbet slutförs.
Försök ett jobb igen#
/v1/jobs/{id}/retrySkapar ett nytt jobb från ett misslyckat jobb vars fel var retryable. Kräver en ny Idempotency-Key; valfri body { "max_credits": 40 }. Prissätts som ett nytt jobb. Fel som är slutgiltiga (privat video, inga undertexter) returnerar 409 JOB_NOT_RETRYABLE: rätta indata och skicka in igen.
Transkriptet#
/v1/transcripts/{id}{"id": "22222222-2222-4222-8222-222222222222","source": { "platform": "youtube", "media_id": "dQw4w9WgXcQ", "canonical_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "title": "Never Gonna Give You Up" },"source_origin": "creator_captions","language": "en","text": "Never gonna give you up. Never gonna let you down.","segments": [{ "start": 0, "end": 2.4, "text": "Never gonna give you up" },{ "start": 2.4, "end": 4.9, "text": "Never gonna let you down" }],"words": null,"timing_granularity": "segment","duration_seconds": 212.0,"recognition": null,"extraction_version": "worker-0.1.0","created_at": "2026-09-16T10:00:14.000Z"}
Transkript sparas under ditt abonnemangs lagringstid (7 dagar på provperioden, 30 på Starter, 90 på Pro och Scale). DELETE /v1/transcripts/{id} tar bort ett transkript i förtid.
Exportera ett transkript#
/v1/transcripts/{id}/export?format=srt| format | Du får |
|---|---|
| txt | Ren text, ett segment per rad. |
| srt | SubRip-undertexter. |
| vtt | WebVTT-undertexter. |
| json | Transkriptobjektet ovan. |
Gratis och obegränsat. srt och vtt kräver tidsättning. Ett transkript utan den returnerar 422 TIMESTAMPS_UNAVAILABLE.
Batcher#
/v1/batchesEn förfrågan, många videor. Varje post har samma fält som Skapa ett jobb; hela batchen accepteras eller avvisas tillsammans. Poster per batch: 1 på provperioden, 10 på Starter, 25 på Pro, 50 på Scale.
curl -X POST https://www.transcriptdock.com/v1/batches \-H "Authorization: Bearer td_live_YOUR_KEY" \-H "Idempotency-Key: playlist-2026-09-16" \-H "Content-Type: application/json" \-d '{ "items": [{ "source": { "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }, "mode": "captions_only" },{ "source": { "url": "https://www.tiktok.com/@tiktok/video/7680721699171601694" }, "mode": "captions_only" }] }'
Batchobjektet har status (queued, processing, succeeded, partial_success, failed, cancelled), antal (total_items, succeeded_items, failed_items, cancelled_items) och items, där varje post har sitt job_id. Läs den med GET /v1/batches/{id}; varje post är ett vanligt jobb.
Uppladdningar#
Ditt eget ljud eller din egen video (mp3, wav, m4a, ogg, aac, mp4, webm; upp till 250 MB och 2 timmar). Reservera en plats, PUT:a filen till den signerade URL:en, markera den som klar och skicka sedan in den som ett jobb med source.upload_id. Uppladdningar använder alltid AI-transkribering.
# 1. Reservecurl -X POST https://www.transcriptdock.com/v1/uploads \-H "Authorization: Bearer td_live_YOUR_KEY" \-H "Content-Type: application/json" \-d '{ "filename": "interview.mp3", "content_type": "audio/mpeg", "bytes": 48213920 }'# -> { "id": "33333333-...", "signed_upload_url": "https://...", "expires_at": "...", "status": "pending" }# 2. Upload the bytes (same Content-Type you declared)curl -X PUT "SIGNED_UPLOAD_URL" -H "Content-Type: audio/mpeg" --data-binary @interview.mp3# 3. Completecurl -X POST https://www.transcriptdock.com/v1/uploads/33333333-3333-4333-8333-333333333333/complete \-H "Authorization: Bearer td_live_YOUR_KEY"# 4. Transcribe itcurl -X POST https://www.transcriptdock.com/v1/jobs \-H "Authorization: Bearer td_live_YOUR_KEY" \-H "Idempotency-Key: interview-01" \-H "Content-Type: application/json" \-d '{ "source": { "upload_id": "33333333-3333-4333-8333-333333333333" }, "mode": "transcribe" }'
Den signerade URL:en är giltig i 24 timmar; reservera en ny plats efter det.
Webhooks#
/v1/webhook-endpointsRegistrera en https-URL och skicka dess id som webhook_endpoint_id när du skickar in. Vi skickar en händelse när jobbet eller batchen är klar. Svaret innehåller signeringshemligheten secret en gång. Att registrera och inaktivera slutpunkter kräver en inloggad session, så gör det på sidan Webhooks i dashboarden. En API-nyckel får 403 FORBIDDEN där men kan lista slutpunkter.
Händelser#
{"event_id": "44444444-4444-4444-8444-444444444444","type": "job.succeeded","created_at": "2026-09-16T10:00:14.000Z","job_id": "11111111-1111-4111-8111-111111111111","batch_id": null,"result_id": "22222222-2222-4222-8222-222222222222","metadata": { "order": "8812" },"error": null}
job.succeeded: hämta eller exporteraresult_id.job.failed:errorinnehåller felkoden.batch.completed: varje post är slutlig; läs batchen för resultat per post.
Svara med en 2xx inom några sekunder. Leveranser som misslyckas försöks igen med ökande väntetid och kan skickas om från dashboarden. En händelse kan komma mer än en gång: filtrera dubbletter på event_id.
Verifiera signaturen#
Headerna X-TranscriptDock-Event-Id, X-TranscriptDock-Timestamp och X-TranscriptDock-Signature. Signaturen är HMAC-SHA256 (hex) av {event_id}.{timestamp}.{raw_body} med din hemlighet. Avvisa allt som är äldre än fem minuter.
import crypto from "node:crypto";export function verify(eventId: string, timestamp: string, rawBody: string, signature: string, secret: string): boolean {if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;const expected = crypto.createHmac("sha256", secret).update(`${eventId}.${timestamp}.${rawBody}`).digest("hex");return expected.length === signature.length && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));}
Hitta videor#
/v1/video-discoveriesSök på YouTube eller lista en kanal, spellista eller TikTok-profil, och mata sedan in URL:erna i jobb. En sökning körs i bakgrunden som ett jobb: läs den med GET /v1/video-discoveries/{id} tills status är succeeded. 1 kredit per sida; resultaten sparas i 24 timmar.
curl -X POST https://www.transcriptdock.com/v1/video-discoveries \-H "Authorization: Bearer td_live_YOUR_KEY" \-H "Idempotency-Key: search-async-rust-1" \-H "Content-Type: application/json" \-d '{ "kind": "youtube_search", "query": "async rust", "limit": 5 }'
POST-anropet svarar 202 med status: "queued". En färdig GET /v1/video-discoveries/{id} ser ut så här:
{"id": "55555555-5555-4555-8555-555555555555","kind": "youtube_search","status": "succeeded","request": { "kind": "youtube_search", "query": "async rust", "limit": 5 },"videos": [{"platform": "youtube","video_id": "wXtngLBkK4Q","url": "https://www.youtube.com/watch?v=wXtngLBkK4Q","title": "Async Rust explained in 20 minutes","channel_id": "UCSp-OaMpsO8K0KkOqyBl7_w","channel_title": "Let's Get Rusty","duration_s": 1155,"published_at": null,"published_text": "5 months ago","view_count": 83635,"view_count_text": "83,635 views","thumbnail_url": "https://i.ytimg.com/vi/wXtngLBkK4Q/hq720.jpg","tiktok": null}],"profile": null,"next_cursor": "opaque-token","error": null,"created_at": "2026-09-16T12:00:00.000Z","updated_at": "2026-09-16T12:00:03.000Z","expires_at": "2026-09-17T12:00:00.000Z"}
Undertextspråk för en video#
/v1/language-discoveriesBody { "source": { "url": "https://www.youtube.com/watch?v=..." } } med en Idempotency-Key (endast YouTube, 1 kredit). Läs GET /v1/language-discoveries/{id} för listan över undertextspår med deras koder, om de är skapade av skaparen eller automatiska, och standardspåret. Använd koderna i caption_languages.
Användning och funktioner#
/v1/usage{"plan": "pro","period_end": "2026-10-16T00:00:00.000Z","credits_remaining": 5840,"credits_total": 6000,"credits_reserved": 4,"prepaid_credits": 0,"transcribe_credits_per_minute": 2,"minimum_billable_seconds": 60,"subscription": {"status": "active","interval": "yearly","cancel_at_period_end": false,"current_period_end": "2027-09-16T00:00:00.000Z"}}
credits_remaining räknar redan bort credits_reserved (reservationer för pågående jobb). prepaid_credits är köpta krediter, som aldrig går ut.
subscription är Stripe-abonnemanget bakom ett betalt abonnemang och null utan ett sådant: dess status, faktureringsintervallet (monthly eller yearly), cancel_at_period_end och current_period_end, alltså när abonnemanget förnyas eller upphör. period_end är när de månatliga krediterna förnyas, varje månad även på årsabonnemang.
/v1/capabilitiesVad din nyckel kan göra just nu: per källa (youtube, tiktok, instagram, upload, direct) vilka lägen som är tillgängliga, samt gränser och priser. Läs detta i stället för att hårdkoda det. Provperioden rapporterar till exempel auto och transcribe som false.
{"youtube": { "enabled": true, "captions_only": true, "auto": true, "transcribe": true, "social_acquisition_fee": true },"tiktok": { "enabled": true, "captions_only": true, "auto": true, "transcribe": true, "social_acquisition_fee": true },"instagram": { "enabled": false, "captions_only": false, "auto": false, "transcribe": false, "social_acquisition_fee": true, "native_captions": "unverified_disabled" },"upload": { "enabled": true, "captions_only": false, "auto": true, "transcribe": true, "social_acquisition_fee": false },"direct": { "enabled": true, "captions_only": false, "auto": true, "transcribe": true, "social_acquisition_fee": false },"max_duration_ms": 7200000,"max_media_bytes": 262144000,"export_formats": ["txt", "json", "srt", "vtt"],"recognition_profiles": ["standard"],"transcribe_credits_per_minute": 2,"minimum_billable_seconds": 60,"price_version": "2026-09-14","asr_enabled": true,"instagram_enabled": false,"free_caption_credits": 50,"free_caption_credits_period": "month"}
Hastighetsgränser#
| Abonnemang | Inskick per minut | Pågående jobb | Läsningar per minut |
|---|---|---|---|
| Provperiod | 10 | 10 | 120 |
| Starter | 60 | 100 | 120 |
| Pro | 120 | 500 | 120 |
| Scale | 300 | 2,000 | 120 |
Över en gräns får du 429 RATE_LIMITED med en retry-after-header (sekunder) och details.detail som namnger gränsen. Inget debiteras. Webhooks och ?wait=25 håller dig långt under läsgränsen.
Fel#
Alla fel har samma form. retryable: true betyder att samma förfrågan kan lyckas senare: vänta retry-after sekunder om den finns, annars några sekunders väntan, och använd samma Idempotency-Key så att inget dubbleras. Alla andra fel kräver en ändring på din sida.
{"error": {"code": "INSUFFICIENT_BALANCE","message": "Not enough credits. Buy credits or upgrade your plan to continue.","retryable": false,"details": { "detail": "This job needs more credits than you have left. Buy credits or upgrade your plan." },"doc_url": "https://www.transcriptdock.com/docs/api-reference#error-codes"},"request_id": "66666666-6666-4666-8666-666666666666"}
Ett jobb som misslyckas efter att det godtagits får fortfarande 200 på GET /v1/jobs/{id}, med status: "failed" och samma felobjekt i error. Ett misslyckat jobb debiteras inte.
Koder#
| Kod | HTTP | Återförsök | Betydelse och vad du gör |
|---|---|---|---|
INVALID_REQUEST | 422 | Nej | A field is missing or has the wrong shape. details.detail names it. |
INVALID_URL | 422 | Nej | The URL is not a valid https link (max 2048 characters). |
UNSUPPORTED_SOURCE | 422 | Nej | The link is not a YouTube or TikTok video URL. |
UNSAFE_URL | 422 | Nej | The direct media link points at a private or blocked network address. |
INVALID_CURSOR | 422 | Nej | A video discovery cursor expired or is malformed. Start again from the first page. A bad job list cursor returns INVALID_REQUEST. |
CAPABILITY_UNAVAILABLE | 422 | Nej | This mode is not available for this source. GET /v1/capabilities shows what is. |
IDEMPOTENCY_CONFLICT | 409 | Nej | This Idempotency-Key was already used with a different body. Use a new key. |
UNAUTHENTICATED | 401 | Nej | No valid API key or OAuth token in the Authorization header. |
FORBIDDEN | 403 | Nej | The key lacks the scope for this endpoint, or the workspace is disabled. |
EMAIL_UNVERIFIED | 403 | Nej | Verify the account email before using the API. |
NOT_FOUND | 404 | Nej | No such object in this workspace. |
INSUFFICIENT_BALANCE | 402 | Nej | Not enough credits for this job. Buy credits or upgrade. |
PLAN_REQUIRED | 402 | Nej | This needs a paid plan (AI transcription, larger batches) or the trial credits are used up. |
BUDGET_EXCEEDED | 402 | Nej | The measured cost is above max_credits. Nothing was charged; raise the cap or skip the media. |
JOB_NOT_RETRYABLE | 409 | Nej | The failure was final (private video, no captions). Fix the input and submit a new job. |
CANCELLATION_NOT_ALLOWED | 409 | Nej | AI transcription already started; the job will finish. |
RATE_LIMITED | 429 | Ja | Over a rate or queue limit. Wait retry-after seconds; details.detail says which limit. |
SOURCE_NOT_FOUND | 422 | Nej | The video does not exist or was removed. |
SOURCE_PRIVATE | 422 | Nej | The video is private. Only public videos work. |
SOURCE_AUTH_REQUIRED | 422 | Nej | The video needs a login, age check or membership. |
SOURCE_REGION_RESTRICTED | 422 | Nej | The video is blocked in the regions we fetch from. |
NO_CAPTIONS | 422 | Nej | No captions on this video and mode was captions_only. Use auto or transcribe. |
LANGUAGE_UNAVAILABLE | 422 | Nej | None of caption_languages exists on this video. Drop the list to take the default track. |
LANGUAGE_UNSUPPORTED | 422 | Nej | AI transcription does not support the requested language. |
NO_SPEECH | 422 | Nej | AI transcription found no speech in the audio. |
NO_AUDIO | 422 | Nej | The media has no audio track. |
INVALID_MEDIA | 422 | Nej | The file could not be read as audio or video. |
UNSUPPORTED_MEDIA | 422 | Nej | Not an audio or video file type. |
DURATION_LIMIT_EXCEEDED | 413 | Nej | Longer than 2 hours. |
FILE_TOO_LARGE | 413 | Nej | Larger than 250 MB. |
TIMESTAMPS_UNAVAILABLE | 422 | Nej | This transcript has no timings, so srt and vtt exports are unavailable. Use txt or json. |
PROVIDER_REJECTED | 422 | Nej | The AI transcription model could not process this audio. |
SOURCE_RATE_LIMITED | 503 | Ja | The source platform is throttling us. The job retries automatically. |
SOURCE_BLOCKED | 503 | Ja | The source platform blocked the fetch. The job retries automatically. |
SOURCE_TIMEOUT | 503 | Ja | The source platform timed out. The job retries automatically. |
SOURCE_CHANGED | 503 | Ja | The source changed while we read it. The job retries automatically. |
PROVIDER_UNAVAILABLE | 503 | Ja | AI transcription is temporarily unavailable. The job retries automatically. |
STORAGE_UNAVAILABLE | 503 | Ja | File storage is temporarily unavailable. Retry the request. |
INTERNAL_ERROR | 500 | Ja | Our fault. Retry with the same Idempotency-Key; quote X-Request-Id if it persists. |