TikTok Transcript Scraper: Captions, Profiles & Batches avatar

TikTok Transcript Scraper: Captions, Profiles & Batches

Pricing

from $1.00 / 1,000 results

Go to Apify Store
TikTok Transcript Scraper: Captions, Profiles & Batches

TikTok Transcript Scraper: Captions, Profiles & Batches

Turn any TikTok video, @username or profile link into a clean transcript. Scrape a whole account in one run (up to 200 targets), choose native captions or AI speech-to-text, skip old videos by date, monitor new uploads, and export SRT/VTT with views, likes and creator stats.

Pricing

from $1.00 / 1,000 results

Rating

5.0

(9)

Developer

APISmith

APISmith

Maintained by Community

Actor stats

5

Bookmarked

507

Total users

186

Monthly active users

2 days ago

Last modified

Security

Limited permissions

Share

TikTok Transcripts Scraper

Turn TikTok into structured, analyzable text. Give the Actor a video link, a short link, a profile URL, or an @username — or a batch that mixes all of them — and get back one clean row per video: the spoken transcript, its source, precise timestamps, optional subtitle and hook text, and the creator and engagement metadata around it.

Paste a target, run the Actor, and export the results to JSON, CSV, Excel, your own API, or an AI pipeline. No browser session, no manual copy-paste, no captions tool to babysit.

The biggest change in this version is profiles. Where you could only point at one video before, you can now point at an entire creator or brand profile and pull transcripts across many of their videos in a single run. Your existing video-URL automations keep working exactly as before — videoUrl accepts the same inputs, now alongside profiles and batches.


What you get

For every video the Actor processes, you receive one dataset row built for downstream use:

  • The transcript — the spoken text, plus timestamped segments you can use for clipping, search, or subtitles.
  • Where it came from — transcriptSource tells you whether the text is TikTok's own caption (tiktok_captions) or generated speech-to-text (ai_transcription), so you never have to guess.
  • Optional extras, built locally — SRT and WebVTT subtitle text, and the spoken first 5 seconds as hookText, with no extra API call.
  • Creator and video context — username, display name, follower counts, post time, duration, thumbnails, music, hashtags, and whether the video is flagged as an ad or AI-generated.
  • Engagement numbers — plays, likes, comments, shares, and collects.
  • A clear status — every input, including ones that fail, returns an explicit row with a stable errorCode instead of disappearing from your results.

Example output

{
"text": "Okay so today I'm showing you the three things I do every single morning before I open my laptop…",
"transcriptSource": "tiktok_captions",
"transcriptMode": "auto",
"aiTranscriptionUsed": false,
"url": "https://www.tiktok.com/@nike/video/7231845600000000001",
"title": "My morning routine 💪",
"username": "nike",
"nickname": "Nike",
"createTimeISO": "2026-10-28T14:03:00Z",
"duration": 42,
"playCount": 184320,
"diggCount": 9120,
"hashtags": ["#morningroutine", "#fyp"],
"sourceTargetType": "video",
"status": "success"
}

A profile or batch run returns the same row shape, with sourceTargetType set to profile and sourceProfile filled in so you can tell which creator each video came from.


Key features

Profiles, not just single videos. Point at @nike or a profile URL and the Actor walks the profile, pulls up to maxVideosPerProfile videos, and transcribes each one — so you research a whole creator in one run instead of hunting down individual links.

Batch up to 200 mixed targets. Send video URLs, short links, profile URLs, and @usernames together in one batchTargets list. One unavailable target does not stop the rest of the batch from returning results.

Native captions first, AI only when needed. In auto mode the Actor uses TikTok's own captions when they exist and falls back to speech-to-text only when they don't. captions_only skips AI entirely; ai always uses it. You choose the trade-off between cost and coverage.

The right language, on purpose. Many TikToks carry several caption tracks — an original plus machine translations. By default you get the video's own spoken language, never a stray translation. Need a different one? Set captionLanguage and the Actor returns that track when it exists, the original language when it doesn't, and tells you which one you got in captionLanguage, captionLanguageRequested, and availableCaptionLanguages.

