DokümantasyonAPI referansı

API referansı

Tüm /v1 endpoint'lerini parametreleri ve örnekleriyle inceleyin. OpenAPI tanımını JSON veya YAML olarak indirin.

Giriş

Base URL
https://api.transcript1.com/v1

Tü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_case kullanılır.
  • Tarih ve saatler UTC üzerinden ISO 8601 biçiminde verilir: 2026-10-13T09:30:00.000Z gibi.
  • 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-Limit ve X-RateLimit-Remaining başlıkları bulunur. Ayrıntılar Ücretlendirme ve limitler sayfasında.
  • source=auto ile 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ı yoksa no_captions alırsınız. source=stt veya 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:read ve transcriptions:write yetkilerini kullanır.
Yetki kapsamıKullanılabilen çağrılar
transcriptions:readGET /v1/transcriptions, GET /v1/transcriptions/:id, GET /v1/transcriptions/:id/upload ve GET /v1/account
transcriptions:writePOST /v1/transcriptions, DELETE /v1/transcriptions/:id ve POST /v1/transcriptions/:id/upload/complete
  • Token gereken yetki kapsamına sahip değilse 403 insufficient_scope alırsınız.
  • Kimlik bilgisi göndermezseniz veya gönderdiğiniz bilgi geçersizse 401 unauthorized dö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_conflict alı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

