All use cases

Transcript API for video pipelines

Your RAG stack can't embed a watch URL. It needs text — with timestamps when you want them, flat prose when you don't. One GET per video, same data + meta envelope as profiles and comments, and TikTok AI fallback when the creator never turned captions on.

What usually breaks first

Most transcripts pipelines fail on schema drift and billing surprises long before they fail on "missing a platform." The notes below are the failure modes we hear about after a DIY scraper or marketplace API is already in production.

Every platform hides captions differently. YouTube has a transcript panel — if auto-captions exist. TikTok often has nothing at all. Instagram Reels may return one track per carousel slide. Building a downloader per network means three parsers, three failure modes, and three billing surprises when a batch job hits a video with no track.

The annoying part isn't fetching text. It's knowing what you got. HTTP 200 with an empty body. WebVTT timing cues you have to strip before embeddings. A photo carousel URL that isn't a video. Language codes that don't match what the creator uploaded. We've seen teams burn a weekend on yt-dlp wrappers only to discover half their corpus returns null on Sundays when YouTube shuffles something upstream.

You need one integration that tells you honestly: found, not_found, or lookup_failed — and charges accordingly. Completed not_found lookups still cost a credit because the upstream lookup ran. Infrastructure failures (lookup_failed, 503 temporarily_unavailable) don't. Branch on data.lookupStatus, not the status code.

That's the contract this page is about. Pass a public URL, read data.transcript, feed whatever you're building — vector store, newsletter draft, sponsorship scanner, or burned-in captions for accessibility.

6 routes for this job

These are the routes we see in live transcripts integrations — YouTube, TikTok, Instagram, X, Facebook, and Reddit in this list. Method, path, and query params match the public OpenAPI spec; when we add a field to docs, it ships in responses.

  • GET /v1/youtube/videos/transcript

    Watch URLs, youtu.be links, Shorts — all normalised. Returns data.transcript.plainText plus timed data.transcript.segments (startMs, endMs per line). Optional language (ISO 639-1, e.g. en) when multiple caption tracks exist. 1 credit per completed lookup.

  • GET /v1/tiktok/videos/transcript

    vm.tiktok.com short links and /@user/video/… URLs. WebVTT when captions exist. Set useAiFallback=true for speech-to-text when there's no track — 11 credits on a completed lookup (1 base + 10 AI surcharge). Photo carousels return 400 transcript_target_not_video after charge.

  • GET /v1/instagram/posts/transcript

    Reels and video posts by URL. Returns data.transcripts[] — one entry per carousel slide when applicable. AI transcription with a 120-second cap; longer Reels return video_too_long_for_transcription. 1 credit per completed lookup.

  • GET /v1/twitter/tweets/transcript

    Video tweets on X. Plain text in data.transcript. Same lookupStatus pattern. Handy when your monitoring pipeline already pulls tweet URLs and you want spoken content without a second vendor.

  • GET /v1/facebook/posts/transcript

    Reels and video posts on Facebook. Plain text response. Same 120-second AI transcription limit as Instagram. Useful for cross-posted creator content you already track on other networks.

  • GET /v1/reddit/posts/transcript

    Hosted video on Reddit posts. Optional language param. data.transcript.plainText when found. Niche, but if you're already mining Reddit threads for product research, you don't need a separate path for v.redd.it clips.

OpenAPI reference →

How teams wire this

A common path starts with “rag ingestion: chunk text, not raw urls.” Your cron cadence, warehouse schema, and alert thresholds will differ — treat the steps as ordering hints, not a checklist you must copy verbatim.

  1. 1

    RAG ingestion: chunk text, not raw URLs

    Pull transcripts from a list of YouTube long-form URLs. Use data.transcript.plainText for embeddings, or data.transcript.segments when you need startMs for citations. TikTok returns WebVTT in data.transcript.content — strip timing cues before your vector store.

  2. 2

    TikTok batch with honest fallback policy

    Run two passes or branch in one job: try without useAiFallback first (1 credit) for caption-backed videos. Re-queue failures with useAiFallback=true only when you need text from every clip in the set. Don't blanket-enable AI on 10k URLs — that's 110k credits instead of 10k.

  3. 3

    Cross-platform repurposing

    Creator posts the same hook on TikTok and YouTube Shorts. Pull both transcripts, diff the spoken lines, generate a blog draft from the longer YouTube take. One auth header, no platform-specific normalizers in your repo.

  4. 4

    Sponsorship and ad-read detection

    Scan YouTube transcripts for 'use code', 'sponsored by', brand names. Timestamps in segments let you jump to the exact moment in the player UI. Pair with /v1/youtube/videos for metadata when you need publish date and view count in the same report.

  5. 5

    Instagram Reels in a creator feed

    List recent Reels via /v1/instagram/profiles/{handle}/reels, then transcript each URL. Carousel posts return multiple data.transcripts entries — iterate the array, don't assume a single string.

  6. 6

    Accessibility and closed captions

    Ship sidecar captions from timed segments. YouTube's data.transcript.segments gives startMs and endMs per line — enough to generate SRT without parsing anything yourself. TikTok's WebVTT in data.transcript.content works when you already have a VTT renderer.

  7. 7

    Handle lookupStatus before you store

    if (data.lookupStatus !== 'found') skip your vector write. not_found still charged. lookup_failed and 503 are free — safe to retry with backoff. Log meta.creditsCharged per row so finance can reconcile batch jobs.

TikTok with AI fallback when captions are missing

Swap YOUR_API_KEY for a key from the dashboard. The playground pre-fills auth if you open the same path there — useful before you paste this into a worker or CI job.

Request
TikTok with AI fallback when captions are missing

Questions we get from teams shipping transcript pipelines

  • Do YouTube and TikTok share a response shape? Yes — data.lookupStatus, data.transcript, meta.creditsCharged. Your parser doesn't fork per platform.
  • What if there's no transcript? data.lookupStatus is not_found. You still pay 1 credit — the lookup completed. On TikTok, useAiFallback=true is your escape hatch (+10 credits).
  • WebVTT or plain text? TikTok returns WebVTT in data.transcript.content. YouTube gives plainText plus segments with millisecond offsets. Twitter and Facebook return plain strings in data.transcript.
  • How do language codes work? Pass language=en (two letters, ISO 639-1). We prefer that track when it exists. No guarantee the creator uploaded in that language.
  • Any rate limits? No published cap beyond your credit balance. For big backfills we suggest staying under ~500 concurrent requests — same guidance as our monitoring endpoints.
  • Why did my TikTok photo URL fail? Photo carousels aren't videos. You get 400 transcript_target_not_video. Filter non-video URLs before enqueueing if you're watching credit burn.
  • Does HTTP 200 mean found? No. Always branch on lookupStatus. We've seen production bugs from teams who assumed 200 = content.
  • Instagram carousels? data.transcripts is an array. A 5-slide post can return five entries. Empty array with found status means the post resolved but had nothing to transcribe.
  • One API key for everything? Same x-api-key header as profiles, comments, search. Batch YouTube and TikTok in one worker pool without juggling marketplace subscriptions.
  • What happens when platforms change? We absorb upstream structure shifts. Your field names stay data.transcript and data.lookupStatus — not whatever HTML class YouTube renamed this week.

Run a transcripts lookup on free credits

You get 100 credits on signup — enough to walk through the curl above against live data and inspect lookupStatus, pagination, and meta.creditsCharged. If the JSON lands cleanly in your pipeline, buy a credit pack once; balances do not expire on a subscription clock.