Video transcription
One transcribe() function that returns the spoken words of a video on YouTube, TikTok, Instagram, Facebook, X, Reddit or LinkedIn. 60 credits on YouTube, 200 on the others.
You will build one transcribe(url) function that returns what was said in a social video, whichever of seven platforms it lives on. Your application code stays platform-agnostic. A short adapter absorbs the differences.
Cost per run
60 credits for a YouTube video, 200 credits for a video on any of the other six platforms. You make exactly one call per video. A video with no captions or no speech is not charged, and transcribing the same URL again within 6 hours is free.
How do you turn a social video into text?
Pass the video URL to that platform's transcript endpoint. Each one returns the spoken content as text. Transcripts are the densest signal in social video: captions and thumbnails are written to get the click, while the spoken words are what the creator actually said.
What you need
| Endpoint | Covers | Credits |
|---|---|---|
GET /v1/youtube/video/transcript | YouTube videos and Shorts | 60 |
GET /v1/tiktok/post/transcript | TikTok videos | 200 |
GET /v1/instagram/media/transcript | Instagram reels and videos up to 2 minutes | 200 |
GET /v1/facebook/post/transcript | Facebook video posts | 200 |
GET /v1/twitter/tweet/transcript | Videos attached to X posts | 200 |
GET /v1/reddit/post/transcript | Reddit video posts | 200 |
GET /v1/linkedin/post/transcript | Videos in LinkedIn posts | 200 |
Every one takes a url parameter.
When there is nothing to transcribe
- YouTube, Instagram and LinkedIn answer
404when a video has no captions or no speech, and name the reason (for exampleno_captionsorno_speech). That is an expected outcome, not a failure, and it is not charged. - Reddit returns an empty transcript with a flag rather than an error when Reddit publishes no captions for the video.
- TikTok reads the video's captions. Add
use_ai_as_fallback=trueto fall back to AI transcription when there are none.
The response shapes differ
Each endpoint keeps the platform's own transcript shape, so you do not lose platform-specific fields. Three shapes to expect:
- YouTube:
data.transcriptis an array of timed segments,data.transcript_only_textis the full text as one string, anddata.languageis the language. - TikTok:
data.transcriptis the full text as a string. - Instagram:
data.transcripts(plural) is an array of{ id, shortcode, text }.
For Facebook, X, Reddit and LinkedIn, inspect the first response you get and extend the adapter below if you want a platform-specific field.
The code
# transcribe.py
# Returns the transcript of a social video URL on any of seven platforms.
# Run with: INSIGHTSOCIAL_API_KEY=isk_live_... python transcribe.py
import os
from urllib.parse import urlparse
import requests
KEY = os.environ["INSIGHTSOCIAL_API_KEY"]
BASE = "https://api.insightsocial.app/v1"
ENDPOINT = {
"youtube": "youtube/video/transcript",
"tiktok": "tiktok/post/transcript",
"instagram": "instagram/media/transcript",
"facebook": "facebook/post/transcript",
"twitter": "twitter/tweet/transcript",
"reddit": "reddit/post/transcript",
"linkedin": "linkedin/post/transcript",
}
HOSTS = {"youtube.com": "youtube", "youtu.be": "youtube", "tiktok.com": "tiktok",
"instagram.com": "instagram", "facebook.com": "facebook", "fb.watch": "facebook",
"x.com": "twitter", "twitter.com": "twitter", "reddit.com": "reddit",
"v.redd.it": "reddit", "linkedin.com": "linkedin"}
def platform_of(url):
host = urlparse(url).netloc.lower().removeprefix("www.").removeprefix("m.")
for suffix, platform in HOSTS.items():
if host == suffix or host.endswith("." + suffix):
return platform
raise ValueError(f"unsupported host: {host}")
def extract_text(platform, data):
if platform == "youtube":
return data.get("transcript_only_text") or ""
if platform == "instagram":
return " ".join(t.get("text", "") for t in data.get("transcripts") or [])
t = data.get("transcript")
if isinstance(t, str):
return t
# Other shapes: fall back to any plain-text field; inspect your first response.
return data.get("transcript_only_text") or data.get("text") or ""
def transcribe(url):
platform = platform_of(url)
res = requests.get(f"{BASE}/{ENDPOINT[platform]}", params={"url": url},
headers={"x-api-key": KEY}, timeout=120)
body = res.json()
if not body["success"]:
# A 404 here usually means "no captions" or "no speech", and costs nothing.
return {"platform": platform, "text": None, "error": body["error"]["type"],
"credits_used": body["credits_used"]}
return {"platform": platform, "text": extract_text(platform, body["data"]),
"credits_used": body["credits_used"]}
# Any public video URL on the seven platforms works; add your own to the list.
for url in [
"https://www.youtube.com/watch?v=dQw4w9WgXcQ",
]:
t = transcribe(url)
if t["text"] is None:
print(f"[{t['platform']}] no transcript ({t['error']}), {t['credits_used']} credits")
else:
print(f"[{t['platform']}] {len(t['text'])} chars, {t['credits_used']} credits")
print(t["text"][:200], "...")What you get back
{
"success": true,
"platform": "youtube",
"endpoint": "/v1/youtube/video/transcript",
"data": {
"transcript": [
{ "text": "...", "startMs": "80", "endMs": "4000", "startTimeText": "0:00" }
],
"transcript_only_text": "...",
"language": "en"
},
"credits_used": 60,
"credits_remaining": 9940,
"request_id": "req_1a2b3c4d5e6f",
"cached": false,
"idempotent_replay": false,
"charge_reason": "miss",
"free_call": false
}What to change
- Cheaper YouTube. If you can parse caption files yourself,
GET /v1/youtube/video/subtitles(20 credits) returns the caption tracks with download URLs instead. - Find a moment instead of reading everything. The YouTube and TikTok transcript endpoints take
q, a question about the video (for exampleq=what discount code do they give), andmoments, a list of moment kinds such assponsor_readorcall_to_action. The matching stretches come back ondata.momentswith their timestamps. - Pick a language. YouTube, TikTok and Reddit take
language, a two-letter code. - Ads too.
GET /v1/facebook/adlibrary/ad/transcript(200 credits) returns what a Facebook Ad Library video ad says out loud. Pass the adidor its library URL.
Related
Search then enrich
Find the posts about a topic on TikTok and Instagram, collect the accounts that made them, and fetch each account's full profile into one lead list. From 240 credits per run.
Ad library aggregation
Pull the ads a brand is running on Meta, LinkedIn and TikTok in one parallel fan-out and flatten them into one table. 300 to 540 credits per brand.