# How to Integrate Retool with YouTube API

- Tool: Retool
- Difficulty: Intermediate
- Time required: 25 minutes
- Last updated: April 2026

## TL;DR

Connect Retool to the YouTube Data API v3 using a REST API Resource with either an API key (for public data) or Google OAuth 2.0 (for private channel data and analytics). Build channel management dashboards that display video statistics, track subscriber growth, monitor comment activity, and manage playlists across one or multiple YouTube channels from a central operations panel.

## Build a YouTube Channel Analytics Dashboard in Retool

YouTube channels generating significant traffic require operational dashboards that go beyond YouTube Studio's native analytics. Content teams, brand managers, and creator operations teams need dashboards that combine video performance data across multiple channels, track subscriber growth against publishing cadence, surface comment moderation queues, and compare video metrics without switching between YouTube's siloed studio interfaces.

Retool's YouTube Data API v3 integration enables building these custom analytics panels. The YouTube Data API exposes video statistics (views, likes, comments, favorites), channel-level metrics (subscriber count, total view count, video count), playlist management, comment threads, and search functionality. For teams managing multiple YouTube channels — a common need for agencies and media companies — a single Retool dashboard can query multiple channels simultaneously using separate API resources or parameterized queries.

YouTube's API has two distinct access tiers that determine what data is available. Public data — any video's view count, title, and description — requires only an API key and does not involve authentication. Private or owned data — your channel's private analytics, comment moderation capabilities, and unposted content — requires OAuth 2.0 authorization with your Google account. This guide covers both access patterns so you can build the right level of integration for your needs. Retool's server-side proxy handles both API key and OAuth token transmission, keeping credentials out of the browser.

## Before you start

- A Google account with access to Google Cloud Console (console.cloud.google.com)
- A Google Cloud project with the YouTube Data API v3 enabled — enable it in Cloud Console → APIs & Services → Library
- For public data: a YouTube Data API v3 API key (created in Cloud Console → APIs & Services → Credentials)
- For private channel data: a Google OAuth 2.0 Client ID and Secret with youtube.readonly and youtube scopes configured
- At least one YouTube channel ID to query (visible in YouTube Studio → Settings → Channel → Advanced Settings, or in the channel URL after /channel/)

## Step-by-step guide

### 1. Create a YouTube Data API key in Google Cloud Console

Start at console.cloud.google.com and sign in with your Google account. If you don't have an existing project for this integration, click the project selector at the top of the page → New Project → enter a project name → Create. Once in your project, navigate to APIs & Services → Library in the left sidebar. Search for 'YouTube Data API v3' and click on it. Click Enable. After enabling, navigate to APIs & Services → Credentials. Click Create Credentials at the top and select API key. Google generates an API key immediately — copy it. Click the edit (pencil) icon on the new key to configure restrictions. Under Application restrictions, select 'IP addresses' and add Retool's IP ranges (35.90.103.132/30 and 44.208.168.68/30 for US West) to restrict the key to only Retool server requests — this prevents unauthorized use if the key is ever exposed. Under API restrictions, select 'Restrict key' and choose 'YouTube Data API v3' from the dropdown — this ensures the key can only be used for YouTube API calls and not other Google APIs. Save the restrictions. Also note your YouTube channel ID: log in to YouTube Studio at studio.youtube.com, click Settings → Channel → Advanced Settings, and copy the Channel ID (format: UCxxxxxxxxxxxxxxxxxxxxxxxx). In Retool's Settings → Configuration Variables, add: YOUTUBE_API_KEY (as a secret variable) and YOUTUBE_CHANNEL_ID (not sensitive, can be non-secret). The API key allows up to 10,000 units of quota per day for free — each API call consumes quota units based on the endpoint type (list operations typically cost 1-100 units).

**Expected result:** A YouTube Data API v3 key is created, restricted to Retool's IP ranges, stored as a Retool configuration variable, and your channel ID is noted for use in queries.

### 2. Create the YouTube REST API Resource in Retool

