curl --request GET \
--url https://k8mfogcvz4.execute-api.us-east-1.amazonaws.com/prod/v1/episodes/{episode_id}/transcript \
--header 'Authorization: Bearer <token>'import requests
url = "https://k8mfogcvz4.execute-api.us-east-1.amazonaws.com/prod/v1/episodes/{episode_id}/transcript"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://k8mfogcvz4.execute-api.us-east-1.amazonaws.com/prod/v1/episodes/{episode_id}/transcript', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://k8mfogcvz4.execute-api.us-east-1.amazonaws.com/prod/v1/episodes/{episode_id}/transcript",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://k8mfogcvz4.execute-api.us-east-1.amazonaws.com/prod/v1/episodes/{episode_id}/transcript"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://k8mfogcvz4.execute-api.us-east-1.amazonaws.com/prod/v1/episodes/{episode_id}/transcript")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://k8mfogcvz4.execute-api.us-east-1.amazonaws.com/prod/v1/episodes/{episode_id}/transcript")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"format": "json",
"is_cached": true,
"credits_charged": 4503599627370495,
"transcript": {
"episode_id": "<string>",
"show_id": "<string>",
"language": "<string>",
"duration_sec": 64800,
"source": "qwen3-asr",
"source_revision": "<string>",
"model_version": "<string>",
"pipeline_version": "<string>",
"timing_precision": "word",
"diarized": false,
"warnings": [
{
"segment": 500000,
"type": "<string>",
"detail": "<string>"
}
],
"segments": [
{
"id": 500000,
"start": 64800,
"end": 64800,
"speaker": null,
"text": "<string>",
"words": [
{
"w": "<string>",
"s": 64800,
"e": 64800
}
]
}
],
"created_at": "2023-11-07T05:31:56Z"
},
"transcript_url": "<string>",
"expires_at": "2023-11-07T05:31:56Z"
}{
"error": {
"code": "invalid_request",
"type": "invalid_request",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"retryable": true
}
}{
"error": {
"code": "invalid_request",
"type": "invalid_request",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"retryable": true
}
}{
"error": {
"code": "invalid_request",
"type": "invalid_request",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"retryable": true
}
}{
"error": {
"code": "invalid_request",
"type": "invalid_request",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"retryable": true
}
}{
"error": {
"code": "invalid_request",
"type": "invalid_request",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"retryable": true
}
}{
"error": {
"code": "invalid_request",
"type": "invalid_request",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"retryable": true
}
}{
"error": {
"code": "invalid_request",
"type": "invalid_request",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"retryable": true
}
}{
"error": {
"code": "invalid_request",
"type": "invalid_request",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"retryable": true
}
}Direct cached fetch of an episode's transcript
Fetches a compatible cached transcript for a canonical episode directly, without submitting a job. When no compatible cache object exists, returns an EpisodeQuoteHint — the same quote figures a dry run reports, but without dry_run, because this request was not a dry run — rather than creating a job. Call POST /v1/transcripts to actually create one.
Delivery format. format: json (or omitted) returns application/json. format: text|srt|vtt|md returns the raw artifact under its own media type (text/plain, application/x-subrip, text/vtt, text/markdown), with provenance in the X-Transcript-Episode-Id, X-Transcript-Source, and X-Transcript-Timing-Precision headers and the charge in X-Credits-Charged. The single content-type switch: a payload over the ~5 MB inline limit returns 200 application/json with { transcript_url, expires_at } in every format. A quote hint — no cached transcript exists to render — is always application/json, whatever format asked for.
curl --request GET \
--url https://k8mfogcvz4.execute-api.us-east-1.amazonaws.com/prod/v1/episodes/{episode_id}/transcript \
--header 'Authorization: Bearer <token>'import requests
url = "https://k8mfogcvz4.execute-api.us-east-1.amazonaws.com/prod/v1/episodes/{episode_id}/transcript"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://k8mfogcvz4.execute-api.us-east-1.amazonaws.com/prod/v1/episodes/{episode_id}/transcript', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://k8mfogcvz4.execute-api.us-east-1.amazonaws.com/prod/v1/episodes/{episode_id}/transcript",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://k8mfogcvz4.execute-api.us-east-1.amazonaws.com/prod/v1/episodes/{episode_id}/transcript"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://k8mfogcvz4.execute-api.us-east-1.amazonaws.com/prod/v1/episodes/{episode_id}/transcript")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://k8mfogcvz4.execute-api.us-east-1.amazonaws.com/prod/v1/episodes/{episode_id}/transcript")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"format": "json",
"is_cached": true,
"credits_charged": 4503599627370495,
"transcript": {
"episode_id": "<string>",
"show_id": "<string>",
"language": "<string>",
"duration_sec": 64800,
"source": "qwen3-asr",
"source_revision": "<string>",
"model_version": "<string>",
"pipeline_version": "<string>",
"timing_precision": "word",
"diarized": false,
"warnings": [
{
"segment": 500000,
"type": "<string>",
"detail": "<string>"
}
],
"segments": [
{
"id": 500000,
"start": 64800,
"end": 64800,
"speaker": null,
"text": "<string>",
"words": [
{
"w": "<string>",
"s": 64800,
"e": 64800
}
]
}
],
"created_at": "2023-11-07T05:31:56Z"
},
"transcript_url": "<string>",
"expires_at": "2023-11-07T05:31:56Z"
}{
"error": {
"code": "invalid_request",
"type": "invalid_request",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"retryable": true
}
}{
"error": {
"code": "invalid_request",
"type": "invalid_request",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"retryable": true
}
}{
"error": {
"code": "invalid_request",
"type": "invalid_request",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"retryable": true
}
}{
"error": {
"code": "invalid_request",
"type": "invalid_request",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"retryable": true
}
}{
"error": {
"code": "invalid_request",
"type": "invalid_request",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"retryable": true
}
}{
"error": {
"code": "invalid_request",
"type": "invalid_request",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"retryable": true
}
}{
"error": {
"code": "invalid_request",
"type": "invalid_request",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"retryable": true
}
}{
"error": {
"code": "invalid_request",
"type": "invalid_request",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"retryable": true
}
}Authorizations
Authorization: Bearer hk_live_... for live keys or Authorization: Bearer hk_test_... for test-mode keys. hk_test_ keys resolve real public catalog metadata but return deterministic committed fixtures, never call inference, and never mutate live credits. This is the only transport for the credential: the x-api-key alias once documented was removed in 0.2.0, because the edge authorizer reads Authorization as its single identity source and a request on any other header is refused before it is authenticated.
Never accepted on a dashboardJwt operation, and there are no exceptions. GET /v1/usage and GET /v1/limits briefly declared both schemes (0.8.0); that was withdrawn in 0.8.1 because no deployed route could honor it — both operations are served by the control-plane API, whose authorizer verifies a Cognito token and refuses an hk_live_ credential on shape, and the customer API does not route either path. An API-key holder reads its balance and reservation from QuoteResponse, which carries balance_credits and reserved_credits on every quote. Every operation in this document takes one scheme or the other and refuses the wrong one as unauthenticated.
Path Parameters
Canonical episode identifier.
^ep_[a-z2-7]{16}$Query Parameters
The derived output to return once the transcript is available, and with it the response media type: json → application/json, text → text/plain, srt → application/x-subrip, vtt → text/vtt, md → text/markdown. An oversized payload is application/json in every format — the one documented content-type switch, described on each operation. Delivering content is the whole point of the operations that use this parameter, so omitting it defaults to json rather than withholding the transcript (contrast PollFormatQueryParam, which has no default).
Delivery-only: never affects the cache key or the produced transcript content.
Delivery-only: never affects the cache key or the produced transcript content. Every format is derived at read time from the one canonical transcript. Response media type per format: json → application/json, text → text/plain, srt → application/x-subrip, vtt → text/vtt, md → text/markdown. The one exception is an oversized payload, which is application/json in every format (see TranscriptUrlRef).
json, text, srt, vtt, md Response
A cached transcript read, or a quote hint if none exists yet.
- Option 1
- Option 2
- Option 3
- Option 4
A synchronous JSON transcript read: a cache hit or publisher passthrough (POST /v1/transcripts), a direct cached fetch (GET /v1/episodes/{episode_id}/transcript), or the re-delivery of a read that was already paid for (GET /v1/reads/{read_id}). credits_charged is what this request charged, which is why it is 0 on the last of the three and the cached-read price for this account on the other two. format is always json here — a text|srt|vtt|md read of the same transcript is delivered as a raw body with X-Credits-Charged carrying this envelope's credits_charged. See the comment above for why this shape is self-contained rather than composed via allOf.
A non-negative JavaScript-safe integer credit amount. The upper bound matches Number.MAX_SAFE_INTEGER, which is enforced by the domain ledger so arithmetic and JSON round-trips cannot silently lose cents worth of credit precision.
0 <= x <= 9007199254740991Show child attributes
Show child attributes
2048