402 Payment Required
{
  "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 status alanı failed olur.

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.
  • message kullanıcıya gösterebileceğiniz açıklamadır. Metni değişebileceği için bu alana göre koşul yazmayın.
  • retryable değeri true olduğunda aynı çağrı daha sonra çalışabilir.

Bazı hatalarda retryable yanında sorunu açıklayan ek alanlar da bulunur:

Alanİlgili hataAçıklama
action_urlinsufficient_minutesPlan seçebileceğiniz veya ek dakika satın alabileceğiniz sayfa.
minutes_needed, minutes_remaininginsufficient_minutesİşlem için gereken dakika ve kullanılabilir bakiyeniz. Gereken süre henüz bilinmiyorsa ilk alan null olur.
supported_platformsunsupported_platformKabul edilen platform değerleri: ["youtube", "x", "tiktok", "instagram", "facebook", "bluesky", "twitch", "dailymotion", "pinterest", "linkedin", "snapchat"].
missing_chunksupload_incompleteSunucuya ulaşmayan parçaların numaraları.
max_bytesmedia_too_largeHesabınızın dosya boyutu limiti, bayt olarak.
paramsinvalid_requestGö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 koducodeAynı istek tekrar denenebilir mi?Neden alırsınız?
400, 422invalid_requestHayırBir 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.
422invalid_urlHayırBağ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.
422unsupported_platformHayırGönderdiğiniz platform değeri desteklenenler arasında değil.
422unsupported_mediaHayırDosyanın uzantısını desteklemiyoruz.
401unauthorizedHayırAPI 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.
403insufficient_scopeHayırOAuth token'ında gereken transcriptions:read veya transcriptions:write yetkisi yok.
403email_not_verifiedHayırE-postanız henüz doğrulanmamış. Transkripsiyon başlatmadan önce adresinizi doğrulayın.
402insufficient_minutesHayırKullanılabilir bakiyeniz 0 veya işlem için gereken dakikadan az.
402no_active_planHayı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.
404not_foundHayırBu transkripsiyon bulunamadı veya başka bir ekibe ait.
409upload_incompleteHayırDosyanın bazı parçaları yüklenmemiş. Eksikleri gönderip tamamlama çağrısını tekrarlayın.
409invalid_stateHayırTranskripsiyon yükleme bekleme aşamasında değil. Artık parça gönderemez veya yüklemeyi tamamlayamazsınız.
409idempotency_conflictHayırAynı Idempotency-Key daha önce farklı parametrelerle kullanılmış.
413media_too_largeHayırDosya, hesabınızın boyut limitini aşıyor. Dosya yükleme sayfasını kontrol edin.
413invalid_requestHayırJSON gövdesi 1 MB'ı aşıyor. Dosya boyutu hatalarında bunun yerine media_too_large kullanılır.
429rate_limitedEvetDakikalık istek limitini aştınız. Retry-After değerinde belirtilen saniye kadar bekleyin.
429too_many_active_jobsEvetAynı anda çalışan transkripsiyon veya açık yükleme limitini aştınız. Retry-After değerinde belirtilen saniye kadar bekleyin.
500internal_errorEvetSunucu tarafında bir sorun oluştu. Biraz bekleyip tekrar deneyin.
503service_unavailableEvettranscript1'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 retryable değeri true olduğunda tekrar gönderin: rate_limited, too_many_active_jobs, internal_error ve service_unavailable.
  • Retry-After varsa belirtilen süreyi bekleyin. Yoksa her denemede bekleme süresini artırın.
  • POST /v1/transcriptions çağrısını tekrarlarken aynı Idempotency-Key baş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.codeNe oldu?Ne yapmalısınız?
media_unavailableVideo bulunamadı veya artık erişilemiyor.Aynı bağlantıyla tekrar denemeyin; URL'yi kontrol edin.
media_privateVideo gizli.Aynı videoyu tekrar göndermeyin. Herkese açık bir gönderi kullanın; YouTube'da liste dışı videolar da çalışır.
login_requiredPlatform videoyu izlemek için giriş yapılmasını istiyor.Kalıcı bir hatadır; tekrar denemeyiz.
no_audioVideoda ses kanalı yok.Kalıcı bir hatadır; tekrar denemeyiz.
age_restrictedVideoda yaş kısıtlaması var.Aynı bağlantıyı tekrar göndermek yerine dosyayı yükleyin.
live_streamYayın devam ediyor veya henüz başlamamış.Yayın sona erdikten sonra deneyin.
no_captionssource için captions seçilmiş, ancak kullanılabilir altyazı bulunamamış.source: "auto" veya "stt" ile gönderin.
media_too_longKayı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_mediaDosyayı okuyamadık veya dosyada ses kanalı yok.Desteklenen bir dosya hazırlayıp gönderin.
no_speechKonuşma algılanmadı.Tekrar denemeyin.
unsupported_languageKayı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_failedBirkaç kez denememize rağmen kaydı indiremedik.Daha sonra tekrar deneyebilirsiniz.
transcription_failedBirkaç 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

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ğerlertranscription

  • statusstringzorunlu

    Alabileceği değerlerawaiting_uploadqueuedfetchingtranscribingcompletedfailedcanceled

  • sourceobjectzorunlu
    Alt alanları gösterin
    With url
    • platformstringzorunlu
    • urlstringzorunlunull alabilir
    • media_idstringzorunlunull alabilir
    With filename
    • platformstringzorunlu

      Alabileceği değerlerupload

    • filenamestringzorunlunull alabilir
    • sizenumberzorunlunull alabilir
  • mediaobjectzorunlunull alabilir
    Alt alanları gösterin
    • 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österin
    • sourcestringzorunlu

      Alabileceği değerlerautocaptionsstt

    • languagestringzorunlu
    • diarizebooleanzorunlu
  • transcript_sourcestringzorunlunull alabilir

    Alabileceği değerleryoutube_captionsx_captionsspeech_to_text

  • caption_kindstringzorunlunull alabilir

    Alabileceği değerlermanualauto_generated

  • languagestringzorunlunull alabilir
  • billed_minutesintegerzorunlunull alabilir
  • cachedbooleanzorunlu
  • errorobjectzorunlunull alabilir
    Alt alanları gösterin
    • codestringzorunlu
    • messagestringzorunlunull alabilir
  • created_atstring · date-timezorunlunull alabilir
  • completed_atstring · date-timezorunlunull alabilir
  • deleted_atstring · date-timezorunlunull alabilir

    When the transcription was deleted. Always null unless the request includes include_deleted=true.

  • transcriptobjectisteğe bağlı

    Included in GET responses for completed transcriptions.

    Alt alanları gösterin
    • textstringzorunlu
    • speakersarray of stringszorunlu
    • segmentsarray of objectszorunlu
      Alt alanları gösterin
      • startnumberzorunlu
      • endnumberzorunlu
      • speakerstringzorunlunull alabilir
      • languagestringzorunlunull alabilir
      • textstringzorunlu
      • wordsarray of objectsisteğe bağlınull alabilir
        Alt alanları gösterin
        • 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/transcriptions

Transcribes 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 same source, language and diarize. It must have been created in the last 24 hours and must not be failed or canceled. Reuses that transcription without creating or charging for a new one.

    Alabileceği değerlertruefalse

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ğerleryoutubextiktokinstagramfacebookblueskytwitchdailymotionpinterestlinkedinsnapchat

  • 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ğerlerautocaptionsstt

  • languagestringisteğe bağlı
  • diarizebooleanisteğe bağlı
  • webhook_urlstring · uriisteğe bağlı
With upload
  • uploadobjectzorunlu
    Alt alanları gösterin
    • filenamestringzorunlu
    • sizeintegerzorunlu
    • mime_typestringisteğe bağlı
  • sourcestringisteğe bağlı

    Alabileceği değerlerautostt

  • 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ğerlerautostt

  • 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 status
  • 201 Created — The transcription is awaiting a chunked upload. upload describes where to send each chunk.
  • 202 Accepted — The transcription is processing

Diğer HTTP durumları

  • 400 Bad Request — The JSON request body is malformed
  • 401 Unauthorized — Missing or invalid credential
  • 402 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 plan
  • 409 Conflict — Idempotency-Key was reused with different parameters.
  • 413 Content Too Large — The upload or the JSON request body is too large
  • 422 Unprocessable Content — Invalid request, URL, platform or file type
  • 429 Too Many Requests — Too many requests or too many active transcriptions. Wait for the number of seconds in Retry-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ğerlerjsontextsrtvtt

  • includestringisteğe bağlı

    Alabileceği değerlerwords

  • timestampsstringisteğe bağlıVarsayılan: false

    Alabileceği değerlertruefalse

  • include_deletedstringisteğe bağlıVarsayılan: false

    Also returns deleted transcriptions as read-only records without a transcript. Their deleted_at is set. Defaults to false.

    Alabileceği değerlertruefalse

Başarılı yanıtlar

  • 200 OK — The transcription, or the rendered transcript
  • 202 Accepted — A rendered format was requested while the transcription is still processing

Diğer HTTP durumları

  • 401 Unauthorized — Missing or invalid credential
  • 403 Forbidden — Insufficient scope or a single-member team plan
  • 404 Not Found — Transcription not found
  • 422 Unprocessable Content — Invalid query parameters
  • 429 Too Many Requests — Too many requests. Wait for the number of seconds in Retry-After.

List transcriptions

GET /v1/transcriptions

Lists 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ğerlerawaiting_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_at is set. Defaults to false.

    Alabileceği değerlertruefalse

Başarılı yanıtlar

  • 200 OK — A page of transcriptions

Diğer HTTP durumları

  • 401 Unauthorized — Missing or invalid credential
  • 403 Forbidden — Insufficient scope or a single-member team plan
  • 422 Unprocessable Content — Invalid query parameters or cursor
  • 429 Too Many Requests — Too many requests. Wait for the number of seconds in Retry-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 credential
  • 403 Forbidden — Insufficient scope, cross-site request or a single-member team plan
  • 404 Not Found — Transcription not found
  • 429 Too Many Requests — Too many requests. Wait for the number of seconds in Retry-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 token
  • 404 Not Found — Transcription not found
  • 409 Conflict — The transcription is no longer awaiting an upload
  • 422 Unprocessable Content — Index outside the chunk plan or wrong body size

Get upload progress

GET /v1/transcriptions/{id}/upload

Lists 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 credential
  • 403 Forbidden — Insufficient scope or a single-member team plan
  • 404 Not Found — Transcription or upload not found
  • 429 Too Many Requests — Too many requests. Wait for the number of seconds in Retry-After.

Complete a chunked upload

POST /v1/transcriptions/{id}/upload/complete

Checks 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 credential
  • 402 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 plan
  • 404 Not Found — Transcription or upload not found
  • 409 Conflict — upload_incomplete means chunks are missing. missing_chunks lists them. invalid_state means 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 in Retry-After.

Account

Your plan, remaining minutes and rate limits.

Get your account

GET /v1/account

Returns 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 credential
  • 403 Forbidden — Insufficient scope or a single-member team plan
  • 404 Not Found — No account found
  • 429 Too Many Requests — Too many requests. Wait for the number of seconds in Retry-After.

Account nesnesi

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ğerleraccount

  • userobjectzorunlu
    Alt alanları gösterin
    • idstringzorunlu
    • emailstringzorunlu
  • planobjectzorunlunull alabilir
    Alt alanları gösterin
    • idstringzorunlu
    • namestringzorunlu
  • minutesobjectzorunlu
    Alt alanları gösterin
    • remainingnumberzorunlu
    • cyclenumberzorunlu
    • topupnumberzorunlu
    • topup_usablebooleanzorunlu
    • resets_atstring · date-timezorunlunull alabilir
  • renews_atstring · date-timezorunlunull alabilir
  • limitsobjectzorunlu
    Alt alanları gösterin
    • 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));
};
transcription.completed
{
  "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?

typeGönderildiği durum
transcription.completedTranskripsiyon tamamlandı; durumu completed.
transcription.failedTranskripsiyon 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 olan transcript bu 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/json
  • User-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. t değ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.
  • t ile ş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_body için request.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 2xx dö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; 3xx yanı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.id ve type çiftini kontrol ederek aynı olayı tekrar işlemeyin.