In Retool, navigate to the Resources tab and click Add Resource. Select REST API. Name it 'YouTube API'. In the Base URL field, enter https://www.googleapis.com/youtube/v3. This is the base URL for all YouTube Data API v3 endpoints — video, channel, playlist, comment, and search endpoints all live under this prefix. Scroll to the Authentication section. For public data access using an API key, select 'No Auth' since YouTube API keys are passed as URL parameters rather than authorization headers. You will include the key in each query's URL parameters rather than the resource configuration. In the Headers section, add a default header: Accept = application/json. Click Save Changes. For future OAuth-based private channel access (needed for comment management and private video operations), you would configure Retool's Custom Auth with Google OAuth endpoints and store credentials accordingly — the API key setup is sufficient for read-only public and owned-channel statistics queries. Verify the resource by creating a quick test query: GET /channels with URL parameters { key: {{ retoolContext.configVars.YOUTUBE_API_KEY }}, id: {{ retoolContext.configVars.YOUTUBE_CHANNEL_ID }}, part: 'snippet,statistics' }. If the response includes your channel's title and subscriber count, the resource is configured correctly.

**Expected result:** A 'YouTube API' resource is created and a test channel query returns your channel's title and statistics, confirming the API key is working.

### 3. Build queries to retrieve channel statistics and video lists

Create your core data queries. First, create a query named 'getChannelStats': select the YouTube API resource, Method GET, Path /channels. Add URL parameters: 'key' = {{ retoolContext.configVars.YOUTUBE_API_KEY }}, 'id' = {{ channelIdInput.value || retoolContext.configVars.YOUTUBE_CHANNEL_ID }}, 'part' = 'snippet,statistics,contentDetails'. Enable 'Run query when app loads'. The response contains channel title, description, subscriber count, total view count, video count, and the uploads playlist ID (which references all uploaded videos). Store the uploads playlist ID from the response for use in the next query: {{ getChannelStats.data.items?.[0]?.contentDetails?.relatedPlaylists?.uploads }}. Create a second query named 'getVideos': Method GET, Path /playlistItems. Add URL parameters: 'key' = {{ retoolContext.configVars.YOUTUBE_API_KEY }}, 'playlistId' = {{ getChannelStats.data.items?.[0]?.contentDetails?.relatedPlaylists?.uploads }}, 'part' = 'snippet,contentDetails', 'maxResults' = 50, 'pageToken' = {{ pagination.nextPageToken || '' }}. This retrieves all uploaded videos. To get statistics for these videos, create a third query named 'getVideoStats': Path /videos, URL parameters: 'key' = key, 'id' = {{ getVideos.data.items.map(v => v.contentDetails.videoId).join(',') }}, 'part' = 'statistics,contentDetails,snippet'. Set this query to trigger After getVideos completes. Write a transformer that joins the playlist items with their statistics by video ID.

```
// Transformer: join playlist items with video statistics
const playlistItems = getVideos.data?.items || [];
const statsItems = data?.items || []; // data = getVideoStats response

const statsMap = {};
statsItems.forEach(v => {
  statsMap[v.id] = v.statistics;
});

return playlistItems.map(item => {
  const videoId = item.contentDetails?.videoId || item.snippet?.resourceId?.videoId;
  const stats = statsMap[videoId] || {};
  const views = parseInt(stats.viewCount) || 0;
  const likes = parseInt(stats.likeCount) || 0;
  const comments = parseInt(stats.commentCount) || 0;
  const engagementRate = views > 0
    ? (((likes + comments) / views) * 100).toFixed(2)
    : '0.00';

  return {
    video_id: videoId,
    title: item.snippet?.title || 'N/A',
    published_at: new Date(item.snippet?.publishedAt).toLocaleDateString(),
    thumbnail: item.snippet?.thumbnails?.medium?.url || '',
    views: views.toLocaleString(),
    view_count: views,
    likes: likes.toLocaleString(),
    comments: comments.toLocaleString(),
    engagement_rate: engagementRate + '%',
    url: `https://www.youtube.com/watch?v=${videoId}`
  };
});
```

**Expected result:** The combined queries return a list of the channel's videos with view counts, engagement rates, and publish dates, joined from the playlist and statistics endpoints.

### 4. Build the YouTube analytics dashboard UI

With data returning from your queries, build the dashboard layout. Add a Text Input component named 'channelIdInput' with placeholder 'Enter Channel ID (or leave blank for default)' and a label. Below it, add a Stats row with four Stat components showing: subscriber count ({{ parseInt(getChannelStats.data.items?.[0]?.statistics?.subscriberCount || 0).toLocaleString() }}), total video count, total views, and average engagement rate across all videos (calculate with a JavaScript transformer). Below the stats row, drag a Table component and bind its Data to your joined video statistics data. Configure columns: title (render as a link to the YouTube URL), published_at, views, likes, comments, and engagement_rate. Apply conditional formatting to the engagement_rate column: green if > 3%, yellow for 1-3%, red for < 1%. Add a column of type Image and set the source to {{ row.thumbnail }} to show video thumbnails inline. Add an input for searching video titles bound to the Table's search property. Below the table, add a Chart component configured as a Bar Chart. Set data to {{ getVideoStats.data.items.map(v => ({ date: new Date(v.snippet.publishedAt).toLocaleDateString(), views: parseInt(v.statistics.viewCount) })).sort((a,b) => new Date(a.date) - new Date(b.date)) }} to show view count per video by publish date. This visualization shows publishing frequency alongside view performance.

```
// JavaScript transformer: calculate channel-level summary metrics
const videos = getVideoStats.data?.items || [];
if (videos.length === 0) return { avg_engagement: '0%', top_video: 'N/A' };