Monitoring that doesn't re-do old work. Turn on onlyNewVideos and schedule the Actor against the same profile: the first run sets a baseline, later runs pick up only videos published since the last successful run. Failed videos are retried next time, and old history is never backfilled.

Predictable, per-video billing. Speech-to-text is the only component that can add a per-result cost, and only when it actually runs. Profile discovery, metadata, hook text, and subtitles are built locally and add nothing extra.

Built for automation. Export to any format, call it through the API, schedule recurring runs, or hand the structured rows straight to an AI workflow.


Quick start

You only need one valid target to get your first result.

  1. Open the Actor page and go to the Input tab.
  2. In videoUrl, paste a single video, short link, profile URL, or @username. For a profile, also set maxVideosPerProfile.
  3. Click Start.
  4. When the run finishes, open the Dataset tab.
  5. Export to JSON, CSV, or Excel, or copy the Dataset API URL into your workflow.

Minimal input:

{
"videoUrl": "@nike"
}

That's it — no Docker, no local setup, no manual export step.


Input

You can provide targets in two ways. videoUrl takes a single target; batchTargets takes a list of up to 200 and, when present, completely replaces videoUrl. At least one of the two is required.

One video

{
"videoUrl": "https://www.tiktok.com/@nike/video/7231845600000000001"
}

One profile

{
"videoUrl": "@nike",
"maxVideosPerProfile": 20
}

A batch of mixed targets

{
"batchTargets": [
"https://www.tiktok.com/@nike/video/7231845600000000001",
"@garyvee",
"https://www.tiktok.com/@adidas",
"https://vm.tiktok.com/ZMabcdef/"
]
}

