X (Twitter) Video Transcript API – Captions, AI Transcription avatar

X (Twitter) Video Transcript API – Captions, AI Transcription

Pricing

from $1.00 / 1,000 results

Go to Apify Store
X (Twitter) Video Transcript API – Captions, AI Transcription

X (Twitter) Video Transcript API – Captions, AI Transcription

Extract transcripts from public X/Twitter videos with native captions first and AI speech-to-text fallback. Get text, timestamps, SRT, WebVTT, optional translation, and structured metadata for AI, research, monitoring, and automation.

Pricing

from $1.00 / 1,000 results

Rating

0.0

(0)

Developer

LanceAPI

LanceAPI

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

4 days ago

Last modified

Categories

Share

X (Twitter) Video Transcript API

Extract native X/Twitter video captions when available, automatically fall back to AI speech recognition when needed, and optionally translate the completed transcript.

Turn public X/Twitter video posts into clean text, timestamped segments, WebVTT, SRT, translations, post metadata, and structured JSON for research, media monitoring, subtitle workflows, AI agents, and automation.

  • 🎯 Native captions first — reuse a usable caption track exposed by X whenever possible.
  • 🤖 AI fallback — transcribe accessible video audio when captions are unavailable or unusable.
  • 🌍 Optional translation — keep the original transcript and add a translated version in one of 20 target languages.
  • 📝 Text, segments, VTT, and SRT — request one or several formats without running transcription more than once.
  • 📦 Batch processing — process up to 1,000 X/Twitter post URLs or Tweet IDs per run.

No X cookies or user-supplied transcription or translation API keys are required for normally accessible public posts. Private, restricted, or login-gated content may still be unavailable.

✨ Key features

  • Native captions first — avoid unnecessary AI speech recognition when a readable native X caption track already exists.
  • Automatic AI transcription fallback — videos without usable captions can still produce transcripts without a separate workflow.
  • Optional transcript translation — translate native or AI transcripts while preserving the original text and segment timing.
  • Keep your original transcript — a translation problem does not throw away a successfully generated transcript. API users receive status: "partial_success".
  • Flexible transcript formats — return complete text, timestamped segments, normalized WebVTT, SRT, or any combination.
  • Three transcription modes — use recommended Auto mode, require native captions, or force AI transcription.
  • One result per video — a post containing multiple videos produces one independently traceable dataset item per video.
  • Consistent structured output — native captions, AI transcripts, translations, and failures follow a predictable schema.

🚀 Quick start

{
"urls": ["https://x.com/nicksortor/status/2095300108095046051?s=20"],
"transcriptionMode": "auto",
"language": "auto",
"formats": ["text", "segments"]
}

In Apify Console:

  1. Paste one or more public X/Twitter video post URLs or Tweet IDs.
  2. Keep Auto — X captions first, AI fallback selected.
  3. Choose the transcript formats you need.
  4. Optionally enable translation and choose a target language.
  5. Click Start, then open Transcript results.

Short output example

{
"success": true,
"status": "success",
"tweetId": "2095300108095046051",
"transcriptSource": "native",
"language": "EN",
"transcriptText": "we have to give that back to the states...",
"translationLanguage": null,
"translationText": "",
"transcript": {
"source": "native",
"language": "EN",
"text": "we have to give that back to the states...",
"segments": [
{
"start": 2.842,
"end": 5.762,
"text": "we have to give that back to the states, by the way, we have to give"
}
]
},
"translation": null
}

Input

