YouTube Data API
This page contains the setup guide and reference information for the YouTube Data API source connector.
This connector uses the YouTube Data API v3 to sync data about your YouTube channels, including video details, channel metadata, and comments. For more detailed analytics and reporting data, use the YouTube Analytics connector.
Prerequisites
- One or more YouTube Channel IDs you want to sync data from
- (For Airbyte Open Source) A Google Cloud project with the YouTube Data API v3 enabled, and one of the following authentication methods from that project:
- A Google API Key (public data only)
- OAuth 2.0 credentials (Client ID, Client Secret, and Refresh Token)
Setup guide
Find your YouTube Channel IDs
- Go to YouTube and navigate to the channel you want to sync.
- The Channel ID is in the URL:
https://www.youtube.com/channel/CHANNEL_ID. Channel IDs are 24 characters long and start withUC. A handle URL such ashttps://www.youtube.com/@handleisn't a Channel ID. - Alternatively, you can find it in YouTube Studio under Settings > Channel > Advanced settings.
The connector fails the connection check if any Channel ID doesn't resolve to an existing channel, so verify each ID before you set up the source.
For Airbyte Cloud
- Log into your Airbyte Cloud account.
- Click Sources and then click + New source.
- Select YouTube Data API from the list.
- Enter a name for your source.
- Choose your authentication method:
- For OAuth 2.0: Click Sign in with Google to authenticate your Google account.
- For API Key: Enter your Google API key.
- Enter one or more Channel IDs to sync data from.
- Click Set up source.
For Airbyte Open Source
Create credentials
You can authenticate using either an API Key or OAuth 2.0.
Option A: API Key (simpler setup, public data only)
- Go to the Google Cloud Console.
- Create a new project or select an existing one.
- Navigate to APIs & Services > Library and enable the YouTube Data API v3.
- Go to APIs & Services > Credentials.
- Click Create Credentials > API key.
- Copy the generated API key.
- (Recommended) Click Restrict key to limit the key's usage to the YouTube Data API v3.
Option B: OAuth 2.0 (required for accessing private data)
- Go to the Google Cloud Console.
- Create a new project or select an existing one.
- Navigate to APIs & Services > Library and enable the YouTube Data API v3.
- Go to APIs & Services > Credentials.
- Click Create Credentials > OAuth client ID. Configure the OAuth consent screen if prompted.
- Select Web application as the application type, and add
https://developers.google.com/oauthplaygroundas an authorized redirect URI so you can generate a refresh token in the next steps. - Copy the Client ID and Client Secret.
- Open the OAuth 2.0 Playground. Click the settings icon, select Use your own OAuth credentials, and enter your Client ID and Client Secret.
- In the scope field, enter
https://www.googleapis.com/auth/youtube.force-ssl, then click Authorize APIs. Sign in with the Google account that owns the channel if you want to sync unlisted and private videos. - Click Exchange authorization code for tokens and copy the Refresh token.
If your OAuth consent screen's publishing status is Testing, Google expires refresh tokens after 7 days, and syncs start failing with authentication errors. Set the publishing status to In production before you generate the refresh token you use for scheduled syncs.
Set up the connector
- In Airbyte, go to Sources and click + New source.
- Select YouTube Data API from the list.
- Enter a name for your source.
- Choose your authentication method and enter the required credentials.
- Enter one or more Channel IDs to sync data from.
- Click Set up source.
Supported sync modes
The YouTube Data API source connector supports the following sync modes:
Every stream except channels supports incremental sync. The YouTube Data API has no date filters, but every endpoint the connector reads lists newest first, so an incremental sync reads pages until it reaches the first record it already has and stops. See Quota and rate limiting for the request cost of each stream.
Two streams behave differently in incremental mode:
videoonly fetches videos published since the last sync. Its statistics fields are a snapshot from the moment the video was first fetched and are not refreshed; usevideo_engagementfor counters that move.video_engagementre-reads the counters of every video on every sync and stamps each record with the fetch time as its cursor. Incremental - Append therefore builds a time series of counters per video, while Incremental - Append + Deduped keeps only the latest counters.
The comment streams use the top-level comment's publish time as the cursor, so incremental syncs don't pick up edits to existing comments or changes to their reply counts. Incremental syncs also don't remove videos or comments that were deleted on YouTube from the destination.
Supported streams
| Stream Name | Primary Key | Cursor | Pagination | Supports Full Sync | Supports Incremental |
|---|---|---|---|---|---|
| videos | videoId | publishedAt | DefaultPaginator | Yes | Yes |
| video | videoId | publishedAt | DefaultPaginator | Yes | Yes |
| video_engagement | videoId | datetime (fetch time) | None | Yes | Yes |
| channels | id | — | DefaultPaginator | Yes | No |
| comments | videoId, id | publishedAt | DefaultPaginator | Yes | Yes |
| channel_comments | channelId, id | publishedAt | DefaultPaginator | Yes | Yes |
Stream descriptions
- videos: One record per upload in each configured channel. For each channel returned by the
channelsstream, this stream reads the channel's uploads playlist withplaylistItems.list, 50 items per page. Records are thin:kindandvideoId(primary key) from the playlist item'sresourceId,channelId,title,publishedAt(when the upload was added to the channel), andprivacyStatus(public,unlisted, orprivate). With OAuth 2.0 as the channel owner this includes unlisted and private uploads; with an API key, or for channels the OAuth user doesn't own, only public uploads. Thevideo,video_engagement, andcommentsstreams use this stream as their parent to identify which videos to fetch. - video: Detailed information about videos from the specified channels, from
videos.list, fetched 50 videos per request. Data includes snippet information (title, description, thumbnails, publish date, tags, category, language settings), content details (duration, dimension, definition, caption availability, region restrictions), statistics (view count, like count, comment count), player information (embed HTML), and status (upload status, privacy status, license, embeddable, made for kids). Each record also includes adatetimefield that the connector sets to the time it fetched the record. It isn't a YouTube timestamp; use it to tell snapshots apart in Full Refresh - Append mode. - video_engagement: The current
statisticsof every video from the specified channels (viewCount,likeCount,commentCount,favoriteCount), fromvideos.listwithpart=statistics, 50 videos per request, plusvideoIdand adatetimefield set to the fetch time. YouTube exposes only cumulative counters, not history, so each sync is one snapshot; schedule the connection at the cadence you want the series sampled. For daily views, watch time, and other report metrics use the YouTube Analytics connector. - channels: Information about the specified YouTube channels, from
channels.list. Data includes snippet information (title, description, custom URL, country, thumbnails), content details (related playlists), statistics (subscriber count, view count, video count), branding settings (channel keywords, trailer, default language), topic details (topic categories), status (privacy status, made for kids), localizations, and content owner details. The connector also adds anuploadsPlaylistIdfield, copied fromcontentDetails.relatedPlaylists.uploads, which thevideosstream uses to list the channel's uploads. - comments: Comment threads on individual videos from the specified channels, from
commentThreads.listfiltered byvideoId. For each video discovered by thevideosstream, this stream fetches the comment threads, newest first, 100 per request. Each record is one thread'ssnippet: the top-level comment is intopLevelComment,totalReplyCountgives the number of replies, and the connector copies the top-level comment's ID into a top-levelidfield (part of the primary key) and itspublishedAtinto a top-levelpublishedAtfield (the cursor). The replies themselves aren't included in the records. Videos with comments disabled and videos that no longer exist are skipped without failing the sync. - channel_comments: All comment threads related to the specified channels, from
commentThreads.listfiltered byallThreadsRelatedToChannelId, newest first, 100 per request. This includes comments on the channel's videos and on the channel page itself, so it provides a broader view of channel engagement than thecommentsstream, and an incremental sync costs one or two requests per channel instead of one per video. Records have the same shape ascomments, including the copiedidandpublishedAtfields. If you don't need comments partitioned by video, prefer this stream overcomments.
Comment records also carry updatedAt inside the nested topLevelComment.snippet object; it isn't hoisted to the top level and isn't used as a cursor.
YouTube API Services usage disclosure
This connector uses YouTube API Services to retrieve data from YouTube. By using this connector, you agree to be bound by the YouTube Terms of Service.
YouTube API Services are provided by Google. For information about how Google handles data, review the Google Privacy Policy.
When using OAuth 2.0 authentication, this connector accesses authorized user data. You can revoke the connector's access to your Google account at any time through the Google security settings page. To delete stored data that was previously synced, remove the relevant connection in your Airbyte workspace or delete the data from your configured destination.
Limitations and considerations
Quota and rate limiting
The YouTube Data API enforces a daily quota per Google Cloud project. Google's documented default allocation is 10,000 quota units per day, and every endpoint this connector reads (playlistItems.list, channels.list, videos.list, and commentThreads.list) costs 1 unit per request. Google notes that defaults are subject to change, so check the Quotas page for the YouTube Data API in the Google Cloud console to see what applies to your project. If you need more, request a quota extension from Google.
Requests per sync scale with the number of videos, V, in the configured channels. The video, video_engagement, and comments streams each read the uploads playlist themselves to find video IDs, so their costs below include that parent read. video reads only new playlist items in incremental mode, while video_engagement and comments re-read the whole playlist on every sync.
| Stream | First sync or Full Refresh | Incremental sync |
|---|---|---|
videos | About V/50 | About one per channel |
video | About V/50 for the playlist plus V/50 for video details | About one per channel, plus one per 50 new videos |
video_engagement | About V/50 for the playlist plus V/50 for statistics | Same as a first sync |
channels | One per channel | Not supported |
comments | About V/50 for the playlist, plus one per video, plus one per additional 100 comment threads on a video | About V/50 for the playlist plus one per video |
channel_comments | One per channel, plus one per additional 100 comment threads | About one or two per channel |
For example, a 5,000-video channel syncing videos, video, video_engagement, channels, and channel_comments incrementally every hour uses roughly 200 units per sync, or about 5,000 per day. Most of that is video_engagement; sync it less often, or not at all, if you don't need frequent counter snapshots.
The connector also paces its own requests as a burst guard: at most 100 requests per minute across all endpoints. A request that would exceed this limit waits for the next free slot rather than failing. If YouTube returns a per-minute rate-limit error (rateLimitExceeded, userRateLimitExceeded, or HTTP 429), the connector retries with backoff. If YouTube reports the daily quota as exhausted (quotaExceeded or dailyLimitExceeded), the sync fails immediately rather than retrying, because the quota only resets at midnight Pacific time; incremental streams resume from their last checkpoint on the next scheduled sync.
The connector's pacing applies to each Airbyte source separately, but Google meters quota per Google Cloud project. If several sources use API keys or OAuth clients from the same project, their requests add up against one quota. Use a separate project for each source, or request more quota.
Authentication
- API keys can only access public data. To sync unlisted and private videos, and comments on them, you must use OAuth 2.0 authentication as the owner of the channel.
- When using OAuth 2.0, the connector requests the
youtube.force-sslscope, which provides read and write access to YouTube resources. This scope is required even though the connector only reads data. - When using OAuth 2.0, the connector refreshes the access token and retries if YouTube returns HTTP 401. If the 401 persists, the sync fails with a configuration error; re-authenticate with Google from the source settings. With an API key there's no token to refresh, so a persistent 401 fails the same way.
- The connector fails with a configuration error, rather than retrying, when YouTube reports that the API key is invalid, the token lacks the
youtube.force-sslscope, the YouTube Data API v3 isn't enabled for the project, or a configured Channel ID doesn't exist. Fix the credentials or Channel IDs and run the sync again. - The connector does not support service account authentication because the YouTube Data API does not support this method for most operations.
Data coverage
- The
videosstream reads each channel's uploads playlist, which has no result cap, so it returns every upload regardless of channel size. - Unlisted and private uploads appear in
videos,video,video_engagement, andcommentsonly when the source authenticates with OAuth 2.0 as the channel owner. With an API key, or for channels the OAuth user doesn't own, these streams contain public videos only. - YouTube exposes only current engagement counters.
video_engagementrecords are per-sync snapshots, not a history the connector can backfill. - The
commentsstream skips videos with comments disabled and deleted videos without producing records or errors. - Incremental
commentskeeps a cursor per video. On channels with more than 10,000 videos the connector switches to a single cursor for the stream, which can re-read more comments per sync than strictly necessary.
IP allow list
If you use Airbyte Cloud and your organization restricts access to specific IPs, add the Airbyte Cloud IP addresses to your allow list.
Reference
Config fields reference
Changelog
Expand to review
| Version | Date | Pull Request | Subject |
|---|---|---|---|
| 1.1.0 | 2026-10-20 | 87495 | Add incremental sync to videos, video, comments, and channel_comments; add the video_engagement stream; add publishedAt, privacyStatus, channelId, and title to videos records; fetch 50 videos per videos.list request and 100 comment threads per commentThreads.list request; fail fast when the daily quota is exhausted |
| 1.0.8 | 2026-10-20 | 89482 | Update dependencies |
| 1.0.7 | 2026-10-13 | 88831 | Update dependencies |
| 1.0.6 | 2026-10-07 | 87637 | Enumerate channel videos through the uploads playlist to remove the search endpoint's 500-video cap. |
| 1.0.5 | 2026-10-06 | 88113 | Update dependencies |
| 1.0.4 | 2026-09-29 | 87429 | Update dependencies |
| 1.0.3 | 2026-09-22 | 86891 | Update dependencies |
| 1.0.2 | 2026-09-21 | 86466 | Fix authentication failures (HTTP 401) on channels with many videos: refresh the access token and retry on 401, and shorten API budget windows so syncs no longer wait past the token lifetime |
| 1.0.1 | 2026-09-15 | 86306 | Update dependencies |
| 1.0.0 | 2026-09-10 | 85214 | Breaking: promote connector to certified — declare primary keys and timestamp formats and restrict videos to video results (see the migration guide) |
| 0.0.66 | 2026-09-08 | 85721 | Update dependencies |
| 0.0.65 | 2026-08-18 | 84813 | Update dependencies |
| 0.0.64 | 2026-08-11 | 84181 | Update dependencies |
| 0.0.63 | 2026-08-04 | 83693 | Update dependencies |
| 0.0.62 | 2026-07-28 | 83186 | Update dependencies |
| 0.0.61 | 2026-07-21 | 82663 | Update dependencies |
| 0.0.60 | 2026-07-14 | 82070 | Update dependencies |
| 0.0.59 | 2026-06-30 | 81317 | Update dependencies |
| 0.0.58 | 2026-06-23 | 80730 | Update dependencies |
| 0.0.57 | 2026-06-16 | 80123 | Update dependencies |
| 0.0.56 | 2026-06-09 | 79580 | Update dependencies |
| 0.0.55 | 2026-06-02 | 79000 | Update dependencies |
| 0.0.54 | 2026-04-28 | 77496 | Update dependencies |
| 0.0.53 | 2026-04-21 | 76818 | Update dependencies |
| 0.0.52 | 2026-04-08 | 75185 | Replace connector icon with updated YouTube logo |
| 0.0.51 | 2026-03-17 | 74392 | Migrate to scopes object array format |
| 0.0.50 | 2026-03-17 | 74698 | Update dependencies |
| 0.0.49 | 2026-03-03 | 73914 | Update dependencies |
| 0.0.48 | 2026-02-17 | 73507 | Update dependencies |
| 0.0.47 | 2026-02-10 | 73175 | Update dependencies |
| 0.0.46 | 2026-01-27 | 72066 | Update dependencies |
| 0.0.45 | 2026-01-14 | 70677 | Update dependencies |
| 0.0.44 | 2026-01-05 | 71016 | Fixed schemas |
| 0.0.43 | 2025-12-19 | 70971 | Add acceptance tests |
| 0.0.42 | 2025-12-16 | 69315 | Add OAuth 2.0 support |
| 0.0.41 | 2025-11-25 | 70079 | Update dependencies |
| 0.0.40 | 2025-11-18 | 69532 | Update dependencies |
| 0.0.39 | 2025-10-29 | 68942 | Update dependencies |
| 0.0.38 | 2025-10-21 | 68456 | Update dependencies |
| 0.0.37 | 2025-10-14 | 67987 | Update dependencies |
| 0.0.36 | 2025-10-07 | 67241 | Update dependencies |
| 0.0.35 | 2025-09-30 | 66846 | Update dependencies |
| 0.0.34 | 2025-09-24 | 66475 | Update dependencies |
| 0.0.33 | 2025-09-09 | 65731 | Update dependencies |
| 0.0.32 | 2025-08-24 | 65468 | Update dependencies |
| 0.0.31 | 2025-08-10 | 64863 | Update dependencies |
| 0.0.30 | 2025-08-02 | 64386 | Update dependencies |
| 0.0.29 | 2025-07-26 | 64056 | Update dependencies |
| 0.0.28 | 2025-07-19 | 63640 | Update dependencies |
| 0.0.27 | 2025-07-12 | 63216 | Update dependencies |
| 0.0.26 | 2025-07-05 | 62701 | Update dependencies |
| 0.0.25 | 2025-06-28 | 62233 | Update dependencies |
| 0.0.24 | 2025-06-21 | 61759 | Update dependencies |
| 0.0.23 | 2025-06-15 | 61171 | Update dependencies |
| 0.0.22 | 2025-05-24 | 60786 | Update dependencies |
| 0.0.21 | 2025-05-10 | 59968 | Update dependencies |
| 0.0.20 | 2025-05-04 | 59566 | Update dependencies |
| 0.0.19 | 2025-04-26 | 58930 | Update dependencies |
| 0.0.18 | 2025-04-19 | 58550 | Update dependencies |
| 0.0.17 | 2025-04-13 | 58052 | Update dependencies |
| 0.0.16 | 2025-04-05 | 57379 | Update dependencies |
| 0.0.15 | 2025-03-29 | 56821 | Update dependencies |
| 0.0.14 | 2025-03-22 | 56338 | Update dependencies |
| 0.0.13 | 2025-03-09 | 55664 | Update dependencies |
| 0.0.12 | 2025-03-01 | 55162 | Update dependencies |
| 0.0.11 | 2025-02-23 | 54632 | Update dependencies |
| 0.0.10 | 2025-02-15 | 53087 | Update dependencies |
| 0.0.9 | 2025-01-25 | 52387 | Update dependencies |
| 0.0.8 | 2025-01-18 | 52006 | Update dependencies |
| 0.0.7 | 2025-01-11 | 51380 | Update dependencies |
| 0.0.6 | 2025-01-04 | 50753 | Update dependencies |
| 0.0.5 | 2024-12-21 | 50326 | Update dependencies |
| 0.0.4 | 2024-12-14 | 49756 | Update dependencies |
| 0.0.3 | 2024-12-12 | 49403 | Update dependencies |
| 0.0.2 | 2024-12-11 | 49125 | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 |
| 0.0.1 | 2024-11-08 | Initial release by @bala-ceg via Connector Builder |