FrameFetch
For agents → Try it free
Reddit

Video Transcript & Data API

Reddit doesn't caption or transcribe its own video. Send a Reddit post or v.redd.it URL and FrameFetch gets past Reddit's anti-bot checkpoint, pulls the post's actual audio-bearing stream, transcribes it with Whisper, and returns metadata, frames, and on-screen text — one URL, one JSON response. (Comments and audience sentiment are YouTube-only — see below.)

Read the docs Pricing

How Reddit actually hosts video

Anonymous requests hit an anti-bot checkpoint before Reddit hands back a post's real data at all — non-JS clients get a lightweight "please wait for verification" interstitial instead of the page, solvable with a small embedded script rather than a real login. Past that checkpoint, a post on r/videos with an embedded clip still isn't serving a single .mp4: Reddit's own video host, v.redd.it, exposes a progressive/DASH fallback_url alongside a separate HLS manifest. The DASH file looks like the obvious download target, but it's video-only — no audio track — even on posts where Reddit's own metadata claims has_audio: true. The HLS manifest is the only stream that actually carries audio. Neither exposes a caption track, and Reddit doesn't run any speech-to-text over the audio on its side.

Why there's basically no competing content for this

YouTube has captions most of the time, so "get a YouTube transcript" is a crowded, well-documented problem. Reddit video transcription is not: there's no captions API to wrap, so most tools that claim to handle Reddit only extract the raw video/audio file and stop there — the caller still has to run their own Whisper pass, or skip transcription entirely. FrameFetch does that last step for you as part of the same call you'd use for metadata or frames.

What FrameFetch does

FrameFetch solves Reddit's anti-bot checkpoint itself (no login, no account), then hands yt-dlp the post's HLS manifest URL directly instead of the reddit.com page — yt-dlp's generic HLS handling downloads and muxes it with zero Reddit-specific extractor code involved, and unlike the DASH fallback file, it actually has audio. From there Reddit is treated exactly like any other caption-less platform: the audio is extracted and sent to Whisper for transcription. The response's transcript.source always reads "whisper" for Reddit — there's no captions branch to prefer, because Reddit never offers one. The checkpoint isn't solvable on every attempt (roughly 60-70% observed, tied to the residential proxy IP's own reputation with Reddit) — FrameFetch retries automatically, and yt-dlp itself sometimes reaches Reddit directly without needing the checkpoint solved at all.

Quickstart

curl -X POST https://framefetch.net/v1/extract \
  -H "Authorization: Bearer <your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://www.reddit.com/r/videos/comments/1abcxyz/a_short_clip/",
    "fields": ["metadata", "transcript"]
  }'

Shape of the response (field names match the schema exactly; content below is illustrative, not a captured call):

{
  "platform": "reddit",
  "metadata": {
    "title": "A short clip",
    "uploader": "u/some_redditor",
    "durationSec": 14,
    "uploadDate": "2026-06-02",
    "thumbnail": "https://external-preview.redd.it/....jpg"
  },
  "transcript": {
    "text": "...",
    "source": "whisper",
    "lang": "en",
    "segments": [ { "start": 0, "end": 3.2, "text": "..." } ]
  },
  "cost": { "totalMicros": 21000 },
  "warnings": []
}

Get a key with POST /v1/keys (free credit). Full reference in the docs. Agents can pay per call with x402 (USDC) — no account.

Call it from Node.js

The framefetch npm package wraps the same call shown above — zero dependencies, just Node 18+'s built-in fetch:

import { FrameFetch } from 'framefetch';

const ff = new FrameFetch({ apiKey: process.env.FRAMEFETCH_API_KEY });

const result = await ff.transcript(
  'https://www.reddit.com/r/videos/comments/1abcxyz/a_short_clip/',
);

console.log(result.transcript.source);      // always "whisper" for Reddit — no captions branch exists
for (const seg of result.transcript.segments ?? []) {
  console.log(`[${seg.start}s] ${seg.text}`);
}

ff.transcript(url) is a scoped helper for fields: ["metadata","transcript"] — same response shape as ff.extract(), less to type. Every method throws a typed FrameFetchError (.status / .code / .hint) on failure instead of handing back a malformed result. npm install framefetch; full method list in the docs.

Accuracy notes — what a Whisper transcript is (and isn't)

Every Reddit transcript comes from Groq's whisper-large-v3-turbo running over the post's own audio — there's no captions branch to prefer here (see above), so quality depends entirely on the source recording, not on anything FrameFetch's pipeline chooses for you. Clear, single-speaker narration transcribes about as well as Whisper does on any platform; heavy background music, several people talking over each other, a strong accent in an English-tagged clip, or a noisy phone-mic recording will all measurably degrade it, the same as any speech-to-text model. FrameFetch doesn't score or hide that — it returns whatever Whisper produced, honestly labeled source: "whisper" so it's never mistaken for a human-authored caption.

One deliberate tradeoff: the audio download picks the smallest stream that's still speech-sufficient (bestaudio[abr<=64], with a format-ladder fallback if that's unavailable) rather than the highest-bitrate copy on offer — Whisper is trained on telephone-grade audio, so a bigger download buys nothing for transcription accuracy, just more residential-proxy bandwidth spent for no benefit. That proxy matters more here than on most platforms this API supports: Reddit and YouTube are the only two where FrameFetch's own retry logic treats a no-proxy attempt as doomed (a short, single-shot budget instead of full retries) rather than a plausible fallback — Pinterest and TikTok extraction works the same from a plain datacenter IP.