FieldTypeRequiredDefaultAllowed values / limitsDescription
urlsarray of stringsYes1–1,000 itemsPublic x.com or twitter.com status URLs and numeric Tweet IDs. Forms can be mixed. Empty entries are ignored. Exact duplicate strings are trimmed and processed once.
transcriptionModestringNoautoauto, native_only, asr_onlyauto tries native captions before AI. native_only never invokes AI. asr_only skips native captions and transcribes audio directly.
languagestringNoautoauto, en, es, fr, de, it, pt, ja, ko, zh, ar, hi, ruSource-language preference. It selects a preferred labelled caption track and provides a hint to AI transcription; it is not a guarantee. This is different from targetLanguage.
formatsarray of stringsNotext, segmentsOne or more of text, segments, vtt, srtControls fields inside both transcript and translation. Multiple formats do not trigger multiple transcription or translation operations.
translatebooleanNofalsetrue, falseKeeps the original transcript and adds a translated version when enabled. No translation request is made when disabled.
targetLanguagestringNoen20 supported values listed belowTranslation target used only when translate is enabled.
maxVideoDurationMinutesintegerNo301–360Maximum duration for AI speech recognition. Native caption transcripts are not blocked by this limit, and translation of a completed transcript is not limited by video duration.
proxyConfigurationobjectNoDirect connectionApify proxy configurationOptionally routes requests through an Apify proxy. It can improve reachability but cannot unlock private or login-gated posts.

Source language vs. target language

{
"language": "auto",
"translate": true,
"targetLanguage": "en"
}

This means: detect or select the original transcript language automatically, retain that transcript, and add an English translation.

Available translation targets:

CodeLanguageCodeLanguage
enEnglishesSpanish
ptPortuguesefrFrench
deGermanitItalian
jaJapanesekoKorean
zh-CNChinese (Simplified)zh-TWChinese (Traditional)
arArabichiHindi
ruRussianidIndonesian
trTurkishviVietnamese
thThainlDutch
plPolishukUkrainian

Transcript formats

FormatOutput
textComplete transcript text in text.
segmentsArray of start, end, and text objects; timestamps are seconds.
vttWebVTT subtitle text with timestamps.
srtSRT subtitle text with timestamps.

VTT and SRT are generated from normalized segments for both native and AI transcripts. They do not invoke another AI operation.

Input examples

The X video URLs below have been used in real Apify cloud runs.

{
"urls": ["https://x.com/nicksortor/status/2095300108095046051?s=20"],
"transcriptionMode": "auto",
"language": "auto",
"formats": ["text", "segments", "srt"]
}

Native captions only with translation

{
"urls": ["https://x.com/nicksortor/status/2095306242507866288?s=20"],
"transcriptionMode": "native_only",
"language": "en",
"formats": ["text", "segments", "vtt", "srt"],
"translate": true,
"targetLanguage": "es"
}

If no usable native caption track exists, this mode returns native_caption_not_found or the relevant caption error and does not run AI transcription or translation.

AI transcription only with translation

{
"urls": ["https://x.com/nicksortor/status/2083859314402382147?s=20"],
"transcriptionMode": "asr_only",
"language": "auto",
"formats": ["text", "segments", "srt"],
"translate": true,
"targetLanguage": "fr",
"maxVideoDurationMinutes": 30
}

Batch processing

{
"urls": [
"https://x.com/nicksortor/status/2095300108095046051?s=20",
"https://x.com/nicksortor/status/2095306242507866288?s=20",
"https://x.com/nicksortor/status/2095163328070840539?s=20"
],
"transcriptionMode": "auto",
"language": "auto",
"formats": ["text", "segments"],
"translate": false,
"maxVideoDurationMinutes": 30,
"proxyConfiguration": {
"useApifyProxy": false
}
}

API usage

