Reference

YouTube Channel Monitor API

A monitor watches a YouTube channel on a schedule and reports every new video, by a signed webhook POST or from the events endpoint, optionally with the video's transcript attached. Create one with the channel as target; tab chooses its uploads, Shorts or live streams; interval_minutes sets how often it is checked; transcripts true delivers each new video's transcript as well. The same endpoint watches TikTok and Instagram profiles.

1 credit per check that finds new videos, free otherwiseView pricing

Creating a monitor is free, and so is every check that finds nothing new. A check that finds videos costs 1 credit, plus 1 per caption transcript with transcripts true; a transcript that has to come from audio is billed on delivery at 1 credit per started 5 minutes of audio.

On this platform

  • target takes the channel in any form the channel endpoint accepts: @handle, UC… id or URL. The platform is read from it.
  • Every webhook delivery is signed with HMAC-SHA256 over the raw body, keyed with the monitor's webhook_secret; verify before parsing.
  • New uploads usually have no automatic captions yet, so captions are retried for a grace period before audio transcription is used.
POST/api/v2/monitorsidempotent

Create a monitor for new videos

Watch a YouTube channel or a TikTok or Instagram profile, and receive every new video as an event, by webhook and from the events endpoint. Creation reads the target once, free, to learn what is already there.

  • Baseline: a channel or profile that does not exist answers 404 not_found. Everything on its first page today is recorded as already seen, baseline_count says how many, so only videos that appear later are reported.
  • Each check, every interval_minutes, reads the newest 30 rows and reports the ones it has not seen as one monitor.videos event, sent to webhook_url when one is set and always readable from the events endpoint. One check reports at most 50 videos; any more are reported by the next checks.
  • Billing: a check that finds nothing new is free. One that finds new videos costs 1 credit, the price of one listing page (plus 1 per caption transcript with transcripts: true), charged before the event is recorded or delivered.
  • An account that cannot pay records nothing: the videos are not marked seen, last_error reads insufficient_credits, the monitor stays active, and the same videos are delivered by the first check after credits return.
  • Limits: 5 monitors and a 60-minute minimum interval without a paid plan, 100 monitors and 15 minutes on any paid plan. Creating past the cap answers monitor_limit_reached.
  • A monitor does not report a video published more than 24 hours before it was created (pinned posts and reordered tabs keep resurfacing old videos).
  • YouTube channels: tab chooses the uploads (default), the Shorts or the live streams; a creator who posts only Shorts needs tab: "shorts". Fixed once created.
  • Monitors watch channels and profiles only. A playlist or search type is refused with invalid_request; read those on demand with the playlist and search endpoints.
  • The 201 response carries webhook_secret, the key every delivery is signed with. It is shown this once: store it.

Body parameters

type"channel"optional
Optional; "channel" is the only type and the default. Monitors watch a YouTube channel or a TikTok or Instagram profile. "playlist" and "search" are refused: read those on demand with the playlist and search endpoints.
Example
targetstringrequired
The YouTube channel (@handle, UC… id or URL) or the TikTok or Instagram profile URL, in any form the channel endpoint accepts. The platform is read from it. Fixed for the life of the monitor.
Example
platformstring (enum)optional
Not needed: the platform is read from target. If you send it anyway it must agree with the target.
tab"videos" | "shorts" | "live"optional
YouTube channel monitors only: which tab to watch. videos (the default) is the channel's uploads, shorts its Shorts, live its live streams (past and upcoming). A creator who posts only Shorts has an empty Videos tab, so a monitor on their uploads never fires: watch their shorts. Refused on TikTok and Instagram, like the channel endpoint refuses it; fixed once the monitor is created.
Example
webhook_urlstring (https URL) | nulloptional
Where to POST each event. The body is the event object (the same object the events endpoint lists, without its delivery block); X-TranscriptFetch-Event carries its type and X-TranscriptFetch-Delivery its id, which stays the same across retries of one event. Every delivery is signed: X-TranscriptFetch-Signature is sha256= followed by the hex HMAC-SHA256 of the raw request body, keyed with the monitor's webhook_secret (the whole string, whsec_ prefix included). Verify it over the exact bytes you received, before parsing, and compare in constant time. Answer with any 2xx within 10 seconds. A failed attempt (another status, a timeout, a redirect, which is never followed, or an unreachable host) is retried after 1, 5, 30, 120 and 720 minutes, then the delivery is marked failed; each event's delivery block shows where it stands. With transcripts: true a delivery carries the full transcripts, so accept bodies of several megabytes. Must be a public https URL on the standard port. It is checked when saved and again before every delivery, so an address that stops resolving publicly receives nothing. Optional: every event is also readable from the events endpoint. Send null on PATCH to remove it.
Example
interval_minutes15 | 60 | 360 | 1440optional
Minutes between checks; default 60. Accounts without a paid plan may use 60, 360, 1440; any paid plan also 15. A new interval takes effect from the moment it is saved. Should the account leave its paid plan, a monitor keeps its setting but is not checked more often than the plan then allows.
Example
transcriptsbooleanoptional
Also deliver each new video's transcript, fetched the way a batch entry is in "auto" mode. Caption transcripts arrive inline in the monitor.videos event and cost 1 credit each. A video with no captions is transcribed from its audio instead, billed on delivery at the AI rate (1 credit per started 5 minutes of audio, minimum 1), and its transcript follows in its own monitor.transcript event; until then its entry reads "processing". Brand-new YouTube uploads usually have no automatic captions yet, so YouTube captions are retried every 15 minutes for up to 60 minutes after the video is found before AI transcription is used: a caption transcript costs 1 credit where a 20-minute video transcribed from audio costs 4. TikTok and Instagram videos without captions go straight to AI transcription. An upcoming or ongoing live stream has no transcript until its recording exists: it is looked for every 30 minutes for up to 7 days, and the caption grace period starts when the stream has ended. A caption transcript the balance cannot cover is not sent: it waits for credits for up to 7 days, then is reported as failed with insufficient_credits. A key with the captions-only policy never transcribes audio, here as anywhere: transcripts it turned on, or that a check it ran left owed, are captions only, and a video still without captions after the grace period is reported as failed (no_captions). Default false.
Example
namestring (up to 100) | nulloptional
Your label for the monitor, returned on the monitor and in every event it produces.
Example

