DokümantasyonAPI referansı
API referansı
Tüm /v1 endpoint'lerini parametreleri ve örnekleriyle inceleyin. OpenAPI tanımını JSON veya YAML olarak indirin.
Giriş
https://api.transcript1.com/v1Tüm endpoint'ler için https://api.transcript1.com/v1 adresini temel alın.
- İstek gövdesini JSON olarak gönderin. Yanıtlar da JSON'dur; alan adlarında
snake_casekullanılır. - Tarih ve saatler UTC üzerinden ISO 8601 biçiminde verilir:
2026-10-13T09:30:00.000Zgibi. - Kayıt süresini ve transkriptteki zamanları saniye olarak alırsınız.
- Hata yanıtlarının yapısı ortaktır. Alanları Hatalar bölümünden inceleyebilirsiniz.
- Kimlik doğrulaması yapılmış her çağrının yanıtında
X-RateLimit-LimitveX-RateLimit-Remainingbaşlıkları bulunur. Ayrıntılar Ücretlendirme ve limitler sayfasında. source=autoile YouTube, X, TikTok, Bluesky, Dailymotion ve LinkedIn'de önce videonun kendi dilindeki kullanılabilir altyazıyı ararız. Bulamazsak sesi STT ile yazıya çeviririz.source=captions(yalnızca altyazı) seçerseniz ses indirmeyiz, STT'ye de geçmeyiz; kullanılabilir altyazı yoksano_captionsalırsınız.source=sttveya konuşmacı ayırma ise altyazı adımını atlar. Platform kısıtlamalarını, segment ve kelime zamanları arasındaki farkları Kaynaklar ve seçenekler sayfasından kontrol edin.
Araçlarınızda kullanmak için OpenAPI tanımını indirin:
Kimlik doğrulama
curl https://api.transcript1.com/v1/account \
-H "Authorization: Bearer $TRANSCRIPT1_API_KEY"API anahtarınızı veya OAuth token'ınızı Authorization başlığına ekleyin. Kullanılacak biçim: Authorization: Bearer <token>.
- API anahtarı:
t1_ile başlar ve tüm endpoint'lerde kullanılabilir. Paneldeki “API keys” sayfasından oluşturun. - OAuth erişim token'ı:
t1o_ile başlar. Claude veya ChatGPT gibi bir MCP istemcisini bağladığınızda istemciye verilir.transcriptions:readvetranscriptions:writeyetkilerini kullanır.
| Yetki kapsamı | Kullanılabilen çağrılar |
|---|---|
transcriptions:read | GET /v1/transcriptions, GET /v1/transcriptions/:id, GET /v1/transcriptions/:id/upload ve GET /v1/account |
transcriptions:write | POST /v1/transcriptions, DELETE /v1/transcriptions/:id ve POST /v1/transcriptions/:id/upload/complete |
- Token gereken yetki kapsamına sahip değilse
403 insufficient_scopealırsınız. - Kimlik bilgisi göndermezseniz veya gönderdiğiniz bilgi geçersizse
401 unauthorizeddöner.
Dosya parçalarını gönderen PUT /v1/transcriptions/:id/upload/chunks/:index çağrısında ise X-Upload-Token kullanın. Bu token yüklemeyi başlattığınızda verilir. Adımlar için Dosya yükleme sayfasına bakın.
Idempotency
curl -X POST https://api.transcript1.com/v1/transcriptions \
-H "Authorization: Bearer $TRANSCRIPT1_API_KEY" \
-H "Idempotency-Key: 5f1c2b0e-8d4a-4c3e-9b7a-2e6f1d0c9a8b" \
-H "Content-Type: application/json" \
-d '{"url":"https://www.youtube.com/watch?v=dQw4w9WgXcQ"}'Bağlantı kesildiğinde veya yeniden denemeniz gerektiğinde aynı transkripsiyonu iki kez başlatmayın. POST /v1/transcriptions çağrısına Idempotency-Key başlığı ekleyin.
Anahtar 1–255 karakter uzunluğunda olmalıdır. Sorgu parametresine yazmayın; HTTP başlığında gönderin.
- Aynı anahtar ve parametrelerle tekrar çağırırsanız ilk transkripsiyonu alırsınız. Yeniden dakika harcamazsınız.
- Parametreleri değiştirip anahtarı aynı bırakırsanız
409 idempotency_conflictalırsınız. - Parçalı yüklemeyi başlatan isteği aynı anahtarla tekrarladığınızda yeni bir yükleme token'ı alırsınız.
Hatalar
{
"error": {
"code": "insufficient_minutes",
"message": "Not enough minutes",
"retryable": false,
"action_url": "https://transcript1.com/dashboard/billing",
"minutes_needed": 20,
"minutes_remaining": 3
}
}- İstek hatası alırsanız API çağrınızı kabul etmemiştir.
- Transkripsiyon hatasında istek kabul edilmiştir, ancak işlem daha sonra başarısız olmuştur. Transkripsiyonun
statusalanıfailedolur.
Hata yanıtının yapısı
/v1 çağrılarında istek hatalarını error nesnesi içinde alırsınız. Bu nesnede code, message ve retryable bulunur.
- Uygulamanızın atacağı adımı
codeüzerinden belirleyin. messagekullanıcıya gösterebileceğiniz açıklamadır. Metni değişebileceği için bu alana göre koşul yazmayın.retryabledeğeritrueolduğunda aynı çağrı daha sonra çalışabilir.
Bazı hatalarda retryable yanında sorunu açıklayan ek alanlar da bulunur:
| Alan | İlgili hata | Açıklama |
|---|---|---|
action_url | insufficient_minutes | Plan seçebileceğiniz veya ek dakika satın alabileceğiniz sayfa. |
minutes_needed, minutes_remaining | insufficient_minutes | İşlem için gereken dakika ve kullanılabilir bakiyeniz. Gereken süre henüz bilinmiyorsa ilk alan null olur. |
supported_platforms | unsupported_platform | Kabul edilen platform değerleri: ["youtube", "x", "tiktok", "instagram", "facebook", "bluesky", "twitch", "dailymotion", "pinterest", "linkedin", "snapchat"]. |
missing_chunks | upload_incomplete | Sunucuya ulaşmayan parçaların numaraları. |
max_bytes | media_too_large | Hesabınızın dosya boyutu limiti, bayt olarak. |
params | invalid_request | Gövde veya sorgu doğrulamasında her hatalı alanı ve o alandaki sorunu gösteren nesne. |
API'nin isteği kabul etmediği durumlar
| HTTP kodu | code | Aynı istek tekrar denenebilir mi? | Neden alırsınız? |
|---|---|---|---|
| 400, 422 | invalid_request | Hayır | Bir parametre veya gövde alanı eksik ya da geçersiz. Örneğin diarize ile source: "captions" veya reuse_recent ile webhook_url birlikte gönderilmiş olabilir. Gövde geçerli JSON değilse de bu kod döner. |
| 422 | invalid_url | Hayır | Bağlantı desteklenmiyor veya platform ile eşleşmiyor. YouTube, X, TikTok, Instagram, Facebook, Bluesky ya da Kaynaklar ve seçenekler sayfasındaki diğer platformlardan birinin bağlantısını kullanın. |
| 422 | unsupported_platform | Hayır | Gönderdiğiniz platform değeri desteklenenler arasında değil. |
| 422 | unsupported_media | Hayır | Dosyanın uzantısını desteklemiyoruz. |
| 401 | unauthorized | Hayır | API kimlik bilginiz eksik, geçersiz, süresi dolmuş veya iptal edilmiş. Geçersiz ya da süresi dolmuş yükleme token'ında da bu kod döner. |
| 403 | insufficient_scope | Hayır | OAuth token'ında gereken transcriptions:read veya transcriptions:write yetkisi yok. |
| 403 | email_not_verified | Hayır | E-postanız henüz doğrulanmamış. Transkripsiyon başlatmadan önce adresinizi doğrulayın. |
| 402 | insufficient_minutes | Hayır | Kullanılabilir bakiyeniz 0 veya işlem için gereken dakikadan az. |
| 402 | no_active_plan | Hayır | Ücretli planınız aktif değilken ek dakika satın almaya çalıştınız. Bu kod yalnızca panelin ücretlendirme endpoint'inden döner; transkripsiyon endpoint'lerinden dönmez. |
| 404 | not_found | Hayır | Bu transkripsiyon bulunamadı veya başka bir ekibe ait. |
| 409 | upload_incomplete | Hayır | Dosyanın bazı parçaları yüklenmemiş. Eksikleri gönderip tamamlama çağrısını tekrarlayın. |
| 409 | invalid_state | Hayır | Transkripsiyon yükleme bekleme aşamasında değil. Artık parça gönderemez veya yüklemeyi tamamlayamazsınız. |
| 409 | idempotency_conflict | Hayır | Aynı Idempotency-Key daha önce farklı parametrelerle kullanılmış. |
| 413 | media_too_large | Hayır | Dosya, hesabınızın boyut limitini aşıyor. Dosya yükleme sayfasını kontrol edin. |
| 413 | invalid_request | Hayır | JSON gövdesi 1 MB'ı aşıyor. Dosya boyutu hatalarında bunun yerine media_too_large kullanılır. |
| 429 | rate_limited | Evet | Dakikalık istek limitini aştınız. Retry-After değerinde belirtilen saniye kadar bekleyin. |
| 429 | too_many_active_jobs | Evet | Aynı anda çalışan transkripsiyon veya açık yükleme limitini aştınız. Retry-After değerinde belirtilen saniye kadar bekleyin. |
| 500 | internal_error | Evet | Sunucu tarafında bir sorun oluştu. Biraz bekleyip tekrar deneyin. |
| 503 | service_unavailable | Evet | transcript1'e şu anda erişilemiyor. Biraz bekleyip tekrar deneyin. |
Tarayıcıdan oturum çereziyle yapılan çağrılarda isteğin geldiği siteyi de kontrol ederiz. Başka bir siteden geliyorsa 403 forbidden_origin döner.
Bu kontrol, Authorization başlığıyla yaptığınız API çağrılarını etkilemez.
Tüm 429 yanıtlarında Retry-After bulunur. Değer saniye cinsindedir. Hesabınıza uygulanan limitleri Ücretlendirme ve limitler sayfasından kontrol edebilirsiniz.
Ne zaman tekrar denemelisiniz?
- Aynı isteği yalnızca
retryabledeğeritrueolduğunda tekrar gönderin:rate_limited,too_many_active_jobs,internal_errorveservice_unavailable. Retry-Aftervarsa belirtilen süreyi bekleyin. Yoksa her denemede bekleme süresini artırın.POST /v1/transcriptionsçağrısını tekrarlarken aynıIdempotency-Keybaşlığını koruyun. İlk çağrı aslında başarılı olduysa böylece ikinci kez dakika harcamazsınız.- Diğer kodlarda önce hatanın nedenini giderin, sonra yeniden gönderin.
İşlem başladıktan sonra oluşan hatalar
Transkripsiyonun status değeri failed olduğunda, code ve message içeren bir error nesnesi de alırsınız.
İstek kabul edildikten sonra da hata oluşabilir. Durumu sorgularken veya transcription.failed webhook bildirimi aldığınızda error alanını kontrol edin.
error.code | Ne oldu? | Ne yapmalısınız? |
|---|---|---|
media_unavailable | Video bulunamadı veya artık erişilemiyor. | Aynı bağlantıyla tekrar denemeyin; URL'yi kontrol edin. |
media_private | Video gizli. | Aynı videoyu tekrar göndermeyin. Herkese açık bir gönderi kullanın; YouTube'da liste dışı videolar da çalışır. |
login_required | Platform videoyu izlemek için giriş yapılmasını istiyor. | Kalıcı bir hatadır; tekrar denemeyiz. |
no_audio | Videoda ses kanalı yok. | Kalıcı bir hatadır; tekrar denemeyiz. |
age_restricted | Videoda yaş kısıtlaması var. | Aynı bağlantıyı tekrar göndermek yerine dosyayı yükleyin. |
live_stream | Yayın devam ediyor veya henüz başlamamış. | Yayın sona erdikten sonra deneyin. |
no_captions | source için captions seçilmiş, ancak kullanılabilir altyazı bulunamamış. | source: "auto" veya "stt" ile gönderin. |
media_too_long | Kayıt, STT için geçerli 5 saat sınırını aşıyor. | Aynı kaydı tekrar göndermeyin; daha kısa parçalara bölün. |
unsupported_media | Dosyayı okuyamadık veya dosyada ses kanalı yok. | Desteklenen bir dosya hazırlayıp gönderin. |
no_speech | Konuşma algılanmadı. | Tekrar denemeyin. |
unsupported_language | Kayıttaki dili desteklemiyoruz. | Aynı ayarla tekrar denemeyin. language için desteklenen bir kod veya "auto" seçin. |
insufficient_minutes | Ücret hesaplanmadan önce dakika bakiyeniz tükendi. | Ek dakika yükledikten sonra deneyin. |
fetch_failed | Birkaç kez denememize rağmen kaydı indiremedik. | Daha sonra tekrar deneyebilirsiniz. |
transcription_failed | Birkaç kez denememize rağmen STT tamamlanamadı. | Daha sonra tekrar deneyebilirsiniz. |
Transkripsiyon başarısız olursa veya iptal edilirse ücret ödemezsiniz. Daha önce dakika düşülmüşse hesabınıza geri ekleriz.
Transcription nesnesi
{
"id": "tr_4fHq8ZbN2xLm0PqRsTuVwX",
"object": "transcription",
"status": "completed",
"source": {
"platform": "youtube",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"media_id": "dQw4w9WgXcQ"
},
"media": {
"title": "Example video",
"author": "Example channel",
"author_url": "https://www.youtube.com/@examplechannel",
"thumbnail_url": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg",
"duration_seconds": 212
},
"options": {
"source": "auto",
"language": "auto",
"diarize": false
},
"transcript_source": "youtube_captions",
"caption_kind": "auto_generated",
"language": "en",
"billed_minutes": 4,
"cached": false,
"error": null,
"created_at": "2026-10-13T09:30:00.000Z",
"completed_at": "2026-10-13T09:30:04.000Z",
"deleted_at": null,
"transcript": {
"text": "Welcome back to the channel. Today we are looking at how transcripts are made.",
"speakers": [],
"segments": [
{
"start": 0,
"end": 4.2,
"speaker": null,
"language": "en",
"text": "Welcome back to the channel."
},
{
"start": 4.2,
"end": 9.8,
"speaker": null,
"language": "en",
"text": "Today we are looking at how transcripts are made."
}
]
}
}Alanlar
- idstringzorunlu
- objectstringzorunlu
Alabileceği değerler
transcription - statusstringzorunlu
Alabileceği değerler
awaiting_uploadqueuedfetchingtranscribingcompletedfailedcanceled - sourceobjectzorunlu
Alt alanları gösterinAlt alanları gizleyin
With
url- platformstringzorunlu
- urlstringzorunlunull alabilir
- media_idstringzorunlunull alabilir
With
filename- platformstringzorunlu
Alabileceği değerler
upload - filenamestringzorunlunull alabilir
- sizenumberzorunlunull alabilir
- mediaobjectzorunlunull alabilir
Alt alanları gösterinAlt alanları gizleyin
- titlestringisteğe bağlınull alabilir
- authorstringisteğe bağlınull alabilir
- author_urlstringisteğe bağlınull alabilir
- thumbnail_urlstringisteğe bağlınull alabilir
- filenamestringisteğe bağlı
- mime_typestringisteğe bağlı
- sizenumberisteğe bağlı
- duration_secondsnumberisteğe bağlınull alabilir
- optionsobjectzorunlu
Alt alanları gösterinAlt alanları gizleyin
- sourcestringzorunlu
Alabileceği değerler
autocaptionsstt - languagestringzorunlu
- diarizebooleanzorunlu
- transcript_sourcestringzorunlunull alabilir
Alabileceği değerler
youtube_captionsx_captionsspeech_to_text - caption_kindstringzorunlunull alabilir
Alabileceği değerler
manualauto_generated - languagestringzorunlunull alabilir
- billed_minutesintegerzorunlunull alabilir
- cachedbooleanzorunlu
- errorobjectzorunlunull alabilir
Alt alanları gösterinAlt alanları gizleyin
- codestringzorunlu
- messagestringzorunlunull alabilir
- created_atstring · date-timezorunlunull alabilir
- completed_atstring · date-timezorunlunull alabilir
- deleted_atstring · date-timezorunlunull alabilir
When the transcription was deleted. Always
nullunless the request includesinclude_deleted=true. - transcriptobjectisteğe bağlı
Included in
GETresponses for completed transcriptions.Alt alanları gösterinAlt alanları gizleyin
- textstringzorunlu
- speakersarray of stringszorunlu
- segmentsarray of objectszorunlu
Alt alanları gösterinAlt alanları gizleyin
- startnumberzorunlu
- endnumberzorunlu
- speakerstringzorunlunull alabilir
- languagestringzorunlunull alabilir
- textstringzorunlu
- wordsarray of objectsisteğe bağlınull alabilir
Alt alanları gösterinAlt alanları gizleyin
- startnumberzorunlu
- endnumberzorunlu
- textstringzorunlu
- confidencenumberisteğe bağlınull alabilir
- speakerstringzorunlunull alabilir
Transcriptions
Create, read, list and delete transcriptions of video links and uploaded files.
Create a transcription
POST /v1/transcriptionsTranscribes an uploaded file or a YouTube, X, TikTok, Instagram, Facebook, Bluesky, Twitch, Dailymotion, Pinterest, LinkedIn, Snapchat link. Social posts must be public; only the first video is used.
Twitch accepts clips and completed VODs; Pinterest accepts native video pins; LinkedIn accepts public video posts; Snapchat accepts Spotlight. New platforms require public recorded native media without supplied account cookies; no live streams or external embeds.
platform is optional and detected from the link. Captions are YouTube/X-only. All sources use the same per-minute price.
Returns 200 for a final result, 201 when awaiting an upload and 202 while processing. Pass wait to wait up to 60 seconds for a final status.
Pass reuse_recent=true with a platform URL to reuse a transcription of the same video and options from the last 24 hours. The response includes reused: true, with no additional charge. Short links may not be matched. An Idempotency-Key replay takes precedence.
curl -X POST https://api.transcript1.com/v1/transcriptions \
-H "Authorization: Bearer $TRANSCRIPT1_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://www.youtube.com/watch?v=dQw4w9WgXcQ"}'{
"id": "tr_4fHq8ZbN2xLm0PqRsTuVwX",
"object": "transcription",
"status": "queued",
"source": {
"platform": "youtube",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"media_id": "dQw4w9WgXcQ"
},
"media": null,
"options": {
"source": "auto",
"language": "auto",
"diarize": false
},
"transcript_source": null,
"caption_kind": null,
"language": null,
"billed_minutes": null,
"cached": false,
"error": null,
"created_at": "2026-10-13T09:30:00.000Z",
"completed_at": null,
"deleted_at": null,
"reused": false
}Query parametreleri
- waitintegeristeğe bağlınull alabilirVarsayılan: 0
Seconds to wait for a final status before responding, up to 60. Defaults to 0.
- reuse_recentstringisteğe bağlıVarsayılan: false
For platform URLs only. Cannot be combined with
webhook_url. Returns the team's most recent transcription of the same video with the samesource,languageanddiarize. It must have been created in the last 24 hours and must not befailedorcanceled. Reuses that transcription without creating or charging for a new one.Alabileceği değerler
truefalse
Header alanları
- Idempotency-Keystringisteğe bağlı
Returns the original transcription when you repeat a request with the same key and parameters.
Body
With url
- platformstringisteğe bağlı
Optional; detected from the link. If supplied, must match the link.
Alabileceği değerler
youtubextiktokinstagramfacebookblueskytwitchdailymotionpinterestlinkedinsnapchat - urlstringzorunlu
YouTube, X, TikTok, Instagram, Facebook, Bluesky, Twitch, Dailymotion, Pinterest, LinkedIn, Snapchat video link. Social posts must be public; only the first video is used. New platforms support public recorded native video without supplied account cookies, not live streams or external embeds.
- sourcestringisteğe bağlı
"auto" uses YouTube or X captions when available, otherwise speech-to-text. "captions" is YouTube/X-only. "stt" always uses speech-to-text.
Alabileceği değerler
autocaptionsstt - languagestringisteğe bağlı
- diarizebooleanisteğe bağlı
- webhook_urlstring · uriisteğe bağlı
With upload
- uploadobjectzorunlu
Alt alanları gösterinAlt alanları gizleyin
- filenamestringzorunlu
- sizeintegerzorunlu
- mime_typestringisteğe bağlı
- sourcestringisteğe bağlı
Alabileceği değerler
autostt - languagestringisteğe bağlı
- diarizebooleanisteğe bağlı
- webhook_urlstring · uriisteğe bağlı
multipart/form-data
- filestring · binaryzorunlu
- sourcestringisteğe bağlı
Alabileceği değerler
autostt - languagestringisteğe bağlı
- diarizebooleanisteğe bağlı
- webhook_urlstring · uriisteğe bağlı
Başarılı yanıtlar
200 OK— The transcription reached a final status201 Created— The transcription is awaiting a chunked upload.uploaddescribes where to send each chunk.202 Accepted— The transcription is processing
Diğer HTTP durumları
400 Bad Request— The JSON request body is malformed401 Unauthorized— Missing or invalid credential402 Payment Required— Not enough minutes. Applies to every request body format.403 Forbidden— Insufficient scope, unverified email, cross-site request or a single-member team plan409 Conflict—Idempotency-Keywas reused with different parameters.413 Content Too Large— The upload or the JSON request body is too large422 Unprocessable Content— Invalid request, URL, platform or file type429 Too Many Requests— Too many requests or too many active transcriptions. Wait for the number of seconds inRetry-After.
Get a transcription
GET /v1/transcriptions/{id}Returns the transcription object. Completed transcriptions include the transcript. Use format to render it as text, SRT or WebVTT.
If you request a rendered format before completion, the response is JSON. It returns 202 while processing or 200 if the transcription failed or was canceled.
With include_deleted=true, a deleted transcription is returned as a record without a transcript. For deleted records, wait is ignored and rendered formats return 404.
curl https://api.transcript1.com/v1/transcriptions/tr_4fHq8ZbN2xLm0PqRsTuVwX \
-H "Authorization: Bearer $TRANSCRIPT1_API_KEY"{
"id": "tr_4fHq8ZbN2xLm0PqRsTuVwX",
"object": "transcription",
"status": "completed",
"source": {
"platform": "youtube",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"media_id": "dQw4w9WgXcQ"
},
"media": {
"title": "Example video",
"author": "Example channel",
"author_url": "https://www.youtube.com/@examplechannel",
"thumbnail_url": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg",
"duration_seconds": 212
},
"options": {
"source": "auto",
"language": "auto",
"diarize": false
},
"transcript_source": "youtube_captions",
"caption_kind": "auto_generated",
"language": "en",
"billed_minutes": 4,
"cached": false,
"error": null,
"created_at": "2026-10-13T09:30:00.000Z",
"completed_at": "2026-10-13T09:30:04.000Z",
"deleted_at": null,
"transcript": {
"text": "Welcome back to the channel. Today we are looking at how transcripts are made.",
"speakers": [],
"segments": [
{
"start": 0,
"end": 4.2,
"speaker": null,
"language": "en",
"text": "Welcome back to the channel."
},
{
"start": 4.2,
"end": 9.8,
"speaker": null,
"language": "en",
"text": "Today we are looking at how transcripts are made."
}
]
}
}Path parametreleri
- idstringzorunlu
Query parametreleri
- waitintegeristeğe bağlınull alabilirVarsayılan: 0
Seconds to wait for a final status before responding, up to 60. Defaults to 0.
- formatstringisteğe bağlıVarsayılan: json
Alabileceği değerler
jsontextsrtvtt - includestringisteğe bağlı
Alabileceği değerler
words - timestampsstringisteğe bağlıVarsayılan: false
Alabileceği değerler
truefalse - include_deletedstringisteğe bağlıVarsayılan: false
Also returns deleted transcriptions as read-only records without a transcript. Their
deleted_atis set. Defaults tofalse.Alabileceği değerler
truefalse
Başarılı yanıtlar
200 OK— The transcription, or the rendered transcript202 Accepted— A rendered format was requested while the transcription is still processing
Diğer HTTP durumları
401 Unauthorized— Missing or invalid credential403 Forbidden— Insufficient scope or a single-member team plan404 Not Found— Transcription not found422 Unprocessable Content— Invalid query parameters429 Too Many Requests— Too many requests. Wait for the number of seconds inRetry-After.
List transcriptions
GET /v1/transcriptionsLists your team's transcriptions, newest first, without transcripts. Pass next_cursor as cursor to get the next page.
Deleted transcriptions are hidden unless you pass include_deleted=true.
curl https://api.transcript1.com/v1/transcriptions \
-H "Authorization: Bearer $TRANSCRIPT1_API_KEY"{
"object": "list",
"data": [
{
"id": "tr_4fHq8ZbN2xLm0PqRsTuVwX",
"object": "transcription",
"status": "completed",
"source": {
"platform": "youtube",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"media_id": "dQw4w9WgXcQ"
},
"media": {
"title": "Example video",
"author": "Example channel",
"author_url": "https://www.youtube.com/@examplechannel",
"thumbnail_url": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg",
"duration_seconds": 212
},
"options": {
"source": "auto",
"language": "auto",
"diarize": false
},
"transcript_source": "youtube_captions",
"caption_kind": "auto_generated",
"language": "en",
"billed_minutes": 4,
"cached": false,
"error": null,
"created_at": "2026-10-13T09:30:00.000Z",
"completed_at": "2026-10-13T09:30:04.000Z",
"deleted_at": null
}
],
"next_cursor": "eyJjcmVhdGVkQXQiOiIyMDI2LTEwLTEzVDA5OjMwOjAwLjAwMFoiLCJpZCI6IjViMGU2YzFjLTBkNmYtNGMxZi05YjVlLThmM2Y0ZDBhN2ExMSJ9"
}Query parametreleri
- limitintegeristeğe bağlıVarsayılan: 20
- cursorstringisteğe bağlı
- statusstringisteğe bağlı
Alabileceği değerler
awaiting_uploadqueuedfetchingtranscribingcompletedfailedcanceled - platformstringisteğe bağlı
- include_deletedstringisteğe bağlıVarsayılan: false
Also returns deleted transcriptions as read-only records without a transcript. Their
deleted_atis set. Defaults tofalse.Alabileceği değerler
truefalse
Başarılı yanıtlar
200 OK— A page of transcriptions
Diğer HTTP durumları
401 Unauthorized— Missing or invalid credential403 Forbidden— Insufficient scope or a single-member team plan422 Unprocessable Content— Invalid query parameters or cursor429 Too Many Requests— Too many requests. Wait for the number of seconds inRetry-After.
Cancel or delete a transcription
DELETE /v1/transcriptions/{id}Cancels an active transcription or one awaiting an upload. Any charged minutes are refunded.
Deletes a completed, failed or canceled transcription together with its stored transcript.
curl -X DELETE https://api.transcript1.com/v1/transcriptions/tr_4fHq8ZbN2xLm0PqRsTuVwX \
-H "Authorization: Bearer $TRANSCRIPT1_API_KEY"Yanıt gövdesi yok
Path parametreleri
- idstringzorunlu
Başarılı yanıtlar
204 No Content— Canceled or deleted
Diğer HTTP durumları
401 Unauthorized— Missing or invalid credential403 Forbidden— Insufficient scope, cross-site request or a single-member team plan404 Not Found— Transcription not found429 Too Many Requests— Too many requests. Wait for the number of seconds inRetry-After.
Uploads
Send a large file in chunks. Start with Create a transcription using an upload body. Send each chunk, then complete the upload.
Upload one chunk
PUT /v1/transcriptions/{id}/upload/chunks/{index}Sends one chunk of a chunked upload as application/octet-stream.
Authenticate with the X-Upload-Token from the create response. This endpoint does not use a bearer credential.
The body must match the planned chunk size exactly. Sending a chunk again replaces it.
curl -X PUT https://api.transcript1.com/v1/transcriptions/tr_4fHq8ZbN2xLm0PqRsTuVwX/upload/chunks/0 \
-H "X-Upload-Token: t1u_Zk3vYb8Nw1ZrT5xLpD0aHcE7sUj9GfMiO2yXtVnR4Bw" \
-H "Content-Type: application/octet-stream" \
--data-binary @chunk-0.bin{
"object": "upload_chunk",
"index": 0,
"size": 838860
}Path parametreleri
- idstringzorunlu
- indexintegeristeğe bağlınull alabilir
Zero-based chunk number from the upload plan
Header alanları
- X-Upload-Tokenstringzorunlu
Body
- (ham içerik)string · binaryzorunlu
Başarılı yanıtlar
200 OK— The chunk was stored
Diğer HTTP durumları
401 Unauthorized— Missing, invalid or expired upload token404 Not Found— Transcription not found409 Conflict— The transcription is no longer awaiting an upload422 Unprocessable Content— Index outside the chunk plan or wrong body size
Get upload progress
GET /v1/transcriptions/{id}/uploadLists the received chunks of a chunked upload so an interrupted upload can resume.
curl https://api.transcript1.com/v1/transcriptions/tr_4fHq8ZbN2xLm0PqRsTuVwX/upload \
-H "Authorization: Bearer $TRANSCRIPT1_API_KEY"{
"object": "upload",
"status": "awaiting_upload",
"total_bytes": 48210334,
"uploaded_bytes": 4194300,
"received_chunks": [
0,
1,
2,
3,
4
],
"chunks": [
{
"index": 0,
"offset": 0,
"size": 838860
},
{
"index": 1,
"offset": 838860,
"size": 838860
},
{
"index": 2,
"offset": 1677720,
"size": 838860
},
{
"index": 3,
"offset": 2516580,
"size": 838860
},
{
"index": 4,
"offset": 3355440,
"size": 838860
},
{
"index": 5,
"offset": 4194300,
"size": 8388608
},
{
"index": 6,
"offset": 12582908,
"size": 8388608
},
{
"index": 7,
"offset": 20971516,
"size": 8388608
},
{
"index": 8,
"offset": 29360124,
"size": 8388608
},
{
"index": 9,
"offset": 37748732,
"size": 8388608
},
{
"index": 10,
"offset": 46137340,
"size": 2072994
}
],
"expires_at": "2026-10-13T10:30:00.000Z"
}Path parametreleri
- idstringzorunlu
Başarılı yanıtlar
200 OK— Upload progress
Diğer HTTP durumları
401 Unauthorized— Missing or invalid credential403 Forbidden— Insufficient scope or a single-member team plan404 Not Found— Transcription or upload not found429 Too Many Requests— Too many requests. Wait for the number of seconds inRetry-After.
Complete a chunked upload
POST /v1/transcriptions/{id}/upload/completeChecks that every planned chunk arrived with the planned size. Then assembles the file and queues the transcription.
curl -X POST https://api.transcript1.com/v1/transcriptions/tr_4fHq8ZbN2xLm0PqRsTuVwX/upload/complete \
-H "Authorization: Bearer $TRANSCRIPT1_API_KEY"{
"id": "tr_4fHq8ZbN2xLm0PqRsTuVwX",
"object": "transcription",
"status": "queued",
"source": {
"platform": "upload",
"filename": "interview.m4a",
"size": 48210334
},
"media": {
"filename": "interview.m4a",
"mime_type": "audio/mp4",
"size": 48210334
},
"options": {
"source": "auto",
"language": "auto",
"diarize": false
},
"transcript_source": null,
"caption_kind": null,
"language": null,
"billed_minutes": null,
"cached": false,
"error": null,
"created_at": "2026-10-13T09:30:00.000Z",
"completed_at": null,
"deleted_at": null
}Path parametreleri
- idstringzorunlu
Başarılı yanıtlar
202 Accepted— The transcription is queued
Diğer HTTP durumları
401 Unauthorized— Missing or invalid credential402 Payment Required— Not enough minutes to queue the transcription. The upload stays awaiting completion.403 Forbidden— Insufficient scope, cross-site request or a single-member team plan404 Not Found— Transcription or upload not found409 Conflict—upload_incompletemeans chunks are missing.missing_chunkslists them.invalid_statemeans the transcription is not awaiting an upload.429 Too Many Requests— Too many requests or too many active transcriptions. Wait for the number of seconds inRetry-After.
Account
Your plan, remaining minutes and rate limits.
Get your account
GET /v1/accountReturns the authenticated user, current plan and remaining transcription minutes.
curl https://api.transcript1.com/v1/account \
-H "Authorization: Bearer $TRANSCRIPT1_API_KEY"{
"object": "account",
"user": {
"id": "5b0e6c1c-0d6f-4c1f-9b5e-8f3f4d0a7a11",
"email": "[email protected]"
},
"plan": {
"id": "9d4e0c0a-2b8a-4f0c-8d63-6a8d3c8a1f22",
"name": "Monthly"
},
"minutes": {
"remaining": 1180,
"cycle": 980,
"topup": 200,
"topup_usable": true,
"resets_at": "2026-11-13T09:30:00.000Z"
},
"renews_at": "2026-11-13T09:30:00.000Z",
"limits": {
"requests_per_minute": 200,
"max_active_jobs": 10
}
}Başarılı yanıtlar
200 OK— The authenticated user's account
Diğer HTTP durumları
401 Unauthorized— Missing or invalid credential403 Forbidden— Insufficient scope or a single-member team plan404 Not Found— No account found429 Too Many Requests— Too many requests. Wait for the number of seconds inRetry-After.
Account nesnesi
{
"object": "account",
"user": {
"id": "5b0e6c1c-0d6f-4c1f-9b5e-8f3f4d0a7a11",
"email": "[email protected]"
},
"plan": {
"id": "9d4e0c0a-2b8a-4f0c-8d63-6a8d3c8a1f22",
"name": "Monthly"
},
"minutes": {
"remaining": 1180,
"cycle": 980,
"topup": 200,
"topup_usable": true,
"resets_at": "2026-11-13T09:30:00.000Z"
},
"renews_at": "2026-11-13T09:30:00.000Z",
"limits": {
"requests_per_minute": 200,
"max_active_jobs": 10
}
}Alanlar
- objectstringzorunlu
Alabileceği değerler
account - userobjectzorunlu
Alt alanları gösterinAlt alanları gizleyin
- idstringzorunlu
- emailstringzorunlu
- planobjectzorunlunull alabilir
Alt alanları gösterinAlt alanları gizleyin
- idstringzorunlu
- namestringzorunlu
- minutesobjectzorunlu
Alt alanları gösterinAlt alanları gizleyin
- remainingnumberzorunlu
- cyclenumberzorunlu
- topupnumberzorunlu
- topup_usablebooleanzorunlu
- resets_atstring · date-timezorunlunull alabilir
- renews_atstring · date-timezorunlunull alabilir
- limitsobjectzorunlu
Alt alanları gösterinAlt alanları gizleyin
- requests_per_minutenumberzorunlu
- max_active_jobsnumberzorunlu
Webhook bildirimleri
import { Buffer } from 'node:buffer';
import crypto from 'node:crypto';
// header: X-Transcript1-Signature, rawBody: the request body exactly as received,
// secret: your full signing secret including the whsec_ prefix.
export const verifySignature = (secret, header, rawBody, nowSeconds = Math.floor(Date.now() / 1000)) => {
const fields = Object.fromEntries(header.split(',').map(part => part.trim().split('=')));
const t = Number(fields.t);
if (!Number.isInteger(t) || !fields.v1 || Math.abs(nowSeconds - t) > 300) {
return false;
}
const expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
return fields.v1.length === expected.length
&& crypto.timingSafeEqual(Buffer.from(fields.v1), Buffer.from(expected));
};{
"type": "transcription.completed",
"created_at": "2026-10-13T09:30:04.000Z",
"data": {
"id": "tr_8fK2Lm0PqRsTuVwXyZaBcD",
"object": "transcription",
"status": "completed",
"transcript_source": "youtube_captions",
"billed_minutes": 4,
"error": null
}
}İşlem sona erdiğinde bildirim almak için transkripsiyonu oluştururken webhook_url gönderin. Transkripsiyon tamamlanırsa veya başarısız olursa bu adrese imzalı bir POST yollarız.
Bu özellik yalnızca REST API'de bulunur. MCP sunucusu webhook parametresi kabul etmez.
Bildirim adresini belirtin
POST /v1/transcriptions çağrısında webhook_url alanını ekleyin:
- Video bağlantısı gönderirken veya parçalı yükleme başlatırken JSON gövdesini kullanın.
- Dosyayı tek istekte yüklüyorsanız aynı alanı forma ekleyin.
Bildirim adresiniz için şu kurallar geçerlidir:
- HTTPS zorunludur.
- URL içinde kullanıcı adı veya parola bulunamaz.
- Adres, internetten erişilebilen bir IP adresine çözümlenmelidir.
Özel ağ, loopback, link-local veya diğer herkese açık olmayan adresler için 422 invalid_request alırsınız. Adresi hem transkripsiyon oluşturulurken hem de her bildirim gönderiminde kontrol ederiz.
webhook_url gönderiyorsanız aynı istekte reuse_recent=true kullanmayın; bu iki seçenek birlikte çalışmaz.
Hangi olaylarda bildirim gelir?
type | Gönderildiği durum |
|---|---|
transcription.completed | Transkripsiyon tamamlandı; durumu completed. |
transcription.failed | Transkripsiyon başarısız oldu; durumu failed. Hatanın code ve message alanları data.error içinde bulunur. |
Transkripsiyonu iptal ederseniz webhook göndermeyiz.
Bildirimin içeriği
Gelen isteğin JSON gövdesinde şu bilgiler bulunur:
created_at: Olayın oluştuğu an.data: Transkripsiyon nesnesi; transkript metni olantranscriptbu nesneye eklenmez.
Metni almak için data içindeki id değerini kullanarak GET /v1/transcriptions/:id çağırın.
Her bildirimde aşağıdaki HTTP başlıklarını göndeririz:
Content-Type: application/jsonUser-Agent: transcript1-webhooks/1.0- İmzayı taşıyan
X-Transcript1-Signature; doğrulama adımları aşağıda.
Gelen isteğin imzasını doğrulayın
X-Transcript1-Signature başlığı her gönderimde bulunur. Değeri t=<unix seconds>,v1=<hex digest> biçimindedir.
t, imzanın oluşturulduğu anı saniye cinsinden Unix zamanı olarak verir.v1,"<t>.<raw body>"metninden hesaplanan HMAC-SHA256 imzasının hex biçimidir.tdeğerini, bir noktayı ve hiç değiştirmediğiniz istek gövdesini birleştirin. HMAC anahtarı olarak gizli imza anahtarınızın tamamını,whsec_önekiyle birlikte kullanın.
İmzayı JSON'u ayrıştırmadan, gövdenin gelen baytları üzerinden doğrulayın. JSON'u ayrıştırıp yeniden oluşturmak boşlukları veya alan sırasını değiştirebilir; bu durumda imza eşleşmez.
- İmzaları sabit zamanda çalışan bir karşılaştırmayla kontrol edin.
tile şu an arasındaki fark çok büyükse isteği reddedin. Örnekler 5 dakikalık farka izin verir.- Express kullanıyorsanız gövdeyi JSON'a çevirmeden ham metin olarak alın.
- Flask kullanıyorsanız
raw_bodyiçinrequest.get_data(as_text=True)değerini gönderin.
Webhook imza anahtarınız
Gizli imza anahtarınız whsec_ ile başlar. Her ekip için tek anahtar vardır; ekibin tüm transkripsiyonlarına ait webhook bildirimlerini bununla imzalarız.
Anahtarı görmek veya yenilemek için paneldeki “Webhooks” sayfasını açın.
Yenilediğiniz anda eski anahtarın yerini yenisi alır. O andan sonra gönderdiğimiz bildirimleri yeni anahtarla imzalarız.
Gönderim ve yeniden deneme kuralları
- Sunucunuz
2xxdöndürürse bildirimi teslim edilmiş sayarız. - Başka bir durum kodu alırsak, bağlantı kurulamazsa veya 10 saniye içinde yanıt gelmezse gönderim başarısız sayılır.
- Başarısız gönderimleri giderek daha uzun aralıklarla tekrarlarız. İlk gönderim dahil en fazla 6 deneme yaparız. Aralarındaki bekleme süreleri 2, 4, 8, 16 ve 32 dakikadır. Son deneme, ilkinden yaklaşık bir saat sonra yapılır.
- Doğrudan bildirimi işleyecek URL'yi belirtin. Yönlendirmeleri takip etmeyiz;
3xxyanıtını başarısız sayarız. - Aynı bildirim birden fazla kez gelebilir. Örneğin sunucunuz zaman aşımından sonra yanıt verdiğinde yeniden gönderim yapabiliriz.
data.idvetypeçiftini kontrol ederek aynı olayı tekrar işlemeyin.