# Integrate HasData YouTube API
## Task
Implement only the YouTube workflow the user requests: transcripts, video metadata, channel content, or keyword search.
If no workflow is specified, ask which one before implementing. Add other endpoints only when the requested workflow needs them.
Inspect project instructions, the server-side runtime, existing HTTP client, and tests first.
Follow project conventions and preserve unrelated code. No new SDK is required.
Use the REST API; do not substitute an MCP connection or a custom scraper.
## References
Read the documentation for each endpoint needed by the requested workflow:
- Transcript: https://docs.hasdata.com/apis/youtube/transcript.md
- Video: https://docs.hasdata.com/apis/youtube/video.md
- Channel: https://docs.hasdata.com/apis/youtube/channel.md
- Search: https://docs.hasdata.com/apis/youtube/search.md
- Error handling: https://docs.hasdata.com/api-codes.md
- Documentation index: https://docs.hasdata.com/llms.txt
- Full documentation (fallback): https://docs.hasdata.com/llms-full.txt
Start with the relevant endpoint references. Use `llms.txt` to find additional pages.
Use `llms-full.txt` only when needed; extract relevant sections instead of loading everything into context.
If a `.md` reference is unavailable, try its HTML URL without `.md`.
If it is still unavailable, ask for the missing documentation rather than guessing.
## Optional agent skill
If the official `hasdata` skill is already available, use its relevant guidance.
Otherwise, if this agent supports skills, ask before installing it in this project:
```sh
npx skills add hasdata/agent-skills --skill hasdata
```
Run from the project directory and select the coding agent in use.
The `hasdata-cli` skill is not required. If installation is declined or unsupported, continue with the docs.
Flag conflicts between skill guidance and current API docs rather than guessing.
## Endpoint selection
All four endpoints use GET under `https://api.hasdata.com/scrape/youtube/`.
- Transcript: `transcript`, required `v` (11-character video ID), optional `languageCode` and `type=asr`. Choose an available caption track; preserve the exact returned language code. Omission of `languageCode` selects the default track. Use `type=asr` for an auto-generated track; omit it for a human-authored track when one exists. Captions and requested languages are not guaranteed.
- Video: `video`, required `v`, optional `gl`, `hl`, `deviceType`.
- Channel: `channel`, required `channelId` (canonical ID or @handle), optional `tab`, `gl`, `hl`, `deviceType`, `paginationToken`. The default `featured` tab returns Home-page content; other tabs have different shapes. Use only the requested tab.
- Search: `search`, required `q`, optional `gl`, `hl`, `deviceType`, `sortBy`, `date`, `videoType`, `length`, `filters[]`, `paginationToken`. Read current allowed values. `videoType` supports video, shorts, channel, playlist, and movie. A supplied raw `sp` token overrides structured sort and filter parameters.
## Implementation
- Encode query parameters correctly and preserve the returned JSON.
- For transcripts, retain `transcript[].snippet`, `startMs`, `endMs`, and `startTimeText`. Offsets are milliseconds; convert explicitly when generating video links. Preserve `availableTranscripts`, including optional track `type`.
- For video metadata, `description` is an object with `content` and `links`. Use numeric `extractedViews` and `extractedLikes` for calculations while retaining display strings.
- For channel Home content, preserve `channelInfo`, `featuredVideo`, and `sections` when present. Numeric subscriber and video counts can originate from rounded display labels.
- For search, preserve distinct result blocks. `shortsResults[].shorts[]` contains Shorts within shelves; result types are optional. `videoResults[].views` is numeric, and `positionOnPage` belongs to the returned page. Search views are video views, not keyword search volume.
- Follow returned pagination only within a user-requested page limit. Do not silently crawl entire channels or result sets.
- Treat missing optional fields as unknown. Do not infer comment text, audience demographics, unique viewers, revenue, or transcript translations.
- Handle timeouts, documented errors, unavailable videos, missing caption tracks, empty results, and missing optional blocks.
- Keep requests server-side. If no suitable runtime exists, discuss options before changing architecture.
## Credentials
- Implement the integration and mocked tests without requiring a live API key.
- Read `HASDATA_API_KEY` from the existing environment or secret store and send it as `x-api-key`.
- If the key is missing before live verification, ask the user to configure it from https://app.hasdata.com/api-keys.
- Never ask the user to paste the key into chat. Check only that it is configured, without printing its value.
- Never put the key in browser code, logs, or version control. Add only a placeholder to example configuration.
- If using a local `.env` file, make sure it is gitignored.
- Send the key only to `https://api.hasdata.com`. Never forward it to documentation, result URLs, or redirects to another origin.
## Verification
- Add mocked tests for the selected workflow: success, unavailable or empty data, missing optional blocks, and errors. Check endpoint-specific shapes, timestamp units, and pagination limits where relevant.
- Include a usage example and run local checks.
- Only with user authorization and a configured key, make one live verification request for the selected workflow and agreed input. Successful requests consume credits.
- Validate HTTP status, documented API status, and response structure. Empty results can be valid.
- Do not automatically repeat paid requests to obtain nonempty results or test every endpoint.
- Report changed files, setup commands, and test results. State separately whether live verification passed, failed, or was skipped.
- Ask before deploying.YouTube Scraper API
for transcripts, video, and channel data
Pull YouTube transcripts, video metadata, channel stats, and search results as clean JSON. One request returns a timestamped transcript when captions are available, ready to feed a model, with proxies handled for you.
of requests succeed
median response
95% finish faster
per 1k scrapes at volume
YouTube keeps moving its data client-side. Your parser shouldn't care.
- Transcripts behind rotating player tokens
- Metadata rendered by client-side JS
- View and like counts in mixed shapes
- Proxy rotation and retries per request
- Re-parse the player after each change
One GET Request. That's the whole integration.
Start with just a query. Add more parameters when your use case needs them.
YouTube Transcript Scraper API
curl -G 'https://api.hasdata.com/scrape/youtube/transcript' \
--data-urlencode 'v=dQw4w9WgXcQ' \
--data-urlencode 'languageCode=en' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json'v * Video IDlanguageCode Language Codetype Transcript TypeYouTube Video Scraper API
curl -G 'https://api.hasdata.com/scrape/youtube/video' \
--data-urlencode 'v=dQw4w9WgXcQ' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json'v * Video IDgl Countryhl LanguagedeviceType DeviceYouTube Channel Scraper API
curl -G 'https://api.hasdata.com/scrape/youtube/channel' \
--data-urlencode 'channelId=@PewDiePie' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json'channelId * Channel IDtab Tabgl Countryhl LanguagedeviceType DevicepaginationToken Pagination TokenYouTube Search Scraper API
curl -G 'https://api.hasdata.com/scrape/youtube/search' \
--data-urlencode 'q=BMW' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json'q * Search Querygl Countryhl LanguagedeviceType Devicesp Search ParameterssortBy Sort Bydate Upload DatevideoType Typelength Durationfilters[] FeaturespaginationToken Pagination TokenAdd YouTube Scraper API with your AI agent
Get a reusable YouTube integration that fits your project, with secure credentials, API references, and tests.
Build with YouTube Scraper API
Build transcript search, video analytics, channel catalogs, and content research tools with structured YouTube data.
Make video transcripts searchable
Build video search and AI knowledge bases from subtitle text, with timestamps that link each match to its source.
- Query: no strangers
- dQw4w9WgXcQ
- English captions
| Matching caption | Start (ms) | End (ms) |
|---|---|---|
| We're no strangers to | 18800 | 21800 |
- API data
transcript[].snippettranscript[].startMstranscript[].endMs- Your app
- Index caption snippets with video IDs and millisecond offsets; generate source links in your application.
Match videos to available caption languages
Build multilingual video libraries around available subtitle tracks, so viewers can find content in their preferred language.
- dQw4w9WgXcQ
- Available caption tracks
| Language | Code |
|---|---|
| English | en |
| German (Germany) | de-DE |
| Portuguese (Brazil) | pt-BR |
- API data
availableTranscripts[].languageNameavailableTranscripts[].languageCode- Your app
- Match returned language codes to viewer preferences and retain track types when multiple tracks share a language.
Track public video performance
Build YouTube analytics dashboards from video views, likes, and duration to compare content performance across saved observations.
- dQw4w9WgXcQ
- September 17, 2026
| Metric | Returned value |
|---|---|
| Views | 1,816,277,496 |
| Likes | 19,394,194 |
| Duration (seconds) | 214 |
- API data
videoIdextractedViewsextractedLikeslengthSeconds- Your app
- Store dated video metrics and calculate changes between observations in your dashboard.
Build a channel video library
Organize channel videos by content shelf to build creator research tools and searchable video catalogs.
- @PewDiePie
- Home tab
| Shelf | Video | Duration |
|---|---|---|
| Videos | Earthquake by Mount Fuji | 32:16 |
| Videos | Meet our newest family member | 24:04 |
- API data
channelInfo.handlesections[]sections[].items[].videoIdsections[].items[].titlesections[].items[].duration- Your app
- Group shelf items by channel and deduplicate video IDs across shelves in your catalog.
Research videos for target keywords
Build topic research tools from YouTube video titles, view counts, and search positions for your chosen keywords.
- BMW
- Search results
| Position on page | Video | Views |
|---|---|---|
| 1 | BELI BMW M2 BARU, HANDOVERNYA DI LUAR DUGAAN | 665,639 |
| 2 | BMW 3 MILIAR INI NYAMANNYA MIRIP ROLLS-ROYCE | 476,042 |
- API data
videoResults[].positionOnPagevideoResults[].titlevideoResults[].viewsvideoResults[].videoId- Your app
- Save query-specific video results and compare titles and page positions across dated searches.
Monitor Shorts around your topics
Build Shorts discovery feeds from keyword searches, with video links and public view counts for short-form content research.
- BMW
- Shorts shelf
| Short ID | Displayed views | Numeric views |
|---|---|---|
| d4WRwrd4Gh8 | 27M views | 27,000,000 |
| QVnYg9Wxwks | 1.5M views | 1,500,000 |
- API data
shortsResults[].shorts[].videoIdshortsResults[].shorts[].linkshortsResults[].shorts[].viewsshortsResults[].shorts[].isNew- Your app
- Collect Shorts by video ID and compare their returned view counts across saved searches.
Timestamped transcript, one predictable schema
Explore timestamped transcripts, video and channel details, recommendations, Shorts and search results from their respective endpoints.
transcript
[
{
"startMs": 320,
"endMs": 18800,
"snippet": "[Music]",
"startTimeText": "0:00"
},
{
"startMs": 18800,
"endMs": 21880,
"snippet": "We're no strangers to love",
"startTimeText": "0:18"
}
]startMs / endMs numberStart and end of the line in milliseconds
snippet stringThe caption text for this segment
startTimeText stringHuman-readable start time, e.g. 0:18
availableTranscripts
Which caption languages exist for the video. Pass a languageCode to pick one.
[
{ "languageName": "English", "languageCode": "en" },
{ "languageName": "Spanish", "languageCode": "es" }
]languageName stringDisplay name of the caption track
languageCode stringCode to request that track, e.g. en
video
The video endpoint: metadata, engagement, music, and related videos for one video.
{
"videoId": "dQw4w9WgXcQ",
"title": "Rick Astley - Never Gonna Give You Up (Official Video)",
"channel": { "name": "Rick Astley", "channelId": "UCuAXFkgsw1L7xaCfnd5JJOw", "extractedSubscribers": 4520000 },
"extractedViews": 1797400025,
"extractedLikes": 19281206,
"publishedDate": "Oct 24, 2009",
"lengthSeconds": 214,
"category": "Music",
"keywords": ["rick astley", "never gonna give you up"],
"music": [ { "song": "Never Gonna Give You Up", "artist": "Rick Astley", "album": "Whenever You Need Somebody" } ]
}videoId / title stringVideo ID and title
channel objectUploader name, ID, and subscriber count
extractedViews / extractedLikes numberView and like counts as numbers
lengthSeconds / category number / stringDuration in seconds and category
keywords string[]Tags on the video
music object[]Songs YouTube detected, with artist and album
channel
The channel endpoint: profile, featured video, and content shelves.
{
"channelInfo": {
"channelId": "UCuAXFkgsw1L7xaCfnd5JJOw",
"name": "Rick Astley",
"handle": "@RickAstleyYT",
"description": "Official YouTube channel..."
},
"featuredVideo": { "videoId": "wvr7-pDJUOA", "title": "Keep Singing (Live at The O2)", "views": 23541 },
"sections": [
{ "title": "Popular uploads", "items": [ { "videoId": "dQw4w9WgXcQ", "title": "Never Gonna Give You Up", "views": 1797400025 } ] }
]
}channelInfo objectID, name, handle, and description
featuredVideo objectThe channel's pinned video
sections[] object[]Shelves of videos, each with a title and items
Search results
A BMW search returns videoResults and adsResults; this excerpt shows one record from each.
{
"videoResults": [
{
"positionOnPage": 1,
"videoId": "xyxBs_QDHV4",
"title": "Bayerische Motoren Werke | BMW Editar | BMW M4 G82",
"views": 3358470,
"length": "0:12"
}
],
"adsResults": [
{
"positionOnPage": 0,
"title": "Cotiza hoy tu Audi A3",
"advertiser": "Audi Chile",
"description": "Aprovecha el precio increíble de Audi A3 y disfruta de su rendimiento de hasta 19,6 km/l."
}
]
}videoResults[].videoId stringYouTube video identifier to pass to a video or transcript request.
videoResults[].title stringTitle of a matching video.
videoResults[].views numberNumeric view count returned in the search result.
videoResults[].length stringVideo duration displayed in the result, such as 0:12.
adsResults[].advertiser stringAdvertiser name reported for the promoted result.
adsResults[].description stringPromotional description shown with the ad.
Shorts discovery
Shorts from the BMW search appear inside a shortsResults shelf, separate from ordinary videoResults.
{
"shortsResults": [
{
"positionOnPage": 2,
"title": "Shorts",
"shorts": [
{
"videoId": "nkVFGe0rdjo",
"title": "Even BMW Would Want This 🥶🔥 #bmw",
"link": "https://www.youtube.com/shorts/nkVFGe0rdjo",
"views": 11000000,
"isNew": false
},
{
"videoId": "QVnYg9Wxwks",
"title": "Crush with BMW! #bmw #automobile #car #luxury #billionaire #shorts #trending #edit #mha #love",
"link": "https://www.youtube.com/shorts/QVnYg9Wxwks",
"views": 666000,
"isNew": true
}
]
}
]
}shortsResults[].positionOnPage numberPosition of the Shorts shelf within the search response.
shortsResults[].title stringShelf heading grouping the short videos.
shortsResults[].shorts[].videoId stringYouTube identifier of a Short inside the shelf.
shortsResults[].shorts[].title stringTitle of the returned Short.
shortsResults[].shorts[].link stringSource URL for opening the Short.
shortsResults[].shorts[].views numberNumeric view count reported for the Short.
shortsResults[].shorts[].isNew booleanNew-content indicator returned with the Short.
Find matching channels
The same BMW search includes a verified channel result with its handle and subscriber count.
{
"channelResults": [
{
"channelId": "UCYwrS5QvBY_JbSdbINLey6Q",
"title": "BMW",
"handle": "@BMW",
"link": "https://www.youtube.com/@BMW",
"verified": true,
"subscribers": 2050000
}
]
}channelResults[].channelId stringChannel identifier for matching or requesting the full channel.
channelResults[].title stringChannel display name in the search result.
channelResults[].handle stringPublic channel handle, including the @ prefix.
channelResults[].link stringYouTube channel URL returned in search.
channelResults[].verified booleanVerification indicator reported for this channel result.
channelResults[].subscribers numberSubscriber count returned with the channel result.
An all-in-one scraping service
Every feature you need to collect data from thousands to millions of requests.
Discover similar
scrapers and APIs
to expand your projects.
TikTok Scraper API
Videos Data • $0.83 / 1k Request
Google Short Videos API
Short Video Results • $0.83 / 1k Request
Fits right into your stack.
Works with the tools you already use.
View Documentation ->Teams that deleted their scraper
Now it's the part of the pipeline they don't think about
HasData delivers exactly what we need: speed and comprehensive search features. It's the fastest API we've used in this space. Plus, their customer support is fantastic.
We rely on HasData for search performance data and broader scraping needs. Their APIs deliver highly structured data that integrates directly into our platforms.
Great web scraping API which is incredibly easy to use. It requires minimal effort to get up and running, and the documentation is very clear and helpful.
I needed to scrape some information they didn't already support, and they wrote the code for me right away, which was super nice of them.
We were particularly impressed with how easily we could integrate HasData into our existing workflow.
Plans that get cheaper at scale
Fixed price, fixed volume, no surprises at the end of the month. Upgrade when you need more.
Free
Startup
Basic
RecommendedGrowth
Monthly scrape volume
Custom price based on required volume
Past 20M credits a month, or terms the self-serve plans do not cover. We shape the contract around your workload. Past 20M credits a month, or need terms the self-serve plans do not cover? We shape the contract, concurrency, and support around your workload.
HasData accesses publicly available data only. YouTube's terms may restrict automated access; you are responsible for compliance. Where data includes personal information, ensure a lawful basis under GDPR/CCPA.
Questions, answered
Four things, each its own endpoint: a video's timestamped transcript, full video metadata (title, views, likes, comment count), channel stats (subscribers, video count), and search results for a query. Same JSON style across all of them.
Available caption tracks appear in availableTranscripts. Pass a returned languageCode to select a language, or omit it for the default track. Set type=asr to request an auto-generated track; omit type for a human-authored track when available.
Yes. Each line is a flat object with the text and its start and end times, so you can drop it straight into a summarizer or join the snippets into one string.
Per successful request. One request is one scrape, a transcript, a video, a channel, or a search page. A failed request costs nothing.
Yes. The free plan renews 1,000 credits every month, covering up to 100 scrapes. No credit card required. When you outgrow it, pick a plan that fits your volume.
Requests start from 10 credits. With monthly billing, the unit price drops with volume, from $2.95 down to $0.83 per 1,000 requests. Need more than the top plan covers? We'll set a custom rate.
No. Requests run on HasData's infrastructure, so there's nothing to provision or maintain. You're responsible for using the results in line with each target site's terms and applicable law.
Your first scrape
is minutes away
100 scrapes free · no credit card