# Integrate HasData TikTok Scraper API
## Task
Add the requested public-video discovery, account-post collection, or user-search workflow to this project using HasData TikTok Scraper API.
Inspect project instructions, the server-side runtime, existing HTTP client, and tests first.
Follow the project's conventions and preserve unrelated code. No new SDK is required.
Implement only the requested workflow. If the workflow is unclear, ask whether the user needs keyword video search, user search, account posts, or a specified combination.
Keep the integration as REST API calls; do not replace it with an MCP connection or a custom TikTok scraper.
## References
Read the endpoint documentation before implementing:
- Keyword video or user search: https://docs.hasdata.com/apis/tiktok/search.md
- Account posts: https://docs.hasdata.com/apis/tiktok/posts.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 endpoint reference. 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.
## Implementation
- For keyword discovery, use `GET https://api.hasdata.com/scrape/tiktok/search` with required `keyword`. Use the documented `type=video` or `type=user` when mode selection is needed; video is the default.
- For account videos, use `GET https://api.hasdata.com/scrape/tiktok/posts` with required `handle`, with or without `@`. Implement only the modes the user requested.
- Encode query parameters with the project HTTP client. A literal hashtag must reach the API as part of `keyword`, not as a URL fragment. Exact hashtag matching is application filtering.
- Preserve the response modes: video search uses `videos`, account retrieval uses `posts`, and user search uses `users`. Do not assume all modes have the same record shape.
- Keep account, video, and sound IDs as strings. Handle absent captions, hashtags, mentions, music, and optional media URLs.
- For requested pagination, pass the returned `pagination.nextPageToken` as `nextPageToken` for the same query and mode when `pagination.hasMore` is true. Treat tokens as opaque strings and deduplicate by record ID. Do not invent offsets or automatically fetch all pages.
- Keep plays, likes, comment counts, shares, and saves distinct. Comment counts do not include comment text. Do not label plays as unique reach or infer conversions.
- Campaign selection, engagement formulas, publication calendars, sound grouping, scheduling, and historical comparisons belong to application code. Save query context and observation times when comparing results.
- Sound titles can repeat across distinct sound IDs. Attribution and returned media URLs do not grant reuse rights; signed media URLs may expire.
- Profile and posts links on search authors are separate API requests. Do not expand them automatically. Returned pages are not guaranteed exhaustive archives or platform-wide trend measurements.
- Handle timeouts and documented errors before reading data. Keep requests server-side. If no suitable runtime exists, discuss options before changing the architecture.
## Credentials
- Implement the integration and mocked tests without requiring a live API key.
- Read `HASDATA_API_KEY` from the project's 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 the project's 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, TikTok, media links, bio links, or redirects to another origin.
## Verification
- Add mocked tests for query encoding, mode-specific response parsing, pagination context, duplicate IDs, success, empty results, missing fields, timeouts, and errors. Include a literal hashtag and a terminal page without a continuation token. Include a usage example and run local checks.
- With a configured key and explicit user approval, including approval already given for this task, make one live verification request with agreed inputs. A successful TikTok request consumes 10 credits.
- Verify one requested endpoint and mode only; cover the remaining modes with mocked tests.
- Validate the HTTP status, documented API status, and response structure. An empty result set can be valid.
- Do not automatically repeat paid requests to obtain a nonempty response or follow pagination during this check.
- Report changed files, setup commands, and test results. State separately whether live verification passed, failed, or was skipped.
- Ask before deploying.TikTok Scraper API
for account videos and keyword search
Pull TikTok videos as clean JSON from a public account or a keyword or hashtag search. Captions, hashtags, engagement counters and playable URLs come back parsed, with proxies and rendering handled for you.
of requests succeed
median response
95% finish faster
per 1k scrapes at volume
TikTok changes weekly. Your code shouldn't notice.
- Signed URLs that expire in an hour
- Signing params you re-derive after every release
- An interstitial instead of the JSON payload
- Rotating residential IPs
- Cursor formats that change without notice
One GET Request. That's the whole integration.
Start with just a query. Add more parameters when your use case needs them.
TikTok Search Scraper API
curl -G 'https://api.hasdata.com/scrape/tiktok/search' \
--data-urlencode 'keyword=dance' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json'keyword * Keywordtype Result TypenextPageToken Next Page TokenTikTok Posts Scraper API
curl -G 'https://api.hasdata.com/scrape/tiktok/posts' \
--data-urlencode 'handle=tiktok' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json'handle * TikTok HandlenextPageToken Next Page TokenAdd TikTok Scraper API with your AI agent
Paste a ready-to-use integration prompt into your coding agent. It includes API references, setup requirements, and testing instructions.
What you can build with TikTok Scraper API
Build content research, campaign reports and creator discovery tools from TikTok search results and account videos.
Find content ideas around a TikTok topic
Explore keyword search results and related hashtags to guide content briefs and topic research.
- Keyword: dance
| Creator | Hashtags |
|---|---|
| ghhmg56154466 | #dancechallenge, #dailyvibes, #danceedit, #trendingnow |
| byronbrunerie | #dance, #dancer, #dancers, #danseur, #danseurs |
| 41_huh_67 | #dance, #colorfulhair, #birthday, #fyp |
- API data
videos[].idvideos[].hashtags[]videos[].author.usernamevideos[].url- Your app
- Group returned videos by hashtag and review examples relevant to your brief within the collected search results.
Compare performance across campaign videos
Compare plays, likes, comments and shares on selected account videos to build campaign performance reports.
- @tiktok
- #songsofthesummer2026
| Video ID | Plays | Likes | Shares |
|---|---|---|---|
| 7680721699171601694 | 280,100 | 12,100 | 1,182 |
| 7680996287877008670 | 394,100 | 51,800 | 3,670 |
| 7681309378095353118 | 181,500 | 6,879 | 1,080 |
- API data
posts[].idposts[].hashtags[]posts[].playsposts[].likesposts[].commentsposts[].shares- Your app
- Select campaign posts in your application and compare their returned counters using the same observation window.
Review an account’s publishing cadence
Arrange account videos by publication time and duration to plan content calendars and review posting patterns.
- @tiktok
| Video ID | Published at (UTC) | Seconds |
|---|---|---|
| 7680721699171601694 | 2026-09-02T00:03:08.000Z | 56 |
| 7680996287877008670 | 2026-09-02T17:48:58.000Z | 59 |
| 7681309378095353118 | 2026-09-03T14:03:39.000Z | 67 |
- API data
posts[].idposts[].createTimeposts[].durationposts[].url- Your app
- Sort collected posts by timestamp, choose a display timezone and calculate publishing intervals in your application.
Compare sounds used in discovered videos
Use sound IDs, titles and author names to organize audio research across collected TikTok videos.
- Keyword: dance
| Sound ID | Title | Author |
|---|---|---|
| 7685287918411205389 | original sound | ghhmg56154466 |
| 7614989103603436310 | son original | Byron.brn |
| 7654387739047938049 | YOP | 1K NAE & ASN JAYBOOG |
- API data
videos[].idvideos[].music.idvideos[].music.titlevideos[].music.authorName- Your app
- Group videos by sound ID in your application and count occurrences within your collected dataset.
Build a creator list from relevant videos
Collect author handles from topic searches to find creators whose published content matches your research.
- Keyword: dance
| Account ID | Handle | Display name |
|---|---|---|
| 7615310982085280781 | ghhmg56154466 | ghhmg56154466 |
| 126093087860252672 | byronbrunerie | Byron.brn |
| 7277679337711944750 | 41_huh_67 | bug |
- API data
videos[].author.idvideos[].author.usernamevideos[].author.nicknamevideos[].author.hasdataLink- Your app
- Deduplicate authors by account ID; make separate profile requests only when your creator research needs more detail.
Search videos or explore an account
Explore search videos, account posts, sound attribution and engagement counts. Use returned pagination tokens to continue collecting results.
videos
From the search endpoint: keyword or hashtag results from across TikTok.
[
{
"id": "7675122879293410591",
"description": "Have you ever wondered what each shoe is made for? 🤭🏃♀️ should …",
"hashtags": [
"runner",
"running",
"runningshoes",
"marathontraining",
"runningshoesexplained"
],
"createTime": "2026-08-17T21:56:58.000Z",
"url": "https://www.tiktok.com/@saramontoyar/video/7675122879293410591",
"duration": 36,
"ratio": "720p",
"coverUrl": "https://p16-common-sign.tiktokcdn-us.com/tos-useast8-p-0068-tx2/…",
"playUrl": "https://v16-webapp-prime.us.tiktok.com/video/tos/useast8/tos-use…",
"downloadUrl": "https://v16-webapp-prime.us.tiktok.com/video/tos/useast5/tos-use…",
"author": {
"id": "7330816931056845866",
"username": "saramontoyar",
"nickname": "Sara🏃♀️Runner&Gym Girl",
"hasdataLink": "https://api.hasdata.com/scrape/tiktok/profile?handle=saramontoya…",
"hasdataPostsLink": "https://api.hasdata.com/scrape/tiktok/posts?handle=saramontoyar"
},
"music": {
"id": "7128257885397583874",
"title": "Naughty Girl",
"authorName": "Beyoncé",
"playUrl": "https://sf19.tiktokcdn-us.com/obj/tos-alisg-ve-2774/cbe9585cb0eb…"
},
"likes": 495,
"comments": 31,
"shares": 36,
"plays": 10600,
"collects": 137,
"reposts": 0
}
]id stringVideo id, the number after /video/ in the URL
description stringCaption text as posted, absent when the video has no caption
hashtags string[]Tags parsed out of the caption, without the #. Absent when the caption has none
mentions string[]@-mentions parsed from the caption, present when the caption has one
createTime stringUpload time, ISO 8601
url stringVideo URL
duration numberLength in seconds
ratio / width / height string, numberQuality label as TikTok reports it, such as 720p, with the pixel size. The label is missing on some videos
coverUrl / dynamicCoverUrl stringStill and animated thumbnails
playUrl / downloadUrl stringPlayable and downloadable video URLs, when TikTok exposes them for that video
author objectid, username and nickname, plus verified when the account carries the badge
music objectid and title always, plus authorName, original and playUrl when TikTok returns them
likes / comments / shares numberEngagement counters
plays / collects / reposts numberViews and saves. reposts is present but comes back 0
author.hasdataLink / hasdataPostsLink stringReady-made calls for that account's profile and its videos. Search results only
posts
From the posts endpoint: one page of a single account's uploads, by handle.
[
{
"id": "7654752160051121422",
"description": "AJ Dybantsa drafted 1st overall by the @Washington Wizards 🏀 #NB…",
"hashtags": [
"nbadraft",
"nba",
"basketball",
"ajdybantsa",
"washingtonwizards"
],
"mentions": [
"wash_wizards"
],
"createTime": "2026-06-24T00:28:10.000Z",
"url": "https://www.tiktok.com/@nba/video/7654752160051121422",
"duration": 28,
"ratio": "720p",
"coverUrl": "https://p16-common-sign.tiktokcdn-us.com/tos-useast5-p-0068-tx/o…",
"playUrl": "https://v16-webapp-prime.us.tiktok.com/video/tos/useast5/tos-use…",
"downloadUrl": "https://v16-webapp-prime.us.tiktok.com/video/tos/useast5/tos-use…",
"author": {
"id": "134941634731003904",
"username": "nba",
"nickname": "NBA",
"verified": true
},
"music": {
"id": "7654752185711856397",
"title": "original sound",
"authorName": "NBA",
"original": true,
"playUrl": "https://v16m.tiktokcdn-us.com/33a5dfa5673cabb81bc3323620df2ac9/6…"
},
"likes": 682400,
"comments": 2826,
"shares": 21000,
"plays": 5600000,
"collects": 29467,
"reposts": 0
}
]id stringVideo id, the number after /video/ in the URL
description stringCaption text as posted
hashtags string[]Tags parsed out of the caption, without the #
mentions string[]@-mentions parsed from the caption, present when the caption has one
createTime stringUpload time, ISO 8601
url stringVideo URL
duration numberLength in seconds
ratio / width / height string, numberQuality label as TikTok reports it, e.g. 720p, and the pixel size
coverUrl / dynamicCoverUrl stringStill and animated thumbnails
playUrl / downloadUrl stringPlayable and downloadable video URLs, when TikTok exposes them for that video
author objectid, username and nickname, plus verified when the account carries the badge
music objectid, title, authorName, original, playUrl
likes / comments / shares numberEngagement counters
plays / collects / reposts numberViews and saves. reposts is present but comes back 0
pagination
{
"count": 33,
"hasMore": true,
"nextPageToken": "1786839505673"
}count numberItems in this page
hasMore booleanWhether another page exists
nextPageToken stringPass it back to get the next page
users
From the search endpoint with type=user: accounts instead of videos.
[
{
"id": "7664638705177150477",
"username": "nasa",
"nickname": "NASA",
"signature": "Making the seemingly impossible, possible.✨",
"verified": true,
"followers": 993200,
"avatarUrl": "https://p16-common-sign.tiktokcdn.com/tos-maliva-avt-0068/e51432…",
"hasdataLink": "https://api.hasdata.com/scrape/tiktok/profile?handle=nasa",
"hasdataPostsLink": "https://api.hasdata.com/scrape/tiktok/posts?handle=nasa"
}
]username stringHandle, as in the profile URL
id / secUid stringNumeric and opaque account ids
nickname stringDisplay name
signature stringBio text, absent when the account left it empty. Named signature here, biography in the Profile API
verified booleanVerified badge, present only on verified accounts
followers numberFollower count
avatarUrl stringAvatar CDN URL
hasdataLink / hasdataPostsLink stringReady-made calls for this account's profile and videos
The hard parts already happened
JS rendering, signed URL refresh and residential proxy rotation run on our side. Your code sends one GET and reads fields.
Discover similar
scrapers and APIs
to expand your projects.
TikTok Profile Scraper API
Social Media Intelligence • $0.83 / 1k Request
Instagram Posts Scraper API
Social Media Intelligence • $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. TikTok'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
Per successful request. The number of videos that come back does not change the price, and a failed request costs nothing.
Yes. The free plan renews 1,000 credits every month, covering up to 100 scrapes. No credit card required.
With monthly billing, paid plans start at $59 per month for up to 20,000 scrapes and scale to 2,000,000 scrapes a month. The unit price drops with volume, from $2.95 down to $0.83 per 1,000 scrapes.
Account videos take a handle and return that account's uploads. Search takes a keyword and returns matching videos from across TikTok.
Yes. Set type to user and the response comes back in a users array instead of videos, with the handle, nickname, bio, avatar, verified flag and follower count. The bio is named signature there, while the Profile API calls it biography, so map that one field when you switch between them.
Yes. Pass the tag as the keyword and search returns videos relevant to it. Percent-encode the hash as %23 if your client does not do it for you, otherwise the tag is read as a URL fragment and never reaches the API. When a caption carries tags, the video comes back with a hashtags array, so exact-match filtering happens in your code.
When pagination.hasMore is true, pass pagination.nextPageToken into the next request with the same query and mode. Use the returned token as a string, and deduplicate results by ID.
No. Requests run on HasData infrastructure against publicly available data, so there is nothing to apply for and no OAuth flow to wire up.
Nothing on your side. We track the changes and keep the response schema stable. Field names and types stay put, and an optional field is simply absent from a video that has no value for it, so read those with a default.
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