Keep your Apify token in an environment variable or secret manager.

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('lance_api/x-twitter-video-transcript-api').call({
urls: ['https://x.com/nicksortor/status/2095300108095046051?s=20'],
transcriptionMode: 'auto',
language: 'auto',
formats: ['text', 'segments', 'srt'],
translate: true,
targetLanguage: 'es',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('lance_api/x-twitter-video-transcript-api').call(run_input={
'urls': ['https://x.com/nicksortor/status/2095300108095046051?s=20'],
'transcriptionMode': 'auto',
'language': 'auto',
'formats': ['text', 'segments', 'srt'],
'translate': True,
'targetLanguage': 'es',
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)

cURL

curl -X POST \
'https://api.apify.com/v2/acts/lance_api~x-twitter-video-transcript-api/run-sync-get-dataset-items' \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"urls": ["https://x.com/nicksortor/status/2095300108095046051?s=20"],
"transcriptionMode": "auto",
"language": "auto",
"formats": ["text", "segments", "srt"],
"translate": true,
"targetLanguage": "es"
}'

For long videos or large batches, start the Actor asynchronously and fetch the default dataset after the run finishes. A synchronous HTTP request can time out while the underlying Actor run continues.

Output

The Actor writes one dataset item per video. Original and translated transcripts use the same selectable format structure:

{
"transcriptSource": "native",
"language": "zh",
"transcriptText": "原始字幕全文...",
"translationLanguage": "en",
"translationText": "Translated text...",
"transcript": {
"source": "native",
"language": "zh",
"text": "原始字幕全文...",
"segments": [
{
"start": 10.2,
"end": 13.8,
"text": "你好,欢迎来到今天的视频。"
}
]
},
"translation": {
"source": "translation",
"language": "en",
"detectedSourceLanguage": "zh-CN",
"text": "Translated text...",
"segments": [
{
"start": 10.2,
"end": 13.8,
"text": "Hello, welcome to today's video."
}
]
}
}

The original transcript is never overwritten by translation. When translation is disabled, translation is null, translationLanguage is null, and translationText is an empty string.

Run summary

Every run writes a SUMMARY record to the default key-value store:

{
"startedAt": "2026-09-03T02:00:00.000Z",
"finishedAt": "2026-09-03T02:00:05.000Z",
"totalUrls": 3,
"totalResults": 4,
"succeeded": 3,
"fullSuccess": 2,
"partialSuccess": 1,
"failed": 1,
"nativeTranscripts": 2,
"asrTranscripts": 1,
"translated": 1,
"translationFailed": 1,
"byStatus": {
"success": 2,
"partial_success": 1,
"asr_failed": 1
}
}

succeeded includes both full and partial successes because the original transcript exists in both cases. totalResults can exceed totalUrls when a post contains multiple videos.

Output field reference

Processing and status

FieldTypeNullableMeaning
requestIdstringNoResult identifier inside the run. Multi-video results add -video-N.
processingTimeMsintegerNoProcessing time for the input post in milliseconds.
processedAtstringNoISO 8601 result timestamp.
successbooleanNotrue when the original transcript was produced, including partial_success.
statusstringNosuccess, partial_success, or a structured failure status.
warningstringYesNon-fatal detail, such as native captions failing before successful AI fallback.
errorobjectYesnull on full success; otherwise code, safe message, and retryable. On partial success it describes the optional translation failure.

Post, author, and video

FieldTypeNullableMeaning
inputUrlstringNoOriginal URL or Tweet ID.
normalizedUrlstringYesCanonical x.com/i/status/{tweetId} URL.
resolutionSourcestringYesDiagnostic information about how the public post was resolved.
tweetIdstringYesNumeric post ID.
tweetTextstringYesPublic post text.
createdAtstringYesISO 8601 post creation timestamp.
authorIdstringYesPublic author account ID.
authorUsernamestringYesAuthor username without @.
authorNamestringYesAuthor display name.
mediaIndexintegerYesZero-based video position in the post.
mediaIdstringYesX media identifier.
durationnumberYesVideo duration in seconds; null when unavailable.
thumbnailUrlstringYesTemporary media thumbnail URL.
videoUrlstringYesResolved media URL; it may expire.

Native caption source

FieldTypeNullableMeaning
nativeCaptionAvailablebooleanNoWhether a native caption track was found during the attempt.
captionUrlstringYesNative caption or caption-playlist URL.
captionLanguagestringYesCaption-track language label.
captionFormatstringYesvtt when a native caption track is selected.

Transcript and translation

FieldTypeNullableMeaning
transcriptSourcestringNonative, asr, or none. Translation never changes this field.
languagestringYesOriginal transcript language when known.
transcriptTextstringNoComplete original text for Dataset, CSV, and spreadsheet convenience, regardless of selected nested formats. Empty on failure.
translationLanguagestringYesRequested target language when translation succeeds; otherwise null.
translationTextstringNoComplete translated text for Dataset, CSV, and spreadsheet convenience. Empty when absent.
transcriptobjectYesOriginal transcript with source, language, and only the requested text, segments, vtt, and srt fields. null on failure.
translationobjectYesTranslation with source: "translation", language, detectedSourceLanguage, and requested formats. null when disabled or unsuccessful.

Each segment contains start and end in seconds plus text. Translation preserves the original segment timestamps.

Engagement

FieldTypeNullableMeaning
likesCountintegerYesPublic like count at processing time; null when unavailable. A reported zero is preserved.
repliesCountintegerYesPublic reply count at processing time; null when unavailable. A reported zero is preserved.
retweetsCountintegerYesPublic repost/retweet count at processing time; null when unavailable. A reported zero is preserved.
quotesCountintegerYesPublic quote-post count at processing time; null when unavailable. A reported zero is preserved.
bookmarksCountintegerYesPublic bookmark count at processing time; null when unavailable. A reported zero is preserved.
viewsCountintegerYesPublic view count at processing time; null when unavailable. A reported zero is preserved.

Transcript and translation sources

ValueMeaning
nativeOriginal transcript came from a usable caption track exposed for the X video.
asrOriginal transcript was generated from accessible video audio through AI speech recognition.
noneNo original transcript was produced; inspect status and error.
translationNested translation was generated from the completed original transcript. It is not a transcript-source value.

Native captions may have been created by the publisher or by the platform; the Actor does not claim who created them.

Status values

StatusMeaning
successOriginal transcript and every requested optional operation succeeded.
partial_successOriginal transcript succeeded, but optional translation failed. The original remains available.
invalid_inputItem is not a supported X/Twitter URL or Tweet ID.
tweet_not_foundPost could not be found through available public sources.
video_not_foundPost resolved but had no supported video.
privatePost is protected, private, or not publicly exposed.
unavailableA required public resource was unavailable for another reason.
login_requiredX requires login, age verification, or another authenticated gate.
blockedA public X request was blocked from the run environment.
rate_limitedPublic access was temporarily rate-limited.
native_caption_not_foundnative_only was selected but no native caption track was found.
caption_fetch_failedSelected caption track or segment could not be downloaded.
caption_parse_failedCaption data contained no readable WebVTT cues.
duration_limitAI transcription was required but exceeded the configured limit.
no_audioResolved media was an animated GIF without audio.
media_resolve_failedNo downloadable media URL was available for AI transcription.
asr_failedAI speech recognition failed or returned no usable transcript.
timeoutA required public request timed out.
charge_limitThe run charge limit could not cover a requested paid operation.
billing_configuration_errorBilling is temporarily unavailable; contact support.

Translation errors use safe public codes such as TRANSLATION_FAILED and TRANSLATION_SERVICE_UNAUTHORIZED.

How it works

  1. Add X/Twitter video posts — provide public post URLs or Tweet IDs.
  2. Choose your transcription mode — use Auto for native captions first with automatic AI fallback, or choose native-only or AI-only when needed.
  3. Choose your output — request text, timestamped segments, VTT, SRT, or multiple formats together.
  4. Optionally translate — keep the original transcript and add a translation in your selected target language.
  5. Run the Actor — each video is processed independently, so multi-video posts can return multiple results.
  6. Use the results — download them from the Dataset or send structured JSON into APIs, AI agents, research pipelines, subtitle workflows, or automation.

💰 Pricing

Pay a base fee for each unique input processed, plus any successful AI transcription or translation you use.

  • Results (base processing) — $1 per 1,000 unique inputs actually processed, whether or not a transcript is produced.
  • AI transcription — from $0.002 per started minute, only when AI speech recognition is needed and successfully produces a usable transcript.
  • Translation — from $0.07 per started 1,000 source characters, only when requested and successfully produced.

Native captions can save AI transcription costs

In Auto mode, the Actor uses available native X/Twitter captions first. When native captions can produce the transcript, there is no AI transcription-minute charge. If AI is needed, started minutes are charged only after a usable transcript is successfully produced.

The base result fee is charged once for each unique input that is actually processed, even if the post is unavailable or no transcript can be produced. AI transcription and translation are separate optional usage charges.

Failed AI transcription has no AI transcription-minute charge. Failed translation has no translation charge. Neither failure cancels the base processing fee.

Selecting multiple output formats such as text, segments, VTT, and SRT does not create additional transcription or translation charges. A multi-video post incurs one base fee for its input, not one per video; successful AI transcription and translation are charged separately for each video that uses them.

Inputs are trimmed and exact duplicates are processed and charged once per run. Different URL forms or a URL and Tweet ID for the same post remain separate inputs under this rule. Internal retries and fallback attempts do not add base fees. Invalid URLs or IDs rejected before processing are not charged.

Check the Actor's Pricing tab for the latest plan-specific rates.

🤖 Use with AI agents and LLM workflows

Use this Actor as the X video → structured transcript and translation layer in an automation or agent workflow. Through the Apify API or an Apify MCP connection, an agent can submit public video posts and receive predictable JSON without building separate workflows for videos with and without native captions.

The output can feed:

  • summarization and key-point extraction;
  • topic classification and content analysis;
  • semantic search and retrieval-augmented generation (RAG);
  • media-monitoring and research agents;
  • translation and multilingual indexing;
  • subtitle editing and content-repurposing pipelines.

These are downstream uses. The Actor itself returns transcripts, optional translations, subtitles, and metadata rather than performing summarization, sentiment analysis, or RAG.

Use cases

  • Media monitoring — convert public statements, interviews, announcements, and clips into searchable text. Auto mode handles captioned and uncaptioned videos in one workflow.
  • Multilingual research — retain source transcripts while adding a normalized target-language version.
  • Subtitle workflows — obtain timestamped segments, WebVTT, or SRT for editing and publishing systems.
  • AI datasets — build transcript corpora with consistent structured results from native captions or AI, avoiding unnecessary AI transcription costs when captions are available.
  • Content intelligence — analyze what creators, brands, executives, journalists, and public organizations say in video posts.
  • Automation — connect X video transcription to the Apify API, MCP, scheduled runs, data stores, and downstream applications.

Public data and responsible use

This Actor is designed for publicly accessible X/Twitter posts. It does not provide access to private content or bypass login, age, regional, or account restrictions.

You are responsible for complying with applicable laws, X's terms, copyright rules, privacy requirements, and obligations that apply to storing or processing results. Do not use the Actor for harassment, spam, unlawful profiling, rights-violating surveillance, or attempts to obtain non-public information.

FAQ

Does every X/Twitter video have native captions?

No. Some videos expose usable native subtitle tracks; others require AI transcription. Check transcriptSource to see which route produced each result.

Am I charged if a post is deleted, private, unavailable, or has no video?

Yes. Once a valid input starts processing, its base result fee applies even if no transcript can be produced. Inputs rejected by initial URL or Tweet ID validation are not charged.

Do native captions cost AI transcription minutes?

No. When native captions produce the transcript, only the base result fee and any requested successful translation apply.

Can I force native captions only?

Yes. Use transcriptionMode: "native_only". If no track exists, the Actor returns a structured failure without calling AI transcription or translation.

Can I force AI transcription?

Yes. Use transcriptionMode: "asr_only" to skip native-caption retrieval and transcribe accessible audio directly.

Is language the translation target?

No. language is the original/source preference. Set translate: true and use targetLanguage for the translation destination.

Am I charged if AI transcription fails?

No. AI transcription minutes are charged only after AI speech recognition successfully produces a usable transcript. The base result fee still applies because the input was processed.

Am I charged if translation fails?

No translation charge is applied when translation fails. A translation problem does not throw away a successfully generated transcript: the original remains available with status: "partial_success". The base result fee and any successful AI transcription charge still apply.

What happens when source and target languages match?

When the source language is known to match the target, the original text and timestamps are also returned as the translation, with no translation charge.

Can I get both SRT and WebVTT?

Yes. Include both srt and vtt in formats to receive both subtitle formats at no additional transcription cost.

What happens if one URL fails?

The rest of the batch continues. The failed video or URL receives a dataset item with success: false, a status, and a structured error.

What happens if one post contains multiple videos?

Each video receives its own item, media identifiers, transcript, translation outcome, and requestId suffix.

Do I need X cookies or a separate transcription or translation subscription?

No. Transcription and optional translation are included in this Actor's workflow. Public posts that require authentication can still be inaccessible.

Limitations

  • X can change public web behavior, metadata availability, caption exposure, and media access without notice.
  • Private, deleted, suspended, unavailable, age-restricted, login-gated, or region-restricted posts may not be accessible.
  • A post that opens in a signed-in browser may not be available through public endpoints from an Apify run location.
  • Native captions are available only when X exposes a readable caption track.
  • Media, thumbnail, and caption URLs can be temporary and may expire.
  • AI transcription requires resolvable video audio. Accuracy varies with noise, accents, language, overlapping speakers, encoding, and recording quality.
  • Translation quality depends on the accuracy and language labelling of the original transcript.
  • Long videos and large batches take longer; synchronous API requests can time out while asynchronous Actor runs continue.
  • maxVideoDurationMinutes applies only to AI transcription, not native captions or translation of completed text.
  • Public engagement counts may be missing, delayed, or differ from values later displayed on X.
  • Optional proxies improve network reachability but cannot grant access to non-public content.

Troubleshooting

Symptom or statusWhat to try
invalid_inputUse a numeric Tweet ID or an x.com / twitter.com URL containing /status/ or /statuses/ followed by the numeric ID.
tweet_not_foundConfirm the post exists and is publicly accessible outside a signed-in browser session.
private or login_requiredThe Actor does not accept cookies to bypass public-access restrictions.
rate_limited, blocked, or timeoutRetry later or try an appropriate Apify proxy for public reachability.
video_not_foundConfirm the post contains video rather than only images, a link card, or unsupported media.
native_caption_not_foundUse auto or asr_only if AI transcription is acceptable.
caption_fetch_failed or caption_parse_failedIn Auto mode, check whether AI fallback succeeded and inspect warning; otherwise retry or use asr_only.
duration_limitIncrease maxVideoDurationMinutes within 1–360, or use native_only when a native track is expected.
asr_failedInspect error.retryable, confirm accessible audio, and retry temporary failures.
TRANSLATION_FAILEDThe original transcript remains available. Retry a temporary failure later.
TRANSLATION_SERVICE_UNAUTHORIZEDContact support with the Run ID; translation is currently unavailable. Your original transcript remains available.
charge_limitIncrease the maximum run charge or disable the optional paid operation.

Run logs include request ID, status, transcript source, resolution source, processing time, and safe error code for each result.

Support

Use the Actor's Issues page or email the address below. Include the Apify Run ID, requestId, status/error code, and a non-sensitive example URL or input. Never send your Apify token, X cookies, translation keys, API keys, or other secrets.

lanceapi2026@hotmail.com