Two ways to get YouTube transcripts: pull on your schedule, or receive them instantly via webhook the moment a new video drops.
The Pull API uses API key authentication. Find your key in the dashboard settings. Pass it using any of these methods:
Authorization: Bearer vp_xxxxxxxxxxxxxxxx
X-Api-Key: vp_xxxxxxxxxxxxxxxx
GET /api/videos?api_key=vp_xxxxxxxxxxxxxxxx
Webhooks don't require authentication — you configure the endpoint URL when creating a subscription. VidProxy will POST to that URL whenever a new video is detected.
Fetch all transcripts detected for your subscriptions within a time window. Good for batch processing, scheduled jobs, or polling-based integrations.
| Parameter | Type | Default | Description |
|---|---|---|---|
since |
string | 24h |
Time window. Accepts Nh (hours) or Nd (days). Examples: 6h, 7d. |
tag |
string | — | Filter by subscription label. If omitted, returns videos from all subscriptions. |
curl https://vidproxy.pro/api/videos?since=24h&tag=my-channel \ -H "Authorization: Bearer vp_xxxxxxxxxxxxxxxx"
{
"videos": [
{
"id": 1234,
"subscription_id": 42,
"channel_id": "UCxxxxxxxxxxxxxxxxxxxxxx",
"channel_name": "HomeBrewers",
"tag": "my-channel",
"video_id": "dQw4w9WgXcQ",
"video_title": "How to Brew a West Coast IPA",
"published_at": "2026-04-30T10:00:00.000Z",
"transcript_available": true,
"transcript_text": "Welcome to today's brew session...",
"transcript_source": "proxy",
"detected_at": "2026-04-30T10:05:12.000Z",
"ai_summary": null,
"ai_key_takeaways": null,
"ai_topics": null
}
],
"query": {
"tag": "my-channel",
"since": "24h",
"cutoff": "2026-04-29T10:05:12.000Z"
}
}
| Field | Type | Description |
|---|---|---|
video_id |
string | YouTube video ID. Construct the full URL as https://www.youtube.com/watch?v={video_id}. Use this for deduplication. |
channel_id |
string | YouTube channel ID (e.g. UCxxxxxx). |
channel_name |
string | Channel display name, as shown on YouTube. |
tag |
string | null | The label you set on the subscription. Useful for routing videos to different pipelines. |
video_title |
string | Video title at time of detection. |
published_at |
ISO 8601 | When the video was published on YouTube. |
transcript_available |
boolean | false only when YouTube explicitly reports transcripts are disabled for this video. |
transcript_text |
string | null | Full transcript as plain text. null if unavailable. |
transcript_source |
string | proxy, direct, or scraperapi — which fetch method succeeded. |
detected_at |
ISO 8601 | When VidProxy first detected this video. |
ai_summary |
string | null | AI-generated 2–3 sentence summary of the video. Pro and Agency plans only. |
ai_key_takeaways |
string[] | null | Array of key takeaways extracted from the transcript. Pro and Agency plans only. |
ai_topics |
string[] | null | Array of topic tags for the video. Pro and Agency plans only. |
subscription_id |
integer | Internal subscription ID. Stable identifier for the channel subscription that triggered this. |
Fetch the transcript for any YouTube video by URL or video ID — no channel subscription required. Each successful fetch counts against your monthly lookup quota. Failed fetches (transcript unavailable) are free.
| Parameter | Type | Description |
|---|---|---|
url |
string | Full YouTube URL (e.g. https://youtube.com/watch?v=abc123 or https://youtu.be/abc123). Use either url or video_id, not both. |
video_id |
string | YouTube video ID (11-character string, e.g. dQw4w9WgXcQ). |
curl "https://vidproxy.pro/api/transcript?video_id=dQw4w9WgXcQ" \ -H "Authorization: Bearer vp_xxxxxxxxxxxxxxxx"
{
"video_id": "dQw4w9WgXcQ",
"available": true,
"text": "Full transcript as plain text...",
"segments": [
{ "start": 0, "duration": 4, "text": "Never gonna give you up" },
...
],
"credits_remaining": 2499
}
| Header | Description |
|---|---|
X-Credits-Remaining |
Lookups remaining this month. unlimited for Agency. |
| Status | Error | Meaning |
|---|---|---|
400 |
url or video_id is required |
Neither parameter was provided, or the URL couldn't be parsed. |
402 |
credits_exhausted |
Monthly lookup quota reached. Resets on the 1st of each month. |
| Plan | Lookups / month |
|---|---|
| Free | 50 |
| Starter | 500 |
| Pro | 2,500 |
| Agency | 10,000 |
VidProxy ships a Model Context Protocol server at https://vidproxy.pro/mcp. Add it to Claude Desktop, Cursor, VS Code, or any MCP-compatible client and your AI assistant gains direct access to your channel data and transcript lookups — no copy-pasting, no API calls to write.
Add the following to your MCP client config. For Claude Desktop that's ~/.config/claude/claude_desktop_config.json; for Cursor it's in Settings → MCP.
{
"mcpServers": {
"vidproxy": {
"url": "https://vidproxy.pro/mcp",
"apiKey": "vp_xxxxxxxxxxxxxxxx"
}
}
}
Your API key is in Dashboard → Settings. The MCP server uses the same key as the REST API.
| Tool | Description | Credits |
|---|---|---|
get_transcript |
Fetch the full transcript for any YouTube video by ID or URL | 1 per successful fetch |
get_recent_videos |
Get videos from your monitored channels within a time window (e.g. since: "24h"), including full transcripts |
Free |
search_videos |
Search your subscription history by keyword — matches video titles and transcript text | Free |
list_channels |
List your monitored channels with latest video info | Free |
Configure a webhook URL on any subscription and VidProxy will POST a JSON payload to it within minutes of a new video being published. No polling required.
| Header | Value |
|---|---|
Content-Type |
application/json |
User-Agent |
VidProxy/1.0 |
X-VidProxy-Event |
new_video |
{
"event": "new_video",
"timestamp": "2026-04-30T10:05:12.000Z",
"subscription": {
"id": 42,
"label": "my-channel",
"channel_id": "UCxxxxxxxxxxxxxxxxxxxxxx",
"channel_name": "HomeBrewers"
},
"video": {
"id": "dQw4w9WgXcQ",
"title": "How to Brew a West Coast IPA",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"published": "2026-04-30T10:00:00.000Z"
},
"transcript": {
"available": true,
"text": "Welcome to today's brew session...",
"segments": [
{ "text": "Welcome to today's brew session", "start": 0.5, "duration": 3.2 }
]
},
"enrichment": {
"summary": "A step-by-step guide to brewing a West Coast IPA...",
"key_takeaways": ["Use high-alpha hops for bittering", "Dry hop at 68°F for best aroma", "Cold crash before packaging"],
"topics": ["IPA", "hops", "dry hopping", "homebrewing"]
}
}
The enrichment field is only present on Pro and Agency plans with AI enrichment enabled. transcript.segments contains per-segment timing data when available.
If your endpoint returns a non-2xx status or times out (10s), VidProxy retries up to 3 times:
After 3 failed retries the delivery is marked failed and logged in your dashboard. Make your endpoint idempotent — use video.id for deduplication.
Return any 2xx status code within 10 seconds. If your processing takes longer, acknowledge immediately and handle async.
Keyword Alerts let you save keywords and receive an email whenever any new video across all your subscriptions mentions them — matched against the video title and transcript. This is separate from per-subscription keyword filters, which control webhook delivery.
Alerts are managed from the Keyword Alerts tab in your dashboard. Add a keyword, and VidProxy will email you each time a new video matches it. Up to 50 keywords per account.
gpt matches "GPT-4", "ChatGPT", etc.Subscriptions also support a per-subscription Keyword Filter (set in the subscription edit modal). This controls webhook delivery only — the webhook fires only when the video title or transcript matches one of the specified keywords. It does not send emails and is independent of Keyword Alerts.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/keyword-alerts | List all keyword alerts |
POST | /api/keyword-alerts | Create a keyword alert — body: { "keyword": "string" } |
DELETE | /api/keyword-alerts/:id | Delete a keyword alert |
The Pull API is rate-limited per API key using a sliding 60-second window. Response headers tell you your current usage:
| Header | Description |
|---|---|
X-RateLimit-Limit |
Max requests per minute for your plan. |
X-RateLimit-Remaining |
Requests remaining in the current window. |
Retry-After |
Seconds until the window resets (only on 429 responses). |
When you exceed the limit you receive a 429 Too Many Requests with a Retry-After header. Back off and retry after that delay.
| Plan | Channels | Webhooks | API req / min | Transcript lookups / mo |
|---|---|---|---|---|
| Free | 1 | 1 | 60 | 10 |
| Starter | 15 | 3 | 60 | 500 |
| Pro | 100 | Unlimited | 300 | 2,500 |
| Agency | 1,000 | Unlimited | 300 | 10,000 |