Request example

curl https://transcriptfetch.com/api/v2/monitors \
  -H "Authorization: Bearer $TRANSCRIPTFETCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target":"@lexfridman","webhook_url":"https://example.com/hooks/transcriptfetch","interval_minutes":60,"transcripts":true,"name":"Lex Fridman uploads"}'

Responses

CreatedExample response envelope
{
  "ok": true,
  "request_id": "req_…",
  "data": {
    "kind": "monitor",
    "id": "mon_m3k1x9qz4vb2p7",
    "type": "channel",
    "platform": "youtube",
    "target": "@lexfridman",
    "options": {
      "tab": "videos"
    },
    "name": "Lex Fridman uploads",
    "status": "active",
    "has_new": true,
    "last_event_id": "mev_m3k1xa0b7c8d9e",
    "interval_minutes": 60,
    "transcripts": true,
    "webhook_url": "https://example.com/hooks/transcriptfetch",
    "next_check_at": "2026-09-25T15:00:12.000Z",
    "last_checked_at": null,
    "last_error": null,
    "created_at": "2026-09-24T09:12:40.000Z",
    "updated_at": "2026-09-24T09:12:40.000Z",
    "webhook_secret": "whsec_…",
    "baseline_count": 30
  },
  "usage": {
    "credits_spent": 0,
    "balance": 250
  }
}

Every YouTube endpoint

Frequently asked questions

How is this different from polling the channel endpoint with since_video_id?
Polling is a call you schedule and pay a credit for whenever something is new. A monitor runs the schedule for you, pushes each new video to your webhook or the events list, and can fetch the transcript on your behalf. Use polling for one script, a monitor for a product.
What does a monitor cost?
A check that finds nothing new costs nothing. A check that finds new videos costs 1 credit, the price of one listing page, plus 1 credit per caption transcript when transcripts is true; audio transcription is billed at the audio rate on delivery. Monitor and interval limits depend on the plan and are stated on the endpoint.
Can a monitor watch a channel's Shorts or live streams?
Yes. Create it with tab shorts or tab live. A creator who posts only Shorts has an empty Videos tab, so a monitor on their uploads never fires; watch their shorts instead. The tab is fixed once the monitor exists.
How do I verify a webhook came from TranscriptFetch?
Compute HMAC-SHA256 of the exact request bytes with the monitor's webhook_secret and compare it, in constant time, with the X-TranscriptFetch-Signature header (sha256= followed by the hex digest). X-TranscriptFetch-Delivery identifies the delivery across retries.
Why does a brand-new upload take a while to get a transcript?
YouTube's automatic captions usually appear some minutes after publishing. The monitor retries captions for a grace period before falling back to audio transcription, because a caption transcript costs 1 credit where a long video transcribed from audio costs more.