The Transcript24 API lets you submit a public social media URL and receive the transcript in one request.
The API automatically decides whether to:
mode: "raw")mode: "asr")The response can also include video metadata such as platform, post ID, duration, views, and likes.
https://api.transcript24.com
Send your API key in the Authorization header.
Authorization: Bearer <API_KEY>
POST /transcribe
Content-Type: application/json
Authorization: Bearer <API_KEY>
{
"url": "https://www.youtube.com/watch?v=..."
}
Only url is required.
Supported request parameters:
| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| url | string | yes | - | Public social media video URL to transcribe. |
| prefer | "auto" or "asr" | no | "auto" | auto uses existing platform captions when available, then falls back to AI transcription. asr always requests AI transcription. |
| sceneDetection | boolean or object | no | false | Set to true to include adaptive scene analysis. You can also pass { "enabled": true, "profile": "recreate_best_v1" }. |
{
"url": "https://www.youtube.com/watch?v=...",
"prefer": "auto",
"sceneDetection": true
}
Equivalent object form:
{
"url": "https://www.youtube.com/watch?v=...",
"sceneDetection": {
"enabled": true,
"profile": "recreate_best_v1"
}
}
Supported prefer values:
auto (default)asrSet sceneDetection to true to add the recreate_best_v1 visual analysis. The
profile uses adaptive scene boundaries, adaptive representative keyframes, and
source clips of at most 8 seconds. Quality settings are controlled by the
server and cannot be downgraded per request. When sceneDetection is enabled,
the request is billed at the same per-minute rate as AI transcription, even if
the transcript itself comes from existing platform captions.
{
"ok": true,
"mode": "raw",
"taskCredits": 1,
"history": false,
"meta": {
"platform": "ytb",
"id": "abc123",
"title": "Video title",
"desc": "Short description",
"duration": 125,
"views": 12345,
"likes": 456,
"image": "https://..."
},
"caption": [
{
"start_time": "00:00:00.000",
"end_time": "00:00:03.200",
"text": "..."
}
]
}
When sceneDetection is enabled, the transcript fields are returned together
with a sceneDetection object.
{
"ok": true,
"mode": "raw",
"taskCredits": 3,
"history": false,
"meta": {
"platform": "ytb",
"id": "abc123",
"title": "Video title",
"duration": 125
},
"caption": [
{
"start_time": "00:00:00.000",
"end_time": "00:00:03.200",
"text": "..."
}
],
"sceneDetection": {
"status": "succeeded",
"profile": "recreate_best_v1",
"manifestUrl": "https://<account>.r2.cloudflarestorage.com/trans24-scene-assets/scene-detect/<job_id>/manifest.json?...",
"manifest": {
"url": "https://<account>.r2.cloudflarestorage.com/trans24-scene-assets/scene-detect/<job_id>/manifest.json?...",
"key": "scene-detect/<job_id>/manifest.json",
"sha256": "..."
},
"summary": {
"sceneCount": 14,
"durationSeconds": 71.566667,
"fps": 30,
"detector": "adaptive"
},
"manifestOnly": true,
"scenesOmitted": 14
}
}
Large scene results are returned as manifestOnly. Fetch manifestUrl to read
the full scene data, keyframe images, source clips, and asset metadata.
{
"schema_version": "recreate_best_v1",
"scene_count": 14,
"asset_storage": {
"mode": "r2",
"persistent": true,
"bucket": "trans24-scene-assets",
"url_mode": "presigned",
"presign_ttl_seconds": 604800
},
"scenes": [
{
"index": 0,
"start_frame": 0,
"end_frame": 98,
"start_s": 0,
"end_s": 3.266667,
"keyframes": [
{
"index": 0,
"frame": 45,
"time_s": 1.5,
"roles": ["representative"],
"asset": {
"storage": "r2",
"bucket": "trans24-scene-assets",
"key": "scene-detect/<job_id>/scenes/scene-0000/unit-000/frame-00000045.webp",
"url": "https://<account>.r2.cloudflarestorage.com/trans24-scene-assets/scene-detect/<job_id>/scenes/scene-0000/unit-000/frame-00000045.webp?...",
"content_type": "image/webp"
}
}
],
"generation_units": [
{
"index": 0,
"start_s": 0,
"end_s": 3.266667,
"source_clip": {
"storage": "r2",
"bucket": "trans24-scene-assets",
"key": "scene-detect/<job_id>/scenes/scene-0000/unit-000.mp4",
"url": "https://<account>.r2.cloudflarestorage.com/trans24-scene-assets/scene-detect/<job_id>/scenes/scene-0000/unit-000.mp4?...",
"content_type": "video/mp4"
}
}
]
}
]
}
Small scene results may be returned inline:
{
"sceneDetection": {
"status": "succeeded",
"profile": "recreate_best_v1",
"manifestUrl": "https://<account>.r2.cloudflarestorage.com/trans24-scene-assets/scene-detect/<job_id>/manifest.json?...",
"summary": {
"sceneCount": 1
},
"scenes": [
{
"start_frame": 0,
"end_frame": 85,
"start_s": 0,
"end_s": 2.83
}
]
}
}
Scene detection is best effort. If transcript generation succeeds but scene analysis fails, the API still returns the transcript with a failed scene status.
{
"ok": true,
"mode": "raw",
"taskCredits": 2,
"history": false,
"meta": {
"platform": "tik",
"id": "7659193282802666772",
"duration": 72
},
"caption": [
{
"start_time": "00:00:00.120",
"end_time": "00:00:04.040",
"text": "it's over. we will never see Neymar in a Brazil jersey again..."
}
],
"sceneDetection": {
"status": "failed",
"error": {
"code": "SCENE_RESULT_MISSING",
"message": "Scene worker returned no scene result"
}
}
}
Field meanings:
mode
raw: existing platform captions were usedasr: AI transcription was usedtaskCredits
history is truehistory
true when this API key's user recently requested the same transcript, the transcript result was available to reuse, and this request was not charged againfalse for first-time requests, requests charged from a shared cached transcript, or requests that must fetch or transcribe the result againmeta
sceneDetection
status: "succeeded" includes scene boundaries and, through manifestUrl,
keyframe image URLs and source clip URLsstatus: "failed" includes a stable error.code and error.messagemanifest includes R2 object metadata for the manifest JSON when availablescenes; when manifestUrl is present, use
it for the full JSONsceneDetection.status: "failed"{
"ok": true,
"mode": "asr",
"taskCredits": 3,
"history": false,
"meta": {
"platform": "tik",
"id": "7345678901234567890",
"title": "Video title",
"duration": 165,
"views": 99887,
"likes": 3201
},
"caption": [
{
"start_time": "00:00:00.000",
"end_time": "00:00:03.200",
"text": "..."
}
]
}
const res = await fetch("https://api.transcript24.com/transcribe", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer <API_KEY>",
},
body: JSON.stringify({
url: "https://www.youtube.com/watch?v=...",
sceneDetection: true,
}),
});
const data = await res.json();
console.log(data.mode);
console.log(data.meta);
console.log(data.caption);
if (data.sceneDetection?.manifestUrl) {
const manifestRes = await fetch(data.sceneDetection.manifestUrl);
const manifest = await manifestRes.json();
console.log(manifest.scenes[0].keyframes[0].asset.url);
}
import requests
res = requests.post(
"https://api.transcript24.com/transcribe",
headers={
"Authorization": "Bearer <API_KEY>",
"Content-Type": "application/json",
},
json={
"url": "https://www.youtube.com/watch?v=...",
"sceneDetection": True,
},
)
data = res.json()
print(data["mode"])
print(data["meta"])
print(data["caption"])
if data.get("sceneDetection", {}).get("manifestUrl"):
manifest = requests.get(data["sceneDetection"]["manifestUrl"]).json()
print(manifest["scenes"][0]["keyframes"][0]["asset"]["url"])
{
"error": "Invalid API key"
}
Common error messages:
Invalid API keyMissing urlFailed to fetch video infoFailed to fetch caption dataFailed to transcribeInsufficient credits. Please buy more credits.Billing follows the same logic as the website:
raw mode: 1 credit per videoasr mode: 1 credit per minute, rounded up with ceil(duration_seconds / 60)sceneDetection enabled: 1 credit per minute, rounded up
with ceil(duration_seconds / 60), including raw transcript resultsExamples for asr mode or any request with sceneDetection enabled:
00:00:59 -> 1 credit00:01:10 -> 2 credits00:02:00 -> 2 creditsNotes:
taskCreditshistory: true means this request reused a recent transcript for the same API key user without charging again; shared cached transcripts for other users can still be chargedsceneDetection is enabled and the
visual analysis succeeds.If you have questions, please contact support with the URL you tested and the timestamp of your request.