The job
Segments carry start and end times, so an answer can link to the second it came from. Fetch, chunk by time, embed, and keep the video url as metadata.
Endpoints
| Endpoint | Returns | Cost |
|---|---|---|
GET /v1/youtube/search | YouTube search | 1 credit |
GET /v1/transcript | Transcript from any video URL | 1 credit |
GET /v1/youtube/video/transcript | YouTube video transcript | 1 credit |
POST /v1/batch | Batch requests | The sum of each sub-request's charge |
POST /v1/monitors | Create a monitor | Free |
Failed requests and cached repeats cost 0 credits. Send max_age_days to accept a recent cached copy. See credits and caching.
Recipe
- Search for the videos on your topic.
- Fetch a transcript with segments for each.
- Chunk by time, embed, store the url and start time.
Preview
The API is in early access. Calls use
api.socialscrape.io and return the shapes in the reference.Python
import os
import requests
API = "https://api.socialscrape.io"
HEADERS = {"x-api-key": os.environ["SOCIALSCRAPE_API_KEY"]}
def get(path, **params):
res = requests.get(API + path, headers=HEADERS, params=params, timeout=60)
res.raise_for_status()
return res.json()["data"]
# YouTube search
found = get("/v1/youtube/search", query="retrieval augmented generation", type="video", duration="long")
# Transcript from any video URL
doc = get("/v1/transcript", url=found["items"][0]["url"])
chunks, buf, start = [], [], None
for seg in doc["segments"]:
start = seg["start"] if start is None else start
buf.append(seg["text"])
if seg["end"] - start >= 60:
chunks.append({"url": doc["url"], "start": start, "text": " ".join(buf)})
buf, start = [], NoneTypeScript
const API = "https://api.socialscrape.io";
const headers = { "x-api-key": process.env.SOCIALSCRAPE_API_KEY! };
async function get(path: string, params: Record<string, string | number | boolean>) {
const query = new URLSearchParams(Object.entries(params).map(([k, v]) => [k, String(v)]));
const res = await fetch(`${API}${path}?${query}`, { headers });
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
return (await res.json()).data;
}
// YouTube search
const found = await get("/v1/youtube/search", { query: "retrieval augmented generation", type: "video", duration: "long" });
// Transcript from any video URL
const doc = await get("/v1/transcript", { url: found.items[0].url });
const chunks: { url: string; start: number; text: string }[] = [];
let buf: string[] = [];
let start: number | null = null;
for (const seg of doc.segments) {
start ??= seg.start;
buf.push(seg.text);
if (seg.end - start >= 60) {
chunks.push({ url: doc.url, start, text: buf.join(" ") });
buf = [];
start = null;
}
}Good to know
Many transcripts at once go in one batch call. Agents can call the same endpoints as tools through the MCP server.