Limits — what won't work

FrameFetch reaches Reddit the same way an anonymous, logged-out browser tab does — it never signs in as a Reddit user and never bypasses an interstitial. That draws a hard line around what a call can reach:

SituationWhat happens
Private or banned subredditThe post JSON isn't publicly reachable; the call fails to extract (no charge)
Deleted or removed postSame — nothing to fetch, extraction fails, no charge
NSFW / quarantined content behind an interstitialWorks when it's reachable without a login; fails the same way if Reddit gates it behind account verification
Crosspost pointing off-Reddit (e.g. an embedded YouTube link)Not supported — send the underlying platform's own URL instead (only reddit.com / redd.it hosts are accepted)
Image-only or gallery postNo video stream to extract — transcript/frames fail; metadata still works

None of this is Reddit-specific special-casing on FrameFetch's side — it's the same "can an anonymous request reach it" rule every platform gets. Failures never surface as a mysterious hang: they come back as a typed error (500 EXTRACTION_FAILED) or, for a field that degrades gracefully, a plain-English string in the response's warnings array.

Comments & audience sentiment — not on Reddit anymore

Reddit used to be one of two platforms FrameFetch supported for comments (the other is YouTube), reading the thread's public JSON endpoint directly — no proxy needed. Reddit deprecated unauthenticated access to that endpoint on 2026-05-28: every variant now returns a hard 403 regardless of proxy, user-agent, or using old.reddit.com, and there's no supported alternative in the current architecture. Requesting "comments" or "comment_sentiment" on a Reddit URL now degrades with a warning and is never billed, the same as on TikTok, Instagram, or Pinterest — check GET /v1/platforms before requesting it. Metadata, transcript, frames, and text_overlay on Reddit are all unaffected. Comment sentiment is still a real, working feature on YouTube.

The degrade is exact and typed, not hand-wavy: the response's warnings array carries exactly comments are not available for reddit; drop "comments" from "fields", and the call is billed as if comments had never been in fields at all.

Frames & on-screen text

Add "frames" for parametrically-sampled stills (every Nth frame, a fixed fps, or a [from,to] range, at any width from 16–7680px), and "text_overlay" alongside it to run OCR — useful for burned-in captions, on-screen labels, or watermark text a spoken-word transcript would miss.

curl -X POST https://framefetch.net/v1/extract \
  -H "Authorization: Bearer <your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://www.reddit.com/r/videos/comments/1abcxyz/a_short_clip/",
    "fields": ["frames", "text_overlay"],
    "frames": { "mode": "fps", "fps": 1, "width": 480 }
  }'

Use it from an AI agent (MCP)

FrameFetch ships an MCP server at POST https://framefetch.net/mcp with the tools framefetch_extract, framefetch_search, framefetch_account and framefetch_platform_capabilities — point your agent at a Reddit URL directly. See the MCP setup guide for a working Claude Desktop / Cursor config.

FAQ

Does Reddit have its own video transcripts or captions?

No. Reddit-hosted video (v.redd.it) has no caption track and no built-in speech-to-text. Its progressive/DASH file is video-only — even on posts where Reddit's own metadata says has_audio: true — the only stream that actually carries audio is a separate HLS manifest. Almost nothing indexes Reddit video text as a result — it's one of the thinnest corners of the video-data-API space.

How does FrameFetch get a Reddit video transcript then?

FrameFetch first solves Reddit's anti-bot checkpoint (a lightweight JS challenge, not a login) to reach the post's real data, then hands yt-dlp the HLS manifest URL instead of the video-only DASH file, so it downloads the stream that actually has audio, extracts it, and transcribes it with Whisper — a Reddit-specific step that TikTok and Instagram, which also don't expose reliable captions, don't need.

What happens with private, NSFW, quarantined, or deleted posts?

FrameFetch never authenticates as a Reddit user or bypasses an age/content gate — it only reaches what an anonymous, logged-out request can see. A private subreddit, a deleted or removed post, or content Reddit blocks from anonymous access fails the same way any inaccessible URL does: no charge, and either a warning on the specific field or a 500 EXTRACTION_FAILED on the whole call.

Can I get comments and audience sentiment on a Reddit post?

No, not anymore. Reddit used to be supported (its public thread JSON endpoint, no proxy needed) alongside YouTube, but Reddit deprecated unauthenticated access to that endpoint on 2026-05-28 — every request now returns a 403 regardless of proxy or user-agent. Requesting comments or comment_sentiment on a Reddit URL now degrades with a warning and is never charged, the same as on TikTok, Instagram, or Pinterest. Metadata, transcript, frames, and text_overlay are all unaffected.

Can I read text overlays on a Reddit video?

Yes — add text_overlay alongside frames to run OCR on each extracted frame and get back on-screen text, per-line confidence, and bounding boxes.

Which Reddit URLs are supported?

Any reddit.com or redd.it URL pointing at a post with a native Reddit-hosted video. Crossposts that just embed a link to another platform aren't — send that platform's own URL (YouTube, TikTok, etc.) instead.