const totalViews = videos.reduce((s, v) => s + (parseInt(v.statistics?.viewCount) || 0), 0);
const totalLikes = videos.reduce((s, v) => s + (parseInt(v.statistics?.likeCount) || 0), 0);
const totalComments = videos.reduce((s, v) => s + (parseInt(v.statistics?.commentCount) || 0), 0);

const avgEngagement = totalViews > 0
  ? (((totalLikes + totalComments) / totalViews) * 100).toFixed(2) + '%'
  : '0%';

const topVideo = videos.reduce((best, v) =>
  (parseInt(v.statistics?.viewCount) > parseInt(best.statistics?.viewCount)) ? v : best
, videos[0]);

return {
  avg_engagement: avgEngagement,
  top_video: topVideo.snippet?.title || 'N/A',
  top_video_views: parseInt(topVideo.statistics?.viewCount || 0).toLocaleString()
};
```

**Expected result:** A YouTube analytics dashboard displays channel stats, a video performance table with thumbnail images and engagement rates, and a Bar Chart showing views per published video over time.

### 5. Add comment monitoring and search functionality

Extend the dashboard with comment data for community management. Create a query named 'getComments': Method GET, Path /commentThreads. Add URL parameters: 'key' = {{ retoolContext.configVars.YOUTUBE_API_KEY }}, 'videoId' = {{ videosTable.selectedRow?.video_id || '' }}, 'part' = 'snippet', 'maxResults' = 100, 'order' = 'time'. Set this query to trigger when a table row is selected via event handler on the Table's 'Row Selection' event. Write a transformer for comment data that extracts: comment ID, author display name, author profile image URL, text display (comment text), like count, publish date, and whether it is a reply or top-level comment. Add a second Table below the videos table bound to getComments data, with columns for author, text preview (first 100 chars), likes, and published date. For search functionality, create a query named 'searchVideos': Method GET, Path /search. Add URL parameters: 'key' = key, 'channelId' = {{ retoolContext.configVars.YOUTUBE_CHANNEL_ID }}, 'q' = {{ searchInput.value }}, 'type' = 'video', 'part' = 'snippet', 'maxResults' = 25, 'order' = 'relevance'. Bind this to a Search Text Input's change event with 500ms debounce. Note that the Search endpoint costs 100 quota units per call (vs 1 for list operations) — add a 'Search' button to trigger it manually rather than on each keystroke to preserve your daily quota. For multi-channel dashboards used by agencies managing many YouTube channels, RapidDev can help architect a parameterized multi-channel Retool solution with quota management.

```
// Transformer: normalize YouTube comment threads
const items = data.items || [];
return items.map(thread => {
  const top = thread.snippet?.topLevelComment?.snippet || {};
  return {
    id: thread.id,
    author: top.authorDisplayName || 'Anonymous',
    author_image: top.authorProfileImageUrl || '',
    text: top.textDisplay || '',
    text_preview: (top.textDisplay || '').substring(0, 100) +
      ((top.textDisplay || '').length > 100 ? '...' : ''),
    likes: parseInt(top.likeCount) || 0,
    published_at: top.publishedAt
      ? new Date(top.publishedAt).toLocaleDateString()
      : 'N/A',
    reply_count: thread.snippet?.totalReplyCount || 0,
    video_id: top.videoId
  };
});
```

**Expected result:** Selecting a video in the table loads its latest comments in a second table, and the search panel allows finding videos by keyword with manual trigger to manage API quota.

## Best practices

- Store the YouTube API key in Retool Configuration Variables marked as secret and restrict the key in Google Cloud Console to Retool's IP ranges — this prevents the key from being used for quota exploitation if accidentally exposed
- Apply query caching (minimum 5 minutes) to all YouTube Data API queries — YouTube video statistics update infrequently and caching dramatically reduces quota consumption when multiple team members have the dashboard open
- Use the /videos endpoint to fetch statistics by video ID rather than the /search endpoint for regular dashboard data — the search endpoint costs 100 quota units per call while the videos list endpoint costs only 1 unit per video ID batch
- Always paginate YouTube playlist and search results using the 'nextPageToken' returned in responses — a channel with 500+ videos requires multiple API calls and the token-based pagination pattern is the only reliable way to traverse the full list
- Display quota-sensitive endpoints (like search) behind manual trigger buttons rather than auto-running on component changes — this prevents quota exhaustion from accidental repeated queries during dashboard interaction
- Include the video ID as a clickable link to youtube.com/watch?v={id} in all video Tables — this allows dashboard users to quickly navigate from the Retool panel to the actual YouTube video for detailed investigation
- For multi-channel agency dashboards, create a Select component populated with channel configurations stored in Retool Database, and dynamically set the channelId query parameter based on selection — this avoids creating separate resources per channel

## Use cases

### Build a multi-channel YouTube video performance tracker

Create a Retool dashboard that queries video statistics for one or more YouTube channels and displays performance metrics in a sortable, filterable Table. Show views, likes, comment count, and publish date for all videos in selected playlists. Calculate engagement rate (likes + comments / views * 100) as a derived column, and highlight top-performing and underperforming videos.

Prompt example:

```
Build a Retool dashboard showing all YouTube videos for a channel ID with columns for title, publish date, view count, likes, comment count, and calculated engagement rate. Sort by most recent, include a date filter, and highlight rows where engagement rate is below 1%.
```

### Build a subscriber growth and publishing cadence analytics panel

Create a Retool analytics panel that tracks YouTube subscriber counts over time by storing daily snapshots to Retool Database, then displays a trend line alongside a Bar Chart of video publish dates. Identify correlations between publishing frequency and subscriber growth spikes to optimize content calendar decisions for the channel team.

Prompt example:

```
Build a Retool panel that shows subscriber growth over 90 days (from stored daily snapshots in Retool Database) as a Line Chart alongside a Bar Chart of video publish dates, helping identify which publishing days correlate with subscriber growth.
```

### Build a comment moderation and audience sentiment dashboard

Create a Retool comment management panel that queries the latest comments across all channel videos and displays them in a Table with video title, commenter name, comment text, and like count. Include buttons to reply to or delete selected comments directly from Retool, enabling community managers to moderate comments without opening each video individually in YouTube Studio.

Prompt example:

```
Build a Retool comment moderation panel that shows the latest 50 comments across all channel videos with video title, commenter, comment text, and likes. Include a reply text field and buttons to reply or mark for deletion.
```

## Troubleshooting

### YouTube API returns 403 Forbidden with 'quotaExceeded' error

Cause: YouTube Data API v3 has a default quota of 10,000 units per day per project. The Search endpoint costs 100 units per call, list endpoints cost 1-50 units each. A dashboard that queries search or fetches video lists frequently can exhaust the daily quota within hours.

Solution: Enable caching on all YouTube read queries (minimum 5 minutes in Retool's Advanced query settings) to prevent redundant API calls when multiple users view the dashboard. Replace Search endpoint queries with playlist-based listing where possible — list operations cost far fewer quota units. Request a quota increase in Google Cloud Console → Quotas & System Limits → YouTube Data API v3 if your use case legitimately requires more daily capacity. Check current quota consumption in Cloud Console → APIs & Services → Dashboard.

### subscriber_count field shows 0 or is missing from channel statistics

Cause: YouTube allows channels to hide their subscriber count from the public API. When a channel has hidden its subscriber count, the statistics.subscriberCount field either returns '0' or is omitted from the response entirely. This is a deliberate privacy setting by the channel owner and cannot be bypassed.

Solution: Display a '—' or 'Hidden' value in your dashboard when subscriberCount is 0 or undefined: const subscribers = parseInt(stats?.subscriberCount) || null; return subscribers ? subscribers.toLocaleString() : 'Hidden by channel'. For your own channel, you can see the actual subscriber count in YouTube Studio even if the public API hides it.

```
const subscriberCount = parseInt(channelStats.statistics?.subscriberCount);
const displayCount = subscriberCount > 0
  ? subscriberCount.toLocaleString()
  : 'Hidden';