Supported target forms in either field: a full video URL, a short URL (vm.tiktok.com / vt.tiktok.com / tiktok.com/t/...), a profile URL (https://www.tiktok.com/@user), or a bare @username. Duplicate forms of the same video or profile are processed once.

Monitor a profile for new videos

{
"videoUrl": "@nike",
"maxVideosPerProfile": 50,
"onlyNewVideos": true
}

Filter by date

{
"videoUrl": "@nike",
"maxVideosPerProfile": 100,
"postedAfter": "2026-10-01"
}

Choose a transcript source

{
"videoUrl": "@nike",
"transcriptMode": "captions_only",
"includeHook": true,
"includeSrt": true
}

Input fields

FieldTypeDefaultDescription
videoUrlstring–One target: video URL, short URL, profile URL, or @username. Name and type are unchanged from previous versions.
batchTargetsarray of strings–Up to 200 targets, mixed types allowed. Overrides videoUrl when non-empty.
maxVideosPerProfileinteger (1–1000)20How many videos are actually transcribed per profile target.
postedAfterstring (date)–Only videos published on or after this date, e.g. 2026-10-01.
onlyNewVideosbooleanfalseProfile monitoring mode (see above).
transcriptModeauto / captions_only / aiautoWhere the transcript may come from.
captionLanguagelanguage codeautoWhich caption track to return. auto gives the video's own language; pick e.g. en or pt-BR to prefer that track instead. If the video has no such track the original language is returned — never an error. Ignored in ai mode.
includeSrtbooleanfalseInclude SRT subtitle text, built locally.
includeVttbooleanfalseInclude WebVTT subtitle text, built locally.
includeHookbooleanfalseInclude the spoken text of the first 5 seconds as hookText.

Invalid input is rejected before any work starts with a stable code: MISSING_TARGET, BATCH_LIMIT_EXCEEDED (more than 200 targets), INVALID_TRANSCRIPT_MODE, INVALID_MAX_VIDEOS_PER_PROFILE, or INVALID_POSTED_AFTER.


Output reference

One row per video. Fields TikTok does not return are simply absent — nothing is guessed or padded with placeholders.

Transcript

FieldNotes
textThe transcript. Empty only when the video has no speech.
transcriptSourcetiktok_captions or ai_transcription.
transcriptModeMode used for this row.
aiTranscriptionUsedtrue only when speech-to-text produced the transcript.
captionLanguageLanguage code of the TikTok caption track used, e.g. eng-GB. Empty when speech-to-text was used.
captionLanguageRequestedWhat the run asked for: auto or the code you passed. Compare it with captionLanguage to see whether the request was satisfied.
availableCaptionLanguagesEvery caption track the video offers, e.g. ["eng-US", "spa-US", "zho-CN"]. Read from TikTok's payload, so it costs no extra request — use it to pick a captionLanguage for a targeted re-run.
machineTranslatedtrue only if TikTok had no original caption and the row came from a machine-translated track. Original speech recognition and creator captions are always preferred.
segments[{ start, end, text }] in seconds.
hookTextFirst 5 seconds of speech, when includeHook is on.
srt, vttSubtitle text, when includeSrt / includeVtt is on.

Video and creator

url, videoUrl, title, createTime (epoch seconds), createTimeISO, duration (seconds), videoId, username, nickname, avatarUri, thumbnail, signature, secUid, followerCount, followingCount, heartCount.

Engagement

playCount, commentCount, diggCount, shareCount, collectCount.

Content attributes

hashtags, musicId, musicTitle, musicAuthor, locationCreated, isAigc, isAd (written only when TikTok reports the flag).

Provenance

sourceTarget (the input you gave), sourceTargetType (video or profile), sourceProfile (the profile a video came from in a batch or profile run).

Status and errors

FieldNotes
statussuccess or failed.
transcriptStatusDetail behind a success: extracted (transcript present) or no_captions (you ran captions_only and this video has no native caption — a completed run, not an error).
errorCodeStable code on failures, e.g. VIDEO_RESOLVE_FAILED, SPEECH2TEXT_FAILED.
errorMessageHuman-readable reason on failures.
errMsgThe original error field, kept for existing integrations.
timestampWhen the row was written.

Failed inputs still produce a row, so a batch never hides which target failed and why. A no_captions row is a success with an empty text: the run completed exactly as the mode asked, and it earns the result fee but never a transcription fee.


Pricing

This Actor uses pay-per-event pricing. There are two things you can be charged for.

1. Result fee — one per processed target

Every processed target produces one result row in the dataset, and each row is charged once.

  • A single video URL → one result.
  • A @username or profile URL → one result per video found in that profile (a profile of 20 videos produces 20 results).
  • The fee applies to every processed target, including music‑only or no‑speech videos, and videos that fail, are private or are unreachable — if it was processed, it is charged.
  • Duplicate targets within the same run are skipped and not charged.
Apify planPer 1,000 resultsPer result
Free$1.50$0.0015
Bronze / Silver / Gold$1.00$0.0010

2. Speech-to-Text fee — per minute, only when AI transcription runs

Charged per started minute of audio, rounded up per video (a 1:30 video bills 2 minutes). It applies only when Speech-to-Text actually produces a transcript:

  • auto (default) — used only for videos with no usable TikTok caption.
  • captions_only — never calls Speech-to-Text and is never charged.
  • ai — runs for every video.
Apify planPer 1,000 minutesPer minute
Free$4.50$0.0045
Bronze$3.50$0.0035
Silver$3.00$0.0030
Gold$2.00$0.0020

Creator metadata, hook text, and SRT/VTT are generated locally and add no separate charge. For live rates, see the Pricing tab on the Actor page.


API and automation

Run the Actor from code and read the results back. Set APIFY_TOKEN to your Apify token.

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('509El6cODefVZLx2W').call({
videoUrl: '@nike',
maxVideosPerProfile: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

from apify_client import ApifyClient
import os
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('509El6cODefVZLx2W').call(run_input={
'videoUrl': '@nike',
'maxVideosPerProfile': 20,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)

cURL

curl -X POST \
"https://api.apify.com/v2/actors/509El6cODefVZLx2W/run-sync-get-dataset-items?waitSecs=120" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "videoUrl": "@nike", "maxVideosPerProfile": 20 }'

The run-sync-get-dataset-items endpoint starts the run, waits for it to finish (up to waitSecs), and returns the dataset items in one call. For longer jobs, start with /runs and poll the Dataset instead.

You can also schedule recurring runs, attach webhooks, or connect the Dataset to tools like Make, Zapier, or n8n — all from the Apify platform.


Use cases

  • Creator and brand research — pull transcripts and metadata from a set of creator or brand profiles to understand their topics, hooks, and posting cadence.
  • Competitor monitoring — schedule the Actor against rival brand profiles and compare what they publish week over week, using the incremental onlyNewVideos mode to avoid re-processing history.
  • AI workflows — feed transcript text and metadata into summarization, translation, classification, or retrieval-augmented-generation pipelines. Each row is already structured for direct ingestion.
  • Accessibility and captioning — reuse native captions or the generated transcript as SRT/VTT subtitles for clips and repurposed video.
  • Content libraries — archive transcripts, hooks, and engagement next to the original video reference so clips and ideas stay searchable.
  • Trend and hashtag analysis — collect transcripts across many profiles to spot recurring themes, phrases, and hashtags.

FAQ

Can I scrape a TikTok profile without logging in? Yes. The Actor works with public profiles and does not require an account or login.

Does a profile with many videos cost more than a single video? Billing is per video transcribed, and speech-to-text only runs when needed. A profile just expands into its individual videos, each handled like a direct input — there is no per-profile surcharge.

Can I monitor a profile for only new videos? Yes. Enable onlyNewVideos; the first run sets a baseline and later runs return only videos published since the last successful run.

What happens when a video has no captions? In auto mode the Actor uses speech-to-text instead. In captions_only mode it returns a success row with transcriptStatus no_captions and an empty text — a completed run, not an error. It earns the result fee but never a transcription fee.

Will the transcript be in the video's own language? Yes by default. TikTok ships several caption tracks per video, including machine translations, so the Actor ranks original speech-recognition and creator captions ahead of translated tracks and returns the spoken language. Three fields make this auditable: captionLanguage is the track that was used, captionLanguageRequested is what you asked for, and machineTranslated is true only if no original track existed and a translation had to be used.

What if I want a specific language, not the original one? Set captionLanguage. Typical case: a Spanish source video that also carries an English machine-translated track — captionLanguage: "en" returns the English text. If a video has no such track, the original language is returned instead of an error, so a 200-target batch is never lost to one video. Check availableCaptionLanguages to see which tracks a video actually has before a targeted re-run.

Why not return all languages at once? One row per video keeps the dataset flat and the result fee unambiguous (one item, one fee). For multi-language work, run the same URL again with a different captionLanguage — this also avoids downloading caption tracks you will never read.

Are failed or empty items still returned? Yes. Every input becomes a dataset row with a status and errorCode, so you can see exactly what did not work rather than losing it silently.

How many targets can I send in one run? Up to 200 in batchTargets. More than that is rejected with BATCH_LIMIT_EXCEEDED.

Can I use the results through an API? Yes. Read the Dataset via the API, or use the run-sync-get-dataset-items endpoint shown above.


Limitations and responsible use

  • Public content only. Private, login-gated, age-restricted, region-blocked, or deleted content cannot be accessed.
  • Video posts only. A profile feed can contain photo or slideshow posts that have no spoken audio; those are skipped, not turned into video rows.
  • Platform access varies. TikTok may intermittently restrict otherwise-public content; some items may return failed with VIDEO_RESOLVE_FAILED. This is a platform condition, not a defect in the Actor.
  • Transcript quality depends on the source. Native captions and speech-to-text are both imperfect; review output where accuracy matters.
  • Optional flags are best-effort. isAd and isAigc are written only when TikTok reports them.

Use this Actor only for data you are permitted to access and process. You are responsible for complying with TikTok's terms, applicable privacy and copyright laws, anti-spam regulations, and the Apify terms of service.


Support

Questions or issues? Email support@apismith.online or open an issue on the Actor page.

When reporting a bug, please include the Apify Run ID, the non-sensitive input you used, the status, and the error code. Do not send your Apify token, cookies, session IDs, passwords, API keys, or proxy credentials.