```

### Video IDs from playlistItems query return empty statistics in the /videos endpoint

Cause: The playlistItems endpoint stores video IDs under contentDetails.videoId, not the top-level id field. Using the wrong path to extract video IDs results in passing invalid or undefined IDs to the /videos endpoint, which returns empty statistics.

Solution: In your transformer or query parameter for video IDs, use: item.contentDetails?.videoId || item.snippet?.resourceId?.videoId. The snippet.resourceId.videoId path is the more reliable fallback. Verify the correct path by logging data.items[0] in the playlistItems transformer to inspect the actual response structure.

```
// Correct video ID extraction from playlistItems
const videoIds = getVideos.data.items
  .map(item => item.contentDetails?.videoId || item.snippet?.resourceId?.videoId)
  .filter(Boolean)
  .join(',');
```

## Frequently asked questions

### Does Retool have a native YouTube API connector?

No, Retool does not include a native YouTube Data API connector. You connect via a REST API Resource configured with your YouTube API key as a URL parameter (for public data) or Google OAuth 2.0 (for private channel data). All requests proxy through Retool's server, so API credentials are not exposed to users' browsers.

### What is the difference between using an API key versus OAuth for the YouTube API in Retool?

An API key provides access only to public YouTube data — video statistics, channel info, and search results that anyone can see. OAuth 2.0 is required for accessing private data: managing your own channel's videos, replying to comments, accessing YouTube Analytics reporting data (which requires the YouTube Analytics API in addition to the Data API), and any write operations. For a read-only video performance dashboard, an API key is sufficient. For comment management or detailed analytics, OAuth is required.

### How do I handle YouTube's 10,000 quota unit daily limit in Retool?

Monitor quota usage in Google Cloud Console → APIs & Services → Dashboard → YouTube Data API v3. Design your Retool app to minimize expensive operations: cache all query results for at least 5 minutes, avoid the Search endpoint (100 units/call) for routine data, and use playlist-based video listing (1 unit/call) instead. For dashboards used by many team members simultaneously, use Retool's shared query caching so multiple users share a single cached API response rather than each triggering their own API call.

### Can I access YouTube Analytics data (views over time, traffic sources) through this integration?

YouTube Analytics time-series data (views per day, traffic sources, audience retention) is available through the separate YouTube Analytics API, not the YouTube Data API v3. To access Analytics data, enable the YouTube Analytics API in your Google Cloud project and use OAuth 2.0 authentication. Create a second Retool resource pointing to https://youtubeanalytics.googleapis.com/v2 and query the /reports endpoint with OAuth tokens for your channel. This requires channel ownership and OAuth scopes specifically for Analytics access.

### How do I track multiple YouTube channels in one Retool dashboard?

Store channel configurations in Retool Database with columns for channel name, channel ID, and a group/owner field. Add a Select component to your Retool app that loads channel options from the database, and reference the selected channel's ID in all query URL parameters as {{ channelSelect.value }}. For parallel multi-channel views, create a JavaScript query that calls multiple channel stat endpoints in parallel using Promise.all() and aggregates the results into a single Table dataset.

---

Source: https://www.rapidevelopers.com/retool-integrations/youtube-api
© RapidDev — https://www.rapidevelopers.com/retool-integrations/youtube-api
