# InsightSocial: everything in one file > InsightSocial gives you public social media data two ways: a free Chrome extension that exports posts, comments, profiles and followers from 6 social platforms, and reviews from sites like Trustpilot and Google Maps, to Excel, and a developer API and hosted MCP server with public data from 22 platforms on one key. Index of every page: https://www.insightsocial.app/llms.txt. Each section below is also served on its own at its page URL plus .md. ## Key facts - Platforms: the Chrome extension scrapes 6 social platforms (TikTok, LinkedIn, Twitter/X, YouTube, Reddit and Pinterest) and the reviews or comments on 10 review and discussion sites (Trustpilot, Amazon, Steam, Product Hunt, Etsy, Google Maps, Hacker News, Quora, Blind and Notion); the developer API serves 22 (see Developer API below). - How it works: a Chrome extension (Manifest V3, Chrome 114+) collects data from pages you are already signed in to. Rows sync to your own account and are exported from the web portal. - Export formats: Google Sheets, CSV, Excel (.xlsx) and JSON, on every plan. Exporting happens in the web portal, not in the extension. - Pricing: Free is $0 forever with 500 credits per month (1 credit = 1 exported row). Pro is $9.99/month, or $7.99/month billed yearly ($95.88/year), with 10,000 credits per month. Studio is $49/month: everything in Pro with 150,000 exported rows per month (API calls stay on Pro's 10,000). A one-time pack of 2,500 credits costs $8 and never expires. - What is metered: one credit balance, spent two ways. Exports cost 1 credit per row (re-exporting a row you already paid for is free), and developer API calls cost a published per-endpoint price in credits (metered endpoints charge within a published range). Scraping with the extension and reading results in the dashboard are unlimited on every plan. - Data history: 30 days on Free, 3 years on Pro. - Pro-only features: Ask your data (chat with your scraped results) and contact enrichment. - Background runs: a run keeps going when you switch to another tab or app, on every social platform. A few pages still need their tab in front (X search and hashtags, some LinkedIn single posts, Google Maps reviews), and the side panel says so before you start. - Scheduled scrapes: on every plan. They fire from Chrome itself (Chrome alarms), so they need Chrome running; nothing runs while the browser is closed, and a turn missed by more than an hour is skipped. - YouTube: comments and replies on videos and Shorts, and the video lists of a channel (Videos or Shorts tab), a search or your home feed. - Developer API: yes, since September 2026. REST over HTTPS at https://api.insightsocial.app/v1, authenticated with an x-api-key header, covering 22 platforms: the extension's 6 plus Bluesky, Truth Social, Snapchat, Telegram, Twitch, Kick, Rumble, Kwai, Douyin, Xiaohongshu (RedNote), Quora, TikTok Shop, Weibo, Zhihu, Substack and Nextdoor (profiles, posts, comments, followers, search). Priced per endpoint in credits from the same balance as exports; the first 10 qualifying calls are free, and failed or empty calls cost nothing. The endpoint catalogue at https://api.insightsocial.app/v1/endpoints is public and needs no key. Overview: https://www.insightsocial.app/social-media-api. Docs for agents: https://www.insightsocial.app/docs/llms.txt - Developer tools: a hosted MCP server at https://api.insightsocial.app/mcp (Streamable HTTP; Claude, ChatGPT and other clients sign in with OAuth, others send the API key as a Bearer token), and an official local MCP server and CLI in one npm package, `insightsocial` (`npx -y insightsocial init` signs in through the browser and sets up the key, the agent skill and the MCP config; `npx -y insightsocial mcp` runs the stdio server), listed in the MCP Registry as app.insightsocial/insightsocial. Agent skills: `npx skills add insightsocial/skills`, also a Claude Code plugin and a Gemini CLI extension. An n8n community node, `n8n-nodes-insightsocial`. An OpenAPI 3.1 spec at https://api.insightsocial.app/v1/openapi.json. All open source at https://github.com/insightsocial. Setup: https://www.insightsocial.app/docs/mcp - Not available: a language SDK (Python, Node), a Zapier or Make integration, or a Firefox or Safari build. In the Chrome extension specifically: private messages; LinkedIn search, hashtag and group pages; TikTok's For You feed; Pinterest profiles, boards and single pins (Pinterest works from search results); bulk lists of URLs in one run. - Review and discussion sites: the same extension reads the reviews or comments on the one page you have open on Trustpilot, Amazon, Steam, Product Hunt, Etsy, Google Maps, Hacker News, Quora, Blind and Notion, one page per run, with star ratings, verified flags, the business's replies and reply nesting where the site has them. Very large pages stop at a row or time limit. Chrome asks for access to each of these sites the first time you use it. Rows sync to your account and export from the dashboard like every other platform. Overview: https://www.insightsocial.app/scraper/reviews - Free tools without an account: TikTok Comment Exporter, Website & Link-in-Bio Email Finder and Hacker News Thread Exporter. See https://www.insightsocial.app/tools - Canonical domain: insightsocial.app. The older insightsocial.xyz redirects here. - Markdown: every scraper, comparison, use-case and blog page has a Markdown copy at its own URL plus .md (for example https://www.insightsocial.app/scraper/reviews.md), and the page URL answers Accept: text/markdown with it. ## Free tools - [TikTok Comment Exporter](https://www.insightsocial.app/tools/tiktok-comment-exporter): Paste a TikTok video link and get its comments as a table and a CSV: username, comment, likes, replies and date. Free, no sign-up. - [Website & Link-in-Bio Email Finder](https://www.insightsocial.app/tools/website-email-finder): Paste a website, Linktree or other link-in-bio page and see the emails, phone numbers and LinkedIn pages it publishes. Free, no sign-up. - [Hacker News Thread Exporter](https://www.insightsocial.app/tools/hacker-news-thread-exporter): Paste a Hacker News link and download every comment in the thread as a CSV: author, text, depth, parent and time. Runs in your browser. Free, no sign-up. --- # Social Media and Review Scrapers Source: https://www.insightsocial.app/scraper, updated 2026-10-23 > Every scraper in the InsightSocial Chrome extension, grouped by platform, one page each. ## TikTok Hub: https://www.insightsocial.app/scraper/tiktok.md - [TikTok Profile Scraper](https://www.insightsocial.app/scraper/tiktok-profile-scraper.md): Export a TikTok creator's videos with follower count, total likes and bio on every row, or a list of creators from search, to Excel or CSV. Free extension. - [TikTok Video Scraper](https://www.insightsocial.app/scraper/tiktok-video-scraper.md): Free TikTok Video Scraper. Extract views, likes, comments, shares, captions, and hashtags from any TikTok video. Export to CSV, Excel, JSON. - [TikTok Comments Scraper](https://www.insightsocial.app/scraper/tiktok-comments-scraper.md): Free TikTok Comments Scraper. Extract comments, replies, and reactions from any TikTok video. Analyze audience sentiment. Export to CSV, Excel, JSON. - [TikTok Analytics Scraper](https://www.insightsocial.app/scraper/tiktok-analytics-scraper.md): Free TikTok analytics scraper Chrome extension. Export view, like, comment and share counts per video from any profile, hashtag or search, plus follower and total-like counts per creator. No API key, no coding. - [TikTok Followers Scraper](https://www.insightsocial.app/scraper/tiktok-followers-scraper.md): Export a TikTok account's followers or following list to Excel or CSV. TikTok shows visitors about 30 accounts per list; each comes with bio and counts. - [TikTok Hashtag Scraper](https://www.insightsocial.app/scraper/tiktok-hashtag-scraper.md): Free TikTok hashtag scraper Chrome extension. Export the videos under any hashtag with views, likes, comments, shares, bookmarks, captions, hashtags, sounds and creator stats to CSV, Excel or JSON. No API key. - [TikTok Search Scraper](https://www.insightsocial.app/scraper/tiktok-search-scraper.md): Free TikTok search scraper Chrome extension. Export keyword search results as videos (views, likes, captions, creators) or as user accounts (bio, followers, total likes, verified) to CSV, Excel or JSON. No API key. ## LinkedIn Hub: https://www.insightsocial.app/scraper/linkedin.md - [LinkedIn Profile Scraper](https://www.insightsocial.app/scraper/linkedin-profile-scraper.md): Save the LinkedIn profile you have open as one row in Excel or CSV: name, headline, location, current company, school, followers and connections. Free extension. - [LinkedIn Posts Scraper](https://www.insightsocial.app/scraper/linkedin-posts-scraper.md): Export LinkedIn posts from a profile, company page or your feed to Excel or CSV: text, date, reactions by type, comments, and author name and headline. - [LinkedIn Company Scraper](https://www.insightsocial.app/scraper/linkedin-company-scraper.md): Free LinkedIn company posts scraper. Export a company page's posts with text, date, reactions by type, comments, reposts, media and post URL to CSV or Excel. - [LinkedIn Post Likers Scraper](https://www.insightsocial.app/scraper/linkedin-post-likers-scraper.md): Export the people who reacted to a LinkedIn post to Excel or CSV: name, headline, profile link, connection degree and reaction type. Free Chrome extension. - [LinkedIn Comments Scraper](https://www.insightsocial.app/scraper/linkedin-comments-scraper.md): Export the comments and replies on a LinkedIn post to Excel or CSV: text, date, likes, replies, and each commenter's name, headline and profile link. Free. ## Twitter/X Hub: https://www.insightsocial.app/scraper/twitter.md - [Twitter Profile Scraper](https://www.insightsocial.app/scraper/twitter-profile-scraper.md): Export an X (Twitter) profile's posts, followers or following to Excel or CSV. Likes, reposts, views per post; bio and counts per follower. Free extension. - [Twitter Posts Scraper](https://www.insightsocial.app/scraper/twitter-posts-scraper.md): Export tweets from any X profile, list or your home feed to Excel or CSV: text, date, likes, reposts, replies, views and media. Free Chrome extension. - [Twitter Followers Scraper](https://www.insightsocial.app/scraper/twitter-followers-scraper.md): Export an X account's followers or following to Excel or CSV, with bio, location, website, follower counts and join date per account. Free extension. - [Twitter Likes Scraper](https://www.insightsocial.app/scraper/twitter-likes-scraper.md): Free Twitter/X Likes Scraper. Export the posts you've liked (text, author, media and engagement) to Excel, CSV or JSON. Back up your likes before they disappear. No API required. - [Twitter Search Scraper](https://www.insightsocial.app/scraper/twitter-search-scraper.md): Free Twitter search scraper for Chrome. Export the tweets from any X keyword search, advanced search or hashtag page to CSV, Excel or JSON: text, author, likes, reposts, replies, views, bookmarks and media. No API key. - [Twitter Replies Scraper](https://www.insightsocial.app/scraper/twitter-replies-scraper.md): Free Twitter replies scraper for Chrome. Export the replies to any tweet on X to CSV, Excel or JSON: reply text, author handle, likes, reposts, views, timestamps and parent reply IDs. Works as a Twitter comment scraper. No API key. ## YouTube Hub: https://www.insightsocial.app/scraper/youtube.md - [YouTube Comments Scraper](https://www.insightsocial.app/scraper/youtube-comments-scraper.md): Export a YouTube video's comments and replies to Excel, CSV or Google Sheets. Free Chrome extension, no API key or Python. Likes, authors, dates, links. - [YouTube Shorts Comments Scraper](https://www.insightsocial.app/scraper/youtube-shorts-comments-scraper.md): Export the comments on any YouTube Short, replies included, to Excel, CSV or Google Sheets. Free Chrome extension, no API key, no Python. - [YouTube Channel Scraper](https://www.insightsocial.app/scraper/youtube-channel-scraper.md): List the videos or Shorts on a YouTube channel in Excel, CSV or Google Sheets: title, link, views, upload date, duration. Free, no API key. - [YouTube Search Scraper](https://www.insightsocial.app/scraper/youtube-search-scraper.md): Export YouTube search results to Excel, CSV or Google Sheets in YouTube's ranking order: title, channel, views, date, duration. Free, no API key. ## Reddit Hub: https://www.insightsocial.app/scraper/reddit.md - [Reddit Comment Scraper](https://www.insightsocial.app/scraper/reddit-comments-scraper.md): Export every comment and reply from a Reddit thread to Excel, CSV or Google Sheets, nested replies kept. Free Chrome extension, no Reddit API key. - [Reddit Search Results Scraper](https://www.insightsocial.app/scraper/reddit-post-scraper.md): Export Reddit search results to Excel, CSV or Google Sheets: up to 250 posts per search, with their comments if you want. Free Chrome extension. - [Reddit Subreddit Scraper](https://www.insightsocial.app/scraper/reddit-subreddit-scraper.md): Export up to 1,000 posts from any subreddit to Excel, CSV or Google Sheets, with every comment if you want. Hot, New, Top. Free Chrome extension. ## Pinterest Hub: https://www.insightsocial.app/scraper/pinterest.md - [Pinterest Profile Scraper](https://www.insightsocial.app/scraper/pinterest-profile-scraper.md): Turn a Pinterest search into a list of accounts with website, followers, monthly views and business email. Excel, CSV or Sheets. Free Chrome extension. - [Pinterest Pin Scraper](https://www.insightsocial.app/scraper/pinterest-pin-scraper.md): Export the pins a Pinterest search returns to Excel, CSV or Google Sheets: title, link, domain, board, pinner and reactions. Free Chrome extension. ## Review and discussion sites Hub: https://www.insightsocial.app/scraper/reviews.md - [Trustpilot Review Scraper](https://www.insightsocial.app/scraper/trustpilot-review-scraper.md): Export any company's Trustpilot reviews to Excel, CSV or Google Sheets: stars, title, text, country, date and company replies. 500 rows a month free. - [Google Maps Review Scraper](https://www.insightsocial.app/scraper/google-maps-review-scraper.md): Export a place's Google reviews to Excel, CSV or Google Sheets, newest first: stars, full text, date, likes and owner replies. 500 rows a month free. - [Amazon Review Scraper](https://www.insightsocial.app/scraper/amazon-review-scraper.md): Download an Amazon product's reviews to CSV, Excel or Google Sheets: stars, headline, text, date, verified purchase and variant. 500 rows a month free. - [Etsy Review Scraper](https://www.insightsocial.app/scraper/etsy-review-scraper.md): Export an Etsy listing's or a whole shop's reviews to CSV, Excel or Google Sheets: stars, text, date, item and seller replies. 500 rows a month free. - [Steam Review Scraper](https://www.insightsocial.app/scraper/steam-review-scraper.md): Export a Steam game's reviews to Excel, CSV or Google Sheets, newest first: recommended or not, text, playtime, language and votes. 500 rows free. - [Product Hunt Scraper](https://www.insightsocial.app/scraper/product-hunt-scraper.md): Free Chrome extension: export a Product Hunt product's reviews or a launch's comment thread to Excel, CSV or Google Sheets. 500 rows a month free. - [Hacker News Comment Scraper](https://www.insightsocial.app/scraper/hacker-news-comment-scraper.md): Export every comment and reply in a Hacker News thread to Excel, CSV, JSON or Google Sheets, with depth and parent. Free extension, 500 rows a month. - [Quora Scraper](https://www.insightsocial.app/scraper/quora-scraper.md): Export every answer to a Quora question, with the comments under each, to Excel, CSV or Google Sheets: author, credential, upvotes. 500 rows free. - [Blind Scraper](https://www.insightsocial.app/scraper/blind-scraper.md): Export the comments on a Blind (teamblind.com) post to Excel, CSV or Google Sheets: text, company, likes, date and replies. 500 rows a month free. - [Notion Database Export](https://www.insightsocial.app/scraper/notion-database-export.md): Export a public Notion database you can only view to CSV, Excel or Google Sheets: one row per entry, each property a column. 500 rows a month free. - [Reddit User Comments Scraper](https://www.insightsocial.app/scraper/reddit-user-comments-scraper.md): Export a Reddit user's comments to Excel, CSV or Google Sheets: text, score, date, subreddit and post. Newest first, 500 rows free. --- # Review and Discussion Site Scrapers Source: https://www.insightsocial.app/scraper/reviews, updated 2026-10-23 > Export the reviews and comments on the page you are viewing, from Trustpilot, Amazon, Steam, Product Hunt, Etsy, Google Maps, Hacker News, Quora, Blind and Notion, to CSV, Excel, JSON or Google Sheets. The InsightSocial Chrome extension reads the reviews or comments on the one page you have open on Trustpilot, Amazon, Steam, Product Hunt, Etsy, Google Maps, Hacker News, Quora, Blind and Notion, and exports them from your dashboard to CSV, Excel, JSON or Google Sheets like every other platform it scrapes. ## How it works 1. Open a page with reviews or comments: a company, a place, a product, a game or a thread. The side panel names what it found there. 2. The first time you use a site, Chrome asks you to let InsightSocial read that one site. Then click Scrape. 3. Rows sync to your dashboard as they come in. Filter them there and export. ## Sites | Site | What you get | Page | | --- | --- | --- | | Trustpilot | Export any company's Trustpilot reviews to Excel, CSV or Google Sheets: stars, title, text, country, date and company replies. 500 rows a month free. | https://www.insightsocial.app/scraper/trustpilot-review-scraper.md | | Amazon | Download an Amazon product's reviews to CSV, Excel or Google Sheets: stars, headline, text, date, verified purchase and variant. 500 rows a month free. | https://www.insightsocial.app/scraper/amazon-review-scraper.md | | Steam | Export a Steam game's reviews to Excel, CSV or Google Sheets, newest first: recommended or not, text, playtime, language and votes. 500 rows free. | https://www.insightsocial.app/scraper/steam-review-scraper.md | | Product Hunt | Free Chrome extension: export a Product Hunt product's reviews or a launch's comment thread to Excel, CSV or Google Sheets. 500 rows a month free. | https://www.insightsocial.app/scraper/product-hunt-scraper.md | | Etsy | Export an Etsy listing's or a whole shop's reviews to CSV, Excel or Google Sheets: stars, text, date, item and seller replies. 500 rows a month free. | https://www.insightsocial.app/scraper/etsy-review-scraper.md | | Google Maps | Export a place's Google reviews to Excel, CSV or Google Sheets, newest first: stars, full text, date, likes and owner replies. 500 rows a month free. | https://www.insightsocial.app/scraper/google-maps-review-scraper.md | | Hacker News | Export every comment and reply in a Hacker News thread to Excel, CSV, JSON or Google Sheets, with depth and parent. Free extension, 500 rows a month. | https://www.insightsocial.app/scraper/hacker-news-comment-scraper.md | | Quora | Export every answer to a Quora question, with the comments under each, to Excel, CSV or Google Sheets: author, credential, upvotes. 500 rows free. | https://www.insightsocial.app/scraper/quora-scraper.md | | Blind | Export the comments on a Blind (teamblind.com) post to Excel, CSV or Google Sheets: text, company, likes, date and replies. 500 rows a month free. | https://www.insightsocial.app/scraper/blind-scraper.md | | Notion | Export a public Notion database you can only view to CSV, Excel or Google Sheets: one row per entry, each property a column. 500 rows a month free. | https://www.insightsocial.app/scraper/notion-database-export.md | ## Also in the same release - [Reddit User Comments Scraper](https://www.insightsocial.app/scraper/reddit-user-comments-scraper.md): Export a Reddit user's comments to Excel, CSV or Google Sheets: text, score, date, subreddit and post. Newest first, 500 rows free. ## What people use it for - **Read your competitors’ customers** (Trustpilot): Export a rival’s Trustpilot page and sort by one and two stars. Their customers’ complaints are your sales pitch. Guide: https://www.insightsocial.app/blog/how-to-export-trustpilot-reviews - **Compare local businesses** (Google Maps): Pull the reviews of every place you compete with, and see what customers keep mentioning and who answers them. Guide: https://www.insightsocial.app/blog/how-to-export-google-reviews - **Find what a best seller gets wrong** (Amazon): Download a product’s reviews, keep the verified purchases, and list what buyers wish were different before you build yours. Guide: https://www.insightsocial.app/blog/how-to-download-amazon-reviews - **Hear players in every language** (Steam): Every review comes with the reviewer’s playtime, so first-hour complaints and veteran feedback sit in separate piles. Guide: https://www.insightsocial.app/blog/how-to-export-steam-reviews - **Learn from someone else’s launch** (Product Hunt): Export a launch’s whole comment thread and read the questions people asked first: they are the ones your page must answer. Guide: https://www.insightsocial.app/blog/how-to-export-product-hunt-reviews - **Research a market in its own words** (Quora): Every answer to a question, with the comments under each, in one sheet you can tag by theme. Guide: https://www.insightsocial.app/blog/how-to-export-quora-answers ## Guides - [Export Trustpilot reviews to CSV or Excel](https://www.insightsocial.app/blog/how-to-export-trustpilot-reviews) - [Export Google reviews to Excel or Google Sheets](https://www.insightsocial.app/blog/how-to-export-google-reviews) - [Download Amazon reviews to Excel or CSV](https://www.insightsocial.app/blog/how-to-download-amazon-reviews) - [Export Etsy shop reviews to a spreadsheet](https://www.insightsocial.app/blog/how-to-export-etsy-reviews) - [Export Steam reviews to CSV or Excel](https://www.insightsocial.app/blog/how-to-export-steam-reviews) - [Export Product Hunt reviews and launch comments](https://www.insightsocial.app/blog/how-to-export-product-hunt-reviews) - [Download every comment from a Hacker News thread](https://www.insightsocial.app/blog/how-to-export-hacker-news-comments) - [Export Quora answers to a spreadsheet](https://www.insightsocial.app/blog/how-to-export-quora-answers) - [Best free review scraper Chrome extensions](https://www.insightsocial.app/blog/best-free-review-scraper-chrome-extensions) - [Best Trustpilot review scrapers](https://www.insightsocial.app/blog/best-trustpilot-review-scrapers) - [Best Google Maps review scrapers](https://www.insightsocial.app/blog/best-google-maps-review-scrapers) - [Best Amazon review scrapers](https://www.insightsocial.app/blog/best-amazon-review-scrapers) ## What each row keeps - Replies keep their depth and parent, so a question and its answer stay together. - A business's, seller's or developer's reply to a review is its own row, labelled as an owner reply. - Stars, votes and helpful counts sit in separate columns. - Dates stay as the site wrote them where it gives no exact time. ## Limits - One page per run: the thread, product, place or company you have open. There is no bulk list of URLs. - Very large pages stop at a row or time limit, and the side panel says where it stopped. Everything collected up to then is kept. - It reads what the site shows you. Google Maps needs you signed in, and Amazon shows signed-out visitors only a few reviews, so sign in there first. - It only reads. It never posts, rates, votes or replies. ## What it costs Scraping and reading results in the dashboard are unlimited on every plan. Only exporting uses credits, one per exported row: the free plan includes 500 a month, and Pro includes 10,000 a month for $9.99/month, or $7.99/month billed yearly. A row you already exported is free to export again. --- # TikTok Profile Scraper Source: https://www.insightsocial.app/scraper/tiktok-profile-scraper, updated 2026-10-18 > Export a TikTok creator's videos with follower count, total likes and bio on every row, or a list of creators from search, to Excel or CSV. Free extension. - **Platform**: tiktok - **Web version**: https://www.insightsocial.app/scraper/tiktok-profile-scraper --- InsightSocial's TikTok Profile Scraper is a free Chrome extension that exports TikTok creator data to Excel, CSV, JSON or Google Sheets. Open a creator's @profile to export their videos, each row carrying the creator's follower count, total likes, bio and verified badge, or search a keyword to export a list of matching creators. It runs in your own browser: no TikTok API key. ## At a glance - **Works on**: A creator's profile and TikTok user search - **On a profile**: Their videos, Latest or Popular, with views, likes, comments, shares, saves, caption and sound, plus the creator's followers, total likes and bio on every row - **From a search**: One row per creator with handle, name, bio, followers, total likes, verified badge and search rank - **Per run**: 50, 100 or 250 - **Export to**: Excel, CSV, JSON, Google Sheets or a share link - **While it runs**: Keeps going in a background tab - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. On TikTok, that icon is how you open it. 3. **Open the page, click Scrape**: Go to the creator's @profile and pick Videos, or search a keyword and pick Users. Choose 50, 100 or 250 and click Scrape. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. Every run stays in your account to re-open later. ## Which TikTok scraper to use This page covers one creator's data from their profile, and lists of creators from search. The other TikTok pages are the same extension aimed at one job: | You want | Open this on TikTok | Use | |---|---|---| | One creator's videos, with their follower count, total likes and bio | Their `tiktok.com/@handle` page | This scraper (Videos) | | A list of creators for a keyword | A search, then the Users option | This scraper, or the [TikTok Search Scraper](/scraper/tiktok-search-scraper) | | Who follows a creator, or who they follow | Their profile, then Followers or Following | [TikTok Followers Scraper](/scraper/tiktok-followers-scraper) | | The videos under a hashtag | `tiktok.com/tag/...` | [TikTok Hashtag Scraper](/scraper/tiktok-hashtag-scraper) | | The comments under one video | The video itself | [TikTok Comments Scraper](/scraper/tiktok-comments-scraper) | ## What a profile run gives you TikTok has no "profile card" export of its own. What a profile page does give is the creator's videos, and every video row carries the creator's details: - **The creator:** handle, display name, bio, follower count, total likes and verified badge, repeated on each row so any single row answers "who is this". - **Each video:** link, caption, hashtags, sound, duration, post date, and views, likes, comments, shares and saves. TikTok doesn't send a following count or a video count with these rows, so neither is in the file. To see who a creator follows, pick Following on their profile; TikTok shows visitors about 30 accounts from that list. ## Getting the data you want **One creator's recent output.** Open their profile, pick *Videos*, sort by *Latest* and choose 50. That is enough to see posting rhythm and typical views. **One creator's best videos.** Sort by *Popular* instead. The run follows TikTok's own Popular tab for that profile. **Many creators in a niche.** Search the niche keyword on TikTok, pick *Users*, and choose 50, 100 or 250. Each row is one creator with bio, followers, total likes, verified badge and their rank for the keyword. If a creator wrote an email in their bio, it lands in its own Emails column. **Comparing creators.** Run each profile in turn. The columns are the same every time, so the files stack into one sheet. ## Working with the file - **Engagement rate per video.** *(Likes + Comments + Shares) / Views* compares videos of different reach. Divide average views by *Creator Followers* to see how much of the audience a creator actually reaches. - **Growth.** Run the same profile again a week or a month later. The change in *Creator Followers* and *Creator Likes* between the two files is the growth. - **Duplicates.** Running the same profile twice returns overlapping videos. Remove duplicates on the video ID. Exporting a row you already exported costs nothing. For a longer walkthrough, see [How to Scrape TikTok Profiles](/blog/how-to-scrape-tiktok-profiles). --- ## FAQ ### Can I get one TikTok account's details for free? Yes. Open the profile, pick Videos and run 50. Every row carries the creator's follower count, total likes, bio and verified badge, and exporting is free up to 500 rows a month. TikTok doesn't show a following count or video count in this view, so those two aren't in the file. ### Can I export many creators at once? Yes. Search a keyword on TikTok, open InsightSocial and pick Users. Each matching creator becomes a row with handle, name, bio, followers, total likes, verified badge and their rank in the results. The TikTok Search Scraper page covers this in detail. ### Does it find a creator's email? Only if the creator wrote it in their bio. In a Users export from search it lands in its own Emails column; in a profile's videos export, read it in the Creator Bio column. ### What is the best TikTok profile scraper? It depends on how you work. Developers who want an API or scheduled cloud jobs usually pick a hosted scraping platform, billed per result. If you want creator data in a spreadsheet without code, InsightSocial is a free Chrome extension that exports a creator's videos with their stats, or a list of creators from search, to Excel, CSV, JSON or Google Sheets from your own browser. Scraping is free and unlimited; only exports are metered: 500 rows a month free, or 10,000 rows a month on Pro for $9.99 a month. ### How many rows can I get per run? Pick 50, 100 or 250 per run. TikTok decides when a profile or search runs out, so a run on a creator with few videos returns fewer. ### Can I scrape any TikTok creator? Any public account. Private accounts show their videos only to approved followers, and the extension sees only what your browser sees. ### Does it keep running if I switch tabs? Yes. TikTok runs keep going in a background tab. Don't close the tab until the run finishes. ### Can I track a creator's growth over time? Run the same profile again later and compare the two exports: the Creator Followers and Creator Likes columns show the change. ### Does it download the video files? No. It exports each video's link and data, not the video file. ## Related scrapers - [TikTok Search Scraper](https://www.insightsocial.app/scraper/tiktok-search-scraper.md): Free TikTok search scraper Chrome extension. Export keyword search results as videos (views, likes, captions, creators) or as user accounts (bio, followers, total likes, verified) to CSV, Excel or JSON. No API key. - [TikTok Followers Scraper](https://www.insightsocial.app/scraper/tiktok-followers-scraper.md): Export a TikTok account's followers or following list to Excel or CSV. TikTok shows visitors about 30 accounts per list; each comes with bio and counts. - [TikTok Hashtag Scraper](https://www.insightsocial.app/scraper/tiktok-hashtag-scraper.md): Free TikTok hashtag scraper Chrome extension. Export the videos under any hashtag with views, likes, comments, shares, bookmarks, captions, hashtags, sounds and creator stats to CSV, Excel or JSON. No API key. - [TikTok Video Scraper](https://www.insightsocial.app/scraper/tiktok-video-scraper.md): Free TikTok Video Scraper. Extract views, likes, comments, shares, captions, and hashtags from any TikTok video. Export to CSV, Excel, JSON. --- # TikTok Video Scraper Source: https://www.insightsocial.app/scraper/tiktok-video-scraper, updated 2026-07-04 > Free TikTok Video Scraper. Extract views, likes, comments, shares, captions, and hashtags from any TikTok video. Export to CSV, Excel, JSON. - **Platform**: tiktok - **Web version**: https://www.insightsocial.app/scraper/tiktok-video-scraper --- ## What is the TikTok Video Scraper? The InsightSocial TikTok Video Scraper is a free Chrome extension that exports video-level data from TikTok: views, likes, comments, shares, captions, hashtags, music, post date, and duration, straight to CSV, Excel, or JSON. No TikTok API, no developer tokens, no scripts to maintain. It works by reading what your own browser session already sees. You browse TikTok the way you normally would (a hashtag feed, a keyword search, or a specific creator's videos), open the InsightSocial sidebar, and the extension captures the video data TikTok is already serving to your screen. Because it only reads what's rendered to you, it never bypasses TikTok's privacy rules and never talks to TikTok on your behalf. The point is turning an endless scroll into a structured dataset. Twenty minutes of watching a hashtag feed tells you a vague story; the same feed exported to a spreadsheet lets you sort by views, compute engagement rates, and count which sounds and hashtags actually correlate with reach. That's the foundation of any serious [TikTok competitor analysis](/blog/tiktok-competitor-analysis-guide). ### Who is it for? - **Content strategists** researching viral video patterns and content trends before planning a calendar - **Social media managers** tracking content performance across competitor accounts - **Marketers** identifying trending formats and topics worth building campaigns around - **Brands** monitoring competitor video strategies with real numbers instead of impressions - **Creators** studying successful content in their niche for format and hook inspiration - **Analysts** gathering raw data for trend reports and performance analysis ### Key Benefits - **Complete video data**: views, likes, comments, shares, caption, post date, and duration per video, in one pass - **Hashtag extraction**: every hashtag used in each video is captured as structured data, ready for frequency analysis - **Music identification**: see which sounds appear in high-performing videos, one of the strongest trend signals on TikTok - **Bulk extraction**: collect many videos in a single session instead of copying metrics one video at a time - **Privacy first**: the scrape runs inside your own browser session; collected data is private to your account - **Analysis-ready exports**: structured CSV, Excel, or JSON that drops straight into Sheets, pivot tables, or Python --- ## How to Use the TikTok Video Scraper ### Step 1: Install the Extension Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. ### Step 2: Navigate to Videos on TikTok Go to a TikTok page that lists the videos you care about: a hashtag feed (`tiktok.com/tag/yourniche`), a keyword search, or a specific creator's content. ### Step 3: Open the InsightSocial Sidebar Click the InsightSocial icon. The sidebar opens on the right and automatically detects the TikTok page type, showing which scrape options apply. ### Step 4: Configure Your Scrape Choose 50, 100 or 250 videos and confirm the scrape type. Larger pulls are better for trend analysis; smaller ones for a quick read on what's working right now. ### Step 5: Start Scraping Click "Scrape". The extension scrolls the feed for you and videos appear in the live preview with creator, caption, and engagement counts as they're collected. ### Step 6: Export Your Data Click "Export" and pick CSV, .xlsx, or JSON. Every session also syncs to your private [InsightSocial portal](/portal), where you can re-open and re-export past scrapes. --- ## Frequently Asked Questions ### What data comes with each video? - Video URL and direct link - Caption / description text - Creator username and display name - Views, likes, comments, shares and saves - Music / sound used - Hashtags (as a structured list) - Post date and video duration ### How do I find what makes videos go viral in my niche? Scrape a large batch of videos from your niche's hashtags or search results, export to Excel, and sort by views. Then look at the outliers: What hooks do their captions use? What duration band do they cluster in? Which sounds repeat? Patterns that are invisible while scrolling become obvious in a sorted spreadsheet. ### Can I analyze trending sounds with this? Yes. That's one of the most common workflows. The music field is captured for every video, so a pivot table on sound name against average views shows which audio is genuinely carrying reach versus which is just popular by volume. ### Does it download the actual video files? No. The scraper extracts metadata: links, engagement counts, captions, music, hashtags, not media files. You get the video URLs, which you can open or process with other tools if you need the content itself. ### How many videos can I collect, and what does it cost? Pick 50, 100 or 250 videos per run. Scraping is free and unlimited on every plan. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99 a month, or $7.99 a month billed yearly. Studio: 150,000 rows a month for $49 a month. One-time packs start at $2 for 250 rows. A single session on a busy hashtag can produce a dataset large enough for a full trend report. ### Are the view counts exact? Yes. Views, likes, comments, shares and saves come as whole numbers from TikTok's own data, as they stood when you ran the scrape. Run it again later for fresh numbers. ### What about the conversations under the videos? Video metrics tell you what performed; comments tell you why. Pair this tool with the [TikTok Comments Scraper](/scraper/tiktok-comments-scraper) to pull the full comment threads from your top-performing finds, or browse all TikTok tools on the [TikTok scraper hub](/scraper/tiktok). --- ## Data Fields | Field | Type | Description | |-------|------|-------------| | Video URL | url | Direct link to video | | Description | text | Video caption/description | | Author Username | text | Creator's @handle | | Author Name | text | Creator's display name | | Views | number | View count | | Likes | number | Like count | | Comments | number | Comment count | | Shares | number | Share count | | Music | text | Sound/music used | | Hashtags | array | Tags used in video | | Post Date | date | When video was posted | | Duration | text | Video length | ## Features - Extract video metadata from hashtags, search, and profiles - Capture engagement metrics (views, likes, comments, shares) - Get hashtags and music information - Bulk extract multiple videos at once - Export to multiple formats - Track viral content and trends ## How to Use 1. **Install InsightSocial**: Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Open a TikTok Page**: Navigate to a hashtag page, search results, a creator's profile, or a single video you want to analyze. 3. **Open the Extension**: Click the InsightSocial icon to open the sidebar panel. 4. **Configure and Extract**: Pick 50, 100 or 250 videos, then click Scrape. 5. **Review in Real-time**: Watch as video data appears in the preview panel with metrics. 6. **Export Your Data**: Download to CSV, Excel, or JSON for analysis in your preferred tools. ## FAQ ### What video data can I extract? Video URL, cover image, caption, views, likes, comments, shares, saves, hashtags, sound, post date, duration, and the creator's handle, name, bio, follower count and total likes. ### Can I extract videos from hashtag pages? Yes. Hashtag pages, search results, and creator profiles are all supported. Open the page, set a video count, and start scraping. ### How do I identify trending sounds? The 'Music' field in exported data shows what sounds are used. Sort by views to see which sounds correlate with viral content. ### Can I download the actual video files? InsightSocial extracts video metadata and URLs, not the files. You can use the URLs with other tools if needed. ### Are the numbers exact? Yes. Views, likes, comments, shares and saves come as whole numbers from TikTok's own data, as they stood when you ran the scrape. Run it again later for fresh numbers. ### How many videos can I extract at once? 50, 100 or 250 per run, and TikTok decides when a feed runs out. Scraping is free and unlimited on every plan; credits go only on the rows you export, one each: the free plan includes 500 exported rows a month, and Pro includes 10,000 for $9.99 a month ($7.99 a month billed yearly). ## Related scrapers - [TikTok Profile Scraper](https://www.insightsocial.app/scraper/tiktok-profile-scraper.md): Export a TikTok creator's videos with follower count, total likes and bio on every row, or a list of creators from search, to Excel or CSV. Free extension. - [TikTok Comments Scraper](https://www.insightsocial.app/scraper/tiktok-comments-scraper.md): Free TikTok Comments Scraper. Extract comments, replies, and reactions from any TikTok video. Analyze audience sentiment. Export to CSV, Excel, JSON. - [TikTok Analytics Scraper](https://www.insightsocial.app/scraper/tiktok-analytics-scraper.md): Free TikTok analytics scraper Chrome extension. Export view, like, comment and share counts per video from any profile, hashtag or search, plus follower and total-like counts per creator. No API key, no coding. --- # TikTok Comments Scraper Source: https://www.insightsocial.app/scraper/tiktok-comments-scraper, updated 2026-07-04 > Free TikTok Comments Scraper. Extract comments, replies, and reactions from any TikTok video. Analyze audience sentiment. Export to CSV, Excel, JSON. - **Platform**: tiktok - **Web version**: https://www.insightsocial.app/scraper/tiktok-comments-scraper --- ## What is the TikTok Comments Scraper? The InsightSocial TikTok Comments Scraper is a free Chrome extension that exports the comments under any TikTok video (comment text, commenter username and profile link, likes per comment, reply counts, timestamps, and thread structure) straight to CSV, Excel, or JSON. No TikTok API, no coding, no copy-pasting comment by comment. It works by reading what your own browser session already sees. You open a TikTok video, start the scrape from the InsightSocial sidebar, and the extension scrolls through the comment section for you, capturing each comment and its replies as TikTok loads them. Because it only collects what's rendered in your own browser, it never bypasses TikTok's privacy rules or accesses anything your session couldn't see anyway. Comments are the most underused dataset on TikTok. View counts tell you a video performed; the comment section tells you *why*: what people loved, what confused them, what questions keep repeating, and how they talk about a brand in their own words. Exported as structured data, that's raw material for sentiment analysis, FAQ mining, and voice-of-customer research. ### Who is it for? - **Brand managers** monitoring audience sentiment and brand perception under relevant videos - **Researchers** analyzing online discussions and social dynamics with real conversation data - **Marketers** mining customer feedback and reactions for messaging and product insight - **Community managers** tracking engagement patterns and the topics audiences keep raising - **Content creators** learning from audience reactions to sharpen their next videos - **PR teams** monitoring public opinion and brand mentions during campaigns or incidents ### Key Benefits - **Full comment threads**: top-level comments and nested replies, with the thread structure preserved - **Commenter profiles**: public profile links for everyone engaging, so you can see who is driving the conversation - **Per-comment engagement**: likes on each comment surface the reactions the audience itself endorsed - **Sentiment-analysis ready**: structured, emoji-preserving exports that feed directly into NLP tools - **Time-stamped data**: comment dates let you map how a conversation evolved after posting - **Private by design**: the scrape runs in your own browser session and your collected data is visible only to your account --- ## How to Use the TikTok Comments Scraper ### Step 1: Install the Extension Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. ### Step 2: Find a TikTok Video Navigate to the video whose comments you want to analyze: a viral post in your niche, a competitor's launch video, or a video mentioning your brand. Comment sections on high-engagement videos yield the richest data. ### Step 3: Open the Video and the Sidebar Open the video so its comment panel is visible, then click the InsightSocial icon. The sidebar detects you're on a single TikTok video and offers the comment scrape. ### Step 4: Configure Your Scrape Choose 50, 100 or 250 top-level comments; the replies to them come along on top. For sentiment work, more is better: a bigger sample smooths out the noise from joke comments and spam. ### Step 5: Start Scraping Click "Scrape". The extension scrolls the comment section automatically, expanding threads as it goes, and comments appear in the live preview as they're collected. ### Step 6: Export for Analysis Click "Export" and choose CSV (spreadsheet filtering), .xlsx (Excel), or JSON (Python / NLP pipelines). Sessions also sync to your private [InsightSocial portal](/portal) for later re-export. --- ## Frequently Asked Questions ### What data comes with each comment? - Full comment text (emojis preserved) - Commenter username, display name, and public profile link - Likes on the comment - Reply count, and whether the comment is itself a reply - Comment date - The parent video's URL ### How do I run sentiment analysis on the export? Export to CSV and feed it to any NLP workflow: a spreadsheet with keyword filters for a quick pass, a dedicated sentiment tool, or a Python script with a library like VADER or a transformer model for anything rigorous. Because emojis are preserved and each row carries likes and timestamps, you can weight sentiment by how much the audience endorsed each comment. ### Can I scrape comments from multiple videos? Yes: run one session per video. Each export includes the parent video URL, so you can concatenate several exports into one dataset and still attribute every comment to its source. This is how teams build comment corpora across a whole campaign or a competitor's recent posts. ### Do I get commenters' emails or private info? No. Only what's publicly visible in the comment section is collected: the comment, public profile link, and engagement counts. No emails, phone numbers, or private account data. The tool never reaches beyond what your own session can see. ### How many sessions do I get? Pick 50, 100 or 250 top-level comments per run; replies to those comments come along on top. Scraping is free and unlimited on every plan. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99 a month, or $7.99 a month billed yearly. Studio: 150,000 rows a month for $49 a month. One-time packs start at $2 for 250 rows. ### How do I choose which videos are worth scraping? Start from the numbers. Use the [TikTok Video Scraper](/scraper/tiktok-video-scraper) to pull a batch of videos from a hashtag, search, or competitor, sort by comment count, and scrape the comment sections of the outliers. Our [TikTok competitor analysis guide](/blog/tiktok-competitor-analysis-guide) walks through this two-step workflow in detail. ### Is scraping TikTok comments ethical? Comments are public statements, and collecting them for research, sentiment analysis, or brand monitoring is a widely accepted practice. Respect TikTok's Terms of Service and privacy laws like GDPR and CCPA, anonymize commenter identities in anything you publish, and never use the data to target or harass individuals. Comparing comment-export tools? See the [best ExportComments alternatives](/blog/exportcomments-alternatives) for bulk comment export without per-link caps. --- ## Data Fields | Field | Type | Description | |-------|------|-------------| | Comment Text | text | Comment content | | Author Username | text | Commenter's @handle | | Author Name | text | Commenter's display name | | Author Profile | url | Link to commenter's profile | | Likes | number | Likes on the comment | | Reply Count | number | Number of replies | | Comment Date | date | When commented | | Video URL | url | Parent video link | | Is Reply | text | Whether it's a reply to another comment | ## Features - Export the comments under any TikTok video, with their replies - Capture nested replies and threads - Get commenter profile information - Analyze audience sentiment - Export for further analysis - Track engagement patterns ## How to Use 1. **Install InsightSocial**: Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Find a TikTok Video**: Navigate to any TikTok video with comments you want to analyze. 3. **Open the Video**: Click on the video to open it in the viewer where comments are displayed. 4. **Start Extraction**: Open InsightSocial, pick 50, 100 or 250 comments and click Scrape. Replies to those comments come along on top. 5. **Monitor Progress**: Watch comments appear in real-time preview as they're collected. 6. **Export for Analysis**: Download to CSV, Excel, or JSON for sentiment analysis or further processing. ## FAQ ### Does it capture reply threads? Yes, InsightSocial extracts both top-level comments and nested replies, preserving the thread structure. ### Can I find every comment one user left on TikTok? Not across TikTok. The scraper works one video at a time. Export a video's comments, then filter the commenter handle column for that user. ### Can I filter comments by keyword? Export to CSV/Excel and use spreadsheet filters to search for specific terms or patterns. ### How many comments can I extract? Pick 50, 100 or 250 top-level comments per run; the replies to those comments come along on top, so a 250 run on a busy video returns more than 250 rows. Scraping is free and unlimited; you only spend credits on the rows you export, one each. ### Is commenter contact info included? Only public profile links are extracted. No private data like emails is collected. ### Can I use this for sentiment analysis? Yes. Export to CSV or Excel for a spreadsheet or a sentiment tool, or JSON for Python NLP libraries. Emojis are kept in the comment text. ### How does it handle emoji reactions? Comment text including emojis is preserved in the export for full sentiment context. ### Is there a free way without installing? Yes, for one video: paste its link into InsightSocial's free TikTok Comment Exporter tool. ## Related scrapers - [TikTok Video Scraper](https://www.insightsocial.app/scraper/tiktok-video-scraper.md): Free TikTok Video Scraper. Extract views, likes, comments, shares, captions, and hashtags from any TikTok video. Export to CSV, Excel, JSON. - [TikTok Profile Scraper](https://www.insightsocial.app/scraper/tiktok-profile-scraper.md): Export a TikTok creator's videos with follower count, total likes and bio on every row, or a list of creators from search, to Excel or CSV. Free extension. - [YouTube Shorts Comments Scraper](https://www.insightsocial.app/scraper/youtube-shorts-comments-scraper.md): Export the comments on any YouTube Short, replies included, to Excel, CSV or Google Sheets. Free Chrome extension, no API key, no Python. --- # TikTok Analytics Scraper Source: https://www.insightsocial.app/scraper/tiktok-analytics-scraper, updated 2026-07-04 > Free TikTok analytics scraper Chrome extension. Export view, like, comment and share counts per video from any profile, hashtag or search, plus follower and total-like counts per creator. No API key, no coding. - **Platform**: tiktok - **Web version**: https://www.insightsocial.app/scraper/tiktok-analytics-scraper --- ## What is the TikTok Analytics Scraper? The InsightSocial TikTok Analytics Scraper is a free Chrome extension that turns any public TikTok account into an analytics dataset: per-video performance (views, likes, comments, shares, saves) with the creator's follower count and total likes on every row, exported to CSV, Excel, or JSON. TikTok's native analytics only covers accounts you own; this covers any account you can see. It works by reading what your own browser session already sees on TikTok. You browse to the account or content you want to analyze, run a scrape from the InsightSocial sidebar, and the extension collects the publicly displayed numbers into one structured export. It never uses TikTok's API, never asks for credentials, and never bypasses privacy rules: private accounts stay out of reach. The difference from eyeballing a profile is that structured data compounds. One export gives you engagement rates and top-performing content for an account. Repeated exports give you growth curves. Exports across several accounts give you a competitor benchmark. That's the workflow our [TikTok competitor analysis guide](/blog/tiktok-competitor-analysis-guide) is built on. ### Who is it for? - **Marketing teams** creating competitor reports backed by real numbers instead of screenshots - **Agencies** building client dashboards and recurring performance reports - **Brands** vetting influencer performance before committing to partnerships - **Analysts** researching TikTok trends and platform dynamics at dataset scale - **Creators** benchmarking their own performance against accounts in the same niche - **Investors** evaluating creator growth potential and audience quality with hard data ### Key Benefits - **Profile + video data in one export**: account-level metrics and per-video performance land in the same structured file - **Engagement-rate ready**: every row carries views, likes, comments, and shares, so rate formulas drop straight in - **Trend identification**: sort and pivot to surface top-performing videos, dominant hashtags, and recurring sounds - **Report-ready exports**: CSV and Excel formats that go straight into pivot tables, charts, and client decks - **Multi-account comparison**: scrape competitors with identical field structure, then compare side-by-side - **Historical tracking**: repeat exports on a schedule to build a growth database TikTok never gives you for other accounts --- ## How to Use the TikTok Analytics Scraper ### Step 1: Install the Extension Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. ### Step 2: Navigate to Your Target Account Open the TikTok account you want to analyze: a competitor, a candidate influencer, or a benchmark creator in your niche. ### Step 3: Open the InsightSocial Sidebar Click the InsightSocial icon. The sidebar opens and automatically detects the TikTok page, showing the scrape options that apply. ### Step 4: Configure a Full Extraction For analytics, more history is better: choose a high video count so your averages and top-content rankings rest on a meaningful sample rather than the last week of posts. ### Step 5: Start Scraping Click "Scrape" and watch the live preview fill with videos and their metrics. The extension scrolls the page for you until it reaches your target count. ### Step 6: Export and Build Your Report Export to .xlsx and build pivot tables for engagement rate, average views, posting frequency, and hashtag performance, or export CSV/JSON into Looker Studio, Tableau, or a notebook. Every session also syncs to your private [InsightSocial portal](/portal) for re-export later. --- ## Frequently Asked Questions ### What analytics can I actually derive from the export? The export carries per-video performance (views, likes, comments, shares, saves, posting dates) and, on every row, the creator's follower count and total likes. Nothing is computed for you. From those raw fields you can derive the metrics that matter: engagement rate, average views per video, posting frequency, like-to-view ratio, top hashtags, best-performing videos, and music trends. The raw counts come from TikTok; the ratios are one spreadsheet formula away. ### Which engagement metrics matter most on TikTok? Engagement rate, (likes + comments + shares) / views, is the standard, because it controls for reach. Beyond that: comments-per-view signals conversation-worthy content, shares-per-view signals content people stake their identity on, and the spread between median and top-video views tells you whether an account grows on consistency or on occasional viral hits. ### How is this different from TikTok's built-in analytics? TikTok Analytics only exists for accounts you own and shows private data like watch time and demographics. This scraper works on **any public account** using publicly displayed metrics, which is exactly what you need for competitor benchmarking and influencer vetting, where you'll never get dashboard access. ### How do I build a competitor benchmark? Scrape each competitor account in its own session, then combine the exports in one spreadsheet: the field structure is identical, so rows align. Normalize by follower count where relevant (engagement rate rather than raw likes), and compare accounts of similar size for a fair read. The [TikTok Profile Scraper](/scraper/tiktok-profile-scraper) fills in the account-level context for the same handles. ### How do I track growth over time? Public TikTok shows current totals, not history, so you build the history yourself. Re-scrape the same accounts weekly or monthly, date each export, and chart the deltas: follower growth, posting cadence, and whether engagement rate holds as the account scales. After a few cycles you have a longitudinal dataset nobody else in your niche has. ### How much data can I pull, and what does it cost? Pick 50, 100 or 250 videos per run. Scraping is free and unlimited on every plan. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99 a month, or $7.99 a month billed yearly. Studio: 150,000 rows a month for $49 a month. One-time packs start at $2 for 250 rows. Tracking five competitors weekly is about 20 scrapes a month, all free to run; what you spend depends on how many rows you export. ### Can I add audience-level insight to the numbers? Yes. Quantitative metrics tell you what performed; the comment sections tell you how the audience actually responded. Pair this tool with the [TikTok Comments Scraper](/scraper/tiktok-comments-scraper) on an account's top videos to layer sentiment and recurring themes onto your performance report. --- ## Data Fields | Field | Type | Description | |-------|------|-------------| | Creator Followers | number | The creator's follower count, on every video row | | Creator Likes | number | Total likes across the creator's account, on every video row | | Views, Likes, Comments | number | Engagement counts per video | | Shares & Bookmarks | number | Share and save counts per video | | Hashtags | array | Every hashtag on each video | | Sound | text | Music name and author | | Posted At | date | Upload date and time (UTC), for working out posting frequency | | Duration (s) | number | Video length in seconds | ## Features - Export any public creator's video stats from their profile, a hashtag or a search - Views, likes, comments, shares and saves per video - Creator follower count and total likes on every row - Every row has the counts engagement rate needs - Posted dates for working out posting frequency - Export to Excel, CSV, JSON or Google Sheets ## How to Use 1. **Install InsightSocial**: Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Choose Your Target**: Open a creator's profile, a hashtag page or a search results page for the videos you want to analyze. 3. **Run Full Extraction**: Pick 50, 100 or 250 videos and click Scrape. 4. **Review Metrics**: See video and creator metrics appear in the real-time preview. 5. **Export to Excel**: Download Excel for pivot tables, charts and engagement-rate formulas. 6. **Build Your Reports**: Create performance reports, competitor comparisons, or trend analyses. ## FAQ ### How is engagement rate calculated? Export the data and calculate: (Likes + Comments + Shares) / Views x 100. You can create formulas in your spreadsheet. ### Can I track growth over time? Run the same profile weekly or monthly and compare the exports: the creator's follower count and total likes on each row show the change. ### Does this replace TikTok Analytics? No. TikTok Analytics shows watch time, traffic sources and audience data, and only for accounts you own. This exports the public counts on any account. ### Can I compare multiple creators? Run a user search for each niche or extract each creator's videos separately, then combine in a spreadsheet for side-by-side comparison. ### What's the best way to present this data? Excel pivot tables work great for summaries. For dashboards, export to CSV and import into Google Data Studio or Tableau. ### How often should I run analytics extraction? Weekly for active monitoring, monthly for trend reports. More frequent for time-sensitive campaigns. ## Related scrapers - [TikTok Profile Scraper](https://www.insightsocial.app/scraper/tiktok-profile-scraper.md): Export a TikTok creator's videos with follower count, total likes and bio on every row, or a list of creators from search, to Excel or CSV. Free extension. - [TikTok Video Scraper](https://www.insightsocial.app/scraper/tiktok-video-scraper.md): Free TikTok Video Scraper. Extract views, likes, comments, shares, captions, and hashtags from any TikTok video. Export to CSV, Excel, JSON. - [TikTok Comments Scraper](https://www.insightsocial.app/scraper/tiktok-comments-scraper.md): Free TikTok Comments Scraper. Extract comments, replies, and reactions from any TikTok video. Analyze audience sentiment. Export to CSV, Excel, JSON. --- # TikTok Followers Scraper Source: https://www.insightsocial.app/scraper/tiktok-followers-scraper, updated 2026-10-18 > Export a TikTok account's followers or following list to Excel or CSV. TikTok shows visitors about 30 accounts per list; each comes with bio and counts. - **Platform**: tiktok - **Web version**: https://www.insightsocial.app/scraper/tiktok-followers-scraper --- ## What is the TikTok Followers Scraper? The InsightSocial TikTok followers scraper is a free Chrome extension that exports the followers (or the following list) of a public TikTok creator to CSV, Excel, or JSON. No developer application, no API key, no coding. Before anything else, the number that actually matters, because almost every other page on this topic will not tell you: **TikTok serves roughly 30 accounts from a follow list and then stops.** That is TikTok's own limit on its own website, it applies to everyone who is not the account owner, and no browser extension can lift it. We would rather you read that here than discover it on your third run. ### What the 30-row ceiling actually is This is worth explaining precisely, because it is not a rate limit you can wait out and not a setting you can change. Open any creator's follower list on tiktok.com yourself and scroll it. TikTok loads one page of about 30 accounts. Its own data says more are available (the list reports `hasMore: true` and hands out a cursor for the next page), but no second request is ever made, because **TikTok's website contains no code path to request page two** for a visitor who is not the account owner. We tested this exhaustively in 2026 against large public accounts: scrolling the container, real hardware-level wheel input, the End key, and scrolling the last row into view all produce exactly nothing. Calling the paging request directly returns an empty response even when the request is correctly signed. So the honest ceiling is one page. In two weeks of production runs to September 2026, every run that captured anything stopped at **28–30 rows**, against target accounts that list between 115 and 22.1 million followers. Our all-time maximum across every run ever recorded is **35**. When TikTok stops early the extension says so on the result card, with the count it got and the total the account claims, rather than showing you a green checkmark over a partial list. ### What it is genuinely good for Given the ceiling, here is where this run earns its place, and where it does not. | Use it for | Not for | |---|---| | The **most recent ~30 followers** of an account, which is what TikTok serves first | Exporting a large creator's whole audience | | **Small follow lists exported complete**: a list under ~30 comes back in full | Audience overlap analysis between big accounts | | A creator's **following list**, which is usually short and deliberate | Anything that needs a representative sample of a large list | | A quick, rich sample: each row carries bio, follower count, likes, and verified status | Follower-graph datasets at scale | The following list is the quietly useful one. Creators follow far fewer accounts than follow them, so a following list often comes back **complete**, and it reveals who a creator actually watches, collaborates with, and is influenced by. That is a real research answer in one run. If you need audience data at volume, a single follower list is the wrong unit on TikTok. Collect the commenters under a creator's videos with the [TikTok Comments Scraper](/scraper/tiktok-comments-scraper) instead: they are the active part of the audience, and each video gives you a fresh set. ### What each row contains Where TikTok is stingy with row count, it is generous with row content. Each of the ~30 accounts arrives with: - Username (@handle) and display name - Bio / signature text - Avatar URL - Follower count, following count, video count, total likes - Verified badge and private-account flag - `sec_uid`, TikTok's stable internal handle, which survives a username change That is enough to vet or rank the accounts you do get, which is the point: 30 fully-described creators beats 3,000 usernames for most research questions. ### Who is it for? - **Creator scouts** checking who a creator follows to find the next tier of talent - **Competitive analysts** sampling the most recent followers of a rival account - **Market researchers** mapping the small, deliberate following lists that show a niche's structure - **Agencies** vetting a creator's follow graph before a partnership - **Content creators** finding collaboration candidates among accounts a peer follows ### Key Benefits - **Honest about the ceiling**: the result card tells you when TikTok stopped early and how far short it fell, instead of presenting 30 rows as a finished job - **Rich rows**: bio, counts, verification, and `sec_uid`, not just handles - **Both directions**: Followers and Following are one scrape type; the following list is often complete - **Private accounts explained, not failed**: a private account returns a clear reason rather than an empty screen - **No API, no coding**: nothing to register, nothing to refresh - **Runs in your own session**: no password shared, no third-party server logging into TikTok for you --- ## How to Use the TikTok Followers Scraper ### Step 1: Install the Extension Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. ### Step 2: Open the Creator's Profile Go to `tiktok.com/@username`. You need to be logged into TikTok: the extension reads your own session and never asks for your password. ### Step 3: Open the Sidebar Click the InsightSocial icon. The sidebar reads the handle and shows it back to you, so you can confirm the target before anything runs. ### Step 4: Pick Followers or Following **Followers** exports who follows the creator; **Following** exports the accounts they follow. Targets of 50, 100, or 250 are offered, but read the ceiling section above before setting expectations on a large account: on most targets the run will end at about 30 regardless of the number you choose. ### Step 5: Start the Scrape Click "Scrape". The extension opens the follow list, captures what TikTok serves, and closes it again. Runs are short: seconds, not minutes. ### Step 6: Export Click "Export" and choose CSV, .xlsx, or JSON. Every run also syncs to your private [InsightSocial portal](/portal), where you can re-export it later at no additional cost. --- ## Frequently Asked Questions ### Why did I only get 30 followers from an account with 200,000? Because TikTok stopped serving the list, not because the scrape failed. Its website loads one page of about 30 accounts to anyone who is not the account owner and then never requests another: there is no page-two code path in TikTok's own client to trigger. Retrying, waiting, or scrolling by hand does not change it, and no extension can. The extension reports the shortfall on the result card so you can see it plainly. ### Is this a limit I can pay to remove? No, and nobody can sell you one for this surface. It is TikTok's own behaviour on its own website, not a quota on our side. Scraping is unlimited on every InsightSocial plan; paid plans change how many rows you can export, not how many TikTok is willing to serve. ### When does it return a complete list? When the list is smaller than about 30, which is common for following lists. A creator following 32 accounts comes back essentially complete, with `hasMore` correctly reporting that there is nothing further. So the ceiling only bites on lists larger than one page. ### Can I scrape followers of a private account? No. TikTok shows a private account's follow lists only to its approved followers, and the extension sees exactly what your session sees. It says so on the result card rather than returning a silent zero. ### What fields does each follower row include? Username, display name, bio, avatar URL, follower count, following count, video count, total likes, verified badge, private flag, and `sec_uid`, TikTok's stable identifier, which is what you want as a join key because it survives a username change. ### Does the export include emails or phone numbers? No. A follow list has public profile fields only. If an account wrote an email in its bio, you can read it in the Bio column. ### Can I export the following list as well? Yes. Same scrape type, other direction, identical columns. On most creators it is the more complete of the two, since following lists are usually short. ### Will the creator know I exported their followers? No notification is sent. The extension reads the same follow dialog you see when browsing normally. ### How much does it cost? Scraping is free and unlimited on every plan. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99 a month, or $7.99 a month billed yearly. Studio: 150,000 rows a month for $49 a month. One-time packs start at $2 for 250 rows. ### Is scraping TikTok followers legal? Collecting publicly visible data for research, competitive analysis, and audience measurement is long-established practice. Respect TikTok's Terms of Service and privacy law such as GDPR and CCPA, anonymise handles in anything you publish, and never use a follow list to target or harass an individual. Getting more out of TikTok where the platform is more forthcoming: the [TikTok Profile Scraper](/scraper/tiktok-profile-scraper) pulls a creator's videos and stats, the [TikTok Comments Scraper](/scraper/tiktok-comments-scraper) exports the discussion under any video, and the [TikTok Analytics Scraper](/scraper/tiktok-analytics-scraper) turns a creator's recent output into engagement numbers. All of them sit on the [TikTok scraper hub](/scraper/tiktok). --- ## Data Fields | Field | Type | Description | |-------|------|-------------| | Username | text | Follower's @handle | | Display Name | text | Follower's public display name | | Bio / Signature | text | Bio text on the profile | | Avatar URL | url | Profile picture | | Follower Count | number | How many people follow them | | Following Count | number | How many accounts they follow | | Video Count | number | How many videos they've posted | | Total Likes | number | Total likes received across their videos | | Verified | text | Verified badge status | | Private | text | Whether the account is private | | Sec UID | text | TikTok's stable long-form handle for API calls | | Source Creator | text | Creator the follower was exported from | ## Features - Export the accounts TikTok shows from a public creator's follower list (about 30); shorter lists come back complete - Export following lists: the accounts a creator follows - Auto-opens and scrolls the followers or following dialog for you - Rich per-follower rows: name, bio, follower count, video count, verified - Export to CSV, Excel, or JSON formats - Feed follower lists into influencer analysis or research notebooks - No TikTok developer application or coding required ## How to Use 1. **Install the Extension**: Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Open the Creator Profile**: Go to TikTok and visit the creator whose followers you want to export (e.g. tiktok.com/@handle). 3. **Open InsightSocial**: Click the InsightSocial icon in your toolbar. The sidebar detects the profile and shows Videos, Followers, and Following as scrape options. 4. **Pick Followers**: Select Followers, or Following to export the accounts the creator follows, and choose 50, 100 or 250. On most accounts the run ends at about 30, because that is all TikTok shows a visitor. 5. **Start Scraping**: Click Scrape. The extension opens the follow list and captures what TikTok serves; runs take seconds. 6. **Export Your Data**: Click 'Export' and choose CSV, Excel, or JSON. Your follower list downloads instantly. ## FAQ ### Can I scrape followers of any TikTok creator? You can export followers of public accounts. Private accounts are only visible to their approved followers, so the extension will only see what your TikTok session can see. ### How many followers can I export? About 30 per run on most accounts: that is TikTok’s own ceiling, not ours. Its website loads one page of roughly 30 accounts to anyone who is not the account owner and never requests another, so retrying or waiting does not help. Lists shorter than one page (most following lists) come back complete. ### What fields does each follower row include? Username, display name, bio, avatar URL, follower count, video count, total likes received, verified status, and TikTok's stable sec_uid handle. Everything you need for creator vetting or network analysis. ### Does it include emails or phone numbers? No. A follow list has public profile fields only. If an account wrote an email in its bio, you can read it in the Bio column. ### Is exporting TikTok followers legal? Extracting publicly available data for research, competitive analysis, or legitimate business purposes is generally permitted. Review TikTok's Terms of Service for your specific use case. ### Will the creator know I scraped their followers? No notification is sent. The extension reads the same followers dialog you see when browsing normally. ### Can I export the following list too? Yes. The same scrape type covers both directions: pick Followers to export who follows a creator, or Following to export the accounts that creator follows. Identical columns and export formats either way. ## Related scrapers - [TikTok Profile Scraper](https://www.insightsocial.app/scraper/tiktok-profile-scraper.md): Export a TikTok creator's videos with follower count, total likes and bio on every row, or a list of creators from search, to Excel or CSV. Free extension. - [TikTok Video Scraper](https://www.insightsocial.app/scraper/tiktok-video-scraper.md): Free TikTok Video Scraper. Extract views, likes, comments, shares, captions, and hashtags from any TikTok video. Export to CSV, Excel, JSON. - [TikTok Comments Scraper](https://www.insightsocial.app/scraper/tiktok-comments-scraper.md): Free TikTok Comments Scraper. Extract comments, replies, and reactions from any TikTok video. Analyze audience sentiment. Export to CSV, Excel, JSON. --- # TikTok Hashtag Scraper Source: https://www.insightsocial.app/scraper/tiktok-hashtag-scraper, updated 2026-10-18 > Free TikTok hashtag scraper Chrome extension. Export the videos under any hashtag with views, likes, comments, shares, bookmarks, captions, hashtags, sounds and creator stats to CSV, Excel or JSON. No API key. - **Platform**: tiktok - **Web version**: https://www.insightsocial.app/scraper/tiktok-hashtag-scraper --- ## What is the TikTok Hashtag Scraper? The InsightSocial TikTok hashtag scraper is a free Chrome extension that exports the videos under any TikTok hashtag to CSV, Excel, JSON, or Google Sheets. One row per video: the link, the creator, the caption, when it was posted, views, likes, comments, shares and bookmarks, every hashtag on the video, the sound it uses, and the creator's bio, follower count and total likes. No API key, no Research API application, no code. It works by reading what your own browser already loads. When you open `tiktok.com/tag/anything`, TikTok's page requests the hashtag's videos in batches as you scroll. The extension scrolls for you, captures each batch as it arrives, and streams the videos into the sidebar so you can watch the count climb and stop whenever you have enough. A hashtag page is the closest thing TikTok has to a topic index. A trend chart can tell you a tag is rising; a hashtag export tells you which videos are carrying it, who made them, which sounds they used, and which other tags travel with it. That is the dataset you actually build a content brief, a creator shortlist or a campaign report from. ### What you get for each video Every row is a full video record, not just a URL: | Group | Columns | |---|---| | **The video** | Video URL, caption, posted date (UTC), duration in seconds, cover image URL, video ID, ad flag | | **Engagement** | Views, likes, comments, shares, bookmarks | | **Discovery signals** | All hashtags on the video, @mentions, links and emails written in the caption | | **Sound** | Music name, music author, music ID | | **The creator** | Name, @handle, profile URL, bio, follower count, total likes, verified badge, creator ID | The hashtags column is worth singling out. It lists every tag on each video, not only the one you scraped, so a simple count across the export shows you the neighbouring hashtags for a topic. Pair it with the music columns and you can see which sounds dominate a tag in a given week. The creator columns turn the same file into a sourcing list. Each video already carries its creator's bio and follower count, so you can filter to creators between, say, 10,000 and 200,000 followers who posted under your tag, without a second tool. ### Who is it for? - **Content researchers** sorting a niche tag by views to see which hooks, formats and lengths actually travel - **Brand and campaign teams** measuring participation and engagement under a branded or campaign hashtag - **Influencer agencies** finding the creators who post about a topic, with follower counts and bios already attached - **Trend analysts** mapping which sounds and co-occurring hashtags ride along with a tag - **Academic researchers** building hashtag datasets of captions, timestamps and engagement - **Creators** studying what the top videos in their niche have in common ### Key Benefits - **Complete engagement per video**: views, likes, comments, shares and bookmarks, all five, on every row - **Creator context in the same file**: handle, bio, follower count, total likes and verified badge, no second pass - **Sounds and co-hashtags**: the raw material for trend and sound research, already split into columns - **Background-tab friendly**: the run keeps collecting while you work in another tab - **Live preview**: videos appear in the sidebar as they are captured, so you can stop the moment the sample is enough - **Private by design**: collection runs in your own browser session and results are visible only to your account --- ## How to Use the TikTok Hashtag Scraper ### Step 1: Install the Extension Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. ### Step 2: Open the Hashtag Page Go to `tiktok.com/tag/yourhashtag`, or click any hashtag in a caption to land on its page. The extension works on whatever hashtag page TikTok shows your browser, and it never asks for your TikTok password. ### Step 3: Open the Sidebar Click the InsightSocial icon. The sidebar recognises the hashtag page and shows the tag back to you (for example `#ultralight`), so you can confirm the target before anything runs. ### Step 4: Choose How Many Videos Pick 50, 100 or 250. The run ends when it reaches that number or when TikTok stops sending new videos, whichever comes first. ### Step 5: Start Scraping Click Scrape. The page reloads once so the extension catches TikTok's very first batch, then it scrolls the grid and videos stream into the live preview. You can switch to another tab while it runs. ### Step 6: Export Click Export and choose CSV, Excel or JSON, or sync the rows to Google Sheets. Every run is also saved to your private [InsightSocial portal](/portal), where you can search, sort and export it again later. --- ## Hashtag Scraping Approaches Compared There are four common ways to get TikTok hashtag data. They suit different people, so here is a feature comparison rather than a verdict. | | InsightSocial extension | Cloud scraping platforms | Open-source scripts | Official research access | |---|---|---|---|---| | **Setup** | Install, open a tag, click Scrape | Create an account, configure a job | Install Python or Node, maintain the code | Apply and wait for approval | | **Coding needed** | None | Little to none | Yes | Yes | | **Where it runs** | Your own browser | The vendor's servers | Your machine or server | TikTok's API | | **Who can use it** | Anyone with Chrome | Anyone with an account | Developers | Approved researchers | | **Breaks when TikTok changes** | We fix it and ship an update | The vendor fixes it | You fix it | Stable, versioned | | **Best for** | Ad hoc research, a few tags at a time | Scheduled, large-scale pipelines | Custom pipelines you control | Formal academic studies | If you need thousands of hashtags on a server schedule, a cloud platform or your own pipeline is the better fit. If you need the videos behind a handful of tags this afternoon, in a spreadsheet, without writing anything, that is what this extension is for. Developers who want TikTok data as JSON from code can also use the [InsightSocial TikTok API](/docs/platforms/tiktok). --- ## Frequently Asked Questions ### Is the TikTok hashtag scraper free? Yes. Scraping is free and unlimited on every plan. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99 a month, or $7.99 a month billed yearly. Studio: 150,000 rows a month for $49 a month. One-time packs start at $2 for 250 rows. ### Do I need a TikTok API key? No. There is no developer account, no Research API application and no token to refresh. The extension reads the hashtag feed tiktok.com already sends to your browser. ### How many hashtag videos can I export? TikTok decides how deep a hashtag feed goes, and it varies by tag and by day. In our production runs a 100-video target usually comes back with 80 to 100 videos, targets of 250 have typically ended between 100 and 160, and the largest single hashtag run we have recorded returned 272. A tag with millions of posts can't be exported in full: a run is the top of the feed TikTok shows you. When TikTok stops paging, the run finishes and keeps everything it collected. ### Can I export the hashtag's total view count? No. Each row carries that video's own views, likes, comments, shares and bookmarks. The total shown at the top of the hashtag page is not recorded, so summing the Views column gives the reach of the videos you collected, not of the whole tag. ### In what order do the videos come? In the order TikTok shows them on the hashtag page. Hashtag pages have no sort control, so sort the export by views, likes or posted date afterwards. ### Can I find creators to work with from a hashtag? Yes, and it is one of the most common uses. Every row carries the creator's handle, bio, follower count, total likes and verified badge. Filter by follower range, then open the shortlisted handles with the [TikTok Profile Scraper](/scraper/tiktok-profile-scraper) to pull their recent videos. Many creators publish a business email in their bio; it is in the Creator Bio column, and any email written in a caption lands in the Emails column. Use it for research and sourcing rather than unsolicited bulk outreach. ### Can I get the comments on the videos I found? Not in the same run. Take the video URLs with the most comments and open each one with the [TikTok Comments Scraper](/scraper/tiktok-comments-scraper), which exports the full comment thread with replies. ### Is scraping TikTok hashtags legal? Collecting publicly visible data for research, trend analysis and competitive analysis is long-established practice. Respect TikTok's Terms of Service and privacy law such as GDPR and CCPA, anonymise creators in anything you publish, and never use the data to target or harass individuals. Searching by keyword instead of by tag? The [TikTok Search Scraper](/scraper/tiktok-search-scraper) exports keyword search results as videos or as creator accounts. For one creator's catalogue, use the [TikTok Profile Scraper](/scraper/tiktok-profile-scraper), and for a deeper look at performance across videos, the [TikTok Analytics Scraper](/scraper/tiktok-analytics-scraper). Everything TikTok we support is on the [TikTok scraper hub](/scraper/tiktok), and the [TikTok competitor analysis guide](/blog/tiktok-competitor-analysis-guide) shows how to put hashtag data to work. --- ## Data Fields | Field | Type | Description | |-------|------|-------------| | Video URL | url | Direct link to the video | | Creator Name | text | Display name of the video's creator | | Creator Handle | text | Creator's @username | | Creator Profile URL | url | Link to the creator's TikTok profile | | Content | text | Full video caption | | Posted At | date | Upload date and time (UTC) | | Views | number | Play count | | Likes | number | Like count | | Comments | number | Comment count | | Shares | number | Share count | | Bookmarks | number | Times the video was saved to favorites | | Hashtags | array | Every hashtag on the video, not only the one you scraped | | Mentions, Links, Emails | array | @mentions, URLs and email addresses found in the caption | | Creator Bio | text | The creator's profile bio | | Creator Followers | number | Creator's follower count | | Creator Likes | number | Total likes across the creator's account | | Creator Verified | text | Whether the creator has a verified badge | | Music Name & Author | text | The sound used, its author and its music ID | | Duration (s) | number | Video length in seconds | | Is Ad | text | Whether TikTok marks the video as an ad | | Media URL | url | Video cover image | | Video ID & Creator ID | text | TikTok's numeric IDs, for joining datasets | ## Features - Export the videos under any TikTok hashtag page - Views, likes, comments, shares and bookmarks per video - Creator handle, bio, follower count, total likes and verified badge on every row - Every co-occurring hashtag plus the sound name, author and ID - Keeps collecting while the tab is in the background - Export to CSV, Excel, JSON or Google Sheets - No TikTok API key, Research API approval or coding ## How to Use 1. **Install the Extension**: Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Open a Hashtag Page**: Go to tiktok.com/tag/yourhashtag, or click any hashtag on TikTok to land on its page. 3. **Open the Sidebar**: Click the InsightSocial icon. The sidebar detects the hashtag page and shows the tag name back to you. 4. **Pick How Many Videos**: Choose 50, 100 or 250. The run stops once that many videos are collected or TikTok stops sending more. 5. **Start Scraping**: Click Scrape. The page reloads once, then the extension scrolls the grid and videos stream into the live preview. 6. **Export**: Download CSV, Excel or JSON, or send the rows to Google Sheets. Every run also syncs to your private portal. ## FAQ ### Is the TikTok hashtag scraper free? Yes. Installing the extension and scraping are free on every plan. Credits are spent only on the rows you export, one per row, and a row you already exported is free to export again: the free plan includes 500 exported rows a month, Pro includes 10,000 a month for $9.99 a month (or $7.99 a month billed yearly), and one-time credit packs start at $2 for 250 rows. ### Do I need a TikTok API key or Research API access? No. There is no developer account, no Research API application and no token. The extension reads the same hashtag feed tiktok.com sends to your own browser when you open a tag page. ### How many videos can I scrape from one hashtag? You set the target (50, 100 or 250), but TikTok decides when the feed ends. In our production runs, a 100-video target on a hashtag usually comes back with 80 to 100 videos, while targets of 250 or more have typically ended somewhere between 100 and 160 videos; the largest single hashtag run we have recorded returned 272. When TikTok stops paging, the run finishes with what it has rather than looping. ### Can I export the hashtag's total view count? No. The export is one row per video, with each video's own views, likes, comments, shares and bookmarks. The hashtag page's headline total is not recorded. Summing the Views column tells you the reach of the videos you collected, not of the whole tag. ### Does it keep running if I switch tabs? Yes. TikTok hashtag runs keep collecting in a background tab. The one exception: if the page loaded while hidden and TikTok has not sent the first batch, or the grid stalls while hidden, the run pauses and resumes when you come back to the tab instead of ending with a short list. ### In what order are the videos? In the order TikTok shows them on the hashtag page. There is no sort option for hashtag pages, so sort the export by views, likes or post date afterwards. ### Can I scrape several hashtags at once? One run covers one hashtag. Each row carries the source hashtag in its Source Name column, so you can run several tags one after another and combine the exports into a single dataset without losing track of where each video came from. ### Does the export include creators' emails? Not as a separate contact lookup. Each row includes the creator's bio, which is where many TikTok creators publish a business email, and any email written in a video caption is pulled into the Emails column. Use it for research and sourcing, not unsolicited bulk outreach. ## Related scrapers - [TikTok Search Scraper](https://www.insightsocial.app/scraper/tiktok-search-scraper.md): Free TikTok search scraper Chrome extension. Export keyword search results as videos (views, likes, captions, creators) or as user accounts (bio, followers, total likes, verified) to CSV, Excel or JSON. No API key. - [TikTok Video Scraper](https://www.insightsocial.app/scraper/tiktok-video-scraper.md): Free TikTok Video Scraper. Extract views, likes, comments, shares, captions, and hashtags from any TikTok video. Export to CSV, Excel, JSON. - [TikTok Profile Scraper](https://www.insightsocial.app/scraper/tiktok-profile-scraper.md): Export a TikTok creator's videos with follower count, total likes and bio on every row, or a list of creators from search, to Excel or CSV. Free extension. - [TikTok Comments Scraper](https://www.insightsocial.app/scraper/tiktok-comments-scraper.md): Free TikTok Comments Scraper. Extract comments, replies, and reactions from any TikTok video. Analyze audience sentiment. Export to CSV, Excel, JSON. - [TikTok Analytics Scraper](https://www.insightsocial.app/scraper/tiktok-analytics-scraper.md): Free TikTok analytics scraper Chrome extension. Export view, like, comment and share counts per video from any profile, hashtag or search, plus follower and total-like counts per creator. No API key, no coding. --- # TikTok Search Scraper Source: https://www.insightsocial.app/scraper/tiktok-search-scraper, updated 2026-10-18 > Free TikTok search scraper Chrome extension. Export keyword search results as videos (views, likes, captions, creators) or as user accounts (bio, followers, total likes, verified) to CSV, Excel or JSON. No API key. - **Platform**: tiktok - **Web version**: https://www.insightsocial.app/scraper/tiktok-search-scraper --- ## What is the TikTok Search Scraper? The InsightSocial TikTok search scraper is a free Chrome extension that exports TikTok keyword search results to CSV, Excel, JSON, or Google Sheets. Search any keyword on TikTok, then export either the **videos** that match it (with views, likes, comments, shares, bookmarks, captions, sounds and creator stats) or the **user accounts** that match it (with bio, follower count, total likes, verified badge and search rank). No API key, no Research API application, no code. TikTok search results are a dataset in their own right. Which videos does TikTok rank for a query? Which creators come up first? How much engagement does the top of the results page carry? A keyword scraper answers those questions in a spreadsheet instead of an afternoon of scrolling and screenshots. It works by reading what your own browser already loads. When you search on tiktok.com, the page requests results in pages as you scroll. The extension scrolls the results for you, captures each page as it arrives, and streams the rows into the sidebar so you can watch the count and stop whenever the sample is enough. ### Two exports from one search TikTok splits search results into tabs, and the extension follows the same split. Pick one per run: | Mode | What you get | Typical use | |---|---|---| | **Videos** | One row per matching video: link, caption, posted date, views, likes, comments, shares, bookmarks, hashtags, sound, duration, plus the creator's handle, bio, followers and total likes | Content and keyword research, competitive monitoring, brand mentions | | **Users** | One row per matching account: username, display name, profile link, bio, followers, total likes, verified badge and label, search keyword, position in the results, TikTok's stable IDs | Influencer discovery, creator sourcing, market mapping | You can start from any results tab (Top, Videos or Users). When you click Scrape, the extension switches to the tab that matches the mode you picked, so the right results load. ### The Users export, in detail TikTok user search is the closest thing the platform has to a creator directory, and the Users mode is the part of this tool people come back to. Each row keeps two things most exports drop: - **The search keyword and the account's position** in TikTok's results, so you can see who TikTok ranks first for a query and compare rankings across keywords. - **Contacts written in the bio**: when a creator puts an email address, a phone number or a link in their bio, it is pulled into its own Emails, Phones or Links column next to the full bio text. Most bios do not contain one, but the ones that do are easy to filter for. Alongside those you get the follower count, total likes across the account, the verified badge with TikTok's verification label, the avatar URL, and TikTok's numeric UID and `sec_uid`, which survive a username change and make good join keys. These are TikTok's search cards, not full profiles: following and video counts aren't part of them. ### Who is it for? - **Influencer marketers** searching a niche keyword in Users mode to build a creator shortlist with follower counts and bios - **Content researchers** exporting the videos TikTok ranks for a keyword to see which hooks and formats win - **SEO and keyword researchers** treating TikTok as a search engine and recording what surfaces for each query - **Brands** searching their own name or product and exporting every video and account that comes up - **Market analysts** comparing result sets across keywords to size a topic and see who dominates it - **Academic researchers** building keyword-based samples of videos or accounts ### Key Benefits - **Videos or users from the same search**: two clean exports, one keyword - **Search rank kept**: every user row records its keyword and position - **Full engagement per video**: views, likes, comments, shares and bookmarks on every row - **Creator context on video rows**: bio, followers and total likes, no second lookup - **Works without a TikTok login** and keeps going in a background tab - **Private by design**: collection runs in your own browser session and results are visible only to your account --- ## How to Use the TikTok Search Scraper ### Step 1: Install the Extension Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. ### Step 2: Search on TikTok Type your keyword into TikTok's search box and press Enter. Any results tab works. The address bar will show something like `tiktok.com/search?q=hiking%20gear`. ### Step 3: Open the Sidebar Click the InsightSocial icon. The sidebar detects the search and shows it back to you as `Search: hiking gear`, so you can confirm the keyword before anything runs. ### Step 4: Pick Videos or Users Choose **Videos** to export the matching videos or **Users** to export the matching accounts. Then pick 50, 100 or 250. ### Step 5: Start Scraping Click Scrape. The extension opens the matching results tab, scrolls it, and streams rows into the live preview. You can switch to another tab while it runs. ### Step 6: Export Click Export and choose CSV, Excel or JSON, or sync the rows to Google Sheets. Every run is also saved to your private [InsightSocial portal](/portal), where you can search, sort and export it again later. To get the other mode for the same keyword, go back to the search and run it again with the other option. --- ## Search Scraping Approaches Compared There are four common ways to get TikTok search data. They suit different needs, so here is a feature comparison rather than a verdict. | | InsightSocial extension | Cloud scraping platforms | Open-source scripts | Official research access | |---|---|---|---|---| | **Setup** | Install, search, click Scrape | Create an account, configure a job | Install Python or Node, maintain the code | Apply and wait for approval | | **Coding needed** | None | Little to none | Yes | Yes | | **Where it runs** | Your own browser | The vendor's servers | Your machine or server | TikTok's API | | **Videos and users** | Both, one mode per run | Depends on the tool | Depends on the library | Depends on access granted | | **Who can use it** | Anyone with Chrome | Anyone with an account | Developers | Approved researchers | | **Best for** | Ad hoc keyword research, a few queries at a time | Scheduled, large-scale pipelines | Custom pipelines you control | Formal academic studies | If you need hundreds of keywords on a server schedule, a cloud platform or your own pipeline is the better fit. If you need what TikTok shows for a handful of queries, in a spreadsheet, today, that is what this extension is for. Developers who want TikTok search as JSON from code can also use the [InsightSocial TikTok API](/docs/platforms/tiktok). --- ## Frequently Asked Questions ### Is the TikTok search scraper free? Yes. Scraping is free and unlimited on every plan. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99 a month, or $7.99 a month billed yearly. Studio: 150,000 rows a month for $49 a month. One-time packs start at $2 for 250 rows. ### Do I need a TikTok API key? No. There is no developer account, no Research API application and no token to refresh. The extension reads the search results tiktok.com already sends to your browser. ### Can I use TikTok user search without an account? Yes. Search runs work without a TikTok login; we test them logged out. Being logged in does no harm, and the extension never asks for your TikTok password. ### How many search results can I export? TikTok decides when results for a query run out, and it varies by keyword. In our production runs video searches up to about 100 results usually complete, larger targets have typically ended between 150 and 300 videos, and the most we have recorded from one search is 385 videos. User searches have returned up to 250 accounts in one run. Rankings also move over time, so keep runs dated if you track them. ### Can I scrape videos and users in one run? No. TikTok serves them on separate tabs, so run one, then the other. Both exports keep the keyword, so they line up. ### Can I find influencers by keyword? Yes; that is what Users mode is for. Search a niche term, export the accounts, and filter by follower count, total likes or verified status. Each row keeps its position in TikTok's results, so you can see who ranks first. For creators worth a closer look, the [TikTok Profile Scraper](/scraper/tiktok-profile-scraper) pulls their recent videos and the [TikTok Followers Scraper](/scraper/tiktok-followers-scraper) shows who they follow. ### Does the export include creators' emails? Only what a creator has written in their own bio. When a bio contains an email address or phone number, it lands in the Emails or Phones column of the Users export. Use it for research and sourcing rather than unsolicited bulk outreach. ### Is scraping TikTok search results legal? Collecting publicly visible data for research, keyword analysis and competitive analysis is long-established practice. Respect TikTok's Terms of Service and privacy law such as GDPR and CCPA, anonymise creators in anything you publish, and never use the data to target or harass individuals. Working from a hashtag instead of a keyword? The [TikTok Hashtag Scraper](/scraper/tiktok-hashtag-scraper) exports the videos under any tag. To read the discussion under a video you found, use the [TikTok Comments Scraper](/scraper/tiktok-comments-scraper). Everything TikTok we support is on the [TikTok scraper hub](/scraper/tiktok), and the [TikTok competitor analysis guide](/blog/tiktok-competitor-analysis-guide) shows how to put search data to work. --- ## Data Fields | Field | Type | Description | |-------|------|-------------| | Video URL | url | Videos mode: direct link to each matching video | | Creator Name & Handle | text | Videos mode: the creator's display name, @username and profile URL | | Content | text | Videos mode: full video caption | | Posted At | date | Videos mode: upload date and time (UTC) | | Views, Likes, Comments | number | Videos mode: engagement counts per video | | Shares & Bookmarks | number | Videos mode: share and save counts per video | | Hashtags | array | Videos mode: every hashtag on the video | | Music Name & Author | text | Videos mode: the sound used, its author and its music ID | | Duration (s) | number | Videos mode: video length in seconds | | Creator Bio, Followers, Likes | text | Videos mode: the creator's bio, follower count and total likes | | Username | text | Users mode: the account's @handle | | Full Name | text | Users mode: display name | | Profile URL | url | Users mode: link to the TikTok profile | | Bio | text | Users mode: profile bio text | | Emails, Phones, Links | array | Users mode: contact details and URLs written in the bio | | Followers | number | Users mode: follower count | | Total Likes | number | Users mode: likes across all of the account's videos | | Verified & Verify Label | text | Users mode: verified badge and TikTok's verification label | | Search Keyword & Position | text | Users mode: the keyword searched and the account's rank in the results | | UID, Sec UID & Avatar URL | text | Users mode: TikTok's stable account IDs and profile picture | ## Features - Export TikTok keyword search results as videos or as user accounts - Views, likes, comments, shares and bookmarks per video - Creator bio, followers, total likes and verified badge per account - Keeps each account's search keyword and rank - Works without a TikTok login and keeps going in a background tab - Export to CSV, Excel, JSON or Google Sheets - No TikTok API key, Research API approval or coding ## How to Use 1. **Install the Extension**: Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Search on TikTok**: Type your keyword into TikTok's search box. Any results tab works: Top, Videos or Users. 3. **Open the Sidebar**: Click the InsightSocial icon. The sidebar detects the search and shows your keyword back to you. 4. **Pick Videos or Users**: Choose Videos for the matching videos or Users for the matching accounts, then pick 50, 100 or 250. 5. **Start Scraping**: Click Scrape. The extension switches to the right results tab, scrolls it, and streams rows into the live preview. 6. **Export**: Download CSV, Excel or JSON, or send the rows to Google Sheets. Every run also syncs to your private portal. ## FAQ ### Is the TikTok search scraper free? Yes. Installing the extension and scraping are free on every plan. Credits are spent only on the rows you export, one per row, and a row you already exported is free to export again: the free plan includes 500 exported rows a month, Pro includes 10,000 a month for $9.99 a month (or $7.99 a month billed yearly), and one-time credit packs start at $2 for 250 rows. ### Do I need a TikTok API key? No. There is no developer account, no Research API application and no token. The extension reads the search results tiktok.com already sends to your browser. ### Can I scrape videos and users in one run? No. TikTok serves them on separate tabs, so they are separate runs: pick Videos or Users, run it, then switch and run the other. Both runs keep the keyword, so the two exports line up. ### How many search results can I scrape? You set the target, and TikTok decides when its results run out. In our production runs, video searches up to about 100 results usually complete, and larger targets have typically ended between 150 and 300 videos; the most we have recorded from one search is 385 videos. User searches have returned up to 250 accounts in one run. ### Does TikTok user search need an account? No. Search runs work without a TikTok login; we test them logged out. Being logged in does no harm, and the extension never asks for your TikTok password. ### Does the export include creators' emails? When a creator writes an email address or phone number in their bio, it is pulled into the Emails and Phones columns of the Users export, next to the full bio. Most bios do not contain one. Use it for research and sourcing, not unsolicited bulk outreach. ### Does it keep running in a background tab? Yes. Both video and user searches keep collecting while the tab is hidden. If TikTok has not sent the first page because the tab loaded hidden, the run waits until you return to the tab rather than ending empty. ### Can I search TikTok by hashtag instead? Yes, with the TikTok Hashtag Scraper: open tiktok.com/tag/yourhashtag and the sidebar offers the hashtag's videos. Keyword search and hashtag pages return different result sets, so many teams run both. ## Related scrapers - [TikTok Hashtag Scraper](https://www.insightsocial.app/scraper/tiktok-hashtag-scraper.md): Free TikTok hashtag scraper Chrome extension. Export the videos under any hashtag with views, likes, comments, shares, bookmarks, captions, hashtags, sounds and creator stats to CSV, Excel or JSON. No API key. - [TikTok Profile Scraper](https://www.insightsocial.app/scraper/tiktok-profile-scraper.md): Export a TikTok creator's videos with follower count, total likes and bio on every row, or a list of creators from search, to Excel or CSV. Free extension. - [TikTok Video Scraper](https://www.insightsocial.app/scraper/tiktok-video-scraper.md): Free TikTok Video Scraper. Extract views, likes, comments, shares, captions, and hashtags from any TikTok video. Export to CSV, Excel, JSON. - [TikTok Followers Scraper](https://www.insightsocial.app/scraper/tiktok-followers-scraper.md): Export a TikTok account's followers or following list to Excel or CSV. TikTok shows visitors about 30 accounts per list; each comes with bio and counts. - [TikTok Comments Scraper](https://www.insightsocial.app/scraper/tiktok-comments-scraper.md): Free TikTok Comments Scraper. Extract comments, replies, and reactions from any TikTok video. Analyze audience sentiment. Export to CSV, Excel, JSON. --- # Twitter Profile Scraper Source: https://www.insightsocial.app/scraper/twitter-profile-scraper, updated 2026-10-18 > Export an X (Twitter) profile's posts, followers or following to Excel or CSV. Likes, reposts, views per post; bio and counts per follower. Free extension. - **Platform**: twitter - **Web version**: https://www.insightsocial.app/scraper/twitter-profile-scraper --- ## What is the Twitter Profile Scraper? InsightSocial's Twitter (X) Profile Scraper is a free Chrome extension that exports what is on an X profile to Excel, CSV, JSON or Google Sheets: the account's posts with likes, reposts, replies, quotes, views and bookmarks, or its followers and following lists. Every follower row carries that account's bio, location, website, follower count and join date. It runs in your own logged-in browser: no X API key. It works by reading what your own logged-in X session already sees. You open a profile at `x.com/username`, pick one export in the side panel, and the extension collects it as X loads the page. It never asks for your X password and never shows you anything your account couldn't already see: protected accounts stay protected unless you're an approved follower. ## What you can export from a profile | You want | Pick | Per run | |---|---|---| | The account's posts with per-post engagement | Posts | 50, 100 or 300 | | Who follows the account, with each follower's bio and counts | Followers | 50, 100 or 500 | | Who the account follows | Following | 50, 100 or 500 | | Posts you have liked (your own profile only) | Liked Posts | 50, 100 or 250 | One export per run. Followers and Following open the account's list page for you, so you can start from the profile itself. **Not yet:** the profile card of the account you are on (its own bio, counts and join date) as a row of its own. It is coming soon. Until then, a followers or following export gives you those fields for every account in the list. ## Working with the file - **Vetting an account.** Export its posts and sort by views or likes to see what actually lands, then export its followers to see who it reaches. - **Profiles in bulk.** A following list is the quickest way to get bios, locations, websites and counts for many accounts at once. Filter the Bio column for keywords and sort by Followers. - **Comparing accounts.** Run the same export on each account and stack the files: the columns are identical. X often stops loading someone else's follower list after about 50 to 70 accounts; following lists usually go further. See the [Twitter Followers Scraper](/scraper/twitter-followers-scraper) for details. --- ## Frequently Asked Questions ### Can I export an X account's bio, follower count and join date? Not for the account you are viewing yet. You can get those fields for many accounts at once: export a followers or following list, and every row carries that account's bio, location, website, counts and join date. ### Can I scrape protected or private accounts? You see exactly what X lets your own session see. Public profiles work for everyone. Protected accounts only show their posts and lists to approved followers: if your account is approved, your session sees them and can export them; if not, neither can the scraper. ### Do I need to keep the tab open while it runs? Keep the tab open, but it doesn't have to be in front. Posts, followers, following and likes runs keep going in a background tab while you work in another. ### How much does it cost? Scraping is free and unlimited on every plan. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99, or $7.99 a month billed yearly. Studio: 150,000 rows for $49 a month. One-time packs start at $2 for 250 rows. ### Where does my scraped data go? Exports download straight to your machine, and every run also syncs to your private account in the [portal](/portal), where you can re-open and re-export it. Only you can see your data. We never see your X password; the scrape runs inside your own logged-in session. ### Is scraping Twitter profiles allowed? Recording publicly visible data for research, journalism or competitive analysis is a common practice. Review X's Terms of Service for your use case, comply with applicable privacy laws (GDPR, CCPA), and never use the data for harassment or spam. Our [guide to scraping Twitter profiles](/blog/how-to-scrape-twitter-profiles) walks through a research workflow. --- ## Data Fields | Field | Type | Description | |-------|------|-------------| | Post URL | url | Direct link to each post (Posts) | | Content | text | Post text (Posts) | | Posted At | date | When the post was published (Posts) | | Likes, Reposts, Replies, Quotes | number | Engagement counts per post (Posts) | | Views, Bookmarks | number | View and bookmark counts per post (Posts) | | Media | array | Image and video links (Posts) | | Handle & Name | text | The account's @handle and display name (Followers / Following) | | Bio | text | The account's profile description (Followers / Following) | | Location & Website | text | As written on the account's profile (Followers / Following) | | Followers, Following, Tweets | number | The account's counts (Followers / Following) | | Account Created | date | The account's join date (Followers / Following) | | Verified | text | Verified and blue-verified flags | ## Features - Export a profile's posts with likes, reposts, replies, quotes, views and bookmarks - Export a profile's followers or following list with bio, location, website and counts per account - Export your own liked posts from your own profile - Keeps going in a background tab - Export to Excel, CSV, JSON or Google Sheets - No API access or coding required ## How to Use 1. **Install the Extension**: Add InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Visit a Twitter Profile**: Navigate to any Twitter/X profile page (x.com/username) while logged in to X. 3. **Open InsightSocial**: Click the InsightSocial icon in your toolbar. The side panel recognises the profile. 4. **Pick What to Export**: Choose one per run: Posts (50, 100 or 300), Followers or Following (50, 100 or 500), or Liked Posts on your own profile (50, 100 or 250). 5. **Start Scraping**: Click Scrape. A profile run keeps going in a background tab while you work in another; just keep the tab open. 6. **Export Your Data**: Download Excel, CSV or JSON, or send the rows to Google Sheets. ## FAQ ### Does this work with X (formerly Twitter)? Yes. InsightSocial works on both twitter.com and x.com profile URLs. ### Can I scrape any Twitter profile? You can scrape any public Twitter profile. Protected/private accounts are not accessible unless you're an approved follower. ### Do I need a Twitter API key? No. InsightSocial works directly in your browser without requiring API access or developer credentials. ### How much does it cost? Scraping is free and unlimited on every plan. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99, or $7.99 a month billed yearly. ### Can I export an X account's bio, follower count and join date? Not for the account you are viewing yet: exporting a profile's own card as a row is coming soon. You can get those fields for many accounts at once: export a followers or following list, and every row carries that account's bio, location, website, counts and join date. ### Is scraping Twitter legal? Extracting publicly available data for research and analysis is generally permitted. Review Twitter's Terms of Service for your specific use case. ### What can I export from a profile? Three things, one per run. Posts: text, date, link, author, likes, reposts, replies, quotes, views, bookmarks and media. Followers or following: one row per account with handle, name, bio, location, website, follower and following counts, post count, join date and verified badge. Liked posts: your own likes, on your own profile. ### Do I need to keep the tab open while it runs? Keep the tab open, but it doesn't have to be in front. Posts, followers, following and likes runs keep going in a background tab while you work in another. ## Related scrapers - [Twitter Posts Scraper](https://www.insightsocial.app/scraper/twitter-posts-scraper.md): Export tweets from any X profile, list or your home feed to Excel or CSV: text, date, likes, reposts, replies, views and media. Free Chrome extension. - [Twitter Followers Scraper](https://www.insightsocial.app/scraper/twitter-followers-scraper.md): Export an X account's followers or following to Excel or CSV, with bio, location, website, follower counts and join date per account. Free extension. - [Twitter Likes Scraper](https://www.insightsocial.app/scraper/twitter-likes-scraper.md): Free Twitter/X Likes Scraper. Export the posts you've liked (text, author, media and engagement) to Excel, CSV or JSON. Back up your likes before they disappear. No API required. - [Twitter Replies Scraper](https://www.insightsocial.app/scraper/twitter-replies-scraper.md): Free Twitter replies scraper for Chrome. Export the replies to any tweet on X to CSV, Excel or JSON: reply text, author handle, likes, reposts, views, timestamps and parent reply IDs. Works as a Twitter comment scraper. No API key. --- # Twitter Posts Scraper Source: https://www.insightsocial.app/scraper/twitter-posts-scraper, updated 2026-10-18 > Export tweets from any X profile, list or your home feed to Excel or CSV: text, date, likes, reposts, replies, views and media. Free Chrome extension. - **Platform**: twitter - **Web version**: https://www.insightsocial.app/scraper/twitter-posts-scraper --- ## What is the Twitter Posts Scraper? InsightSocial's Twitter Posts Scraper is a free Chrome extension that exports tweets from an X profile, a list, a community, Explore or your home feed to Excel, CSV, JSON or Google Sheets. Each row has the text, date, link, author, likes, reposts, replies, quotes, views, bookmarks, media and hashtags. It runs in your own logged-in browser: no X API key. It works by reading what your own logged-in X session already sees. Open a timeline, pick 50, 100 or 300 posts in the side panel and click Scrape; the extension collects each post as X loads it. It never asks for your X password and never shows you anything your account couldn't already see: protected accounts stay visible only if you're an approved follower. ## Which X page to open | You want | Open this on X | Use | |---|---|---| | One account's posts | The profile (`x.com/username`) | This scraper | | Posts from a curated set of accounts | A list (`x.com/i/lists/...`) | This scraper | | What X is surfacing to you | Your home feed, Explore or a community | This scraper | | Posts matching a keyword, hashtag or date range | A search or hashtag page | [Twitter Search Scraper](/scraper/twitter-search-scraper) | | The replies under one tweet | The tweet itself | [Twitter Replies Scraper](/scraper/twitter-replies-scraper) | Profiles, lists and your home feed keep going in a background tab. Explore and community pages only load more posts while their tab is in front: keep the tab in front, and if you switch away the run waits and carries on when you return. ## Working with the file - **Engagement rate.** Divide *Likes + Reposts + Replies + Quotes* by *Views* for each post, then average across the export. Every input is in the file; nothing in the extension computes it for you. A posts export has no follower count, so for a follower-based rate take the follower count from the account's profile and divide by that instead. - **What performs.** Sort by views or likes, then compare post types (text, photo, video) to see which format earns the most. - **Competitors side by side.** Export each account's profile separately and stack the files: the columns are identical. Our [Twitter competitor analysis guide](/blog/twitter-competitor-analysis-guide) walks through the workflow. - **Dates.** There is no date filter in the panel. Filter the *Posted At* column afterwards, or use X search with `since:` and `until:` and the [Twitter Search Scraper](/scraper/twitter-search-scraper). --- ## Frequently Asked Questions ### What does each exported row contain? The post URL, author name and handle, text, date, likes, reposts, replies, quotes, views, bookmarks, post type (text, photo or video), media links, and the hashtags, mentions and links found in the text. There is no separate retweet or thread column; the *Conversation ID* column groups posts from the same conversation. ### How far back can I go on a profile? As far as X keeps loading the timeline for your session. The run stops at your count or when X stops serving older posts. ### Does it capture who posted, not just what? Yes. Every row carries the author's name and handle, so a home-feed or list export doubles as a map of which accounts are active. For bios and follower counts of many accounts at once, export a following list with the [Twitter Followers Scraper](/scraper/twitter-followers-scraper). ### How much does it cost? Scraping is free and unlimited on every plan. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99, or $7.99 a month billed yearly. Studio: 150,000 rows for $49 a month. One-time packs start at $2 for 250 rows. ### Is scraping tweets allowed? Collecting publicly visible posts for research, journalism or competitive analysis is a common practice: you're recording what your own session already displays. Review X's Terms of Service for your use case, respect applicable privacy laws (GDPR, CCPA), and don't republish scraped content as your own or use it for spam. --- ## Data Fields | Field | Type | Description | |-------|------|-------------| | Tweet Text | text | Full tweet content | | Author Username | text | @handle of poster | | Author Name | text | Display name | | Likes | number | Like count | | Reposts | number | Repost count | | Replies | number | Reply count | | Views | number | View count (when available) | | Quotes | number | Quote tweet count | | Bookmarks | number | Bookmark count | | Tweet Date | date | When tweeted | | Tweet URL | url | Direct link to tweet | | Media URLs | array | Attached images/videos | | Hashtags | array | Hashtags used | | Post Type | text | Text, photo or video | | Conversation ID | text | Groups posts from the same conversation | ## Features - Export tweets from a profile, list, community, Explore or your home feed - Likes, reposts, replies, quotes, views and bookmarks per post - Media links, hashtags, mentions and links per post - Keeps going in a background tab on profiles, lists and the home feed - Export to Excel, CSV, JSON or Google Sheets - Real-time progress in the side panel ## How to Use 1. **Install InsightSocial**: Add the extension from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Open a Timeline**: Go to a profile, a list, a community, Explore or your home feed while logged in to X. 3. **Open the Extension**: Click the InsightSocial icon to open the side panel. It recognises the page. 4. **Pick How Many**: Choose 50, 100 or 300 posts. 5. **Start Scraping**: Click Scrape. Profiles, lists and your home feed keep going in a background tab; on Explore and community pages keep the tab in front. 6. **Export Results**: Download Excel, CSV or JSON, or send the rows to Google Sheets. ## FAQ ### Can I extract tweets from any profile? Yes, from any public X profile. Protected accounts only show their posts to approved followers, and the extension sees exactly what your session sees. ### Which X pages does it work on? A profile, a list, a community, Explore and your home feed. For a keyword or hashtag, use the Twitter Search Scraper; for the replies under one tweet, the Twitter Replies Scraper. Profiles, lists and the home feed keep going in a background tab. Explore and community pages only load more posts while their tab is in front, so the run waits and carries on when you return. ### What engagement metrics are included? Likes, reposts, replies, quotes, views and bookmarks for every post, plus the post type (text, photo or video), media links, hashtags, mentions and links found in the text. There is no separate retweet or thread column; the Conversation ID column groups posts from the same conversation. ### How do I calculate engagement rate for tweets? In your spreadsheet: (Likes + Reposts + Replies + Quotes) / Views for each post, then average across the posts you exported. Every input is in the file. Nothing in the extension computes it for you, and a posts export has no follower count, so for a follower-based rate take the account's follower count from its profile and divide by that instead. ### Can I filter tweets by date? Not in the panel. For a date range, use X search with since: and until: and the Twitter Search Scraper. On a profile, the run starts from the newest post and you filter the Posted At column afterwards. ### How far back can I scrape tweets? As far as X keeps loading the timeline for your session. The run stops at your count or when X stops serving older posts. ### How much does it cost? Scraping is free and unlimited on every plan. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99, or $7.99 a month billed yearly. ## Related scrapers - [Twitter Search Scraper](https://www.insightsocial.app/scraper/twitter-search-scraper.md): Free Twitter search scraper for Chrome. Export the tweets from any X keyword search, advanced search or hashtag page to CSV, Excel or JSON: text, author, likes, reposts, replies, views, bookmarks and media. No API key. - [Twitter Replies Scraper](https://www.insightsocial.app/scraper/twitter-replies-scraper.md): Free Twitter replies scraper for Chrome. Export the replies to any tweet on X to CSV, Excel or JSON: reply text, author handle, likes, reposts, views, timestamps and parent reply IDs. Works as a Twitter comment scraper. No API key. - [Twitter Profile Scraper](https://www.insightsocial.app/scraper/twitter-profile-scraper.md): Export an X (Twitter) profile's posts, followers or following to Excel or CSV. Likes, reposts, views per post; bio and counts per follower. Free extension. - [Twitter Followers Scraper](https://www.insightsocial.app/scraper/twitter-followers-scraper.md): Export an X account's followers or following to Excel or CSV, with bio, location, website, follower counts and join date per account. Free extension. --- # Twitter Followers Scraper Source: https://www.insightsocial.app/scraper/twitter-followers-scraper, updated 2026-10-18 > Export an X account's followers or following to Excel or CSV, with bio, location, website, follower counts and join date per account. Free extension. - **Platform**: twitter - **Web version**: https://www.insightsocial.app/scraper/twitter-followers-scraper --- ## What is the Twitter Followers Scraper? InsightSocial's Twitter Followers Scraper is a free Chrome extension that exports an X account's followers or following list to Excel, CSV or JSON. Each row is one account with bio, location, website, follower and following counts, post count, join date and verified badge. X often stops loading someone else's follower list after about 50 to 70 accounts; following lists usually go further. It works through your own logged-in X session. You open a profile, pick Followers or Following in the side panel, and the extension opens the right list page and collects accounts as X loads them. It never asks for your X password and sees exactly what your session sees: protected accounts' lists stay off-limits unless you're an approved follower. ## How big a list you will get Pick 50, 100 or 500 accounts. The run stops at your number or when X stops loading the list, whichever comes first. - **Someone else's followers.** X usually stops serving another account's follower list after about 50 to 70 accounts, however large the account is. Treat it as a sample, not the full audience. - **Following lists.** These usually go further than follower lists. - **Short lists** come back complete either way. The run keeps going in a background tab while you work in another; just keep the tab open. ## Working with the file - **Who an account listens to.** A following list shows its sources and peers, each with bio, website and counts. Filter the Bio column for job titles or topics and sort by Followers. - **Overlap between two accounts.** Export each list and match on handle (a `VLOOKUP` or a pandas merge). Accounts in both lists are the shared audience. - **Verified accounts.** Filter the verified and blue-verified columns. --- ## Frequently Asked Questions ### What do I get for each account? Handle, display name, profile URL, bio, location, website, follower and following counts, post count, join date and verified badge. Bio, location and website are blank when the account left them empty. ### Can I scrape the followers of any account? Any public account, yes, within the limit X sets on how much of the list it shows. Protected accounts hide their lists from non-followers: if X doesn't show your session the list, the scraper can't see it either. ### What's the difference between scraping followers and following? Followers answer "who listens to this account". Following answers "who this account listens to". Both produce the same per-account columns, so you can run each and compare them in one spreadsheet. ### How much does it cost? Scraping is free and unlimited on every plan. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99, or $7.99 a month billed yearly. Studio: 150,000 rows for $49 a month. One-time packs start at $2 for 250 rows. Other [Twitter/X scrapers](/scraper/twitter) draw from the same allowance. ### Is exporting follower lists allowed? Follower lists on public accounts are publicly visible, and recording what your own session displays for research or competitive analysis is a common practice. Review X's Terms of Service for your use case, comply with GDPR/CCPA where they apply, and never use exported lists for spam, mass DMs or harassment. --- ## Data Fields | Field | Type | Description | |-------|------|-------------| | Username | text | Follower's @handle | | Display Name | text | Profile name | | Bio | text | Profile description | | Followers | number | Their follower count | | Following | number | Their following count | | Location | text | Profile location | | Website | url | Profile website | | Verified | text | Verification status | | Posts Count | number | Their total post count | | Account Created | date | When the account joined | | Profile URL | url | Direct link to profile | ## Features - Export the followers or following list of any public account - Bio, location, website, counts and join date for each account - 50, 100 or 500 accounts per run - Keeps going in a background tab - Export to Excel, CSV, JSON or Google Sheets - No API access required ## How to Use 1. **Install the Extension**: Add InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Open Any Profile**: Go to any public Twitter/X profile. No need to click into the followers list yourself. 3. **Pick Followers or Following**: Open the sidebar and select the Followers or Following scrape type. The extension navigates to the right list automatically. 4. **Set Extraction Limit**: Choose how many accounts to collect: 50, 100 or 500. 5. **Start Scraping**: Click Scrape and watch follower data load in real-time. 6. **Export for Analysis**: Download CSV for your BI tool, research notebook, or analysis pipeline. ## FAQ ### Can I extract all followers from an account? Usually not from someone else's account. X often stops loading another account's follower list after about 50 to 70 accounts, so a run on a large account returns that many rows, whatever count you pick. Following lists usually go further, and short lists come back complete. ### What profile data is included for each follower? Handle, display name, profile URL, bio, location, website, follower and following counts, post count, join date and verified badge. ### Can I also extract following lists? Yes. Pick the Following scrape type from any profile (or open the /following page directly) and you get the same per-account columns for every account they follow. ### How many accounts can I pick per run? 50, 100 or 500. The run stops at your number or when X stops loading the list, whichever comes first. ### How is this useful for competitive research? Export the followers of competitor accounts or industry voices to study who they reach: sort by follower count, filter bios for keywords, and compare lists on handle. ### Can I filter followers by criteria? Not in the panel. After export, use spreadsheet filters to sort by follower count, location, or keywords in bios. ### Are verified accounts identified? Yes. Verified and blue-verified flags are in the export so you can filter for them. ### How much does it cost? Scraping is free and unlimited on every plan. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99, or $7.99 a month billed yearly. ## Related scrapers - [Twitter Profile Scraper](https://www.insightsocial.app/scraper/twitter-profile-scraper.md): Export an X (Twitter) profile's posts, followers or following to Excel or CSV. Likes, reposts, views per post; bio and counts per follower. Free extension. - [Twitter Posts Scraper](https://www.insightsocial.app/scraper/twitter-posts-scraper.md): Export tweets from any X profile, list or your home feed to Excel or CSV: text, date, likes, reposts, replies, views and media. Free Chrome extension. - [Twitter Replies Scraper](https://www.insightsocial.app/scraper/twitter-replies-scraper.md): Free Twitter replies scraper for Chrome. Export the replies to any tweet on X to CSV, Excel or JSON: reply text, author handle, likes, reposts, views, timestamps and parent reply IDs. Works as a Twitter comment scraper. No API key. - [Twitter Search Scraper](https://www.insightsocial.app/scraper/twitter-search-scraper.md): Free Twitter search scraper for Chrome. Export the tweets from any X keyword search, advanced search or hashtag page to CSV, Excel or JSON: text, author, likes, reposts, replies, views, bookmarks and media. No API key. --- # Twitter Likes Scraper Source: https://www.insightsocial.app/scraper/twitter-likes-scraper, updated 2026-10-18 > Free Twitter/X Likes Scraper. Export the posts you've liked (text, author, media and engagement) to Excel, CSV or JSON. Back up your likes before they disappear. No API required. - **Platform**: twitter - **Web version**: https://www.insightsocial.app/scraper/twitter-likes-scraper --- ## What is the Twitter Likes Scraper? The InsightSocial Twitter Likes Scraper is a free Chrome extension that exports the posts you've liked on Twitter/X (with text, author details, media links, engagement counts and dates) into CSV, Excel or JSON. No developer API and no rate-limit tier. It runs inside your own logged-in session and reads what X already shows you on your Likes page (`x.com/i/history/likes`, where X now sends your profile's Likes tab). Since X made likes private in 2024, only you can see your own likes, so only you can archive them. The run keeps going in a background tab while you work in another. People use it to back up curated reading before authors delete posts, to audit what a brand account has engaged with across campaigns, or to turn an unsearchable feed into a spreadsheet they can actually filter. ### Who is it for? - **Content researchers** turning months of likes into a searchable dataset of ideas and sources - **Social media managers** auditing what their brand account has engaged with per campaign - **Writers and curators** recovering saved threads and articles from a feed X won't let them search - **Trend watchers** analyzing which topics, formats, and authors dominate their engagement - **Personal archivists** backing up liked posts before they vanish behind deletions and suspensions - **Analysts** feeding liked-post data into notebooks and BI tools to study engagement patterns ### Key Benefits - **Your likes in a file**: liked posts with text, author, media, and engagement counts - **Automatic navigation**: pick "Liked Posts" on your profile and the extension opens your Likes page for you - **Media URLs captured**: image and video links preserved alongside each post - **Deleted-proof backup**: your export keeps a copy after authors delete or accounts get suspended - **No API, no code**: runs on your own Likes tab; no developer account or API key needed - **Excel, CSV, JSON export**: feeds directly into Sheets, notebooks, or a BI pipeline --- ## How to Use the Twitter Likes Scraper ### Step 1: Install the Extension Add InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. ### Step 2: Open Your Likes While logged in to X, open `x.com/i/history/likes`, or your own profile (`x.com/yourusername`). Likes are only visible to their owner, so this only works for the account you're logged into. ### Step 3: Open the InsightSocial Sidebar Click the InsightSocial icon. The sidebar opens on the right and recognises your Likes page or your profile. ### Step 4: Pick "Liked Posts" Select the Liked Posts scrape type. From your profile, the extension opens your Likes page for you. ### Step 5: Set a Target and Start Choose how many liked posts to collect: 50, 100 or 250. Click "Scrape" and watch the live preview fill in. ### Step 6: Export Your Archive Click "Export" and pick CSV (drops straight into Sheets or Excel), .xlsx (native Excel with formatting), or JSON (for scripts and BI). Every scrape also stays in the [InsightSocial portal](/portal) under your account history, ready to re-export later. --- ## Frequently Asked Questions ### Can I scrape someone else's likes? No. X made likes private in 2024. They're only visible to the account owner while logged in. The scraper works on your own liked posts and nothing else. For competitor engagement patterns, use the [Twitter Posts Scraper](/scraper/twitter-posts-scraper) on their timeline instead. ### What exactly gets captured for each liked post? Post text and post type (text, photo or video), media links, the original author's username, display name, and verified status, engagement counts (likes, reposts, replies, views), the post URL, and the timestamp. It's a record of the post as it appeared on your Likes page. ### How far back does the export reach? As far as X keeps loading your Likes timeline. The run stops at your count or when X stops serving older likes, and X sometimes returns fewer likes than you have. ### Why bother exporting instead of just scrolling the tab? The Likes tab has no search, no filters, and no way to sort. Worse, posts silently disappear when the author deletes them or their account gets suspended. An export gives you a copy you can search. For competitor content patterns rather than personal archives, the [Twitter Posts Scraper](/scraper/twitter-posts-scraper) is a better fit. ### Do I need a Twitter/X API key or developer account? No. The extension works on the page in your browser while you're signed in. There's no developer account to set up, no API subscription, no rate-limit tier to worry about. ### How much does it cost? Scraping is free and unlimited on every plan. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99, or $7.99 a month billed yearly. Studio: 150,000 rows for $49 a month. One-time packs start at $2 for 250 rows. You see the results before you spend anything, so you can export just the stretch you want. ### Where does my exported data live? The scrape stays in your private [InsightSocial portal](/portal), tied to your account and no one else's. The data itself flows only between your browser and your own InsightSocial account: we don't sell or share it, and we never see your Twitter/X password. See the [Twitter competitor analysis guide](/blog/twitter-competitor-analysis-guide) for ideas on turning liked-post archives into strategy input. --- ## Data Fields | Field | Type | Description | |-------|------|-------------| | Post Text | text | Full text of the liked post | | Author Username | text | Original poster's @handle | | Author Name | text | Original poster's display name | | Verified | text | Author verification status | | Post Type | text | Text, photo or video | | Media URLs | array | Attached image / video links | | Engagement | number | Likes, reposts, replies, views | | Post URL | url | Direct link to the post | | Timestamp | date | When the post was published | ## Features - Export your liked posts, 50, 100 or 250 per run - Opens your Likes page from your profile - Media URLs captured with every post - Author and engagement data included - Excel, CSV, and JSON export - No API access required ## How to Use 1. **Install the Extension**: Add InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Open Your Likes**: While logged in to X, open x.com/i/history/likes, or your own profile. X now redirects your profile's Likes tab to that page. 3. **Open InsightSocial**: Click the extension icon to open the sidebar panel. 4. **Pick Liked Posts**: Select the Liked Posts scrape type. From your profile, the extension opens your Likes page for you. 5. **Set a Target**: Choose how many liked posts to collect: 50, 100 or 250. 6. **Export Your Likes**: Download the archive as Excel (.xlsx), CSV, or JSON. ## FAQ ### Can I scrape another account's likes? No. X made likes private in 2024, so likes are only visible to the account owner while logged in. The scraper works on your own liked posts. ### What data is captured for each liked post? Post text, post type (text, photo or video), media links, the original author's handle, display name and verified status, engagement counts (likes, reposts, replies, views), the post URL and the date. ### How far back can I export my likes? As far as X keeps loading your Likes timeline. The run stops at your count (50, 100 or 250) or when X stops serving older likes, and sometimes X returns fewer than you have. ### Why export likes instead of just scrolling the tab? X's Likes page has no search and no filters, and posts disappear when authors delete them or accounts get suspended. An export gives you a copy you can search. ### Do I need a Twitter/X API key? No. The extension works directly in your browser while you're logged in: no developer account, no API costs, no rate-limit tiers. ### What export formats are supported? Excel (.xlsx), CSV, and JSON: ready for spreadsheets, notebooks, or any analysis pipeline. ### What's the best tool for exporting Twitter likes? For your own likes, without code: open x.com/i/history/likes while logged in, open InsightSocial, pick 50, 100 or 250 and click Scrape. The run keeps going in a background tab. Export to Excel, CSV or JSON. Scraping is free; exporting is free for 500 rows a month. ## Related scrapers - [Twitter Posts Scraper](https://www.insightsocial.app/scraper/twitter-posts-scraper.md): Export tweets from any X profile, list or your home feed to Excel or CSV: text, date, likes, reposts, replies, views and media. Free Chrome extension. - [Twitter Followers Scraper](https://www.insightsocial.app/scraper/twitter-followers-scraper.md): Export an X account's followers or following to Excel or CSV, with bio, location, website, follower counts and join date per account. Free extension. - [Twitter Profile Scraper](https://www.insightsocial.app/scraper/twitter-profile-scraper.md): Export an X (Twitter) profile's posts, followers or following to Excel or CSV. Likes, reposts, views per post; bio and counts per follower. Free extension. --- # Twitter Search Scraper Source: https://www.insightsocial.app/scraper/twitter-search-scraper, updated 2026-10-15 > Free Twitter search scraper for Chrome. Export the tweets from any X keyword search, advanced search or hashtag page to CSV, Excel or JSON: text, author, likes, reposts, replies, views, bookmarks and media. No API key. - **Platform**: twitter - **Web version**: https://www.insightsocial.app/scraper/twitter-search-scraper --- ## What is the Twitter Search Scraper? The InsightSocial Twitter search scraper is a free Chrome extension that exports the tweets behind any X search to CSV, Excel, JSON or Google Sheets. Search a keyword, an exact phrase, an advanced query or a hashtag on x.com, open the sidebar, and every tweet X loads becomes one row: the text, when it was posted, likes, replies, reposts, quotes, views, bookmarks, media links, and who posted it. There is no developer account, no API key and no query language to learn. The extension doesn't run its own search. It reads the results X already serves to your logged-in browser tab, so anything X's search box accepts, the scraper can export, including date ranges and the other operators covered below. One thing to know before you start, because it changes how you run it: **X search only loads more results while its tab is on screen.** Profiles, lists, your home feed and reply threads keep collecting when you switch to another tab. Search and hashtag pages don't, and neither do Explore and community pages. The sidebar says so under the Start button, and the section on limits below explains why. ### Two ways in: keyword search and hashtag pages The extension recognizes two X pages as search sources. Both use the same Posts scrape type and export the same columns: | Source | Example URL | What gets collected | |---|---|---| | **Search** | `x.com/search?q=standing desk&f=live` | The tweets X returns for your query on the tab you picked (Top or Latest) | | **Hashtag** | `x.com/hashtag/buildinpublic` | The tweets X shows for that hashtag | The sidebar shows the source back to you as `Search: standing desk` or `#buildinpublic`, so you can confirm the query before anything runs. The same label is saved on every exported row in the Source Name column, which lets you stack several searches into one sheet and still tell them apart. ### Searching by date, account or language Because the scraper exports whatever X renders, X's own advanced search operators work as filters. Type them into the search box or build them with X's Advanced Search form: - `"exact phrase"` for an exact match - `since:2026-09-01 until:2026-10-01` for a date range, which is how you search Twitter by date - `from:handle` for one account's tweets, `to:handle` for replies sent to it - `lang:en` to keep one language - `min_faves:100` or `min_retweets:20` to skip low-engagement posts - `filter:media` for tweets with images or video, or `-filter:replies` to drop replies Pick **Latest** for a chronological record of everything matching, or **Top** for X's ranked selection. Latest is the better choice for monitoring and research datasets because it isn't filtered by X's ranking. ### Who is it for? - **Brand and product teams** exporting every recent mention of a product name, including misspellings and competitors' names - **Researchers** building keyword and hashtag datasets for discourse, sentiment or misinformation studies - **Marketers** finding which posts on a topic earned the most views and reposts before planning content - **Analysts** tracking how a campaign hashtag spreads over a date range - **Agencies** pulling topic and competitor mentions into a weekly client report - **Journalists** collecting public reaction to a launch, statement or event in one sheet --- ## How to Use the Twitter Search Scraper ### Step 1: Install the Extension Add InsightSocial from the Chrome Web Store. The icon appears in your toolbar. ### Step 2: Run Your Search on X Log in to X, then search your keyword or advanced query, or open a hashtag page. X only shows search results to signed-in accounts, and the extension reads your own session. It never asks for your password. ### Step 3: Open the Sidebar Click the InsightSocial icon. It detects the Search or Hashtag page and offers the **Posts** scrape type, listing the fields it will collect: post text, post type, media URLs, likes, reposts, replies, quotes, views, bookmarks, author details, post URL and timestamp. ### Step 4: Pick How Many Posts Choose 50, 100 or 300 posts. For a first run on an unfamiliar query, 100 shows you quickly whether the search returns what you expected. ### Step 5: Start Scraping, With the Tab in Front Click "Scrape" and keep the X tab visible. Tweets stream into the sidebar's live preview as each page of results loads. If you switch away, the run waits; switch back and it carries on. It stops when it reaches your number or when X stops returning results. ### Step 6: Export Click "Export" and choose CSV, Excel (.xlsx), JSON, or Google Sheets. Every run also syncs to your private [InsightSocial portal](/portal), where you can sort by views or likes, search the text, and export again later. --- ## What You Get for Each Tweet | Column group | Fields | |---|---| | **The tweet** | Post URL, content, posted at (UTC), post type (text, photo or video), post ID | | **Engagement** | Likes, replies, reposts, quotes, views, bookmarks | | **Author** | Display name, @handle, profile URL, avatar, author ID, verified and blue-verified flags | | **Media** | Image URLs, video URLs, first media URL and media type | | **Pulled from the text** | Hashtags, @mentions, links, plus any email address or phone number written in the tweet | | **Provenance** | Source type (search or hashtag), the query, scraped at, session ID | Hashtags, mentions and links are split into their own columns, so counting the most-used co-hashtags in a campaign, or the domains people link to on a topic, is a pivot table instead of a text-parsing job. --- ## How It Compares There are three common ways to get tweets for a keyword into a spreadsheet. They suit different jobs: | | InsightSocial extension | Official X API | Hosted scraping services | |---|---|---|---| | Setup | Install, log in to X, search | Developer account, app keys, code | Vendor account, enter queries in their form or API | | Query syntax | X's own search box and operators | API query language | Varies by vendor | | Where it runs | Your own browser tab | Your server or script | The vendor's servers | | Runs unattended | No, the search tab stays in front | Yes | Yes | | Sees what | What your logged-in account sees | What your API access allows | What the vendor's accounts see | | Output | CSV, Excel, JSON, Google Sheets | JSON | Usually JSON or CSV | If you need tweets streaming into a pipeline overnight, an API or a hosted service fits better. If you need a clean sheet of tweets for a query you can type, from searches you can already see, without writing code, the extension is the shortest path. --- ## Frequently Asked Questions ### Is it free? Scraping is free and unlimited on every plan. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99, or $7.99 a month billed yearly. Studio: 150,000 rows for $49 a month. One-time packs start at $2 for 250 rows. ### Do I need an API key? No. There is no developer app, no bearer token and no rate-limit tier to manage. The extension reads the results x.com loads in your browser. ### Does the search tab need to stay in front? Yes, for Search and Hashtag pages. X only lets its own page load the next set of search results, so the run scrolls the page like you would. If you switch tabs it pauses and carries on when you come back; the side panel says so before you start. ### How do I export a month of tweets on a busy keyword? Run several shorter searches with X's `since:` and `until:` operators, for example one week each, instead of one long search. Each run is its own session, and the Source Name column keeps them apart when you combine the files. ### How many tweets can I export from a search? Pick 50, 100 or 300. The practical ceiling is how many results X returns for your query; when X stops serving pages, the run ends with what it has. ### Does it work as a Twitter hashtag scraper? Yes. Open any `x.com/hashtag/...` page and the sidebar detects it as a Hashtag source with the same columns as a keyword search. To combine a hashtag with other filters, search it instead, for example `#buildinpublic lang:en min_faves:20`. ### Can I export tweets from one account instead of a search? You can, with `from:handle` in a search, but the [Twitter Posts Scraper](/scraper/twitter-posts-scraper) is the better route: open the profile and it collects the account's timeline, which keeps going in a background tab and isn't limited by what X's search index returns. The [Twitter Profile Scraper](/scraper/twitter-profile-scraper) covers the same profile page. ### Can I get the replies under the tweets I found? A search export gives you each tweet's reply count. To export the replies themselves, open the tweet and use the [Twitter Replies Scraper](/scraper/twitter-replies-scraper), which collects the reply thread under one post with each reply's author and engagement. Going further with the people you found? The [Twitter Followers Scraper](/scraper/twitter-followers-scraper) exports who follows any of them, and the [Twitter Posts Scraper](/scraper/twitter-posts-scraper) exports an account's own posts with likes, reposts and views. --- ## Data Fields | Field | Type | Description | |-------|------|-------------| | Post URL | url | Direct link to the tweet | | Content | text | Full tweet text | | Posted At | date | When the tweet was posted (UTC) | | Author Name | text | Display name of the poster | | Author Handle | text | @username of the poster | | Author Profile URL | url | Link to the poster's X profile | | Author Verified | text | Verified or blue-verified badge | | Likes | number | Like count | | Replies | number | Reply count | | Reposts | number | Repost (retweet) count | | Quotes | number | Quote count | | Views | number | View count where X shows one | | Bookmarks | number | Bookmark count | | Post Type | text | Text, photo or video | | Images / Videos | array | URLs of attached media | | Hashtags | array | Hashtags found in the text | | Mentions | array | @mentions found in the text | | Links | array | URLs found in the text | | Source Name | text | The search query or hashtag the row came from | ## Features - Export tweets from any X keyword search, advanced search or hashtag page - Works with X's own operators: since:, until:, from:, lang:, min_faves:, filter: - Likes, replies, reposts, quotes, views and bookmarks on every tweet - Author handle, profile URL, avatar and verified flags per row - Hashtags, mentions and links split into their own columns - CSV, Excel, JSON or Google Sheets export ## How to Use 1. **Install InsightSocial**: Add the free extension from the Chrome Web Store. 2. **Run Your Search on X**: Log in to X and search a keyword, phrase or advanced query, or open a hashtag page. Pick the Top or Latest tab. 3. **Open the Sidebar**: Click the InsightSocial icon. It detects the Search or Hashtag page and shows your query back to you. 4. **Pick How Many Posts**: Choose 50, 100 or 300 posts. 5. **Start and Keep the Tab in Front**: Click Scrape. X search only loads more results while its tab is visible, so leave it in front until the run finishes. 6. **Export**: Download CSV, Excel or JSON, or send the rows to Google Sheets. ## FAQ ### Is this Twitter search scraper free? Scraping is free and unlimited on every plan. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99, or $7.99 a month billed yearly. One-time packs start at $2 for 250 rows. ### Do I need a Twitter/X API key or developer account? No. The extension reads the search results X already loads in your own logged-in browser tab. There is no developer app to register and no token to manage. You do need to be logged in to X, because X only shows search results to signed-in accounts. ### Can I use advanced search operators like since:, until: or from:? Yes. The extension exports whatever results page X shows, so any query X's own search accepts works: exact phrases in quotes, from:handle, to:handle, since:YYYY-MM-DD and until:YYYY-MM-DD for a date range, lang:en, min_faves:100, filter:media, -filter:replies. Build the query in X's search box or Advanced Search form, then start the scrape. ### Does it work on hashtag pages? Yes. Open x.com/hashtag/yourtag (or click any hashtag) and the sidebar detects it as a Hashtag source. It collects the posts X shows for that tag, with the same columns as a keyword search. ### Why does the scrape pause when I switch tabs? X's search timeline only fetches the next page when its tab is on screen, and it refuses a re-sent request for the next page, so the extension cannot continue in the background the way it does for profiles, lists and replies. The sidebar tells you this before you start ("Keep this tab in front while it runs"). Switch back and the run picks up where it stopped. ### How many tweets can I export from one search? Pick 50, 100 or 300 posts. How deep a search goes is up to X: when it stops serving more results the run ends with what it has collected. Popular keywords on the Latest tab go deepest; the Top tab is a ranked selection and usually ends sooner. For a long date range, split it into several since:/until: windows and run each one. ### What data do I get for each tweet? Post URL, content, posted time, likes, replies, reposts, quotes, views, bookmarks, post type (text, photo or video), image and video URLs, the hashtags, mentions and links found in the text, and the author's display name, @handle, profile URL, avatar, ID and verified/blue-verified flags. Each row also records the search it came from. ### Can I search tweets from protected accounts? Only if your own account follows them, because X only returns protected posts to approved followers. The extension sees exactly what your session sees and nothing more. ## Related scrapers - [Twitter Posts Scraper](https://www.insightsocial.app/scraper/twitter-posts-scraper.md): Export tweets from any X profile, list or your home feed to Excel or CSV: text, date, likes, reposts, replies, views and media. Free Chrome extension. - [Twitter Profile Scraper](https://www.insightsocial.app/scraper/twitter-profile-scraper.md): Export an X (Twitter) profile's posts, followers or following to Excel or CSV. Likes, reposts, views per post; bio and counts per follower. Free extension. - [Twitter Followers Scraper](https://www.insightsocial.app/scraper/twitter-followers-scraper.md): Export an X account's followers or following to Excel or CSV, with bio, location, website, follower counts and join date per account. Free extension. --- # Twitter Replies Scraper Source: https://www.insightsocial.app/scraper/twitter-replies-scraper, updated 2026-10-15 > Free Twitter replies scraper for Chrome. Export the replies to any tweet on X to CSV, Excel or JSON: reply text, author handle, likes, reposts, views, timestamps and parent reply IDs. Works as a Twitter comment scraper. No API key. - **Platform**: twitter - **Web version**: https://www.insightsocial.app/scraper/twitter-replies-scraper --- ## What is the Twitter Replies Scraper? The InsightSocial Twitter replies scraper is a free Chrome extension that exports the replies under any tweet on X to CSV, Excel, JSON or Google Sheets. Open a tweet, start the scrape from the sidebar, and each reply becomes one row: the reply text, when it was posted, likes, replies, reposts, quotes, views and bookmarks, plus the replier's name, @handle, profile URL and verified status. X calls them replies. Plenty of people call them comments, so if you were looking for a Twitter comment scraper or an X comments exporter, this is the same thing. It works through your own logged-in X session. The extension reads the conversation X already loads for the tweet, page by page, the same requests X's page makes as you scroll. It doesn't call the X API, doesn't ask for your password, and only sees what your account can see. Reply threads are where the reaction to a post actually lives. A view count tells you a tweet travelled; the replies tell you whether people agreed, what they asked, and which answers the audience itself liked. As a spreadsheet, that's material for sentiment analysis, FAQ mining, giveaway entry lists and voice-of-customer research. ### What gets collected from one tweet A replies run produces two things: | Output | What it holds | |---|---| | **The original tweet** | Its URL, author, text, likes, replies, views, bookmarks and posted time, shown above the replies in the portal | | **The replies** | One row per reply with its author, text, engagement, media and timestamp, plus the original tweet's details on every row | Because each reply row repeats the original tweet's URL, author and text, a replies file still makes sense on its own after you've combined several of them. ### Who is it for? - **Brand managers** reading every reaction to a launch, announcement or incident post - **Researchers** building reply datasets for sentiment, stance or discourse studies - **Giveaway hosts** exporting the handles of everyone who replied to a contest tweet - **Social analysts** finding the replies the audience itself liked and reposted most - **Community managers** triaging questions and complaints from a busy thread - **PR teams** measuring public response to a statement or news post --- ## How to Use the Twitter Replies Scraper ### Step 1: Install the Extension Add InsightSocial from the Chrome Web Store. The icon appears in your toolbar. ### Step 2: Open the Tweet Log in to X and open the single post, at a URL like `x.com/username/status/1234567890`. Being logged in matters: X shows signed-out visitors only a small part of a reply thread. ### Step 3: Open the Sidebar Click the InsightSocial icon. The sidebar recognizes a **Single Post** and offers the **Replies** scrape type, listing what it collects: the original post, each reply's author, text, engagement and timestamp, and the parent reply ID for conversation context. ### Step 4: Pick How Many Replies Choose 50, 100 or 500 replies. For a quick sentiment read, 100 is usually enough. For a giveaway or a full audit, pick 500 and let the run end when the conversation does. ### Step 5: Start Scraping Click "Scrape". Replies appear in the sidebar's live preview as each page of the conversation loads. You can switch to another tab while it runs; reply threads keep collecting in the background. ### Step 6: Export Click "Export" and choose CSV, Excel (.xlsx), JSON, or Google Sheets. The session also syncs to your private [InsightSocial portal](/portal), where the original tweet sits above its replies and you can sort the replies or search them by keyword. --- ## What You Get for Each Reply | Column group | Fields | |---|---| | **The reply** | Reply URL, content, posted at (UTC), reply ID, media URLs | | **Engagement** | Likes, replies, reposts, quotes, views, bookmarks | | **Replier** | Display name, @handle, profile URL, avatar, author ID, verified and blue-verified flags | | **Thread position** | Parent reply ID and depth (for replies to replies), whether the replier is the original poster, conversation ID | | **Pulled from the text** | @mentions, links, and any email address or phone number written in the reply | | **The original tweet** | Post URL, author name and handle, content, likes, replies and posted time | | **Provenance** | Source, scraped at, session ID | The "is the original poster" column is useful on its own: filter it to see every answer the author gave in their own thread. --- ## How Far a Run Goes The run ends on the first of these: 1. **Your number is reached.** The export holds exactly the count you picked. 2. **X signals the end of the conversation.** Each page X sends for a thread says whether another page exists. When it doesn't, the run stops, because there is nothing more to load in that view. 3. **X stops serving pages.** If no new replies arrive for a sustained stretch, for example because X is rate-limiting your account, the run ends and keeps what it collected. Trying again later usually goes further. Each run also has a fixed scroll budget, so on threads with thousands of replies, plan for a large sample rather than a complete copy. ### What isn't collected The extension follows the conversation as X lays it out. It doesn't press X's buttons: - **"Show more replies" sub-threads.** Replies to replies that X shows inline are collected, each with its parent reply ID. Deeper branches that X collapses behind a "Show more replies" link are not opened. - **"Show probable spam" and other hidden replies.** Replies X tucks behind those prompts aren't loaded. - **Deleted replies, replies from accounts you've blocked, and protected accounts you don't follow.** Your session can't see them, so the scraper can't either. How much X collapses varies by thread. On very large or heated threads, the collapsed parts can be a meaningful share, so check the tweet's reply count against your export before you report "all replies." --- ## How It Compares | | InsightSocial extension | Official X API | Copying replies by hand | |---|---|---|---| | Setup | Install, log in to X, open the tweet | Developer account, app keys, code | None | | Engagement per reply | Likes, reposts, quotes, replies, views, bookmarks | Depends on your API access | Whatever you copy | | Replier details | Handle, name, profile URL, avatar, verified flags | Yes | Manual | | Thread structure | Parent reply ID on replies to replies | Yes | Lost | | Runs in a background tab | Yes | Yes (server-side) | No | | Output | CSV, Excel, JSON, Google Sheets | JSON | Whatever you paste into | If you need replies flowing into a pipeline automatically, the API is built for that. If you need a clean sheet of the replies to a tweet you're looking at, without code, the extension is the shortest path. --- ## Frequently Asked Questions ### Is it free? Scraping is free and unlimited on every plan. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99, or $7.99 a month billed yearly. Studio: 150,000 rows for $49 a month. One-time packs start at $2 for 250 rows. ### Do I need an API key? No. There is no developer app and no token. The extension reads the conversation x.com loads in your browser. ### Can I pick a giveaway winner from the replies? Export the replies, then de-duplicate by Author Handle so each person counts once, and draw from that list. Each row has the replier's profile URL: to check whether a winner follows you, open the winner's profile link. ### How do I find which tweets are worth scraping? Start from the numbers. Export a profile's timeline with the [Twitter Posts Scraper](/scraper/twitter-posts-scraper), or a keyword or hashtag with the [Twitter Search Scraper](/scraper/twitter-search-scraper), sort by reply count, and run the replies scrape on the outliers. ### Can I scrape replies from several tweets at once? One session covers one tweet. Every reply row carries the original tweet's URL and ID, so several exports combine cleanly into one dataset. Working on an account rather than a single tweet? The [Twitter Posts Scraper](/scraper/twitter-posts-scraper) exports its posts with likes, reposts and views, and the [Twitter Profile Scraper](/scraper/twitter-profile-scraper) starts from its profile page. --- ## Data Fields | Field | Type | Description | |-------|------|-------------| | Reply URL | url | Direct link to the reply | | Content | text | Full reply text | | Posted At | date | When the reply was posted (UTC) | | Author Name | text | Display name of the replier | | Author Handle | text | @username of the replier | | Author Profile URL | url | Link to the replier's X profile | | Author Verified | text | Verified or blue-verified badge | | Likes | number | Likes on the reply | | Replies | number | Replies to the reply | | Reposts | number | Reposts of the reply | | Quotes | number | Quotes of the reply | | Views | number | Views on the reply | | Bookmarks | number | Bookmarks on the reply | | Media | array | Image and video URLs attached to the reply | | Mentions / Links | array | @mentions and URLs found in the reply text | | Parent Reply ID | text | The reply this one answers (blank when it answers the tweet) | | Post URL | url | The original tweet the replies are under | | Post Content | text | Text of the original tweet | | Post Author Handle | text | @username of the original poster | ## Features - Export the replies under any tweet you can open on X - Replier handle, display name, profile URL, avatar and verified flags - Likes, replies, reposts, quotes, views and bookmarks per reply - Parent reply ID on replies to replies for thread reconstruction - Keeps collecting while the tab is in the background - CSV, Excel, JSON or Google Sheets export ## How to Use 1. **Install InsightSocial**: Add the free extension from the Chrome Web Store. 2. **Open the Tweet**: Log in to X and open the single post whose replies you want (x.com/username/status/...). 3. **Open the Sidebar**: Click the InsightSocial icon. It detects a Single Post and offers the Replies scrape type. 4. **Pick How Many Replies**: Choose 50, 100 or 500 replies. 5. **Start Scraping**: Click Scrape. Replies stream into the live preview, and the run keeps going if you switch tabs. 6. **Export**: Download CSV, Excel or JSON, or send the rows to Google Sheets. ## FAQ ### Is this Twitter replies scraper free? Scraping is free and unlimited on every plan. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99, or $7.99 a month billed yearly. One-time packs start at $2 for 250 rows. ### Do I need a Twitter/X API key? No. The extension reads the conversation X loads in your own logged-in browser tab. There is no developer account, app or token. You do need to be logged in to X, because X shows signed-out visitors only a small part of a reply thread. ### Is this the same as a Twitter comment scraper? Yes. X calls them replies; many people call them comments. Open any tweet and the extension exports the replies underneath it, one row per reply, with the replier's handle, the reply text and its engagement. ### How many replies can I export from one tweet? Pick 50, 100 or 500. The run stops at your number, or earlier if X signals there are no more replies to load or stops serving pages. On very large threads, expect a large sample rather than every reply: X keeps some replies behind buttons the extension does not press (see the next question). ### Are nested replies and hidden replies included? Replies to replies are included when X shows them inline in the conversation, and each one carries its parent reply's ID. The extension does not click X's "Show more replies" or "Show probable spam" buttons, so sub-threads and replies X tucks behind those are not collected. Deleted replies and replies from accounts you have blocked are not visible to your session, so they are not collected either. ### Can I keep using my browser while it runs? Yes. Reply threads keep collecting when the tab is in the background: the extension requests the next page of the conversation itself, the same way X's page does. The sidebar confirms this under the Start button. ### What data comes with each reply? Reply URL, text, posted time, likes, replies, reposts, quotes, views and bookmarks; the replier's display name, @handle, profile URL, avatar, ID and verified flags; media URLs; mentions, links, and any email or phone number written in the reply; the parent reply ID for replies to replies; and the original tweet's URL, author, text, likes, replies and posted time. ### Can I export replies from several tweets? Run one session per tweet. Every reply row carries the original tweet's URL and ID, so you can combine several exports into one dataset and still tell which tweet each reply belongs to. ## Related scrapers - [Twitter Posts Scraper](https://www.insightsocial.app/scraper/twitter-posts-scraper.md): Export tweets from any X profile, list or your home feed to Excel or CSV: text, date, likes, reposts, replies, views and media. Free Chrome extension. - [Twitter Followers Scraper](https://www.insightsocial.app/scraper/twitter-followers-scraper.md): Export an X account's followers or following to Excel or CSV, with bio, location, website, follower counts and join date per account. Free extension. - [Twitter Profile Scraper](https://www.insightsocial.app/scraper/twitter-profile-scraper.md): Export an X (Twitter) profile's posts, followers or following to Excel or CSV. Likes, reposts, views per post; bio and counts per follower. Free extension. --- # LinkedIn Profile Scraper Source: https://www.insightsocial.app/scraper/linkedin-profile-scraper, updated 2026-10-18 > Save the LinkedIn profile you have open as one row in Excel or CSV: name, headline, location, current company, school, followers and connections. Free extension. - **Platform**: linkedin - **Web version**: https://www.insightsocial.app/scraper/linkedin-profile-scraper --- ## What is the LinkedIn Profile Scraper? InsightSocial's LinkedIn Profile Scraper is a free Chrome extension that saves the LinkedIn profile you have open as one row in Excel, CSV or JSON: name, headline, location, current company, school, website, follower and connection counts, and, for your 1st-degree connections, the email and phone LinkedIn shows you. It reads the page in your own logged-in browser, one profile per run. If LinkedIn hides something from you, such as contact details reserved for 1st-degree connections, the extension never sees it either. ## What a run saves depends on your LinkedIn layout LinkedIn is moving accounts to a new page layout, and the two layouts give different rows. | | Older layout | New layout | |---|---|---| | Name, headline, location, profile link | Yes | Yes | | Current company, school, website | Yes | Yes | | Followers and connections | Yes | Yes | | Current title, skills shown on the page | Yes | No | | Email and phone (1st-degree connections only) | Yes | No | | Full experience, education and skills lists | No | No | Which layout you see is LinkedIn's choice, not a setting in the extension. ## Profiles at scale The profile run is one profile at a time; there is no list or Sales Navigator mode. To collect many people with their name, headline and profile link in one run, start from a post instead: - [LinkedIn Post Likers Scraper](/scraper/linkedin-post-likers-scraper): everyone who reacted to a post, with the reaction type. - [LinkedIn Comments Scraper](/scraper/linkedin-comments-scraper): everyone who commented, with what they wrote. The headline is where most people put their job title and company, so those exports often answer "who are these people" without opening each profile. ## The person's posts On the same profile, pick **Posts** instead of **Profile** to export what they published, with reactions by type, comments and reposts. Profile and Posts are separate runs. See the [LinkedIn Posts Scraper](/scraper/linkedin-posts-scraper). ## Using the data responsibly LinkedIn's terms restrict automated collection, and that risk sits with the account you use. Keep runs to what you need, and handle personal data under GDPR, CCPA and the rules where you work. --- ## Data Fields | Field | Type | Description | |-------|------|-------------| | Name | text | First and last name | | Headline | text | Professional headline | | Location | text | Location shown on the profile | | Current Company | text | Company shown on the top card | | School | text | School shown on the top card | | Website | url | Website shown on the profile | | Followers | number | Follower count | | Connections | number | Connection count | | Profile URL | url | Direct link | | Current Title | text | Older layout only | | Skills | array | Skills shown on the page, older layout only | | Email | text | 1st-degree connections only, when LinkedIn shows it | ## Features - One profile per run, saved as one row - Name, headline, location, current company, school, website, followers, connections - Email and phone for your 1st-degree connections, where LinkedIn shows them - Excel, CSV, JSON or Google Sheets - Runs in your own logged-in browser ## How to Use 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Open the profile**: Go to the person's profile (linkedin.com/in/username) and click the InsightSocial icon. 3. **Pick Profile, click Scrape**: The side panel recognises the profile. Choose Profile (or Posts, one per run) and click Scrape. 4. **Export**: Download Excel, CSV or JSON, or send the row to Google Sheets. Every run stays in your account to re-open later. ## FAQ ### What does a profile run save? One row for the profile you have open: name, headline, location, current company, school, website, follower and connection counts, and profile link. For your 1st-degree connections it also saves the email and phone LinkedIn shows you. LinkedIn is moving accounts to a new page layout; on that layout a run saves the profile's top card only (name, headline, location, current company, school, website, followers, connections), without contact details. ### Does it export work history and skills? Only partly, and it depends on your account. On LinkedIn's older layout the row carries the current title and the skills LinkedIn shows on the page, not the full experience and education lists. On the new layout it saves the top card only. ### Can I scrape many profiles at once? No, one profile per run. To collect many people at once, with name, headline and profile link, use the LinkedIn Post Likers or LinkedIn Comments scrapers on a post. ### Does this work with LinkedIn Sales Navigator? No. Sales Navigator pages aren't recognised. It works on regular linkedin.com/in/ profiles. ### Can I get someone's email address? Only for your 1st-degree connections, and only when LinkedIn shows it to you on their contact info. It never guesses or looks up emails elsewhere. For anyone else the email column stays empty. ### Can I also get the person's posts? Yes, in a separate run: on the same profile pick Posts instead of Profile. The LinkedIn Posts Scraper page covers that. ### How much does it cost? Scraping is free and unlimited on every plan; only exporting is metered, one credit per row. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99, or $7.99 a month billed yearly. A row you already exported is free to export again. ### Is scraping LinkedIn against their terms? LinkedIn's terms restrict automated collection, and that risk sits with the account you use. The extension reads only what your own session already sees, one profile at a time. Handle the data under privacy laws like GDPR and CCPA. ## Related scrapers - [LinkedIn Posts Scraper](https://www.insightsocial.app/scraper/linkedin-posts-scraper.md): Export LinkedIn posts from a profile, company page or your feed to Excel or CSV: text, date, reactions by type, comments, and author name and headline. - [LinkedIn Post Likers Scraper](https://www.insightsocial.app/scraper/linkedin-post-likers-scraper.md): Export the people who reacted to a LinkedIn post to Excel or CSV: name, headline, profile link, connection degree and reaction type. Free Chrome extension. - [LinkedIn Comments Scraper](https://www.insightsocial.app/scraper/linkedin-comments-scraper.md): Export the comments and replies on a LinkedIn post to Excel or CSV: text, date, likes, replies, and each commenter's name, headline and profile link. Free. - [LinkedIn Company Scraper](https://www.insightsocial.app/scraper/linkedin-company-scraper.md): Free LinkedIn company posts scraper. Export a company page's posts with text, date, reactions by type, comments, reposts, media and post URL to CSV or Excel. --- # LinkedIn Posts Scraper Source: https://www.insightsocial.app/scraper/linkedin-posts-scraper, updated 2026-10-18 > Export LinkedIn posts from a profile, company page or your feed to Excel or CSV: text, date, reactions by type, comments, and author name and headline. - **Platform**: linkedin - **Web version**: https://www.insightsocial.app/scraper/linkedin-posts-scraper --- InsightSocial's LinkedIn Posts Scraper is a free Chrome extension that exports posts from a LinkedIn profile, a company page or your home feed to Excel, CSV, JSON or Google Sheets. Each row has the post text, date, link and type, reactions split by type, comments and reposts, and the author's name and headline, which holds their job title and company. It runs in your own logged-in browser. ## At a glance - **Works on**: A person's posts, a company page, and your home feed on accounts LinkedIn hasn't moved to its new feed - **Per run**: 50, 100 or 250 posts - **Each row**: Text, date, link, type, reactions by type, comments, reposts, media, article or document title, author name and headline - **Not supported**: Hashtag feeds, groups and search results - **Export to**: Excel, CSV, JSON, Google Sheets or a share link - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. On LinkedIn, that icon is how you open it. 3. **Open the page, click Scrape**: Go to a person's profile, a company page or your home feed. The side panel recognises it; pick 50, 100 or 250 posts and click Scrape. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. Every run stays in your account to re-open later. ## Which LinkedIn scraper to use This page covers the posts on a profile, a company page or your home feed. The other LinkedIn pages are the same extension aimed at one job: | You want | Open this on LinkedIn | Use | |---|---|---| | Posts with their reactions, comment counts and authors | A profile, a company page or your feed | This scraper | | The comments on one post, with each commenter's name and headline | The post itself | [LinkedIn Comments Scraper](/scraper/linkedin-comments-scraper) | | Everyone who reacted to one post, with the reaction type | The post itself | [LinkedIn Post Likers Scraper](/scraper/linkedin-post-likers-scraper) | | A company's posts, with company-page details explained | The company page | [LinkedIn Company Scraper](/scraper/linkedin-company-scraper) | | One person's profile as a row | Their profile | [LinkedIn Profile Scraper](/scraper/linkedin-profile-scraper) | ## Getting the author's details Every post row carries its author: **name**, **headline**, **profile link** and whether the author is a company page. LinkedIn has no separate job-title or company field on a post. Both live in the headline, for example *"Head of Growth at Acme"*, which is exported as written. - **Two columns from one.** Split *Author Headline* on `" at "` in Sheets or Excel. Headlines that don't follow the "Title at Company" pattern stay in the first column; check those by hand. - **Authors from many posts at once.** Scrape your home feed, or a company page whose posts are written by staff, and you get one author per post. Remove duplicates on *Author Profile URL* for a list of people. - **One post you already have open.** The name and headline are on the post. The extension doesn't take a single post link and return its author; on a post page it offers the comments and the reactions instead. ## Working with the file - **Engagement rate.** Divide *Reactions + Comments + Reposts* by the follower count shown on the profile or company page to compare accounts of different sizes. - **What a post made people feel.** The per-type columns tell a post that drew *Insightful* from one that drew *Funny*, which the total hides. - **Articles and documents.** A shared article or document arrives as its title, link and description (or page count), not its full text. - **Duplicates.** Running the same profile twice returns overlapping posts. Remove duplicates on *Post URL*. Exporting a row you already exported, from this run or an earlier one, costs nothing. --- ## FAQ ### How do I get the author's name, title and company from LinkedIn posts? Scrape the page the posts are on: a person's profile, a company page or your home feed. Every row carries the author's name, profile link and headline. LinkedIn has no separate job-title or company field on a post: both sit in the headline, for example "Head of Growth at Acme", which is exported as written, so split it on " at " in your spreadsheet if you need two columns. For one post you already have open, the author's name and headline are on the post itself; the extension doesn't take a single post link and return its author. ### Which LinkedIn pages does it work on? A person's profile (their posts), a company page (the company's posts) and your home feed. LinkedIn is moving some accounts to a new home feed that carries no post links; on those accounts the side panel says the feed can't be collected yet, while profiles and company pages still work. Hashtag feeds, groups and search results aren't supported. ### What does each post row contain? The post text, date, link and type (text, image, video, article, document or poll), total reactions and each reaction type (Like, Celebrate, Support, Love, Insightful, Funny), comment and repost counts, image and video links, a promoted flag, and the author's name, headline, profile link and whether the author is a company. For an article or a document, the row holds its title, link and description or page count, not the full article text. ### Are reactions broken down by type? Yes. Each row has the total and a column per reaction type: Like, Celebrate, Support, Love, Insightful and Funny. ### How many posts can I export per run? Pick 50, 100 or 250 posts. The run starts from the newest post and stops at the count, or earlier if LinkedIn stops loading older posts. Scraping is free and unlimited on every plan; only exporting is metered, one credit per row. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99, or $7.99 a month billed yearly. A row you already exported is free to export again. ### Can I filter posts by date? Not in the side panel. The run collects the count you pick, newest first; filter the Posted At column in your spreadsheet afterwards. ### Does it export the comments on a post? The posts scrape gives each post's comment count. To export the comments themselves, with each commenter's name and headline, open the post and use the LinkedIn Comments Scraper. To export the people who reacted, use the LinkedIn Post Likers Scraper. ### Do I need to keep the LinkedIn tab in front? No. Profile, company page and home feed runs keep going in a background tab while you work in another; just leave the tab open. ### Is scraping LinkedIn posts allowed? The extension reads only what your own logged-in session can already see, and it never posts, reacts or messages. LinkedIn's terms restrict automated collection, and that risk sits with the account you use, so keep volumes reasonable and handle the data under privacy laws like GDPR and CCPA. ## Related scrapers - [LinkedIn Comments Scraper](https://www.insightsocial.app/scraper/linkedin-comments-scraper.md): Export the comments and replies on a LinkedIn post to Excel or CSV: text, date, likes, replies, and each commenter's name, headline and profile link. Free. - [LinkedIn Post Likers Scraper](https://www.insightsocial.app/scraper/linkedin-post-likers-scraper.md): Export the people who reacted to a LinkedIn post to Excel or CSV: name, headline, profile link, connection degree and reaction type. Free Chrome extension. - [LinkedIn Company Scraper](https://www.insightsocial.app/scraper/linkedin-company-scraper.md): Free LinkedIn company posts scraper. Export a company page's posts with text, date, reactions by type, comments, reposts, media and post URL to CSV or Excel. - [LinkedIn Profile Scraper](https://www.insightsocial.app/scraper/linkedin-profile-scraper.md): Save the LinkedIn profile you have open as one row in Excel or CSV: name, headline, location, current company, school, followers and connections. Free extension. --- # LinkedIn Company Scraper Source: https://www.insightsocial.app/scraper/linkedin-company-scraper, updated 2026-10-18 > Free LinkedIn company posts scraper. Export a company page's posts with text, date, reactions by type, comments, reposts, media and post URL to CSV or Excel. - **Platform**: linkedin - **Web version**: https://www.insightsocial.app/scraper/linkedin-company-scraper --- ## What is the LinkedIn Company Scraper? The InsightSocial LinkedIn Company Scraper is a free Chrome extension that exports the posts a LinkedIn company page publishes. Open a company page, pick how many posts you want, and every post lands as one row: the text, when it went out, what kind of post it was, its media, a direct link, and how it performed (total reactions, reactions split by type, comments and reposts). Export it to CSV, Excel or JSON. It runs inside your own logged-in LinkedIn session. The extension opens the company's Posts tab and collects posts newest first, the same posts you would see by scrolling it yourself. No LinkedIn API key, no developer app, and nothing your account cannot already see. To set expectations clearly: **this is a company posts scraper, not a company profile scraper.** It does not export the About section. Industry, company size, headquarters, founded year, specialties and the page's follower count are not in the file. If those are what you need, the section on company profile details below explains where to get them. ### What you get, and what you don't | In the export | Not in the export | |---|---| | Post text, post type, publish date and time, post URL | Industry, company size, headquarters, founded year | | Total reactions plus Like, Love, Celebrate, Support, Insightful, Funny | Specialties, About description, website | | Comment count and repost count | Company follower count and employee list | | Image and video URLs, shared article or document title and link | Impressions or views (LinkedIn shows those only to page admins) | | Hashtags, mentions and links found in the post text | Comment text and commenter names (see the [comments scraper](/scraper/linkedin-comments-scraper)) | | Author name, page slug and page URL, promoted flag | The people who reacted (see the [post likers scraper](/scraper/linkedin-post-likers-scraper)) | ### Who is it for? - **Competitive analysts** auditing what a rival company publishes and which formats earn engagement - **B2B marketers** benchmarking their own page's cadence and reactions against peers - **Agencies** reporting on client and competitor company pages with real per-post numbers - **Employer branding teams** studying how other companies' hiring and culture posts perform - **Sales teams** reading a target account's recent announcements before reaching out - **Researchers** building datasets of how companies communicate on LinkedIn ### Key Benefits - **Per-post engagement, not page totals**: reactions, comments and reposts sit on each post's row, so you can sort by what worked - **Reaction types split out**: Celebrate-heavy launch posts and Insightful-heavy thought leadership look different, and the export shows it - **Post type on every row**: compare text, image, video, article, document and poll posts side by side - **Runs in the background**: start a run and switch tabs; company posts keep collecting - **Works on LinkedIn's new layout**: when the page loads posts in a way the extension cannot read while scrolling, it asks LinkedIn for them directly, page by page - **CSV, Excel or JSON**: pivot in a spreadsheet, chart in Excel, or load the JSON into a script --- ## How to Use the LinkedIn Company Scraper ### Step 1: Install the Extension Add InsightSocial from the Chrome Web Store and make sure you are signed in to LinkedIn in the same Chrome profile. The extension uses that session; it never asks for your LinkedIn password. ### Step 2: Open the Company Page Go to the company you want, at `linkedin.com/company/name`. You can start from the landing page, the About tab or the Posts tab. If you start anywhere other than Posts, the extension moves the tab to `linkedin.com/company/name/posts/` itself when the run begins, because that is the tab where LinkedIn loads the company's updates. ### Step 3: Open the Sidebar Click the InsightSocial icon in the toolbar. The sidebar detects the company page, shows its slug as the source, and offers **Posts**. ### Step 4: Pick How Many Posts Choose 50, 100 or 250. Fifty is enough for a quick read of what a company has been saying lately; 250 covers several months for most companies and gives you enough rows to compare formats. ### Step 5: Start the Run Click Scrape. Posts appear in the sidebar as they are collected, newest first. You can move to another tab while it works; the extension icon shows the count as it climbs and marks the run done when it finishes. Stop at any time and you keep what was collected. ### Step 6: Export Open the results page and export to CSV, Excel or JSON. The run is also saved in your [InsightSocial portal](/portal), so you can search, sort and export it again later. --- ## What a Company Posts Export Looks Like Each row is one post. The columns lead with what you usually look at first, then the detail: - **Post URL**, **Author Name**, **Author Handle** and **Author Profile URL**: the link to the post and the page that published it - **Content** and **Posted At (UTC)**: the full post text and its publish date and time - **Reactions**, **Comments**, **Reposts**: the engagement totals LinkedIn shows under the post - **Like**, **Love**, **Celebrate**, **Support**, **Insightful**, **Funny**: the reaction total broken down by type - **Hashtags**, **Mentions**, **Links**: pulled out of the post text, so campaign hashtags and outbound links are easy to count - **Post Type**: text, image, video, article, document or poll - **Images**, **Videos**, **Article**, **Document**: media URLs and the title and link of anything shared - **Is Promoted**, **Post ID**, **Post URN**, plus the source and the time it was collected Because the date and the engagement numbers are separate columns, the useful analysis is a few clicks away: posts per week, average reactions by post type, the ten best posts of the quarter, or which hashtags show up on the posts that did well. --- ## LinkedIn Company Scraper vs Other Ways to Get Company Posts | | InsightSocial extension | LinkedIn Page analytics export | Copy and paste | InsightSocial API | |---|---|---|---|---| | Which pages | Any company page you can open | Only pages you administer | Any page you can open | Any company page, by ID | | Runs where | Your own browser | LinkedIn admin tools | By hand | Our servers, called from your code | | Post text, date, link | Yes | Partly | Yes, slowly | Yes | | Reactions, comments, reposts per post | Yes, reactions split by type | Yes, plus impressions | Only what you retype | Yes | | Needs a LinkedIn login | Yes, your own | Yes, as page admin | Yes | No | | Setup | Install the extension | None, if you are an admin | None | API key and code | If the company page is yours, LinkedIn's own analytics export also gives you impressions, which no outside tool can see. For competitors and any page you do not run, the extension is the quickest route. If you want company posts inside a pipeline without a browser, the [LinkedIn company posts API](/social-media-api/linkedin/company-posts) returns the same kind of data as JSON. Hosted scrapers for LinkedIn company posts exist too; the extension's difference is that it runs in your own session and costs nothing to collect with. --- ## Use Cases ### Competitor content audit Export the last 250 posts from three competitors, put them in one sheet, and sort by reactions. Within minutes you can see which formats each company leans on, what its best posts have in common, and how often it publishes. Do the same for your own page and you have a benchmark. ### Posting cadence and timing The **Posted At** column turns a company page into a timeline. Count posts per week, look for gaps around launches or quiet periods, and see whether a competitor's engagement moved when its cadence did. ### Reaction mix as a signal A post with mostly Celebrate reactions reads differently from one with mostly Insightful. The per-type columns let you separate announcement posts from thought-leadership posts and see which kind a company's audience rewards. ### From the post to the people The company posts export tells you which posts drew a crowd. To see who was in that crowd, open one of those posts and run the [LinkedIn Comments Scraper](/scraper/linkedin-comments-scraper) for the comment thread or the [LinkedIn Post Likers Scraper](/scraper/linkedin-post-likers-scraper) for everyone who reacted. Then use the [LinkedIn Profile Scraper](/scraper/linkedin-profile-scraper) on the profiles that matter. ### Account research before outreach Before contacting a target account, export its last 50 posts and read them in one place: product launches, hiring pushes, events and partnerships. It is faster than scrolling the page, and the links take you straight to anything worth quoting. For posts from people rather than companies, or from your home feed, use the [LinkedIn Posts Scraper](/scraper/linkedin-posts-scraper). Every LinkedIn tool is listed on the [LinkedIn scraper overview](/scraper/linkedin). --- ## Company Profile Details Are Not in the Export Company profile scrapers that return industry, size range, headquarters and specialties are a different tool. The extension does not read the About section, and we would rather say so than sell you a file with empty columns. If you need those details, the [LinkedIn company API](/social-media-api/linkedin/company) looks up a company page by URL and returns its name, description, follower count, headquarters location, website and logo. It is a paid, per-call API rather than part of the free extension, and it also gives you the company ID that the [company posts API](/social-media-api/linkedin/company-posts) uses. --- ## Is Scraping LinkedIn Company Posts Allowed? Company posts are content an organization publishes on purpose to reach as many people as possible, which makes them among the least sensitive data on LinkedIn. LinkedIn's User Agreement still restricts automated collection, so collect at a normal pace, use the data for legitimate research, and quote posts accurately. The extension only reads what your own account can see, and it does not send your LinkedIn password or cookies to us. --- ## Data Fields | Field | Type | Description | |-------|------|-------------| | Post URL | url | Direct link to the post | | Author Name | text | Who published the post, normally the company itself | | Author Handle | text | The company's LinkedIn page slug | | Author Profile URL | url | Link to the company page that posted | | Content | text | Full post text | | Posted At | date | Publish date and time (UTC) | | Reactions | number | Total reaction count | | Like / Love / Celebrate / Support / Insightful / Funny | number | Reaction count by type | | Comments | number | Comment count | | Reposts | number | Repost count | | Post Type | text | Text, image, video, article, document or poll | | Images / Videos | array | Media URLs attached to the post | | Article / Document | text | Title and link of a shared article or document | | Hashtags / Mentions / Links | array | Pulled out of the post text | | Is Promoted | text | Whether LinkedIn marked the post as sponsored | | Post ID / Post URN | text | LinkedIn's identifiers for the post | ## Features - Export a LinkedIn company page's posts to CSV, Excel or JSON - Reactions broken down by type, plus comment and repost counts - Post text, type, date, media URLs and direct link - 50, 100 or 250 posts per run, newest first - Keeps collecting while the tab is in the background - No LinkedIn API key needed; runs in your own logged-in browser ## How to Use 1. **Install InsightSocial**: Add the free extension from the Chrome Web Store and sign in to LinkedIn in the same browser. 2. **Open a Company Page**: Go to any linkedin.com/company/name page. The landing page, About tab or Posts tab all work. 3. **Open the Sidebar**: Click the InsightSocial icon. The sidebar detects the company page and offers Posts. 4. **Pick How Many Posts**: Choose 50, 100 or 250 posts. 5. **Start the Run**: The extension opens the company's Posts tab if needed and collects posts newest first. 6. **Export**: Download CSV, Excel or JSON from the results page, or reopen the run later in your portal. ## FAQ ### Does the LinkedIn company scraper export company details like industry, size or headquarters? No. The extension exports a company page's posts, not its About section. Industry, company size, headquarters, founded year, specialties and follower count are not in the export. If you need company profile details, the InsightSocial API has a LinkedIn company endpoint that returns the company name, description, follower count, headquarters, website and logo for a page URL. It is a separate, paid per-call product. ### Is the LinkedIn company posts scraper free? Yes. Installing the extension and collecting posts costs nothing. Only exporting is metered, one credit per row, and a row you already exported is free to export again. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99, or $7.99 a month billed yearly. One-time packs start at $2 for 250 rows. ### Do I need a LinkedIn API key or developer access? No. There is no API key, app review or developer account involved. The extension reads the company's posts through your own logged-in LinkedIn session, so you do need to be signed in to LinkedIn in Chrome. ### How many posts can I export from one company page? Each run collects up to the number you pick: 50, 100 or 250. A run also ends early when the company has published fewer posts or LinkedIn stops returning more. Each exported post counts as one row against your monthly allowance. ### Can I switch tabs while it scrapes a company page? Yes. Company posts keep collecting while the tab is in the background, and the extension icon shows the count as it climbs. You can stop a run at any time and keep what it has collected. ### Does it include the comments and the people who reacted to each post? The company posts export has the comment, repost and reaction counts for every post. To get the comment text and commenter names, or the list of people who reacted, open that single post and use the LinkedIn Comments Scraper or the LinkedIn Post Likers Scraper. ### Why did my run stop before reaching the number I asked for? Usually because the company has published fewer posts than you asked for, or LinkedIn stopped returning older ones. On accounts that LinkedIn has moved to its new page layout, the extension switches to asking LinkedIn for the posts directly after two scrolls that load nothing, which can make the first seconds of a run look idle. ### Can I scrape several LinkedIn companies at once? One company page per run. Open the next company page and start another run; each run is saved separately in your portal and can be exported on its own. ## Related scrapers - [LinkedIn Posts Scraper](https://www.insightsocial.app/scraper/linkedin-posts-scraper.md): Export LinkedIn posts from a profile, company page or your feed to Excel or CSV: text, date, reactions by type, comments, and author name and headline. - [LinkedIn Comments Scraper](https://www.insightsocial.app/scraper/linkedin-comments-scraper.md): Export the comments and replies on a LinkedIn post to Excel or CSV: text, date, likes, replies, and each commenter's name, headline and profile link. Free. - [LinkedIn Post Likers Scraper](https://www.insightsocial.app/scraper/linkedin-post-likers-scraper.md): Export the people who reacted to a LinkedIn post to Excel or CSV: name, headline, profile link, connection degree and reaction type. Free Chrome extension. - [LinkedIn Profile Scraper](https://www.insightsocial.app/scraper/linkedin-profile-scraper.md): Save the LinkedIn profile you have open as one row in Excel or CSV: name, headline, location, current company, school, followers and connections. Free extension. --- # LinkedIn Post Likers Scraper Source: https://www.insightsocial.app/scraper/linkedin-post-likers-scraper, updated 2026-10-18 > Export the people who reacted to a LinkedIn post to Excel or CSV: name, headline, profile link, connection degree and reaction type. Free Chrome extension. - **Platform**: linkedin - **Web version**: https://www.insightsocial.app/scraper/linkedin-post-likers-scraper --- ## What is the LinkedIn Post Likers Scraper? InsightSocial's LinkedIn Post Likers Scraper is a free Chrome extension that exports the people who reacted to a LinkedIn post to Excel, CSV, JSON or Google Sheets. Open the post, pick how many reactors to collect, and each person becomes a row with name, headline, profile link, connection degree and reaction type. Keep the tab in front while it runs. LinkedIn shows reactions as a scrolling list you can read but not export. The extension reads that same list inside your own logged-in session and turns it into rows. It only reads: it never sends messages, connection requests or reactions. ## How many reactors a run returns Pick 50, 100 or 500. The run stops at that count, or earlier if LinkedIn stops loading the list, so a post with thousands of reactions gives you the count you picked, not all of them. On a single post the run pauses while the tab is hidden; the side panel says so, and the run carries on when you switch back. A few members with strict privacy settings appear as "LinkedIn Member" with fewer fields. The extension exports what LinkedIn shows your session for each person. ## Working with the list - **Who reacted, by role.** The headline is where most people put their title and company. Filter or pivot on it to see which roles a topic reached. - **Reaction mix.** Count the *Reaction Type* column to see whether a post drew *Insightful* or *Funny*, which a single total hides. - **Your network vs. new reach.** The *Degree* column (1st, 2nd, 3rd+) shows how much of the engagement came from outside your connections. - **Duplicates across posts.** Export several posts and remove duplicates on the profile link to see who engages repeatedly. ## The comments and the post itself For what people wrote under the post, use the [LinkedIn Comments Scraper](/scraper/linkedin-comments-scraper) on the same page. For a profile's or company's posts with their reaction counts by type, use the [LinkedIn Posts Scraper](/scraper/linkedin-posts-scraper). ## Using the data responsibly Reactions are public engagement, and the extension captures only what your account already sees. LinkedIn's terms restrict automated collection, and that risk sits with the account you use. Keep volumes reasonable and handle personal data under GDPR and CCPA. --- ## Data Fields | Field | Type | Description | |-------|------|-------------| | Reactor Name | text | Full name of the person who reacted | | Headline | text | Their LinkedIn headline, usually title and company | | Profile URL | url | Direct link to their profile | | LinkedIn Username | text | Public identifier from the profile URL | | Connection Degree | text | 1st, 2nd, or 3rd+ | | Reaction Type | text | Like, Celebrate, Support, Love, Insightful, Funny | | Profile Photo URL | url | Reactor's profile image | | Post Reference | text | URN of the post the reaction belongs to | ## Features - Export the people who reacted to any LinkedIn post you can open - 50, 100 or 500 reactors per run - Reaction type per person (Like, Celebrate, Support, Love, Insightful, Funny) - Name, headline, profile link and connection degree - CSV, Excel, JSON and Google Sheets export ## How to Use 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Open the post**: Click the post's timestamp to open its own page (linkedin.com/posts/... or /feed/update/...). 3. **Pick Reactions, click Scrape**: Click the InsightSocial icon. The side panel recognises the post; pick Reactions, choose 50, 100 or 500 and click Scrape. Keep the tab in front while it runs. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. ## FAQ ### How do I see everyone who liked a LinkedIn post? LinkedIn's reactions list scrolls but can't be exported. Open the post, open InsightSocial, pick Reactions and choose 50, 100 or 500 reactors. Each person becomes a row with name, headline, profile link, connection degree and reaction type. On a very large post, a run returns the count you picked, not the whole list. ### Can I export likers from someone else's post? Yes. Any post you can open in your browser works: your own, a competitor's or an industry post. ### Does it capture the reaction type? Yes. Each row has the reaction the person left: Like, Celebrate, Support, Love, Insightful or Funny. ### How many reactors can I export per post? Pick 50, 100 or 500 per run. LinkedIn sometimes stops loading the list early, so a run can return fewer than you asked for. Scraping is free and unlimited on every plan; only exporting is metered, one credit per row. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99, or $7.99 a month billed yearly. ### Do I need to keep the tab in front? Yes. On a single post the run pauses while the tab is hidden, and the side panel says so. If you switch away, the run waits and carries on when you come back. ### Can it message everyone who liked a LinkedIn post? No. InsightSocial only reads and exports; it never sends messages, connection requests or reactions. ### Can I export LinkedIn post reactions to Excel? Yes. Download .xlsx, CSV or JSON, or send the rows to Google Sheets. ### Is scraping who liked a post allowed? Reactions are public engagement, and the extension reads only what your logged-in session already sees. LinkedIn's terms restrict automated collection, and that risk sits with the account you use, so keep volumes reasonable and handle the data under GDPR and CCPA. ## Related scrapers - [LinkedIn Comments Scraper](https://www.insightsocial.app/scraper/linkedin-comments-scraper.md): Export the comments and replies on a LinkedIn post to Excel or CSV: text, date, likes, replies, and each commenter's name, headline and profile link. Free. - [LinkedIn Posts Scraper](https://www.insightsocial.app/scraper/linkedin-posts-scraper.md): Export LinkedIn posts from a profile, company page or your feed to Excel or CSV: text, date, reactions by type, comments, and author name and headline. - [LinkedIn Profile Scraper](https://www.insightsocial.app/scraper/linkedin-profile-scraper.md): Save the LinkedIn profile you have open as one row in Excel or CSV: name, headline, location, current company, school, followers and connections. Free extension. --- # LinkedIn Comments Scraper Source: https://www.insightsocial.app/scraper/linkedin-comments-scraper, updated 2026-10-18 > Export the comments and replies on a LinkedIn post to Excel or CSV: text, date, likes, replies, and each commenter's name, headline and profile link. Free. - **Platform**: linkedin - **Web version**: https://www.insightsocial.app/scraper/linkedin-comments-scraper --- ## What is the LinkedIn Comments Scraper? InsightSocial's LinkedIn Comments Scraper is a free Chrome extension that exports the comments on a LinkedIn post to Excel, CSV, JSON or Google Sheets. Each comment is a row with its text, date, like and reply counts, and the commenter's name, headline and profile link; replies sit under the comment they answer. Choose 50, 100 or 500 top-level comments, and keep the tab in front while it runs. LinkedIn gives you no way to export a comment thread. The extension reads the thread through your own logged-in session and turns it into rows. It only reads: it never comments, reacts or messages. ## How much of a thread a run returns The number you pick counts top-level comments. Replies to those comments are collected after them and come on top, so a 100-comment run often returns more than 100 rows. On a single post the run pauses while the tab is hidden; the side panel says so, and the run carries on when you switch back. ## What the file holds depends on your LinkedIn layout LinkedIn is moving accounts to a new page layout. On both layouts every comment has its text, date, like and reply counts, the commenter's name, headline and profile link, and its place in the thread. On accounts that still have the older layout, each comment also carries a reaction breakdown by type, a link to the comment, and edited and pinned flags. On the new layout those columns are empty. Which layout you see is LinkedIn's choice, not a setting in the extension. ## Working with the thread - **Who is talking.** The headline is where most people put their title and company. Filter it for a role or industry keyword to read what that group said. - **What landed.** Sort by likes or reply count to read the comments that drew a response first. - **Themes.** Paste the *Content* column into a spreadsheet or text tool and tag questions, objections and requests. - **Replies in context.** Each reply carries the id of the comment it answers, so you can rebuild sub-threads. ## Reactions and the post itself For everyone who reacted to the same post, with the reaction type, use the [LinkedIn Post Likers Scraper](/scraper/linkedin-post-likers-scraper). For a profile's or company's posts with their reaction and comment counts, use the [LinkedIn Posts Scraper](/scraper/linkedin-posts-scraper). ## Using the data responsibly Comments are public contributions, and the extension captures only what your account already sees. LinkedIn's terms restrict automated collection, and that risk sits with the account you use. Keep volumes reasonable and handle personal data under GDPR and CCPA. --- ## Data Fields | Field | Type | Description | |-------|------|-------------| | Comment Text | text | Full comment content | | Commenter Name | text | Full name of the commenter | | Headline | text | Their LinkedIn headline, usually title and company | | Profile URL | url | Direct link to their profile | | LinkedIn Username | text | Public identifier from the profile URL | | Likes | number | Like count on the comment | | Reaction Breakdown | array | Counts per reaction type (older LinkedIn layout only) | | Reply Count | number | Number of replies to the comment | | Parent Comment | text | Which comment a reply belongs to (empty for top-level) | | Comment Date | date | When the comment was posted | | Comment Permalink | url | Direct link to the comment (older LinkedIn layout only) | | Comment Flags | text | Edited, pinned and author markers (older LinkedIn layout only) | | Profile Photo URL | url | Commenter's profile image | ## Features - Export the comments on any LinkedIn post you can open - 50, 100 or 500 top-level comments per run, replies included - Commenter name, headline and profile link per row - Replies threaded to their parent comment - CSV, Excel, JSON and Google Sheets export ## How to Use 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Open the post**: Click the post's timestamp to open its own page (linkedin.com/posts/... or /feed/update/...). 3. **Pick Comments, click Scrape**: Click the InsightSocial icon. The side panel recognises the post; pick Comments, choose 50, 100 or 500 top-level comments and click Scrape. Keep the tab in front while it runs. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. ## FAQ ### How do I export comments from a LinkedIn post? Open the post's own page, open InsightSocial, pick Comments and choose 50, 100 or 500 top-level comments. Each comment becomes a row with its text, date, like and reply counts, and the commenter's name, headline and profile link. Replies to those comments come too, under the comment they answer, and don't count toward the number you picked. ### Can I scrape comments from someone else's post? Yes. Any post you can open in your browser works: your own, a competitor's or an industry post. ### Do I get each commenter's job title and company? Yes, as LinkedIn shows them in the commenter's headline (for example "VP Sales at Acme"), exported as written. LinkedIn has no separate title or company field on a comment. ### Does it capture replies and comment engagement? Yes: replies come as their own rows linked to the comment they answer, and every comment has its like and reply counts. LinkedIn is moving accounts to a new page layout; on accounts that still have the older layout, each comment also carries a reaction breakdown by type, a link to the comment, and edited and pinned flags. On the new layout those fields are empty. ### How many comments can I export per post? Pick 50, 100 or 500 top-level comments per run; their replies come on top. Scraping is free and unlimited on every plan; only exporting is metered, one credit per row. Free: 500 rows a month. Pro: 10,000 rows a month for $9.99, or $7.99 a month billed yearly. ### Do I need to keep the tab in front? Yes. On a single post the run pauses while the tab is hidden, and the side panel says so. If you switch away, the run waits and carries on when you come back. ### Can it reply to or message the commenters? No. InsightSocial only reads and exports; it never sends messages, connection requests, comments or reactions. ### Is scraping LinkedIn comments allowed? Comments are public contributions, and the extension reads only what your logged-in session already sees. LinkedIn's terms restrict automated collection, and that risk sits with the account you use, so keep volumes reasonable and handle the data under GDPR and CCPA. ## Related scrapers - [LinkedIn Post Likers Scraper](https://www.insightsocial.app/scraper/linkedin-post-likers-scraper.md): Export the people who reacted to a LinkedIn post to Excel or CSV: name, headline, profile link, connection degree and reaction type. Free Chrome extension. - [LinkedIn Posts Scraper](https://www.insightsocial.app/scraper/linkedin-posts-scraper.md): Export LinkedIn posts from a profile, company page or your feed to Excel or CSV: text, date, reactions by type, comments, and author name and headline. - [LinkedIn Profile Scraper](https://www.insightsocial.app/scraper/linkedin-profile-scraper.md): Save the LinkedIn profile you have open as one row in Excel or CSV: name, headline, location, current company, school, followers and connections. Free extension. --- # YouTube Comments Scraper Source: https://www.insightsocial.app/scraper/youtube-comments-scraper, updated 2026-10-18 > Export a YouTube video's comments and replies to Excel, CSV or Google Sheets. Free Chrome extension, no API key or Python. Likes, authors, dates, links. - **Platform**: youtube - **Web version**: https://www.insightsocial.app/scraper/youtube-comments-scraper --- InsightSocial's YouTube Comments Scraper is a free Chrome extension that exports the comments on a YouTube video to Excel, CSV, JSON or Google Sheets. Each row has the comment text, author, likes, reply count, date and a link to that comment, with reply threads opened and linked to their parent. It runs in your own browser: no YouTube API key, no Python, no quota. ## At a glance - **Works on**: Any YouTube video's watch page. Shorts have their own page: YouTube Shorts Comments Scraper - **Per run**: 100, 250 or 500 comments. Replies count toward it - **Each row**: Text, author and channel ID, verified and by-the-creator flags, likes, replies, date, link to the comment - **Export to**: Excel, CSV, JSON, Google Sheets or a share link - **Login**: No YouTube password shared and no API key. It reads what your browser shows - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. On YouTube, that icon opens the side panel. 3. **Open the video, press Scrape**: The side panel recognises the video. Pick 100, 250 or 500 comments and press Scrape. Reply threads open on their own. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. Every run stays in your account to re-open later. ## How to export YouTube comments to Excel Open the video on YouTube, click the InsightSocial icon, pick how many comments you want (100, 250 or 500) and press Scrape. The extension opens reply threads as it goes and keeps going if you switch to another tab. When it finishes, download Excel, CSV or JSON, or send the rows to Google Sheets. ## What each row contains One row per comment or reply: the text, the author's name, channel ID and avatar, whether the author is verified, whether the comment was written by the video's own channel, likes, reply count, the date, and a link that opens the video at that comment. Replies carry the ID of the comment they answer, so you can rebuild each thread in a spreadsheet. Every row also names the video and its channel. Dates come from YouTube's "3 weeks ago" text, so a recent comment is dated to the day and an old one to the month or year. ## Picking the videos To compare the comments across a channel's uploads, export the channel's video list first with the [YouTube Channel Scraper](/scraper/youtube-channel-scraper), sort it by views, then run this scraper on the videos that matter. Comparing comment-export tools? See the [best ExportComments alternatives](/blog/exportcomments-alternatives). Want the comments in code instead? The [InsightSocial API](/social-media-api/youtube) returns a video's comments as JSON with one key. --- ## FAQ ### How do I scrape YouTube comments? Open the video in Chrome, click the InsightSocial icon, choose how many comments you want and press Scrape. The extension scrolls the comments, opens reply threads and saves the rows as it goes. Then export to Excel, CSV, JSON or Google Sheets. There is nothing to install besides the extension and nothing to code. ### Is the YouTube Comments Scraper free? Yes. Scraping is free and unlimited. You pay only for rows you export: the free plan includes 500 rows a month, and Pro includes 10,000 for $9.99 a month ($7.99 a month billed yearly). Exporting a comment you already exported is free. ### Can I get YouTube comments without Python or an API key? Yes. The extension reads the comments in your own browser, so there is no Google Cloud project, no API key and no daily quota. If you do want code, the InsightSocial API returns YouTube comments as JSON with one key. ### Does it include replies? Yes. Reply threads, including "Show more replies", are opened automatically. Each reply is its own row and carries the ID of the comment it answers, so you can rebuild the conversation. ### How many comments can I export from one video? A run collects 100, 250 or 500 comments, whichever you pick, and replies count toward that number. It ends sooner if the video has no more comments to load. In our October 2026 test, a 500-comment run on a video with about 1,800 comments returned 500 rows with the tab in the background. ### Does it keep going if I switch tabs? Yes. You can work in another tab while it runs. Keep the video's tab open until it finishes. ### Can I tell which comments the creator wrote? Yes. Each row has an Author Is Creator column for comments posted by the video's own channel, and a verified flag for verified channels. Filter on either in your spreadsheet. The export does not show which comments the creator hearted. ### Does it work on Shorts and on non-English videos? Yes to both. Shorts have their own page, the YouTube Shorts Comments Scraper, with the same columns. Comment text and emoji come through as written, in any language. ### Can I use this for sentiment analysis? Yes. Load the CSV into a spreadsheet or a sentiment tool, or the JSON into a Python script. Each row carries the comment's likes, so you can weight a comment by how many people agreed with it. ### Is it safe for my YouTube account? It only reads the comments your browser can already see, at a reading pace, and never posts, likes or subscribes. You don't share your password with InsightSocial. ### Is it legal to scrape YouTube comments? Comments on public videos are public, and collecting them for research or audience analysis is common practice. You are still bound by YouTube's Terms of Service and privacy laws such as GDPR. Don't publish commenters' names, and don't use the data to contact or target people. ## Related scrapers - [YouTube Shorts Comments Scraper](https://www.insightsocial.app/scraper/youtube-shorts-comments-scraper.md): Export the comments on any YouTube Short, replies included, to Excel, CSV or Google Sheets. Free Chrome extension, no API key, no Python. - [YouTube Channel Scraper](https://www.insightsocial.app/scraper/youtube-channel-scraper.md): List the videos or Shorts on a YouTube channel in Excel, CSV or Google Sheets: title, link, views, upload date, duration. Free, no API key. - [TikTok Comments Scraper](https://www.insightsocial.app/scraper/tiktok-comments-scraper.md): Free TikTok Comments Scraper. Extract comments, replies, and reactions from any TikTok video. Analyze audience sentiment. Export to CSV, Excel, JSON. --- # YouTube Shorts Comments Scraper Source: https://www.insightsocial.app/scraper/youtube-shorts-comments-scraper, updated 2026-10-18 > Export the comments on any YouTube Short, replies included, to Excel, CSV or Google Sheets. Free Chrome extension, no API key, no Python. - **Platform**: youtube - **Web version**: https://www.insightsocial.app/scraper/youtube-shorts-comments-scraper --- InsightSocial's YouTube Shorts Comments Scraper is a free Chrome extension that exports the comments on a YouTube Short to Excel, CSV, JSON or Google Sheets. It opens the Short's comment panel for you, pauses the video, and saves each comment and reply with its author, likes, reply count, date and link. No API key and no code. ## At a glance - **Works on**: Any youtube.com/shorts/ page, including one you reached from the Shorts feed - **Per run**: 100, 250 or 500 comments. Replies count toward it - **Each row**: Text, author and channel ID, verified and by-the-creator flags, likes, replies, date, link - **Export to**: Excel, CSV, JSON, Google Sheets or a share link - **While it runs**: The Short stays paused. You can work in another tab - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. On YouTube, that icon opens the side panel. 3. **Open the Short, press Scrape**: The side panel recognises the Short. Pick 100, 250 or 500 comments and press Scrape. The comment panel opens and the Short pauses. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. ## How to export comments from a YouTube Short Open the Short (from the Shorts feed, a channel's Shorts tab or a direct youtube.com/shorts/ link), click the InsightSocial icon, pick how many comments you want and press Scrape. The extension opens the comment panel, pauses the Short so it can't swipe to the next one, and opens reply threads as it goes. Export to Excel, CSV, JSON or Google Sheets when it finishes. The columns are the same as for regular videos: comment text, author, verified and by-the-creator flags, likes, reply count, date, a link to the comment, and the Short's title and channel. Dates come from YouTube's "3 weeks ago" text, so older comments are dated to the month or year. For a regular video, use the [YouTube Comments Scraper](/scraper/youtube-comments-scraper). To list a channel's Shorts with their views, use the [YouTube Channel Scraper](/scraper/youtube-channel-scraper). Comparing the same clip on TikTok? The [TikTok Comments Scraper](/scraper/tiktok-comments-scraper) exports the same kind of rows. --- ## FAQ ### Can I export the comments on a YouTube Short? Yes. Open the Short, press Scrape in the InsightSocial side panel, and the extension opens the comment panel, collects the comments and their replies, and exports them to Excel, CSV, JSON or Google Sheets. Scraping is free; exports use your monthly rows (500 free). ### Is this different from the regular YouTube comments scraper? Same extension, same columns. Shorts keep their comments in a slide-in panel instead of under the video, so on a Shorts page the extension opens that panel and pauses the Short first. Regular videos use the YouTube Comments Scraper. ### Can I start from the Shorts feed? Yes. Swipe to the Short you want, then open the side panel. The Short stays paused until the run ends, so it can't move on to the next one. ### How many comments can I get from one Short? A run collects 100, 250 or 500 comments, whichever you pick, and replies count toward that number. In our October 2026 test, a 300-comment run on a Short with about 28,000 comments returned 300 rows with the tab in the background. ### Does it include replies? Yes. Reply threads are opened as the panel scrolls, and each reply row carries the ID of the comment it answers, so you can rebuild conversations. ### Can I export a channel's Shorts themselves, not their comments? Yes, with the YouTube Channel Scraper: open the channel, pick Channel Shorts, and you get the Shorts with their title, link, views and thumbnail. ### Does it get the Short's view count? No. Comment rows carry the Short's title, link and channel. For view counts, export the channel's Shorts list with the YouTube Channel Scraper. ### Do I need a YouTube API key? No. The extension reads the Short in your own browser. No Google Cloud project, no key, no quota. ### Does it work on non-English Shorts? Yes. Comment text and emoji come through as written, in any language. ## Related scrapers - [YouTube Comments Scraper](https://www.insightsocial.app/scraper/youtube-comments-scraper.md): Export a YouTube video's comments and replies to Excel, CSV or Google Sheets. Free Chrome extension, no API key or Python. Likes, authors, dates, links. - [YouTube Channel Scraper](https://www.insightsocial.app/scraper/youtube-channel-scraper.md): List the videos or Shorts on a YouTube channel in Excel, CSV or Google Sheets: title, link, views, upload date, duration. Free, no API key. - [TikTok Comments Scraper](https://www.insightsocial.app/scraper/tiktok-comments-scraper.md): Free TikTok Comments Scraper. Extract comments, replies, and reactions from any TikTok video. Analyze audience sentiment. Export to CSV, Excel, JSON. --- # YouTube Channel Scraper Source: https://www.insightsocial.app/scraper/youtube-channel-scraper, updated 2026-10-18 > List the videos or Shorts on a YouTube channel in Excel, CSV or Google Sheets: title, link, views, upload date, duration. Free, no API key. - **Platform**: youtube - **Web version**: https://www.insightsocial.app/scraper/youtube-channel-scraper --- InsightSocial's YouTube Channel Scraper is a free Chrome extension that lists the videos, or the Shorts, on a YouTube channel in Excel, CSV, JSON or Google Sheets. Each row has the title, link, views, upload date, duration and thumbnail, newest first. Open any page of the channel and the extension opens the Videos or Shorts tab for you. No API key, no quota. ## At a glance - **Works on**: Any page of a channel: @handle, /channel/, /c/ or /user/ links, its home, About or Playlists - **Per run**: 50, 200 or 500 videos, newest first. Videos and Shorts are separate runs - **Each row**: Title, link, video ID, views, upload date, duration, thumbnail, Short and live flags, position, channel - **Not included**: Likes, comment counts and full descriptions: a channel's video list doesn't show them - **Export to**: Excel, CSV, JSON, Google Sheets or a share link - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. On YouTube, that icon opens the side panel. 3. **Open the channel, press Scrape**: Pick Channel Videos or Channel Shorts, choose 50, 200 or 500 and press Scrape. The extension opens the right tab. 4. **Export**: Download Excel, CSV or JSON, or send the list to Google Sheets. Sort by views to find the channel's biggest videos. ## Videos tab or Shorts tab YouTube keeps a channel's long-form videos and its Shorts on separate tabs, and the extension gives you a run for each: | Run | What it lists | What each row carries | |---|---|---| | **Channel Videos** | The videos on the channel's Videos tab, newest first | Title, URL, views, upload age and calculated date, duration, thumbnail, live flag, position | | **Channel Shorts** | The Shorts on the channel's Shorts tab | Title, URL, views, thumbnail, position | Both runs attach the channel's name, @handle, channel ID and avatar to every row. If you need both formats, run Videos and Shorts one after the other. Each is its own session in your dashboard. You can start from any page of the channel: `youtube.com/@handle`, its About page or its Playlists. Pick Videos or Shorts in the side panel and the extension opens the matching tab before it starts. Channel URLs in the `/channel/UC...`, `/c/name` and `/user/name` forms work too. ## Working with the file - **Most popular videos.** Sort the Views column. Because the run follows the Videos tab rather than YouTube's "Popular" shortcut, older breakout videos are in the file too. - **Back to YouTube's order.** The List Position column keeps the tab's order (1 is the newest upload), so you can sort back to it after re-sorting by views. - **Dates.** Upload dates are calculated from YouTube's "3 weeks ago" text: exact to the day for recent uploads, to the month or year for older ones. - **Comments on one video.** Take its link from your export to the [YouTube Comments Scraper](/scraper/youtube-comments-scraper), or the [YouTube Shorts Comments Scraper](/scraper/youtube-shorts-comments-scraper) for a Short. To list videos from every channel that ranks for a topic, start from a search with the [YouTube Search Scraper](/scraper/youtube-search-scraper), then export the channels that keep appearing here. For the same job on other platforms, the [TikTok Video Scraper](/scraper/tiktok-video-scraper) lists a creator's TikTok videos. --- ## FAQ ### How do I get a list of all videos on a YouTube channel? Open the channel in Chrome, pick Channel Videos in the InsightSocial side panel, choose 50, 200 or 500 and press Scrape. The run lists the Videos tab newest first and ends early when the tab runs out, so a channel with up to 500 uploads comes back in full. Then export to Excel, CSV, JSON or Google Sheets. ### Is the YouTube channel scraper free? Yes. Scraping is free on every plan. You pay only for rows you export: 500 a month on the free plan, 10,000 on Pro for $9.99 a month ($7.99 a month billed yearly), and one-time credit packs from $2 that never expire. Exporting a row you already paid for is free. ### Do I need a YouTube Data API key? No. There is no Google Cloud project, no API key and no daily quota. The extension reads the channel's Videos or Shorts tab in your own browser, the same list you see when you scroll it yourself. ### Do I need the YouTube Data API instead? Only if you need exact upload times, likes and comment counts for every video and are happy to write code within Google's daily quota. If you want a channel's video list in a spreadsheet, the extension gets it with no developer account. The API returns more per video; the extension needs no setup. ### Can I export a channel's Shorts as well as its videos? Yes. Pick Channel Shorts instead of Channel Videos. YouTube's Shorts tab shows less than the Videos tab, so Shorts rows carry the title, link, views and thumbnail, but no upload date or duration. Videos and Shorts are two separate runs. Live streams, playlists and Community posts are not part of a channel run. ### Does it keep going if I switch to another tab? Yes. You can work in another tab while it runs. Don't move the scraping tab to another page, though: the run stops when the page it started on changes, and keeps what it collected. ### Why did my run stop early? Either the channel's tab ran out of videos, the scraping tab moved to another page, or YouTube stopped answering for a while. Everything collected up to then is saved. Running it again later usually completes. ### Why does it show '3 weeks ago' instead of an exact upload date? Because that is all a channel's video list shows. Each row keeps YouTube's text and adds a calculated date: a video from last week is dated to the day, one from 2019 to the year. Likes, comment counts and full descriptions are not on the list either, so they are not in the export. ### Are the view counts exact? They match what the channel tab shows, including YouTube's rounding on large numbers (1.2M views), at the moment you ran it. A stream that is live right now has no view count. ### Does it download the videos themselves? No. It exports the channel's video list: titles, links, views, upload age, duration and thumbnail URLs. It does not download video or audio files. ### Can I track a channel over time? Run the same channel again later and compare the two exports by video ID. New uploads appear as new IDs, and the Views column shows how each video moved between the two dates. ## Related scrapers - [YouTube Search Scraper](https://www.insightsocial.app/scraper/youtube-search-scraper.md): Export YouTube search results to Excel, CSV or Google Sheets in YouTube's ranking order: title, channel, views, date, duration. Free, no API key. - [YouTube Comments Scraper](https://www.insightsocial.app/scraper/youtube-comments-scraper.md): Export a YouTube video's comments and replies to Excel, CSV or Google Sheets. Free Chrome extension, no API key or Python. Likes, authors, dates, links. - [YouTube Shorts Comments Scraper](https://www.insightsocial.app/scraper/youtube-shorts-comments-scraper.md): Export the comments on any YouTube Short, replies included, to Excel, CSV or Google Sheets. Free Chrome extension, no API key, no Python. - [TikTok Video Scraper](https://www.insightsocial.app/scraper/tiktok-video-scraper.md): Free TikTok Video Scraper. Extract views, likes, comments, shares, captions, and hashtags from any TikTok video. Export to CSV, Excel, JSON. --- # YouTube Search Scraper Source: https://www.insightsocial.app/scraper/youtube-search-scraper, updated 2026-10-18 > Export YouTube search results to Excel, CSV or Google Sheets in YouTube's ranking order: title, channel, views, date, duration. Free, no API key. - **Platform**: youtube - **Web version**: https://www.insightsocial.app/scraper/youtube-search-scraper --- InsightSocial's YouTube Search Scraper is a free Chrome extension that exports YouTube search results to Excel, CSV, JSON or Google Sheets, in the order YouTube ranked them. Each row has the title, link, channel, views, upload date, duration, description snippet and its position. Filters you set on YouTube carry over. No API key and no daily search limit. ## At a glance - **Works on**: Any YouTube search results page, with or without YouTube's filters - **Per run**: 50, 100 or 300 results. Ends early if YouTube runs out - **Each row**: Title, link, channel, views, upload date, duration, snippet, badges, result position, search query - **Left out**: Ads, Shorts shelves, channel and playlist cards - **Export to**: Excel, CSV, JSON, Google Sheets or a share link - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. On YouTube, that icon opens the side panel. 3. **Search, then press Scrape**: Search on YouTube and set any filters. The side panel shows your query; pick 50, 100 or 300 results and press Scrape. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. Each row keeps its rank and the query it came from. ## What a search run collects A YouTube results page mixes several kinds of item. Here is how each one is handled: | On the results page | In your export | |---|---| | **Videos** | Included, with title, channel, views, upload date, duration, snippet and badges | | **Shorts shelves** | Left out, so the rows you asked for are the ranked results | | **Ads and sponsored results** | Left out | | **Channel and playlist results** | Left out: they are not videos | Every row also carries the search query it came from, which keeps exports from several searches easy to combine in one sheet. ## Getting the results you want **Only recent videos.** Set an upload-date filter in YouTube's Filters panel before you start; the run collects the filtered results. To see the normal ranking ordered by age instead, run the search as is and sort the date column. The Result Position column keeps YouTube's original order either way. **A new keyword.** Start with 100 results to see how deep the search goes. Narrow searches run out sooner than broad ones. **Dates.** Upload dates are calculated from YouTube's "2 weeks ago" text, so a "3 years ago" result is dated to the year, not the day. A results page does not show like counts, comment counts or the full description, so those are not in the export. When a result is worth reading in depth, take its link to the [YouTube Comments Scraper](/scraper/youtube-comments-scraper). When a channel keeps appearing across your searches, the [YouTube Channel Scraper](/scraper/youtube-channel-scraper) lists its videos. Researching the same topic elsewhere? The [TikTok Hashtag Scraper](/scraper/tiktok-hashtag-scraper) exports the videos under a hashtag. --- ## FAQ ### How do I export YouTube search results to CSV or Excel? Search on YouTube in Chrome, open the InsightSocial side panel, choose 50, 100 or 300 results and press Scrape. When the run finishes, export to CSV, Excel (.xlsx), JSON or Google Sheets. Each video is one row, in the order YouTube ranked it. ### Is the YouTube search scraper free? Yes. Scraping is free on every plan. You pay only for rows you export: 500 a month on the free plan, 10,000 on Pro for $9.99 a month ($7.99 a month billed yearly), and one-time credit packs from $2 that never expire. Exporting a row you already paid for is free. ### Do I need the YouTube Data API to export search results? No. The extension saves the results page you see, in YouTube's order, with no key or code. Use the API if you are building a product and need exact upload times and like counts per video. Its search allowance is limited per day, and its ranking can differ from what YouTube shows you. ### How many search results can I export? A run collects 50, 100 or 300 results, whichever you pick. It ends sooner if YouTube runs out of results for the search: broad searches go much deeper than narrow ones, and where a search ends is YouTube's decision. ### Does it work with YouTube's search filters? Yes. Filters such as upload date, duration or type change the results page's address, and the run collects from that address, so the export follows the filters you set before starting. ### Are Shorts, channels and ads included? No. A search run collects the ranked video results. Shorts shelves, ads, channel cards and playlists are left out, so a 100-result run gives you 100 videos. To list Shorts, open a channel and use the YouTube Channel Scraper's Shorts run. ### Can I scrape several keywords at once? Each search is its own run. Search the first keyword, run it, then search the next. Every row carries its search query, so the files combine cleanly into one sheet. ### Will my results match what someone else sees? Not always. YouTube personalises search by account, watch history, language and location, and the run collects what your session is shown. For a less personalised snapshot, run it in a Chrome profile that is not signed in to YouTube. ### Can I track where a video ranks over time? Run the same search on different days and compare the exports by video ID. The Result Position column shows where each video sat on each date. Keep the filters and the Chrome profile the same between runs. ### Does it keep going if I switch tabs? Yes. You can work in another tab while it runs. Moving the scraping tab to another page ends the run, with everything collected so far saved. ### Can I export my YouTube home feed? Yes. Open youtube.com, and the side panel offers a Home Feed run of 50, 100 or 300 recommended videos with the same columns. ## Related scrapers - [YouTube Channel Scraper](https://www.insightsocial.app/scraper/youtube-channel-scraper.md): List the videos or Shorts on a YouTube channel in Excel, CSV or Google Sheets: title, link, views, upload date, duration. Free, no API key. - [YouTube Comments Scraper](https://www.insightsocial.app/scraper/youtube-comments-scraper.md): Export a YouTube video's comments and replies to Excel, CSV or Google Sheets. Free Chrome extension, no API key or Python. Likes, authors, dates, links. - [YouTube Shorts Comments Scraper](https://www.insightsocial.app/scraper/youtube-shorts-comments-scraper.md): Export the comments on any YouTube Short, replies included, to Excel, CSV or Google Sheets. Free Chrome extension, no API key, no Python. - [TikTok Video Scraper](https://www.insightsocial.app/scraper/tiktok-video-scraper.md): Free TikTok Video Scraper. Extract views, likes, comments, shares, captions, and hashtags from any TikTok video. Export to CSV, Excel, JSON. --- # Reddit Comment Scraper Source: https://www.insightsocial.app/scraper/reddit-comments-scraper, updated 2026-10-18 > Export every comment and reply from a Reddit thread to Excel, CSV or Google Sheets, nested replies kept. Free Chrome extension, no Reddit API key. - **Platform**: reddit - **Web version**: https://www.insightsocial.app/scraper/reddit-comments-scraper --- InsightSocial's Reddit Comment Scraper is a free Chrome extension that exports every comment and reply in a Reddit thread to Excel, CSV, JSON or Google Sheets. Each row has the comment text, author, score, date and link, plus the comment it answered and how deep it sits, so the conversation can be rebuilt. It runs in your own browser while you are signed in to Reddit: no API key, no developer app. ## At a glance - **Works on**: Any Reddit thread, on new or old Reddit - **Per run**: The whole thread, replies included. In our tests (Oct 2026), 424 comments took 42 seconds - **Each row**: Text, author, score, date, link, the comment it replied to, depth, OP and moderator flags - **Many threads**: From a subreddit or a search: 25, 50 or 100 posts with all their comments in one run - **Export to**: Excel, CSV, JSON or Google Sheets - **Login**: Your own Reddit session in the same browser. No password shared, no API key - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. On Reddit, that icon is how you open it. 3. **Open the thread, click Scrape**: Sign in to Reddit in the same browser and open the post. The side panel recognises the thread; click Scrape and the replies load with it. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. Every run stays in your account to re-open later. ## Finding the threads worth exporting Start from engagement, not from a feed. Run the [Reddit Search Results Scraper](/scraper/reddit-post-scraper) on your topic, sort the file by comment count, then export the comments of the top few threads. That is faster than reading a subreddit in date order. To take the comments of many threads in one go, pick *Posts and Comments* on the search or on a [subreddit](/scraper/reddit-subreddit-scraper) instead. ## What one row looks like One row per comment: who wrote it, when, the text, its score, the comment it answered and how deep it sits. The post's own title, text and score come with the run, so every file says which thread it came from. *Is Submitter (OP)* marks comments by the person who posted the thread, and *Distinguished* marks moderator and admin comments, so you can filter either in or out. All Reddit scrapers are on the [Reddit scraper hub](/scraper/reddit). Comparing comment-export tools? See the [best ExportComments alternatives](/blog/exportcomments-alternatives). --- ## FAQ ### Is the Reddit Comment Scraper free? Yes. Collecting and reading your results in the dashboard are free and unlimited. Only exporting uses rows, one per comment: the free plan exports 500 rows a month, and Pro exports 10,000 for $9.99 a month ($7.99 a month billed yearly). A row you already exported is free to export again. ### Does it keep the replies nested? Yes. Every reply is its own row and names the comment it answered, plus a Depth number (0 for a top-level comment). You can sort the file back into thread order or rebuild the tree in Excel or Python. Replies are never squashed into one cell. ### Do I need to be signed in to Reddit? Yes. Reddit refuses this data to signed-out browsers, so sign in to Reddit in the same Chrome profile first. If you are signed out, the run stops and asks you to sign in. You also need a free InsightSocial account to export. The extension only reads: it never posts, votes or messages. ### Do I need a Reddit API key? No. There is no developer app to register and no key to paste. InsightSocial reads Reddit in your own signed-in browser, the same way you would scroll it. ### Why does my file have fewer comments than Reddit shows? Reddit's comment count includes comments that were deleted or removed, and those no longer exist to export. The run collects every comment Reddit still shows, including the ones behind "load more replies" and "continue this thread". ### How long does a big thread take? Usually under a minute. In our tests (Oct 2026), a thread of 424 comments with eight levels of replies took 42 seconds. Very large threads take longer because Reddit hands out replies in batches. You can switch to another tab while it runs. ### Can I export comments from many threads at once? Yes. Open a subreddit or a Reddit search instead and pick Posts and Comments. One run takes 25, 50 or 100 posts and every comment under each, all in one file. See the Reddit Subreddit Scraper and the Reddit Search Results Scraper. ### Can I export every comment one user wrote? Yes, from their profile page while you are signed in to Reddit. The run collects their comments, newest first, up to the roughly 1,000 that Reddit lists. See the Reddit User Comments Scraper. ### What order are the comments in? Reddit's Best order, the one a thread opens with. Every comment is collected whatever the order, so sort the file by score or date afterwards to get Top or New. ### How do I rebuild the thread in Excel? Each row has a Comment ID, a Parent Comment ID and a Depth. Top-level comments have Depth 0 and a blank Parent Comment ID. For a reply, Parent Comment ID is the Comment ID of the comment it answered, so a lookup (VLOOKUP or XLOOKUP) against the Comment ID column puts each reply next to its parent. ### Will Reddit block or ban my account? It is unlikely at normal volumes, but no tool can promise it. The extension reads from your own session and never posts, votes or messages. Reddit limits how fast any browser can load pages; when that limit is close, the run waits for it to reset instead of pushing through, so a big run can pause for a few minutes and then carry on by itself. ### Can I use the export for sentiment or AI analysis? Yes. Comment text keeps its emoji and formatting. The CSV drops into ChatGPT, Claude or a spreadsheet, and the JSON suits Python. The score on each row lets you weight what the community agreed with. If you publish results, anonymise usernames and follow privacy law such as GDPR and CCPA. ## Related scrapers - [Reddit Subreddit Scraper](https://www.insightsocial.app/scraper/reddit-subreddit-scraper.md): Export up to 1,000 posts from any subreddit to Excel, CSV or Google Sheets, with every comment if you want. Hot, New, Top. Free Chrome extension. - [Reddit User Comments Scraper](https://www.insightsocial.app/scraper/reddit-user-comments-scraper.md): Export a Reddit user's comments to Excel, CSV or Google Sheets: text, score, date, subreddit and post. Newest first, 500 rows free. - [Hacker News Comment Scraper](https://www.insightsocial.app/scraper/hacker-news-comment-scraper.md): Export every comment and reply in a Hacker News thread to Excel, CSV, JSON or Google Sheets, with depth and parent. Free extension, 500 rows a month. --- # Reddit Search Results Scraper Source: https://www.insightsocial.app/scraper/reddit-post-scraper, updated 2026-10-18 > Export Reddit search results to Excel, CSV or Google Sheets: up to 250 posts per search, with their comments if you want. Free Chrome extension. - **Platform**: reddit - **Web version**: https://www.insightsocial.app/scraper/reddit-post-scraper --- InsightSocial's Reddit Search Results Scraper is a free Chrome extension that exports the posts a Reddit search returns to Excel, CSV, JSON or Google Sheets: title, text, author, subreddit, score, upvote ratio, comment count, flair and link. Search all of Reddit or inside one subreddit, keep the sort and time filter you set on Reddit, and add every post's comments in the same run if you want them. ## At a glance - **Works on**: Reddit search, across all of Reddit or inside one subreddit - **Per run**: 50, 100 or 250 posts. Reddit shows about 250 results for any one search - **With comments**: 25, 50 or 100 posts, each with every comment and reply under it - **Each row**: Title, text, author, subreddit, score, upvote ratio, comments, flair, link, post type - **Sort and time**: Whatever you picked on Reddit's results page, NSFW toggle included - **Export to**: Excel, CSV, JSON or Google Sheets, posts and comments in one file - **Login**: Your own Reddit session in the same browser. No API key - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. On Reddit, that icon is how you open it. 3. **Search, then click Scrape**: Sign in to Reddit, search, and set the sort and time on Reddit's own results page. In the side panel pick Posts or Posts and Comments, choose how many, and click Scrape. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. Posts and their comments land in one file. ## FAQ ### Which Reddit pages does it work on? Reddit search results pages: site-wide (reddit.com/search?q=…) and searches inside one community (reddit.com/r/{subreddit}/search?q=…). A subreddit's own Hot, New or Top feed is the Reddit Subreddit Scraper's job, a single thread's discussion the Reddit Comment Scraper's, and a user's comments the Reddit User Comments Scraper's. All of them are the same extension. ### How many posts can one search export? About 250. Reddit stops showing results for a search at roughly 250 posts, whatever the sort, so the choices are 50, 100 and 250. To go wider, run a few narrower searches with other keywords, time ranges or subreddits. Collecting is free; only exported rows count. ### Is it free? Yes. Collecting and reading your results in the dashboard are free and unlimited. Only exporting uses rows, one per post or comment: the free plan exports 500 rows a month, and Pro exports 10,000 for $9.99 a month ($7.99 a month billed yearly). A row you already exported is free to export again. ### Do I need a Reddit developer account or API key? No. There is no app to register and no key. You do need to be signed in to Reddit in the same browser, because Reddit refuses this data to signed-out visitors. ### How do I scrape posts from a specific subreddit? Two ways. To export the community itself, open it and use the Reddit Subreddit Scraper: it follows the Hot, New or Top tab and exports up to 1,000 posts. To pull one topic out of that community, use its search box instead: the export stays inside that subreddit and reaches about 250 matching posts. ### Can I control the sort and timeframe? Yes, on Reddit itself. Whatever sort, time range and NSFW setting you chose on the results page is what gets exported. ### Can I export the comments too? Yes. Pick Posts and Comments instead of Posts and choose 25, 50 or 100 posts. The run collects the posts, then every comment and reply under each one. Everything lands in one file: a Row Type column marks each line as Post, Comment or Reply, Level gives the nesting depth, and Post ID ties every comment back to its post. ### Can I export Reddit comments that mention my brand? This scraper finds posts that match your search, and their comments if you pick Posts and Comments. It does not search inside comments on its own. If you need comment-level search, the InsightSocial API has a Reddit comment search endpoint. ### Does it work for private or NSFW communities? Yes, if your Reddit account can already see them: private communities you have joined and NSFW content you have opted into. It never gets around access controls. ### Will Reddit block or ban my account? It is unlikely at normal volumes, but no tool can promise it. The extension reads from your own session and never posts, votes or messages. Reddit limits how fast any browser can load pages; when that limit is close, the run waits for it to reset instead of pushing through, so a big run can pause for a few minutes and then carry on by itself. ## Related scrapers - [Reddit Subreddit Scraper](https://www.insightsocial.app/scraper/reddit-subreddit-scraper.md): Export up to 1,000 posts from any subreddit to Excel, CSV or Google Sheets, with every comment if you want. Hot, New, Top. Free Chrome extension. - [Reddit Comment Scraper](https://www.insightsocial.app/scraper/reddit-comments-scraper.md): Export every comment and reply from a Reddit thread to Excel, CSV or Google Sheets, nested replies kept. Free Chrome extension, no Reddit API key. - [Reddit User Comments Scraper](https://www.insightsocial.app/scraper/reddit-user-comments-scraper.md): Export a Reddit user's comments to Excel, CSV or Google Sheets: text, score, date, subreddit and post. Newest first, 500 rows free. --- # Reddit Subreddit Scraper Source: https://www.insightsocial.app/scraper/reddit-subreddit-scraper, updated 2026-10-18 > Export up to 1,000 posts from any subreddit to Excel, CSV or Google Sheets, with every comment if you want. Hot, New, Top. Free Chrome extension. - **Platform**: reddit - **Web version**: https://www.insightsocial.app/scraper/reddit-subreddit-scraper --- InsightSocial's Subreddit Scraper is a free Chrome extension that exports up to 1,000 posts from any subreddit to Excel, CSV, JSON or Google Sheets, in the sort you are viewing: Hot, New, Top, Rising or Controversial. Each row has the title, text, author, score, upvote ratio, comment count, flair and link. Pick Posts and Comments to get every comment under 25, 50 or 100 of those posts in the same run. ## At a glance - **Works on**: Any subreddit you can open, on any sort tab, with Reddit's time filter - **Per run**: 100, 250, 500 or 1,000 posts. Reddit's list stops at 1,000 per sort - **With comments**: 25, 50 or 100 posts, each with every comment and reply - **Each row**: Title, text, author, score, upvote ratio, comments, flair, link, subscriber count - **Export to**: Excel, CSV, JSON or Google Sheets, posts and comments in one file - **Login**: Your own Reddit session in the same browser. No API key - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. On Reddit, that icon is how you open it. 3. **Open the subreddit, click Scrape**: Sign in to Reddit, open the subreddit and pick the sort tab you want (Top this year, New…). In the side panel choose Posts or Posts and Comments, pick how many, and click Scrape. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. Every run stays in your account to re-open later. ## Getting more than 1,000 posts from one community Reddit lists 1,000 posts per sort, and the sorts overlap. Export *New* for recent posts, then *Top* with the time filter on Year, Month and Week, and remove duplicates by *Post ID*. For older or narrower slices, search inside the subreddit with the [Reddit Search Results Scraper](/scraper/reddit-post-scraper). ## Posts and comments in one file With *Posts and Comments*, each post is followed by its comments in thread order. *Row Type* says whether a line is a Post, Comment or Reply, *Level* gives the nesting depth, and *Post ID* ties every comment back to its post, so a pivot table can count comments per post or per author. For one thread on its own, use the [Reddit Comment Scraper](/scraper/reddit-comments-scraper). All Reddit scrapers are on the [Reddit scraper hub](/scraper/reddit). --- ## FAQ ### How many posts can I export from one subreddit? Up to 1,000 for each sort: pick 100, 250, 500 or 1,000. That is where Reddit's own list ends, the same place you would stop scrolling. A Reddit search inside the subreddit reaches only about 250, so for a whole community, start here. ### How do I get more than 1,000 posts from a community? The 1,000 limit is per sort, not per subreddit. Run New for recent posts, then Top with the time filter set to Year, Month and Week, and remove duplicates by Post ID. For older or narrower slices, search inside the community with the Reddit Search Results Scraper. ### Can I scrape a subreddit's posts and comments at the same time? Yes. Pick Posts and Comments and choose 25, 50 or 100 posts. The run collects the posts, then every comment and reply under each one. Everything lands in one file: a Row Type column marks each line as Post, Comment or Reply, Level gives the nesting depth, and Post ID ties every comment back to its post. ### Which sorts are supported? Hot, New, Top, Rising and Controversial. Open the tab you want on Reddit and the run follows it, including the time window on Top and Controversial. A plain reddit.com/r/{subreddit} link is Reddit's Hot default. ### Do I need to be signed in to Reddit? Yes. Reddit refuses this data to signed-out browsers, so sign in to Reddit in the same Chrome profile first. If you are signed out, the run stops and asks you to sign in. You also need a free InsightSocial account to export. The extension only reads: it never posts, votes or messages. ### Do I need a Reddit API key or developer app? No. There is no developer app to register and no key to paste. InsightSocial reads Reddit in your own signed-in browser, the same way you would scroll it. ### Does it work on private or NSFW subreddits? Yes, if your Reddit account can already see them: private communities you have been approved for and NSFW communities you have opted into. It never gets around an access control you do not already have. ### What is the difference between this and the Reddit Search Results Scraper? This one takes a community and gives you its feed: everything posted, in the order Reddit ranks it, up to 1,000. The search scraper takes a keyword and gives you matches across all of Reddit or inside one community, up to about 250. Use this one to study a community; use search to follow a topic across communities. ### Is it free? Yes. Collecting and reading your results in the dashboard are free and unlimited. Only exporting uses rows, one per post or comment: the free plan exports 500 rows a month, and Pro exports 10,000 for $9.99 a month ($7.99 a month billed yearly). A row you already exported is free to export again. ### Will Reddit block or ban my account? It is unlikely at normal volumes, but no tool can promise it. The extension reads from your own session and never posts, votes or messages. Reddit limits how fast any browser can load pages; when that limit is close, the run waits for it to reset instead of pushing through, so a big run can pause for a few minutes and then carry on by itself. ## Related scrapers - [Reddit Search Results Scraper](https://www.insightsocial.app/scraper/reddit-post-scraper.md): Export Reddit search results to Excel, CSV or Google Sheets: up to 250 posts per search, with their comments if you want. Free Chrome extension. - [Reddit Comment Scraper](https://www.insightsocial.app/scraper/reddit-comments-scraper.md): Export every comment and reply from a Reddit thread to Excel, CSV or Google Sheets, nested replies kept. Free Chrome extension, no Reddit API key. - [Reddit User Comments Scraper](https://www.insightsocial.app/scraper/reddit-user-comments-scraper.md): Export a Reddit user's comments to Excel, CSV or Google Sheets: text, score, date, subreddit and post. Newest first, 500 rows free. --- # Pinterest Profile Scraper Source: https://www.insightsocial.app/scraper/pinterest-profile-scraper, updated 2026-10-23 > Turn a Pinterest search into a list of accounts with website, followers, monthly views and business email. Excel, CSV or Sheets. Free Chrome extension. - **Platform**: pinterest - **Web version**: https://www.insightsocial.app/scraper/pinterest-profile-scraper --- InsightSocial's Pinterest Profile Scraper is a free Chrome extension that turns a Pinterest search into a list of the accounts behind it, exported to Excel, CSV, JSON or Google Sheets. Each row has the username, name, bio, website, followers, monthly views and pin count, plus the email and phone a business account publishes. It starts from a search: you type a topic, it collects the accounts. ## At a glance - **Works on**: Pinterest search results. Single profile pages and boards are not supported yet - **Per run**: 50, 100 or 250 accounts. A narrow search can run out sooner - **Each row**: Username, name, bio, website, verified-domain flag, followers, monthly views, pins, boards, merchant flag - **Contacts**: The email and phone a business account lists on Pinterest or writes in its bio, when it has one - **Export to**: Excel, CSV, JSON or Google Sheets - **Login**: Signed in to Pinterest in the same browser. No password shared, no API key - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. On Pinterest, that icon is how you open it. 3. **Search, pick Profiles, click Scrape**: Sign in to Pinterest and search your topic. In the side panel choose Profiles, pick 50, 100 or 250, and click Scrape. You can switch tabs while it runs. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. Sort by followers or filter to accounts with an email. ## FAQ ### How do I export a list of Pinterest accounts? Search your topic on Pinterest, open the InsightSocial side panel, choose Profiles and pick how many. The run collects the accounts the search returns, one row per account, and you download Excel, CSV or JSON or send them to Google Sheets. ### Does it export emails and phone numbers? Yes, when the account publishes them. Business accounts can list a contact email and phone on Pinterest, and some write an email in their bio. Both land in the Emails and Phones columns. The extension does not visit the account's website or guess addresses, so accounts that list nothing come back blank. ### Does it capture the website each account links to? Yes. The website is its own column, with a separate flag for whether Pinterest has verified that the account owns that domain. A verified domain is a claimed site, not just a link. ### How many accounts can one run collect? 50, 100 or 250. Pinterest shows a limited number of accounts for each search, so a narrow topic can end before your number. Run a few related searches to build a longer list. Collecting is free; exporting uses one row per account. ### Can I collect profiles from a board or a single account's page? Not in the extension yet. It starts from a search. To read one known pin or board, the InsightSocial API has Pinterest pin and board endpoints, including the list of a user's boards. ### Can I collect accounts and pins in the same run? No. Pinterest lists accounts and pins separately, so each run collects one or the other. Run Profiles for the accounts, then Pins on the same search if you want the content too. ### Do I need a Pinterest account? Yes. Sign in to Pinterest in your own browser first, because Pinterest limits what it shows to signed-out visitors. The extension reads what your session already shows and never sees your password. You also need a free InsightSocial account to export. ### Is it free? Yes. Collecting and reading your results in the dashboard are free and unlimited. Only exporting uses rows, one per account: the free plan exports 500 rows a month, and Pro exports 10,000 for $9.99 a month ($7.99 a month billed yearly). A row you already exported is free to export again. ### Is scraping Pinterest legal? Collecting publicly shown information for research is generally lawful, but you are responsible for Pinterest's Terms of Service and the laws that apply to you, especially around personal data such as emails and phone numbers. Use contact details only for businesses and creators that publish them. ## Related scrapers - [Pinterest Pin Scraper](https://www.insightsocial.app/scraper/pinterest-pin-scraper.md): Export the pins a Pinterest search returns to Excel, CSV or Google Sheets: title, link, domain, board, pinner and reactions. Free Chrome extension. - [TikTok Profile Scraper](https://www.insightsocial.app/scraper/tiktok-profile-scraper.md): Export a TikTok creator's videos with follower count, total likes and bio on every row, or a list of creators from search, to Excel or CSV. Free extension. - [YouTube Channel Scraper](https://www.insightsocial.app/scraper/youtube-channel-scraper.md): List the videos or Shorts on a YouTube channel in Excel, CSV or Google Sheets: title, link, views, upload date, duration. Free, no API key. --- # Pinterest Pin Scraper Source: https://www.insightsocial.app/scraper/pinterest-pin-scraper, updated 2026-10-23 > Export the pins a Pinterest search returns to Excel, CSV or Google Sheets: title, link, domain, board, pinner and reactions. Free Chrome extension. - **Platform**: pinterest - **Web version**: https://www.insightsocial.app/scraper/pinterest-pin-scraper --- InsightSocial's Pinterest Pin Scraper is a free Chrome extension that exports the pins a Pinterest search returns to Excel, CSV, JSON or Google Sheets. Each row has the pin's title, description, the link it points to and that link's domain, the board it was saved to, the pinner and their follower count, reactions, date and image link. You search on Pinterest; it collects the results. ## At a glance - **Works on**: Pinterest search results. Boards and single pin pages are not supported yet - **Per run**: 50, 100 or 250 pins - **Each row**: Title, description, outbound link and domain, board, pinner and followers, reactions, date, image and video links - **Export to**: Excel, CSV, JSON or Google Sheets - **Login**: Signed in to Pinterest in the same browser. No API key - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. On Pinterest, that icon is how you open it. 3. **Search, pick Pins, click Scrape**: Sign in to Pinterest and search your keyword. In the side panel choose Pins, pick 50, 100 or 250, and click Scrape. You can switch tabs while it runs. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. Group by domain to see which sites a search sends traffic to. ## FAQ ### How do I export Pinterest search results? Search the keyword on Pinterest, open the InsightSocial side panel, select Pins and choose 50, 100 or 250. The run collects the results, one row per pin, and you download Excel, CSV or JSON or send them to Google Sheets. ### Does it include the link a pin points to? Yes. The outbound link and its domain are separate columns. Grouping a few hundred rows by domain is the quickest way to see which sites are winning a search. ### Does it show how many times a pin was saved? No. It exports the pin's reaction count, the total of the reactions Pinterest shows on the pin. Save counts are not part of the search results. ### Can I export Pinterest ads? No. This exports the pins a normal Pinterest search shows, not ads or ad reports. For your own ads, use the export in Pinterest Ads Manager. ### Can I scrape pins from a board or one specific pin? Not yet. Search is the starting point. The board each pin belongs to is exported with the pin, so board names still show up in your results. To read one known pin or board, the InsightSocial API has Pinterest pin and board endpoints. ### Are images downloaded? No. The image link is a text column, so you can review or fetch images separately. Nothing is downloaded to your computer during a run. ### Can I get the accounts as well as the pins? Each run collects one or the other, because Pinterest lists pins and accounts separately. Every pin carries its pinner's handle, name and follower count, so run Pins first and use the Pinterest Profile Scraper when you need full account details. ### Do I need to be logged in? Yes. Signed out, Pinterest hides pin details, and the panel asks you to sign in to Pinterest first. You sign in to Pinterest as usual; the extension never sees your password. You also need a free InsightSocial account to export. ### Is it free? Yes. Collecting and reading your results in the dashboard are free and unlimited. Only exporting uses rows, one per pin: the free plan exports 500 rows a month, and Pro exports 10,000 for $9.99 a month ($7.99 a month billed yearly). A row you already exported is free to export again. ## Related scrapers - [Pinterest Profile Scraper](https://www.insightsocial.app/scraper/pinterest-profile-scraper.md): Turn a Pinterest search into a list of accounts with website, followers, monthly views and business email. Excel, CSV or Sheets. Free Chrome extension. - [TikTok Video Scraper](https://www.insightsocial.app/scraper/tiktok-video-scraper.md): Free TikTok Video Scraper. Extract views, likes, comments, shares, captions, and hashtags from any TikTok video. Export to CSV, Excel, JSON. - [TikTok Hashtag Scraper](https://www.insightsocial.app/scraper/tiktok-hashtag-scraper.md): Free TikTok hashtag scraper Chrome extension. Export the videos under any hashtag with views, likes, comments, shares, bookmarks, captions, hashtags, sounds and creator stats to CSV, Excel or JSON. No API key. --- # Trustpilot Review Scraper Source: https://www.insightsocial.app/scraper/trustpilot-review-scraper, updated 2026-10-18 > Export any company's Trustpilot reviews to Excel, CSV or Google Sheets: stars, title, text, country, date and company replies. 500 rows a month free. - **Platform**: trustpilot - **Web version**: https://www.insightsocial.app/scraper/trustpilot-review-scraper --- InsightSocial's Trustpilot Review Scraper is a free Chrome extension that exports a company's Trustpilot reviews to Excel, CSV, JSON or Google Sheets. Each row has the stars, title, full text, reviewer country, date, verified flag and helpful votes, and the company's reply sits in its own row underneath. Open the company's page on Trustpilot and click Scrape: no Trustpilot API, no code. ## At a glance - **Works on**: Any company page on trustpilot.com or its country sites, such as uk.trustpilot.com - **Per run**: One company. Small ones come back whole; a very large one comes back in part - **Each row**: Stars, title, text, reviewer, country, date, verified flag, helpful votes, company reply - **Export to**: Excel, CSV, JSON or Google Sheets - **Login**: No Trustpilot account needed. Signed in to Trustpilot, a big company comes back more complete - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. That icon opens the side panel. 3. **Open the company, click Scrape**: Go to the company's review page on Trustpilot and open the side panel. The first time, Chrome asks to let InsightSocial read trustpilot.com. Allow it, then click Scrape. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. Every run stays in your account to re-open later. ## What you get One row per review: the stars, the title, the full text, the reviewer's name and country, the date, whether Trustpilot marks it verified, and how many people found it useful. When the company answered, its reply is its own row directly under that review, so you can keep replies or filter them out. Each run also records the company's TrustScore, review total and how many reviews sit at each star. It works on any `trustpilot.com/review/…` company page, on trustpilot.com or a country site such as uk.trustpilot.com. Filter by rating, date or country once the file is open: the run reads everything it can reach. For a step-by-step walkthrough, including the official routes for your own company, read [How to export Trustpilot reviews](/blog/how-to-export-trustpilot-reviews). Reviews of a place are on the [Google Maps Review Scraper](/scraper/google-maps-review-scraper), product reviews on the [Amazon Review Scraper](/scraper/amazon-review-scraper), and every site is on the [review scraper hub](/scraper/reviews). --- ## FAQ ### How do I export Trustpilot reviews to Excel? Install the free InsightSocial extension, open the company's review page on Trustpilot, open the side panel and click Scrape. When the run ends, open it in your dashboard and choose Excel, CSV or Google Sheets. You get one row per review, with the company's replies as their own rows. The first 500 exported rows each month are free. ### Can I export every review of a big company? Often not all of them. Trustpilot shows signed-out visitors only part of a long review list, so on a big company the extension collects what it can reach and tells you how many it got out of the total. In our tests (Oct 2026), a company with 20,624 reviews returned 4,994, signed out. Signing in to Trustpilot in the same browser lets a run reach further. Small companies come back whole: 83 reviews and 5 replies in 4 to 7 seconds. ### Do I need a Trustpilot account? No. Trustpilot reviews are public, so the extension works signed out. Signing in to Trustpilot in the same browser helps only on big companies, because Trustpilot shows signed-out visitors part of a long list. The extension never posts, flags or reports a review, and it never sees your Trustpilot password. ### Are the company's replies included? Yes. Each reply is its own row, directly under the review it answers, marked as an owner reply. The side panel counts them apart, for example "83 reviews + 5 owner replies", so you can keep them or filter them out. ### Is it safe to run on many companies? The extension only reads public pages. If you run several big companies back to back, Trustpilot may slow your connection down for a few minutes. The run waits and carries on by itself; if the limit holds, it stops and keeps every review collected so far. ### Do I need a Trustpilot API key? No. If the company is yours, Trustpilot's business tools and its paid API are the official route to your own reviews. InsightSocial reads the public company page in your own browser, so it works on any company, with no key, no developer account and no code. ### Is it legal to export Trustpilot reviews? Trustpilot reviews are public, and reading them for research is common. You are responsible for following Trustpilot's terms and privacy laws such as GDPR when you store or share the data: keep reviewer names out of anything you publish, and do not use the file to contact reviewers. ### Why does Chrome ask for permission the first time? InsightSocial reads review sites only when you use them, so the first run asks Chrome for access to trustpilot.com, and Chrome's prompt names that site. It reads only after you click Scrape, and you can take the permission back any time in Chrome's extension settings. ### Is the Trustpilot review scraper free? Yes, to collect. Scraping and reading reviews in your dashboard are free and unlimited. Exporting uses one credit per row, replies included: 500 rows a month on the free plan, 10,000 on Pro for $9.99 a month ($7.99 a month billed yearly). A row you exported before is free to export again. ## Related scrapers - [Google Maps Review Scraper](https://www.insightsocial.app/scraper/google-maps-review-scraper.md): Export a place's Google reviews to Excel, CSV or Google Sheets, newest first: stars, full text, date, likes and owner replies. 500 rows a month free. - [Amazon Review Scraper](https://www.insightsocial.app/scraper/amazon-review-scraper.md): Download an Amazon product's reviews to CSV, Excel or Google Sheets: stars, headline, text, date, verified purchase and variant. 500 rows a month free. - [Etsy Review Scraper](https://www.insightsocial.app/scraper/etsy-review-scraper.md): Export an Etsy listing's or a whole shop's reviews to CSV, Excel or Google Sheets: stars, text, date, item and seller replies. 500 rows a month free. --- # Google Maps Review Scraper Source: https://www.insightsocial.app/scraper/google-maps-review-scraper, updated 2026-10-18 > Export a place's Google reviews to Excel, CSV or Google Sheets, newest first: stars, full text, date, likes and owner replies. 500 rows a month free. - **Platform**: googlemaps - **Web version**: https://www.insightsocial.app/scraper/google-maps-review-scraper --- InsightSocial's Google Maps Review Scraper is a free Chrome extension that exports the Google reviews of a place to Excel, CSV, JSON or Google Sheets, newest first. Each row has the stars, full text, date, likes and the owner's reply. Sign in to Google, open the place on Google Maps and click Scrape: no Places API, no code. ## At a glance - **Works on**: Any place on Google Maps: shops, restaurants, hotels, clinics, offices - **Per run**: One place, newest first. Most places come back whole in seconds - **Each row**: Stars, full text, reviewer, date, likes and the owner's reply - **Export to**: Excel, CSV, JSON or Google Sheets - **Login**: Your own Google sign-in in Chrome. Signed out, Maps shows only a few reviews, so the run asks you to sign in - **While it runs**: Keep the Maps tab in front. Maps stops loading reviews in a background tab - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. That icon opens the side panel. 3. **Open the place, click Scrape**: Open the place on Google Maps in a browser where you are signed in to Google. Allow google.com the first time Chrome asks, click Scrape, and stay on the tab until the side panel says it is done. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. Every run stays in your account to re-open later. ## What you get One row per review, newest first: the stars, the full text, the reviewer's name, when it was posted and how many people liked it. When the owner answered, the reply is its own row directly under that review. Star-only reviews stay in with an empty text, so your rating counts add up. Each run also records the place's name, address, average rating and review total. Dates come out exact wherever Google sends one; otherwise you get Google's own wording, such as "3 months ago". To compare places, export each one and put the files side by side by month: rating trend, share of one-star reviews, and how often the owner replies. For a step-by-step walkthrough, including Google's own options for a business you manage, read [How to export Google reviews](/blog/how-to-export-google-reviews). Company reviews are on the [Trustpilot Review Scraper](/scraper/trustpilot-review-scraper), and every site is on the [review scraper hub](/scraper/reviews). --- ## FAQ ### How do I export Google reviews to Excel? Sign in to Google in Chrome, open the place on Google Maps, open the InsightSocial side panel and click Scrape. When it finishes, open the run in your dashboard and choose Excel, CSV or Google Sheets. Each review is a row, newest first, with the owner's reply underneath. The first 500 exported rows each month are free. ### How many Google reviews can I export from one place? All of them on most places. In our tests (Oct 2026), a place with 89 reviews came back whole, with 87 owner replies, in 10 seconds. On very large places the Maps page slows down as the list grows, and a run stops after two and a half minutes with the newest reviews it reached: 640 to 720 in our tests. ### Why do I need to be signed in to Google? Because Google Maps shows signed-out visitors only a few reviews and no sorting. Signed in, it shows the full list, and that list is what the extension reads. It never posts, rates or changes anything on your Google account. ### Can I switch tabs while it runs? Not on Google Maps. Maps stops loading reviews in a background tab, but the run's time limit keeps counting, so switching away means fewer reviews. Stay on the tab until the side panel says it is done. Most places finish in seconds. ### Can I export reviews for many places at once? Not in one run. Each run reads the place you have open, and the run is named after it. Open the next place and click Scrape again. It does not work through a list of Maps search results. ### Do I need a Google Maps API key? No. Google's own routes are narrow: Google Takeout and the Business Profile API cover places you manage, and the Places API returns at most five reviews per place. InsightSocial reads the reviews Google Maps shows you when you are signed in, so it works on any place, with no developer account, key or code. ### Why does Chrome ask for access to google.com? Because Google Maps runs on www.google.com. The first time you scrape a place, Chrome asks you to allow InsightSocial there. It reads only the Maps place you open, only after you click Scrape, and you can take the permission back any time in Chrome's extension settings. ### Is it legal to export Google reviews? Google reviews are public, and reading them for research is common. You are responsible for following Google's terms and privacy laws such as GDPR when you store or share the data: keep reviewer names out of anything you publish, and do not use the file to contact reviewers. ### Is the Google Maps review scraper free? Yes, to collect. Scraping and reading reviews in your dashboard are free and unlimited. Exporting uses one credit per row, and owner replies are rows too: 500 rows a month on the free plan, 10,000 on Pro for $9.99 a month ($7.99 a month billed yearly). A row you exported before is free to export again. ## Related scrapers - [Trustpilot Review Scraper](https://www.insightsocial.app/scraper/trustpilot-review-scraper.md): Export any company's Trustpilot reviews to Excel, CSV or Google Sheets: stars, title, text, country, date and company replies. 500 rows a month free. - [Amazon Review Scraper](https://www.insightsocial.app/scraper/amazon-review-scraper.md): Download an Amazon product's reviews to CSV, Excel or Google Sheets: stars, headline, text, date, verified purchase and variant. 500 rows a month free. - [Etsy Review Scraper](https://www.insightsocial.app/scraper/etsy-review-scraper.md): Export an Etsy listing's or a whole shop's reviews to CSV, Excel or Google Sheets: stars, text, date, item and seller replies. 500 rows a month free. --- # Amazon Review Scraper Source: https://www.insightsocial.app/scraper/amazon-review-scraper, updated 2026-10-18 > Download an Amazon product's reviews to CSV, Excel or Google Sheets: stars, headline, text, date, verified purchase and variant. 500 rows a month free. - **Platform**: amazon - **Web version**: https://www.insightsocial.app/scraper/amazon-review-scraper --- InsightSocial's Amazon Review Scraper is a free Chrome extension that downloads the reviews of an Amazon product to Excel, CSV, JSON or Google Sheets. Each row has the stars, headline, full text, date, verified-purchase flag, helpful votes and the variant bought. Sign in to Amazon, open the product page and click Scrape. It works on 20 Amazon storefronts. ## At a glance - **Works on**: Product pages on 20 Amazon storefronts, including .com, .co.uk, .de, .co.jp, .in and .com.br - **Per run**: One product. Signed in, the reviews Amazon will show, up to about 1,200 - **Each row**: Stars, headline, text, reviewer, country, date, verified purchase, helpful votes, variant - **Export to**: Excel, CSV, JSON or Google Sheets - **Login**: Your own Amazon sign-in in Chrome. Signed out, Amazon shows only the few reviews on the product page - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. That icon opens the side panel. 3. **Open the product, click Scrape**: Sign in to Amazon and open the product page. Allow that Amazon site the first time Chrome asks, then click Scrape. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. Every run stays in your account to re-open later. ## What you get One row per review: the stars, the headline, the full text, the reviewer's name, the country Amazon names for the review, the date, whether it is a verified purchase, how many people found it helpful, and the size, colour or style the reviewer bought. Each run also records the product's title, brand, average rating and review total. ## Making sense of the export - **Split by variant.** Amazon often pools the reviews of a product's sizes and colours on one listing. The Variant column lets you separate them before you draw conclusions. - **Filter on Verified.** Reviews Amazon marks as verified purchases come from people Amazon knows bought the product. - **Rank by Helpful.** Helpful votes are the closest thing Amazon has to a shoppers' consensus on which review matters. - **Use the storefront where the product sells.** Each storefront has its own reviews, plus a few it borrows from other countries, marked by the Country column. For a step-by-step walkthrough, and why most exporters return only a dozen reviews, read [How to download Amazon reviews](/blog/how-to-download-amazon-reviews). Handmade-shop reviews are on the [Etsy Review Scraper](/scraper/etsy-review-scraper), and every site is on the [review scraper hub](/scraper/reviews). --- ## FAQ ### How do I export Amazon reviews to Excel? Sign in to Amazon in Chrome, open the product page, open the InsightSocial side panel and click Scrape. When it finishes, open the run in your dashboard and choose Excel, CSV or Google Sheets. Each review is a row. The first 500 exported rows each month are free. ### Can I download reviews from Amazon directly? No. Amazon has no export button for shoppers: reviews show ten to a page, behind star filters. InsightSocial reads those pages for you and gives you one spreadsheet row per review, with the stars, headline, text, date, verified-purchase flag, helpful votes and variant. ### How many Amazon reviews can I export? Up to about 1,200 per product when you are signed in, which is as many as Amazon's own review pages will show. The extension reads each star rating, one to five, and keeps every review once, so a popular product with heavy overlap gives fewer. One- and two-star reviews come before five-star ones, so a run cut short still has the complaints. ### Why do I need to sign in to Amazon? Because Amazon shows its review pages only to signed-in shoppers. Signed out, you get the dozen or so reviews on the product page (13 in our tests, Oct 2026), and on amazon.com sometimes none. Any shopping account works, and the extension only reads. ### Is it safe for my Amazon account? The extension only reads, and it pauses between pages the way a person would. After many review pages, Amazon may limit review access for your account for a while or ask for a captcha. The run then stops and keeps everything it collected. Wait before the next big run. ### Which Amazon sites does it work on? 20 storefronts: amazon.com, .co.uk, .ca, .de, .fr, .it, .es, .nl, .se, .pl, .com.tr, .ae, .sa, .eg, .in, .co.jp, .com.au, .sg, .com.br and .com.mx. Ratings and dates are read in each site's own language, so "5,0 von 5 Sternen" becomes 5. Chrome asks for access the first time you use each one. ### Can I export reviews for a list of products? Not in one run. Each run reads the product you have open and is named after it. Open the next product page and click Scrape again. ### Does it include the verified-purchase badge and the variant? Yes. The Verified column says yes when Amazon marks a verified purchase. The Variant column shows the size, colour or style the reviewer bought, so you can separate "the black one" from "the white one". ### Do I need an Amazon API key? No. InsightSocial reads the review pages your signed-in browser can open, so there is no developer account, no key and no code. ### Is it legal to export Amazon reviews? Amazon reviews are public, and reading them for research is common. You are responsible for following Amazon's terms and privacy laws such as GDPR when you store or share the data: keep reviewer names out of anything you publish, and do not use the file to contact reviewers. ### Is the Amazon review scraper free? Yes, to collect. Scraping and reading reviews in your dashboard are free and unlimited. Exporting uses one credit per row: 500 rows a month on the free plan, 10,000 on Pro for $9.99 a month ($7.99 a month billed yearly). A row you exported before is free to export again. ## Related scrapers - [Etsy Review Scraper](https://www.insightsocial.app/scraper/etsy-review-scraper.md): Export an Etsy listing's or a whole shop's reviews to CSV, Excel or Google Sheets: stars, text, date, item and seller replies. 500 rows a month free. - [Trustpilot Review Scraper](https://www.insightsocial.app/scraper/trustpilot-review-scraper.md): Export any company's Trustpilot reviews to Excel, CSV or Google Sheets: stars, title, text, country, date and company replies. 500 rows a month free. - [Google Maps Review Scraper](https://www.insightsocial.app/scraper/google-maps-review-scraper.md): Export a place's Google reviews to Excel, CSV or Google Sheets, newest first: stars, full text, date, likes and owner replies. 500 rows a month free. --- # Etsy Review Scraper Source: https://www.insightsocial.app/scraper/etsy-review-scraper, updated 2026-10-18 > Export an Etsy listing's or a whole shop's reviews to CSV, Excel or Google Sheets: stars, text, date, item and seller replies. 500 rows a month free. - **Platform**: etsy - **Web version**: https://www.insightsocial.app/scraper/etsy-review-scraper --- InsightSocial's Etsy Review Scraper is a free Chrome extension that exports the reviews of an Etsy listing, or of a whole Etsy shop, to Excel, CSV, JSON or Google Sheets. Each row has the stars, review text, date, buyer, the item reviewed and the seller's reply. Open the listing or shop on Etsy and click Scrape: no Etsy API key, no code. ## At a glance - **Works on**: Any Etsy listing (that item's reviews) or shop page (reviews across everything it sells) - **Per run**: Up to 5,000 reviews. A listing with 1,028 reviews took 41 seconds in our tests (Oct 2026) - **Each row**: Stars, text, date, buyer, would-recommend answer, item reviewed, seller reply - **Export to**: Excel, CSV, JSON or Google Sheets - **Login**: No Etsy account needed. Any shop's reviews are public - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. That icon opens the side panel. 3. **Open the listing or shop, click Scrape**: Open an Etsy listing for that item's reviews, or a shop for all of them. Allow etsy.com the first time Chrome asks, then click Scrape. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. Every run stays in your account to re-open later. ## What you get One row per review: the stars, the review text, the buyer's name, the date, and the buyer's would-recommend answer where Etsy asked it. On a shop run, each row also names the item the review is about. When the seller answered, the reply is its own row directly under that review. Each run records the shop's average rating and review total too. Open a listing (`etsy.com/listing/…`) for one item's reviews, or the shop (`etsy.com/shop/…`) for every item at once. Etsy reviews have no headline, so the text column carries the whole review. For a step-by-step walkthrough, including Etsy's own data download for your shop, read [How to export Etsy reviews](/blog/how-to-export-etsy-reviews). Product reviews are on the [Amazon Review Scraper](/scraper/amazon-review-scraper), and every site is on the [review scraper hub](/scraper/reviews). --- ## FAQ ### How do I export Etsy reviews to Excel? Install the free InsightSocial extension, open the Etsy listing or shop, open the side panel and click Scrape. When it finishes, open the run in your dashboard and choose Excel, CSV or Google Sheets. Each review is a row, with the seller's reply in its own row underneath. The first 500 exported rows each month are free. ### What is the difference between a listing run and a shop run? A listing run collects the reviews of that one item. A shop run collects the reviews across everything the shop sells, and each row names the item it is about. Open whichever page you want and the side panel adapts. ### How many Etsy reviews can one run export? Up to 5,000. In our tests (Oct 2026), a listing returned 1,028 reviews and 403 seller replies in 41 seconds. A big shop can have far more than 5,000. The side panel tells you where the run stopped, and you keep every review it collected. ### Can I export another seller's Etsy reviews? Yes. Etsy reviews are public, and the extension reads the same reviews any visitor sees. You do not need an Etsy account or an API key, so a competitor's shop works the same way as your own. For your own shop, Etsy's own data download is the official route. ### What if Etsy asks me to prove I am human? Etsy sometimes checks a browser that has loaded many pages. If it does, the run stops and keeps what it collected. Finish the check on the Etsy page, then click Scrape again. ### Is it legal to export Etsy reviews? Etsy reviews are public, and reading them for research is common. You are responsible for following Etsy's terms and privacy laws such as GDPR when you store or share the data: keep reviewer names out of anything you publish, and do not use the file to contact reviewers. ### Why does Chrome ask for permission the first time? InsightSocial reads review sites only when you use them, so the first run asks Chrome for access to etsy.com, and Chrome's prompt names that site. It reads only after you click Scrape, and you can take the permission back any time in Chrome's extension settings. ### Is the Etsy review scraper free? Yes, to collect. Scraping and reading reviews in your dashboard are free and unlimited. Exporting uses one credit per row, seller replies included: 500 rows a month on the free plan, 10,000 on Pro for $9.99 a month ($7.99 a month billed yearly). A row you exported before is free to export again. ## Related scrapers - [Amazon Review Scraper](https://www.insightsocial.app/scraper/amazon-review-scraper.md): Download an Amazon product's reviews to CSV, Excel or Google Sheets: stars, headline, text, date, verified purchase and variant. 500 rows a month free. - [Trustpilot Review Scraper](https://www.insightsocial.app/scraper/trustpilot-review-scraper.md): Export any company's Trustpilot reviews to Excel, CSV or Google Sheets: stars, title, text, country, date and company replies. 500 rows a month free. - [Product Hunt Scraper](https://www.insightsocial.app/scraper/product-hunt-scraper.md): Free Chrome extension: export a Product Hunt product's reviews or a launch's comment thread to Excel, CSV or Google Sheets. 500 rows a month free. --- # Steam Review Scraper Source: https://www.insightsocial.app/scraper/steam-review-scraper, updated 2026-10-18 > Export a Steam game's reviews to Excel, CSV or Google Sheets, newest first: recommended or not, text, playtime, language and votes. 500 rows free. - **Platform**: steam - **Web version**: https://www.insightsocial.app/scraper/steam-review-scraper --- InsightSocial's Steam Review Scraper is a free Chrome extension that exports a game's Steam reviews to Excel, CSV, JSON or Google Sheets, newest first and in every language. Each row says whether the player recommends the game, with the review text, playtime, language, date, helpful and funny votes, and the developer's reply. Open the game's store page and click Scrape. ## At a glance - **Works on**: Any game's page on the Steam store, age-gated games included - **Per run**: The newest 10,000 reviews. Smaller games come back whole - **Each row**: Recommended or not, text, playtime, language, date, helpful and funny votes, developer reply - **Export to**: Excel, CSV, JSON or Google Sheets - **Login**: No Steam account and no API key - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. That icon opens the side panel. 3. **Open the game, click Scrape**: Open the game's page on store.steampowered.com. Allow Steam the first time Chrome asks, then click Scrape. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. Every run stays in your account to re-open later. ## What you get One row per review, newest first: whether the player recommends the game, the review text, how many hours they had played, the language, the date, and how many people found it helpful or funny. When the developer answered, the reply is its own row directly under that review. Each run also records the game's review totals. It works on any game's store page (`store.steampowered.com/app/…`), age-gated games included, and reads reviews in every language without translating them. Filter the Language column to study one market, or the Recommends column to read only the negative reviews. For a step-by-step walkthrough, including Steam's own review feed for a full history, read [How to export Steam reviews](/blog/how-to-export-steam-reviews). Product launch reviews are on the [Product Hunt Scraper](/scraper/product-hunt-scraper), and every site is on the [review scraper hub](/scraper/reviews). --- ## FAQ ### How do I export Steam reviews to Excel? Install the free InsightSocial extension, open the game's page on the Steam store, open the side panel and click Scrape. When it finishes, open the run in your dashboard and choose Excel, CSV or Google Sheets. Each review is a row, newest first. The first 500 exported rows each month are free. ### How many Steam reviews can I export? Up to the newest 10,000 per run. Smaller games come back whole: in our tests (Oct 2026), a game with 78 reviews returned all of them, plus the developer's reply, in 10 to 17 seconds. A big game stops at its newest 10,000. ### Can I get reviews older than the newest 10,000? Not in one run. The extension always starts from the newest, because after a patch or a launch those are the reviews that matter. For the full history of a very large game, our guide How to export Steam reviews shows how to page through Steam's own review feed. ### Does it get reviews in every language? Yes. Reviews come back in the language they were written in, with a Language column, and nothing is translated. Filter the Language column to study one market. ### Do I need a Steam account or an API key? No. Steam reviews are public, and the extension works signed out, with no key and no code. Steam does publish a free review feed for developers, but it returns raw data a page at a time. The extension turns the same reviews into a spreadsheet from the game's store page. ### Is it legal to export Steam reviews? Steam reviews are public, and reading them for research is common. You are responsible for following Steam's terms and privacy laws such as GDPR when you store or share the data: keep reviewer names out of anything you publish, and do not use the file to contact reviewers. ### Why does Chrome ask for permission the first time? InsightSocial reads review sites only when you use them, so the first run asks Chrome for access to the Steam store, and Chrome's prompt names that site. It reads only after you click Scrape, and you can take the permission back any time in Chrome's extension settings. ### Is the Steam review scraper free? Yes, to collect. Scraping and reading reviews in your dashboard are free and unlimited. Exporting uses one credit per row, developer replies included: 500 rows a month on the free plan, 10,000 on Pro for $9.99 a month ($7.99 a month billed yearly). A row you exported before is free to export again. ## Related scrapers - [Product Hunt Scraper](https://www.insightsocial.app/scraper/product-hunt-scraper.md): Free Chrome extension: export a Product Hunt product's reviews or a launch's comment thread to Excel, CSV or Google Sheets. 500 rows a month free. - [Reddit Comment Scraper](https://www.insightsocial.app/scraper/reddit-comments-scraper.md): Export every comment and reply from a Reddit thread to Excel, CSV or Google Sheets, nested replies kept. Free Chrome extension, no Reddit API key. - [Hacker News Comment Scraper](https://www.insightsocial.app/scraper/hacker-news-comment-scraper.md): Export every comment and reply in a Hacker News thread to Excel, CSV, JSON or Google Sheets, with depth and parent. Free extension, 500 rows a month. --- # Product Hunt Scraper Source: https://www.insightsocial.app/scraper/product-hunt-scraper, updated 2026-10-18 > Free Chrome extension: export a Product Hunt product's reviews or a launch's comment thread to Excel, CSV or Google Sheets. 500 rows a month free. - **Platform**: producthunt - **Web version**: https://www.insightsocial.app/scraper/product-hunt-scraper --- InsightSocial's Product Hunt Scraper is a free Chrome extension that exports a product's reviews, or every comment on a launch with the replies under it, to Excel, CSV, JSON or Google Sheets. Each row has the author, text, date and link, plus the star rating on a review or the upvotes on a comment. You need no Product Hunt account and no API token. ## At a glance - **Works on**: A product's reviews page, or one of its launch pages - **Per run**: One product or one launch, up to 5,000 reviews or comments - **Each row**: Author, text, date, link; star rating and maker reply on reviews; upvotes, reply depth and maker badge on comments - **Export to**: Excel, CSV, JSON or Google Sheets - **Login**: No Product Hunt account needed - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store and sign in with Google or email. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. That icon opens the side panel. 3. **Open the product or launch, click Scrape**: Go to a product's reviews page or one of its launch pages. The first time, Chrome asks you to allow producthunt.com. Then click Scrape. 4. **Export**: Open the run in your InsightSocial dashboard and download Excel, CSV or JSON, or send it to Google Sheets. ## What you get A run reads one Product Hunt page. On a product's reviews page you get one row per review, with the star rating, text, reviewer, date and the maker's reply. On a launch page you get the comment thread: each comment and reply with its depth, upvotes and whether a maker wrote it, so a question sits right above the maker's answer. Makers use the launch file to turn launch-day questions into docs and onboarding. The review file is a quick way to read how people rate a tool you compete with, or to find quotes for your own site. For the long version, with Product Hunt's own API compared, read [How to export Product Hunt reviews](/blog/how-to-export-product-hunt-reviews). Startup discussions also run on Hacker News: the [Hacker News Comment Scraper](/scraper/hacker-news-comment-scraper) exports a whole Show HN thread. Every site is on the [review scraper hub](/scraper/reviews). --- ## FAQ ### How do I export Product Hunt reviews to Excel or CSV? Open the product's reviews page, open InsightSocial and click Scrape. Every review comes back with its star rating, text, reviewer, date and the maker's reply, and you download it as Excel, CSV or JSON, or send it to Google Sheets. In our tests (Oct 2026) a product returned all 162 of its reviews in 14 seconds. ### Can I export all the comments on a Product Hunt launch? Yes. Open the launch page and click Scrape. You get the comments and the replies under them, each with its depth, upvotes and whether a maker wrote it, so the thread reads as it does on the page. In our tests (Oct 2026) a launch returned 212 of its 213 comments in 11 seconds. ### How many reviews or comments can one run export? Up to 5,000. A launch thread usually has a few hundred comments, so it usually comes back whole; only a heavily reviewed product reaches the limit, and the side panel tells you if it did. One run reads one product or one launch; open the next page for the next one. ### Can I scrape the Product Hunt leaderboard or a day's launches? No. A run reads the one product or launch page you have open. It does not walk the daily leaderboard. ### Do I need a Product Hunt account or API token? No. The extension reads the page you have open in Chrome, so there is no token to request and no code to write. Product Hunt's own API needs a developer token and, by its terms, Product Hunt's permission before any commercial use. ### Can I get makers' emails? No. Each row carries the name Product Hunt shows on the review or comment, not contact details. ### Is it legal to export Product Hunt reviews? Reading public pages is generally allowed, but you are responsible for how you use what you export: follow the site's terms and privacy law, especially where names are involved. The extension only reads the page you have open in your own browser; it never upvotes, comments or posts. ### Why does Chrome ask for permission the first time? InsightSocial reads review and discussion sites only when you use them. The first Product Hunt run asks Chrome for access to producthunt.com, and you can withdraw it any time from the extension's settings in Chrome. ### Is the Product Hunt scraper free? Yes. Collecting runs and reading them in your dashboard are free and unlimited. Only exporting uses credits, one per row: the free plan exports 500 rows a month, Pro exports 10,000 rows for $9.99 a month ($7.99 a month billed yearly), and one-time packs start at $2 for 250 rows. A row you already exported is free to export again. ## Related scrapers - [Hacker News Comment Scraper](https://www.insightsocial.app/scraper/hacker-news-comment-scraper.md): Export every comment and reply in a Hacker News thread to Excel, CSV, JSON or Google Sheets, with depth and parent. Free extension, 500 rows a month. - [Steam Review Scraper](https://www.insightsocial.app/scraper/steam-review-scraper.md): Export a Steam game's reviews to Excel, CSV or Google Sheets, newest first: recommended or not, text, playtime, language and votes. 500 rows free. - [Reddit Comment Scraper](https://www.insightsocial.app/scraper/reddit-comments-scraper.md): Export every comment and reply from a Reddit thread to Excel, CSV or Google Sheets, nested replies kept. Free Chrome extension, no Reddit API key. --- # Hacker News Comment Scraper Source: https://www.insightsocial.app/scraper/hacker-news-comment-scraper, updated 2026-10-18 > Export every comment and reply in a Hacker News thread to Excel, CSV, JSON or Google Sheets, with depth and parent. Free extension, 500 rows a month. - **Platform**: hackernews - **Web version**: https://www.insightsocial.app/scraper/hacker-news-comment-scraper --- InsightSocial's Hacker News Comment Scraper is a free Chrome extension that exports every comment in a Hacker News thread, replies included, to Excel, CSV, JSON or Google Sheets. Each row has the author, text, time, the links in the comment, and how deep in the thread it sits. It needs no Hacker News account. For a quick one-off CSV, the free Hacker News Thread Exporter needs no install. ## At a glance - **Works on**: Any Hacker News thread: a story, Ask HN, Show HN, or a single comment and its replies - **Per run**: One thread, every comment and reply, including replies under deleted comments - **Each row**: Author, text, time, links in the comment, depth, parent and a link to the comment - **Export to**: Excel, CSV, JSON or Google Sheets - **Login**: No Hacker News account needed - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store and sign in with Google or email. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. That icon opens the side panel. 3. **Open the thread, click Scrape**: Open the thread's comments page on news.ycombinator.com. The first time, Chrome asks you to allow news.ycombinator.com. Then click Scrape. 4. **Export**: Open the run in your InsightSocial dashboard and download Excel, CSV or JSON, or send it to Google Sheets. ## What you get A run reads one Hacker News thread: a story, an Ask HN, a Show HN, or a single comment opened as its own page. Each comment becomes a row with its author, time, full text, the links written inside it, how deep it sits and the comment it replies to. Every row also carries the story's title, link, points and comment count, so files from several threads stack into one sheet. Founders keep every comment from their Show HN in one sheet and sort it into questions, objections and requests. Readers pull every link a big "what are you reading" thread recommends from the links column. Only need one thread as a CSV? The free [Hacker News Thread Exporter](/tools/hacker-news-thread-exporter) works in your browser with nothing to install. For the official API routes and their trade-offs, read [How to export Hacker News comments](/blog/how-to-export-hacker-news-comments). For the same job on Reddit, use the [Reddit Comments Scraper](/scraper/reddit-comments-scraper). Every site is on the [review scraper hub](/scraper/reviews). --- ## FAQ ### How do I export a Hacker News thread to Excel or CSV? Open the thread, open InsightSocial and click Scrape. You get one row per comment, with its author, time, text, links and depth, as Excel, CSV or JSON, or in Google Sheets. In our tests (Oct 2026) a 71-comment thread took 6 seconds and a 2,484-comment thread took 2 minutes 22 seconds. ### Does it get the replies hidden behind “more” and under deleted comments? Yes. It collects the whole thread, not just what the page has expanded. When a comment was deleted or flagged, its replies are kept and placed under the nearest comment still standing, so the conversation still reads in order. ### Why is there no score column? Hacker News keeps comment points private, so there is no score to collect. Each row does carry the story's title, link, points and comment count. ### Do I need a Hacker News account or API key? No. Threads are public and the extension reads them for you, so there is nothing to sign up for and no code to write. If you program, Hacker News' free API works too, but you fetch each comment one by one and rebuild the tree yourself. ### Can I export many threads, a search or a user's comments? No. A run reads one thread. Open the next thread and click Scrape again. ### What is the difference from the free Hacker News Thread Exporter? The free exporter runs on our site, needs no install and gives you one CSV. The extension adds Excel, JSON and Google Sheets, and keeps every run in your dashboard to re-open later. ### Is it legal to export Hacker News comments? Reading public pages is generally allowed, but you are responsible for how you use what you export: follow the site's terms and privacy law, especially where names are involved. The extension only reads the page you have open in your own browser; it never votes, comments or posts. ### Why does Chrome ask for permission the first time? InsightSocial reads review and discussion sites only when you use them. The first Hacker News run asks Chrome for access to news.ycombinator.com, and you can withdraw it any time from the extension's settings in Chrome. ### Is the Hacker News scraper free? Yes. Collecting runs and reading them in your dashboard are free and unlimited. Only exporting uses credits, one per row: the free plan exports 500 rows a month, Pro exports 10,000 rows for $9.99 a month ($7.99 a month billed yearly), and one-time packs start at $2 for 250 rows. A row you already exported is free to export again, so exporting a thread again after more comments arrive charges only the new ones. ## Related scrapers - [Reddit Comment Scraper](https://www.insightsocial.app/scraper/reddit-comments-scraper.md): Export every comment and reply from a Reddit thread to Excel, CSV or Google Sheets, nested replies kept. Free Chrome extension, no Reddit API key. - [Quora Scraper](https://www.insightsocial.app/scraper/quora-scraper.md): Export every answer to a Quora question, with the comments under each, to Excel, CSV or Google Sheets: author, credential, upvotes. 500 rows free. - [Product Hunt Scraper](https://www.insightsocial.app/scraper/product-hunt-scraper.md): Free Chrome extension: export a Product Hunt product's reviews or a launch's comment thread to Excel, CSV or Google Sheets. 500 rows a month free. --- # Quora Scraper Source: https://www.insightsocial.app/scraper/quora-scraper, updated 2026-10-18 > Export every answer to a Quora question, with the comments under each, to Excel, CSV or Google Sheets: author, credential, upvotes. 500 rows free. - **Platform**: quora - **Web version**: https://www.insightsocial.app/scraper/quora-scraper --- InsightSocial's Quora Scraper is a free Chrome extension that exports the answers to a Quora question, with the comments and replies under each, to Excel, CSV, JSON or Google Sheets. Each row has the full text, author, credential, upvotes, date and links. It reads the full answer, not the cut-off preview, and works on Quora's language sites too. ## At a glance - **Works on**: Any Quora question, on quora.com or a language site such as es.quora.com - **Per run**: One question: the answers, then the comments under each, up to 3,000 rows - **Each row**: Full text, author, credential, upvotes, date, links, and whether it is an answer or a comment - **Export to**: Excel, CSV, JSON or Google Sheets - **Login**: Works signed out on most questions; sign in to Quora for questions with thousands of answers - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store and sign in with Google or email. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. That icon opens the side panel. 3. **Open the question, click Scrape**: Open the Quora question, on quora.com or a language site such as es.quora.com. The first time, Chrome asks you to allow quora.com. Then click Scrape. 4. **Export**: Open the run in your InsightSocial dashboard and download Excel, CSV or JSON, or send it to Google Sheets. ## What you get A run reads one Quora question. Each answer is a row with its full text (line breaks and links kept), author, credential, upvotes and date. The comments and replies under it follow, one level deeper each, so you can read an answer and the discussion it started side by side. People use the file to collect how practitioners phrase a problem, for content and FAQs, or to compare many answers to one question in a sheet instead of scrolling. For keyword searches across many questions from your own code, the [InsightSocial API has Quora endpoints](/social-media-api/quora). For more on Quora's limits and the manual routes, read [How to export Quora answers](/blog/how-to-export-quora-answers). Discussion threads elsewhere: the [Reddit Comments Scraper](/scraper/reddit-comments-scraper) and the [Hacker News Comment Scraper](/scraper/hacker-news-comment-scraper). Every site is on the [review scraper hub](/scraper/reviews). --- ## FAQ ### How do I export Quora answers to Excel or CSV? Open the question, open InsightSocial and click Scrape. Each answer comes back as a row with its full text, author, credential, upvotes and date, followed by the comments under it, and you download Excel, CSV or JSON, or send it to Google Sheets. In our tests (Oct 2026) smaller questions took 11 to 12 seconds. ### Does it get the full answer, not the “Continue Reading” preview? Yes. Signed out, Quora shows a few answers, cuts each one short and blurs the rest. The extension collects each answer's full text without you clicking anything, with line breaks and links kept. ### How many answers can one run export? Up to 3,000 answers and comments together. Most questions are far smaller and come back whole. In our tests (Oct 2026) a very large question reached that limit in 2 minutes 26 seconds, with 1,047 answers and 1,977 comments. One run reads one question; it does not walk a topic or a Space. ### Do I need a Quora account? Not for most questions. On a question with thousands of answers, Quora can stop serving answers to a signed-out browser partway, and the side panel tells you when that happens. Sign in to Quora in the same Chrome and run it again to collect more. ### Is there a Quora API I could use instead? Quora does not publish an API for its questions and answers, so the extension is the no-code route. If you need Quora data inside your own software, the InsightSocial API has Quora endpoints, paid from the same credits. ### Why do I get fewer answers than the count Quora shows? Quora's count includes answers it collapses or no longer shows, such as deleted ones, and it does not list those. The extension exports the answers Quora actually lists, and the side panel shows its own count. ### Does it work on Quora in other languages? Yes. Open the question on Quora's site for that language, such as es.quora.com, and the run works the same way. ### Is it legal to export Quora answers? Reading public pages is generally allowed, but you are responsible for how you use what you export: follow the site's terms and privacy law, especially where names are involved. The extension only reads the page you have open in your own browser; it never upvotes, answers, comments or follows. ### Why does Chrome ask for permission the first time? InsightSocial reads review and discussion sites only when you use them. The first Quora run asks Chrome for access to quora.com, and you can withdraw it any time from the extension's settings in Chrome. ### Is the Quora scraper free? Yes. Collecting runs and reading them in your dashboard are free and unlimited. Only exporting uses credits, one per row: the free plan exports 500 rows a month, Pro exports 10,000 rows for $9.99 a month ($7.99 a month billed yearly), and one-time packs start at $2 for 250 rows. Comments count as rows too, and a row you already exported is free to export again. ## Related scrapers - [Reddit Comment Scraper](https://www.insightsocial.app/scraper/reddit-comments-scraper.md): Export every comment and reply from a Reddit thread to Excel, CSV or Google Sheets, nested replies kept. Free Chrome extension, no Reddit API key. - [Hacker News Comment Scraper](https://www.insightsocial.app/scraper/hacker-news-comment-scraper.md): Export every comment and reply in a Hacker News thread to Excel, CSV, JSON or Google Sheets, with depth and parent. Free extension, 500 rows a month. - [Blind Scraper](https://www.insightsocial.app/scraper/blind-scraper.md): Export the comments on a Blind (teamblind.com) post to Excel, CSV or Google Sheets: text, company, likes, date and replies. 500 rows a month free. - [Product Hunt Scraper](https://www.insightsocial.app/scraper/product-hunt-scraper.md): Free Chrome extension: export a Product Hunt product's reviews or a launch's comment thread to Excel, CSV or Google Sheets. 500 rows a month free. --- # Blind Scraper Source: https://www.insightsocial.app/scraper/blind-scraper, updated 2026-10-18 > Export the comments on a Blind (teamblind.com) post to Excel, CSV or Google Sheets: text, company, likes, date and replies. 500 rows a month free. - **Platform**: blind - **Web version**: https://www.insightsocial.app/scraper/blind-scraper --- InsightSocial's Blind Scraper is a free Chrome extension that exports the comments on a Blind (teamblind.com) post to Excel, CSV, JSON or Google Sheets. Each row has the comment, the company Blind shows next to the commenter, likes, date and which comment it replies to. Small posts come back whole; on a busy post you get the comments Blind lets a browser load, and the side panel shows how many that is. ## At a glance - **Works on**: Any post on teamblind.com - **Per run**: One post's comments and replies. On busy posts, the part of the discussion Blind loads - **Each row**: Comment text, nickname, company, likes, date, reply depth and parent - **Export to**: Excel, CSV, JSON or Google Sheets - **Login**: Not needed for public posts; members-only posts need you signed in to Blind - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store and sign in with Google or email. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. That icon opens the side panel. 3. **Open the post, click Scrape**: Open the post on teamblind.com. The first time, Chrome asks you to allow teamblind.com. Click Scrape; the side panel says how many comments it reached out of the total. 4. **Export**: Open the run in your InsightSocial dashboard and download Excel, CSV or JSON, or send it to Google Sheets. ## What you get A run reads the comments on one Blind post. Each comment becomes a row with its text, the nickname and company Blind shows next to it, likes, date, and the comment it replies to, so the thread keeps its shape in a spreadsheet. Copying a thread by hand loses the companies and the reply structure, which are usually the point. People use it to keep a useful offer, layoff or interview thread as a file, and to read how a company's employees describe pay and culture. Blind is anonymous: the file holds what the page shows, nothing that identifies the person behind a nickname. Workplace talk also happens on Reddit: the [Reddit Comments Scraper](/scraper/reddit-comments-scraper) exports a full thread. Every site is on the [review scraper hub](/scraper/reviews). --- ## FAQ ### How do I export Blind comments to Excel or CSV? Open the post on teamblind.com, open InsightSocial and click Scrape. Each comment becomes a row with its text, the commenter's company, likes, date and the comment it replies to. Download Excel, CSV or JSON, or send it to Google Sheets. ### Does it get every comment on a Blind post? On small posts, yes. On a busy post, no: Blind only lets a browser load part of the discussion, so the extension collects the threads it can reach, with all their replies, and the side panel tells you how many it got out of the total. ### Can I find out who wrote a Blind comment? No. Blind is anonymous, and the export carries only what the page shows: the nickname and the company Blind lists next to it. Use the file to read what people say about pay, hiring or a company, not to identify or contact the people saying it. ### Do I need a Blind account? Not for public posts. Some posts are for signed-in members only; for those, sign in to Blind in the same Chrome first, and the run tells you if it hits one. Signing in does not change how many comments a busy post returns. ### Is there a Blind API? Blind does not offer a public API. The extension reads the post you have open in Chrome, so there is no key and no code to write. ### Can it export a whole channel, company page or salaries? No. A run reads one post's comments. Open the next post to collect it too. ### Is it legal to export Blind comments? Reading public pages is generally allowed, but you are responsible for how you use what you export: follow the site's terms and privacy law, especially where names are involved. The extension only reads the page you have open in your own browser; it never posts, likes or messages. ### Why does Chrome ask for permission the first time? InsightSocial reads review and discussion sites only when you use them. The first Blind run asks Chrome for access to teamblind.com, and you can withdraw it any time from the extension's settings in Chrome. ### Is the Blind scraper free? Yes. Collecting runs and reading them in your dashboard are free and unlimited. Only exporting uses credits, one per row: the free plan exports 500 rows a month, Pro exports 10,000 rows for $9.99 a month ($7.99 a month billed yearly), and one-time packs start at $2 for 250 rows. A run usually returns well under a hundred rows, so most fit the free month. ## Related scrapers - [Reddit Comment Scraper](https://www.insightsocial.app/scraper/reddit-comments-scraper.md): Export every comment and reply from a Reddit thread to Excel, CSV or Google Sheets, nested replies kept. Free Chrome extension, no Reddit API key. - [Hacker News Comment Scraper](https://www.insightsocial.app/scraper/hacker-news-comment-scraper.md): Export every comment and reply in a Hacker News thread to Excel, CSV, JSON or Google Sheets, with depth and parent. Free extension, 500 rows a month. - [Quora Scraper](https://www.insightsocial.app/scraper/quora-scraper.md): Export every answer to a Quora question, with the comments under each, to Excel, CSV or Google Sheets: author, credential, upvotes. 500 rows free. --- # Notion Database Export Source: https://www.insightsocial.app/scraper/notion-database-export, updated 2026-10-18 > Export a public Notion database you can only view to CSV, Excel or Google Sheets: one row per entry, each property a column. 500 rows a month free. - **Platform**: notion - **Web version**: https://www.insightsocial.app/scraper/notion-database-export --- InsightSocial's Notion Database Export is a free Chrome extension that turns a public Notion database into a spreadsheet, even when you can only view it and Notion shows no export option. Each entry becomes a row, each property a column in the view's order, with the text of the entry's page. It exports to Excel, CSV, JSON or Google Sheets. For a database in your own workspace, Notion's built-in export is enough. ## At a glance - **Works on**: Public Notion databases and pages on notion.site or notion.so, including view-only ones - **Per run**: One database or page, up to 3,000 rows - **Each row**: Database: title, every property as a column, the entry's page text. Page: one row per block, nesting kept - **Export to**: Excel, CSV, JSON or Google Sheets - **Login**: No Notion account needed. Private pages are out of reach - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store and sign in with Google or email. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. That icon opens the side panel. 3. **Open the database, click Scrape**: Open the public database on its own page (its address has ?v= in it) to get one row per entry, or any public page for its blocks. The first time, Chrome asks you to allow that Notion site. Then click Scrape. 4. **Export**: Open the run in your InsightSocial dashboard and download Excel, CSV or JSON, or send it to Google Sheets. ## What you get On a public database, each entry becomes a row. Every property is its own column, in the order the view shows them: Company, Location and Type on a job board, Status and Votes on a feedback board. Each row also carries the text of the entry's own page, who created it and when, and the links inside it. On an ordinary public page, each block (a paragraph, heading, to-do or list item) becomes a row, with nested blocks under the block they sit in. A database embedded in the page adds its entries under its own row. This is for pages you can only view: a public directory, job board, roadmap or resource list someone else published. If the page is in your own workspace, Notion's built-in export from the ••• menu does the job. Every site is on the [review scraper hub](/scraper/reviews). --- ## FAQ ### Why not use Notion's own export? Use it if you can. Notion exports a database as CSV and a page as Markdown, HTML or PDF, from the ••• menu. But the export option needs full access to the page, so a visitor to a page published on the web usually has none. InsightSocial reads what the public page shows and gives you the same kind of spreadsheet. ### How do I export a public Notion database I don't own to Excel or CSV? Open the database on its own page, open InsightSocial and click Scrape. Each entry becomes a row, with every property as its own column in the order the view shows them, plus the text of the entry's page. Download Excel, CSV or JSON, or send it to Google Sheets. ### How many rows can one run export? Up to 3,000. Most public databases are far smaller: in our tests (Oct 2026) a 206-entry database took 3 to 7 seconds. A very long page with a lot of text can stop early, and the side panel tells you where it stopped. ### What does a row look like on a page that is not a database? One row per block (a paragraph, heading, to-do or list item), with nested blocks as replies to the block they sit under. A database embedded in the page adds its entries under its own row. ### Does it work on private pages? No. Only pages published to the web, the ones anyone with the link can open. A page shared only inside a workspace is out of reach. ### What if the run stops early? Notion sometimes slows down a browser that asks for a lot, or shows a check. The run waits briefly, then keeps what it has. If Notion shows a check, finish it on the page and click Scrape again. ### Does it export comments? No. It exports a database's entries or a page's blocks, not the comment threads on them. Notion's own HTML export can include comments, on pages where you have full access. ### Is it legal to export a public Notion page? Reading public pages is generally allowed, but you are responsible for how you use what you export: follow the site's terms and privacy law, especially where names are involved. The extension only reads the page you have open in your own browser; it never edits, comments or posts. ### Why does Chrome ask for permission the first time? InsightSocial reads review and discussion sites only when you use them. The first Notion run asks Chrome for access to that Notion site, and you can withdraw it any time from the extension's settings in Chrome. ### Is the Notion export free? Yes. Collecting runs and reading them in your dashboard are free and unlimited. Only exporting uses credits, one per row: the free plan exports 500 rows a month, Pro exports 10,000 rows for $9.99 a month ($7.99 a month billed yearly), and one-time packs start at $2 for 250 rows. A row you already exported is free to export again. ## Related scrapers - [Hacker News Comment Scraper](https://www.insightsocial.app/scraper/hacker-news-comment-scraper.md): Export every comment and reply in a Hacker News thread to Excel, CSV, JSON or Google Sheets, with depth and parent. Free extension, 500 rows a month. - [Product Hunt Scraper](https://www.insightsocial.app/scraper/product-hunt-scraper.md): Free Chrome extension: export a Product Hunt product's reviews or a launch's comment thread to Excel, CSV or Google Sheets. 500 rows a month free. - [Quora Scraper](https://www.insightsocial.app/scraper/quora-scraper.md): Export every answer to a Quora question, with the comments under each, to Excel, CSV or Google Sheets: author, credential, upvotes. 500 rows free. --- # Reddit User Comments Scraper Source: https://www.insightsocial.app/scraper/reddit-user-comments-scraper, updated 2026-10-18 > Export a Reddit user's comments to Excel, CSV or Google Sheets: text, score, date, subreddit and post. Newest first, 500 rows free. - **Platform**: reddit - **Web version**: https://www.insightsocial.app/scraper/reddit-user-comments-scraper --- InsightSocial's Reddit User Comments Scraper is a free Chrome extension that exports the public comments of one Reddit profile to Excel, CSV, JSON or Google Sheets, newest first. Each row has the comment, its score and date, the subreddit, and the post it was left on. Reddit lists about the newest 1,000 comments per profile, and you need to be signed in to Reddit. ## At a glance - **Works on**: A Reddit profile (reddit.com/user/… or /u/…) or its Comments tab - **Per run**: About the newest 1,000 comments, where Reddit stops listing. In our tests (Oct 2026), 1,100 comments took 24 seconds - **Each row**: Comment text, score, date, subreddit, post title and link, what it replied to, link to the comment - **Not included**: The user's own posts, and comments that were deleted - **Export to**: Excel, CSV, JSON or Google Sheets - **Login**: Signed in to Reddit in the same browser; any Reddit account works - **While it runs**: Keeps going in a background tab while you work in another - **Price**: Free for 500 exported rows a month. Pro: 10,000 rows for $9.99 a month ## How it works 1. **Add it to Chrome**: Install InsightSocial from the Chrome Web Store and sign in. It is free and asks for no card. 2. **Pin the icon**: Click the puzzle piece in Chrome's toolbar and pin InsightSocial. On Reddit, that icon is how you open it. 3. **Open the profile, click Scrape**: Sign in to Reddit and open the profile. The side panel names the user; click Scrape. You can switch tabs while it runs. 4. **Export**: Download Excel, CSV or JSON, or send the rows to Google Sheets. Every run stays in your account to re-open later. ## What it is for A profile's comment list is public: anyone signed in to Reddit can scroll it. This tool turns that list into rows you can sort, filter and keep. People use it to: - **archive their own history** before deleting an account or leaving a community; - **moderate**: review a reported account's recent comments in one sheet, with the subreddit and thread of each; - **research** how a brand, public figure or bot account takes part across communities over time; - **audit a brand account**: see what your company's own Reddit account has said, and where. It reads only what the profile shows. It does not recover deleted comments, and it is not a way to find out who someone is. To export a whole thread with its nesting instead, use the [Reddit Comment Scraper](/scraper/reddit-comments-scraper). If you write code, the tutorial [How to Scrape Reddit Posts and Comments with Python](/blog/reddit-scraping-api-guide-2026) covers user profiles through the InsightSocial API. All Reddit scrapers are on the [Reddit scraper hub](/scraper/reddit). --- ## FAQ ### How many comments can I export from one profile? About the newest 1,000. Reddit stops listing a profile's comments there however old the account is, and the run tells you the date it reached back to. In our tests (Oct 2026), a profile returned 1,100 comments in 24 seconds. ### Does it export the user's posts too? No, comments only. For posts, use the Reddit Subreddit Scraper or the Reddit Search Results Scraper. ### Why do I need to be signed in to Reddit? Reddit refuses a profile's comment list to signed-out visitors, and the run stops with "Sign in to Reddit". Any Reddit account works. You also need a free InsightSocial account to export. The extension only reads. ### Can I export my own Reddit comment history? Yes. Open your own profile and click Scrape to get a spreadsheet of your newest comments, with a link back to every thread. Reddit's own data request, in your account settings, sends a copy of your account's data too, but you have to wait for it. ### Why did my run pause? Reddit limits how many pages any browser can load in a few minutes. When the limit is close, the run waits for it to reset instead of getting blocked, then carries on by itself, even in a background tab. ### Is this for looking up people? No. It reads only what the profile already shows to anyone signed in to Reddit, nothing hidden or deleted. Use it for research, moderation or your own archive. If you store comments that identify a person, privacy laws such as GDPR and CCPA apply to that file. ### Can I do this with Python instead? Yes, if you write code. Our tutorial on scraping Reddit with Python covers user profiles as well as subreddits, search and comment threads, through the InsightSocial API. The extension is the no-code route for one profile at a time. ### Is the Reddit user comments scraper free? Yes, to collect and to read in your dashboard. Exporting uses one row per comment: the free plan exports 500 rows a month, and Pro exports 10,000 for $9.99 a month ($7.99 a month billed yearly). A full profile is about 1,000 rows. Export the same profile again next month and only the new comments count. ## Related scrapers - [Reddit Comment Scraper](https://www.insightsocial.app/scraper/reddit-comments-scraper.md): Export every comment and reply from a Reddit thread to Excel, CSV or Google Sheets, nested replies kept. Free Chrome extension, no Reddit API key. - [Reddit Subreddit Scraper](https://www.insightsocial.app/scraper/reddit-subreddit-scraper.md): Export up to 1,000 posts from any subreddit to Excel, CSV or Google Sheets, with every comment if you want. Hot, New, Top. Free Chrome extension. - [Reddit Search Results Scraper](https://www.insightsocial.app/scraper/reddit-post-scraper.md): Export Reddit search results to Excel, CSV or Google Sheets: up to 250 posts per search, with their comments if you want. Free Chrome extension. --- # InsightSocial vs Apify Source: https://www.insightsocial.app/alternatives/apify, updated 2026-10-23 > Apify bills compute units, proxies and actor fees; you see a run's cost only after it ends. InsightSocial: a no-code extension, or an API with published prices. - **Web version**: https://www.insightsocial.app/alternatives/apify - **Compared against**: Apify (https://apify.com) - **Pricing verified**: 2026-10-18, source https://apify.com/pricing --- ## Summary InsightSocial is a simpler Apify alternative for social media data. Its free Chrome extension exports TikTok, LinkedIn, YouTube and more social platforms from your own browser (500 rows a month free, Pro $9.99 for 10,000), and its API covers 22 platforms with a published price per call. Apify is the better choice for million-row pipelines, cloud schedules and non-social sites. Apify is a developer platform: 90,000+ Actors, schedulers, webhooks and the lowest price per row at volume. If you are running a million-row pipeline, it is the stronger tool. InsightSocial is narrower on purpose, and gives you two ways in. If you want a spreadsheet, the extension exports from the tab you already have open, on your own logged-in session. If you are writing code, one API key covers 22 platforms: a single GET returns JSON in the same response, every endpoint has a published price you can read before calling it (metered endpoints quote a range), and a call that fails or finds nothing costs nothing. ## Feature Comparison | Feature | InsightSocial | Apify | Advantage | | --- | --- | --- | --- | | What you pay per month | $0 free (500 exported rows) or $9.99 Pro (10,000) | $0 free ($5 credits), then $19 / $199 / $999 tiers | InsightSocial | | Can you predict the bill? | Yes. Exports cost one credit per row, and every API endpoint has a published price | Pay-per-result actors: yes. Compute-unit actors: only after the run, because compute units, proxy GB and actor fees stack | InsightSocial | | Setup before first export | Install extension, click Scrape | Create account, pick an actor, configure input JSON, get API token | InsightSocial | | Coding required | None | None for basic actor runs; yes for pipelines and custom actors | InsightSocial | | Login-gated content (pages only your account sees, your own feed) | Extension: yes, on your own logged-in browser session. API: public data only | Needs cookies or credentials handed to a cloud actor | InsightSocial | | Proxies to configure | None. Extension: it is your normal browser traffic. API: handled on our side, inside the endpoint price | Residential/datacenter proxies billed per GB on top | InsightSocial | | Runs with your browser closed | The API does. Extension scrapes need Chrome open | Yes, fully cloud-hosted with schedulers | Comparable | | Scale ceiling | Thousands of rows per session, one browser | Millions of rows, unlimited concurrency | Apify | | Site coverage | 6 social platforms and 10 review and discussion sites, purpose-built extractors | 90,000+ Actors covering most of the public web | Apify | | REST API | One key for 22 platforms, with the same auth, errors and pricing on every endpoint | One API, but each platform is a different actor with its own input and output | InsightSocial | | Getting data from code | One GET request, JSON back in the same response | Start an actor run, then read its dataset (the sync endpoint waits up to 5 minutes) | InsightSocial | | Failed or empty calls | Free, and a retry sent with the same Idempotency-Key is free too | Compute used by a failed run is still billed | InsightSocial | | Price per profile at volume | A published price per call (a TikTok profile is 10 credits, about $0.01 on Pro) | Per-result actors are cheaper per row at volume | Apify | | Webhooks and cloud schedules | Not built in. Call the API from your own cron | Built in | Apify | | Bio-link email + phone enrichment | On Pro: follows link-in-bio pages to find contacts | Requires chaining a separate actor | InsightSocial | | Ask questions of your data in plain English | On Pro: AI chat over your scrapes (Ask your data) | Not included | InsightSocial | ## Pricing ### InsightSocial - **Free** · $0/mo: Unlimited scraping, 500 rows exported per month - **Pro monthly** · $9.99/mo: 10,000 rows exported per month, every supported site - **Pro yearly** · $7.99/mo: $95.88 billed yearly, 10,000 rows every month - **API** · Same credits: 10 free calls, then a published price per endpoint; metered endpoints quote a range (TikTok profile: 10 credits) ### Apify - **Free** · $0/mo: $5 platform credits, $0.20 per compute unit - **Starter** · $19/mo: $19 platform credits, $0.20 per compute unit - **Scale** · $199/mo: $199 platform credits, $0.16 per compute unit - **Business** · $999/mo: $999 platform credits, $0.13 per compute unit Apify's plan price is a credit allowance, not a cap on spend. Compute units (1 CU = 1 GB of RAM for 1 hour) are drawn against it, and proxies, extra concurrent runs and extra actor memory are billed separately. Many Store actors instead charge per result, priced on each actor's own page. InsightSocial has one balance for both products. An exported row costs one credit, and an API call costs the price listed for its endpoint in the free GET /v1/endpoints catalogue. ## Moving off Apify from code - [TikTok scraper API](https://www.insightsocial.app/social-media-api/tiktok): Replaces Apify's TikTok actors: profiles, videos, comments, followers, hashtags and search. ## The compute unit problem Apify's most-cited friction point is not the sticker price. It is that you cannot know the price in advance. A compute unit is 1 GB of RAM running for one hour. How many units a social media scrape burns depends on the actor's memory setting, how long the target site takes to respond, and how many retries it needs when a proxy gets blocked. None of that is knowable before you press run. - Platform credits are consumed by compute units, storage, and data transfer - Residential proxy traffic is billed per GB on top of the plan - Extra concurrent runs and extra actor RAM are paid add-ons - Third-party Store actors can charge their own rental or per-result fee - A run that fails halfway still consumed the compute it used ## If you call Apify from code Apify's API is built around actors. You start a run, wait for it, then read the dataset it wrote, and each social platform is a different actor, often from a different author, with its own input JSON and output fields. InsightSocial's API is a plain REST call: GET /v1/tiktok/profile?handle=nasa with an x-api-key header returns the profile as JSON in the same response. - One API key for 22 platforms, including TikTok, LinkedIn, X, YouTube, Reddit, Pinterest, Bluesky and Telegram - Profiles, posts, comments and replies, followers, search and transcripts - The price of every endpoint is published before you call it. Metered endpoints quote a range and charge only what the call read - Calls that fail or find nothing cost nothing - A public, keyless GET /v1/endpoints catalogue lets an AI agent or an n8n workflow plan calls and estimate cost first - The same credit balance pays for Chrome extension exports ## Extension: why scraping in your own browser avoids blocking This is about the Chrome extension, not the API. Any cloud scraper, our API included, reaches public pages from servers and has to handle access on its side; that is a solved problem when the price covers it. The extension works differently: it reads the data the page already loaded into your browser, so the requests come from your IP, with your cookies, at the speed you scroll. - Extension: no proxy bill, because there are no proxies - Extension: no CAPTCHA-solving fees - Extension: pages only your account can see and your own feed are reachable - API: access and unblocking are inside each endpoint's published price, never billed per GB ## What you actually get out InsightSocial ships purpose-built extractors per platform rather than generic page-readers, so the exports carry the structured fields the platform's own API returns (engagement counts, timestamps, author metadata, comment threads, follower edges) instead of whatever happened to be painted on screen. - TikTok: videos with view, like and share counts; profiles; comments with replies; followers; following - LinkedIn: posts, profiles, companies, post reactions and comments - Plus X/Twitter, YouTube, Reddit and Pinterest, and reviews from Trustpilot, Google Maps, Amazon, Etsy, Steam and Product Hunt - Export to CSV, Excel, JSON or straight to Google Sheets ## When Apify is the better choice Apify is a genuinely strong platform and there are jobs it does that InsightSocial simply cannot. Pick Apify when: - You need scraping to run on a schedule with your laptop closed - You need webhooks, retries and cloud scheduling built into the platform - You want the lowest cost per row at volume. Pay-per-result actors are several times cheaper per profile than our API - You need millions of rows, or high concurrency across many targets at once - Your targets go beyond social media: e-commerce, SERPs, directories, maps - You want to write and host a custom scraper in TypeScript or Python - Your team already has engineers who will own the integration ## FAQ ### What is the best free Apify alternative for social media? For social platforms specifically, InsightSocial's free tier gives you unlimited scraping plus 500 exported rows per month, no credit card and no compute-unit metering. Developers also get 10 free API calls. Apify's free tier gives $5 in platform credits, which is consumed by compute units, storage and proxy traffic. A heavy TikTok or LinkedIn run can exhaust it quickly. If your targets are outside social media, Apify's free tier is the more flexible starting point. ### Is there an Apify alternative with an API for social media? Yes. InsightSocial's API gives you one key for 22 platforms, including TikTok, LinkedIn, X, YouTube, Reddit, Pinterest, Bluesky and Telegram. A single GET returns JSON in the same response, with no actor run to start and no dataset to fetch afterwards. Every endpoint has a published price, calls that fail or find nothing are free, and the first 10 calls are free with no credit card. ### Can I replace an Apify actor in n8n or an AI agent? Yes, as long as the actor is doing social media reads. In n8n, install the n8n-nodes-insightsocial community node, or point an HTTP Request node at the endpoint with your key in an x-api-key header. AI agents such as Claude, Cursor or Codex can use the official MCP server (npx -y insightsocial mcp), or read the public GET /v1/endpoints catalogue, which lists every path, parameter and price, and call the API directly. ### Is InsightSocial actually cheaper than Apify? For exporting social data from the extension, usually yes. InsightSocial Pro is $9.99/month for 10,000 exported rows, with scraping itself unmetered. Apify's entry paid tier is $19/month, and that $19 is a credit allowance rather than a ceiling: compute units, residential proxy GB, extra concurrency and actor fees all draw against it or bill on top. For bulk API work the answer flips. Apify's per-result actors are cheaper per profile than our API at volume. Our API is priced for one key across 22 platforms and a bill you can predict, not for million-row jobs. ### What are Apify compute units and why do they matter? One compute unit equals 1 GB of RAM running for one hour, priced from $0.13 to $0.20 per unit depending on your plan. It matters because consumption depends on the actor's memory setting, target site response time and retry count, none of which you know before the run starts. It is a common complaint about Apify's pricing. InsightSocial has no equivalent unknown: scraping is free, an export costs exactly one credit per row, and every API endpoint has a published price. Metered endpoints quote a range up front and charge what the call actually read. ### Can InsightSocial read pages only my account can see? With the Chrome extension, yes: it exports what your own logged-in session can see. Because the extension runs inside your own browser, it can read anything you can read by scrolling the page yourself. The API returns public data only: reaching a private page from a server would mean handing your credentials or cookies to a remote worker, which we never ask for. ### Does InsightSocial need proxies like Apify does? No, on either product. The extension runs in your own browser, so requests come from your IP with your cookies at human scrolling speed and there is nothing to proxy. The API handles access on our side and its cost is inside each endpoint's published price. Either way there is no proxy line item, no per-GB charge and no CAPTCHA-solving fee. ### Can InsightSocial run on a schedule while my computer is off? Yes, through the API. Call it from your own cron job, server or n8n workflow and nothing needs to be open. Scheduled scrapes in the Chrome extension fire from the browser, so Chrome has to be running for those. If you want scheduling and webhooks managed for you, Apify has them built in and we do not. ### Which platforms does InsightSocial support? The extension covers TikTok, LinkedIn, X/Twitter, YouTube, Reddit and Pinterest, plus 10 review and discussion sites (Trustpilot, Google Maps, Amazon, Etsy, Steam, Product Hunt, Hacker News, Quora, Blind and Notion), each with a purpose-built extractor rather than a generic page reader. The API covers 22 platforms. Apify's Store covers far more of the web overall, so for non-social targets it remains the broader option. ### Do I have to give InsightSocial my social media password? Never. The extension works alongside the session you are already signed into in Chrome. You sign in to InsightSocial itself with Google, and you never enter your TikTok, LinkedIn or X credentials anywhere. --- # InsightSocial vs Thunderbit Source: https://www.insightsocial.app/alternatives/thunderbit, updated 2026-10-23 > Thunderbit charges 1 credit per row scraped. InsightSocial scrapes TikTok, LinkedIn, YouTube and more for free and charges only for rows you export. - **Web version**: https://www.insightsocial.app/alternatives/thunderbit - **Compared against**: Thunderbit (https://thunderbit.com) - **Pricing verified**: 2026-10-18, source https://thunderbit.com/pricing --- ## Summary InsightSocial and Thunderbit are both no-code Chrome extensions. Thunderbit's AI scrapes almost any website and charges 1 credit per row scraped (Starter: 500 credits a month). InsightSocial covers 6 social platforms and 10 review and discussion sites; scraping there is free and you pay per exported row: 500 a month free, 10,000 on Pro for $9.99. Both scrape using your own logged-in session, and both are built for people who do not write code. The difference is scope. Thunderbit's AI points at any website and infers the columns for you, which is genuinely impressive on a product catalogue or a directory. Social platforms are a different shape of problem: endless scroll, data delivered by internal APIs rather than rendered HTML, and structures like comment threads and follower edges that do not fit a flat table. InsightSocial builds a dedicated extractor per site because of it. ## Feature Comparison | Feature | InsightSocial | Thunderbit | Advantage | | --- | --- | --- | --- | | Coverage | 6 social platforms and 10 review and discussion sites, purpose-built per site | Any website, via generic AI field detection | Thunderbit | | Social data structures | Comment threads, follower edges, reactions, post analytics | Flat rows inferred from what is rendered on screen | InsightSocial | | Billing unit | One credit = one exported row. Scraping is unmetered | 1 credit per row scraped by the AI Web Scraper | InsightSocial | | Cost of an infinite-scroll feed | Free to scroll and read, whether it returns 100 or 5,000 posts | Scales with the number of rows returned | InsightSocial | | Data source | Reads the data the app loads, including fields the screen doesn't show | Rendered page content read by the AI | InsightSocial | | Setup for a new site | Not applicable: supported sites only | AI Suggest Fields, then scrape. Very fast | Thunderbit | | Login-gated content | Yes, your own session | Yes, your own session | Comparable | | Export formats | CSV, Excel, JSON, Google Sheets | CSV, Excel, Google Sheets, Airtable, Notion | Thunderbit | | Bio-link email + phone enrichment | On Pro: follows link-in-bio pages to find contacts | Not purpose-built for social bio links | InsightSocial | | Ask questions of your data in plain English | On Pro: AI chat over your scrapes (Ask your data) | Not included | InsightSocial | | Cloud scraping with browser closed | Extension: no, Chrome must be open. API: yes, for public data, from code | Yes, for a limited number of pages | Thunderbit | | API, CLI and MCP | REST API for 22 platforms, a CLI and an MCP server | Web Scraper API, a CLI and an MCP server | Comparable | ## Pricing ### InsightSocial - **Free** · $0/mo: Unlimited scraping, 500 rows exported per month - **Pro monthly** · $9.99/mo: 10,000 rows exported per month, every supported site - **Pro yearly** · $7.99/mo: $95.88 billed yearly, 10,000 rows every month ### Thunderbit - **Free** · $0: Up to 6 pages, at most 30 credits a page - **Starter** · See their site: 500 credits a month, 1 credit per row scraped - **Pro / Advanced** · See their site: Larger monthly credit allowance - **Business** · Custom: Custom pricing and billing terms Thunderbit publishes its dollar prices through a live pricing widget, so we do not quote a dollar figure here; check their pricing page for today's rate. Its pricing FAQ does state the allowances: 1 credit is consumed per output row for the AI Web Scraper, the Free plan scrapes up to 6 pages with at most 30 credits a page, the Starter plan provides 500 credits a month, and yearly plans save 20% with all credits upfront. That model is efficient on a finite page and expensive on an infinite feed, because the meter runs while you are still discovering how big the job is. InsightSocial meters exports rather than scraping: scrolling a feed costs nothing, and you only spend credits on rows you choose to take out. ## Why scrape-metered credits and social feeds fight each other Charging as rows are scraped makes sense when a job has a knowable size. Scraping 200 product pages costs 200 pages' worth of credits, and you know that before you start. A social feed has no such number. A TikTok hashtag, a LinkedIn post's commenters, a YouTube channel's videos: these are all infinite scroll, and the size of the job is only revealed as you run it. InsightSocial moves the meter to the other end: collect as much as you like, then pay only for the rows you export. - Scraping is unmetered, so an exploratory hashtag pull cannot run up a bill - You see the full result set and its exact row count before spending anything - A wasted scrape (private account, empty hashtag, wrong filter) costs nothing - The export menu names the exact price before you click, so no charge is a surprise ## Rendered HTML versus the data underneath Social platforms are single-page apps. When you scroll TikTok, the app is quietly requesting structured JSON from an internal API and painting a subset of it on screen. A generic AI scraper reads what got painted. A purpose-built extractor reads the response itself, which carries fields that never appear in the interface at all. - More fields per row, including IDs and timestamps the UI never shows - Fewer parsing errors, because nothing depends on CSS class names - Nested structures survive: comment replies, follower edges, reaction breakdowns - Layout redesigns do not silently break the extractor ## Workflows a general-purpose scraper does not have Some social jobs are not really 'read this page into a table'. They are multi-step, and InsightSocial builds them as first-class features rather than something you assemble by hand. - Export every comment on a post, replies included, with each commenter's profile link - Export a follower or following list as a contact sheet - Follow link-in-bio pages to pull emails and phone numbers (Pro) - Collect post likers on LinkedIn as a prospecting list - Ask your data questions across a finished scrape in plain English (Pro) ## When Thunderbit is the better choice Thunderbit is a well-built product with a genuinely clever AI layer, and for a large class of jobs it is the right pick. Choose Thunderbit when: - Your targets are ordinary websites: directories, catalogues, listings, news - You need to scrape many different sites and do not want a tool per site - You want AI to infer the columns instead of using a fixed schema - You need subpage scraping, where each row links to a detail page - You want native Airtable or Notion export - You need a modest amount of cloud scraping without your browser open ## FAQ ### What is the best Thunderbit alternative for social media scraping? For social platforms, InsightSocial: a dedicated extractor per platform, unlimited scraping, and you pay only for the rows you export (500 a month free). It also exports followers, comment threads with replies and, on Pro, bio-link emails. For ordinary websites Thunderbit is the more flexible tool, and many people run both. ### Is there a free Thunderbit alternative? InsightSocial's free tier is unlimited scraping plus 500 exported rows per month, with no credit card required. Because only exports are metered, you can explore as many hashtags, profiles and comment threads as you like on the free plan and spend the allowance solely on the rows worth keeping. ### How is InsightSocial's pricing different from Thunderbit's credits? Both sell credits, but they meter opposite ends of the job. Thunderbit's credits are consumed as rows are scraped, so the bill grows while you are still finding out how big the dataset is. InsightSocial's are consumed only when rows leave the product (a download, a share link, or a Google Sheets sync), so scraping and browsing results are free and you know the exact row count before you spend. On a finite page the two are comparable; on an infinite social feed, paying at the export step is far more predictable. ### Does Thunderbit work on TikTok and LinkedIn? Yes. Thunderbit's AI field detection can read social pages, and their own documentation covers social use cases. The trade-off is that it reads what is rendered on screen as flat rows, so nested structures like comment threads and follower edges, and fields the interface never displays, are harder to capture reliably. ### Can I use both tools together? Plenty of people do, and it is a reasonable setup. Thunderbit handles the long tail of ordinary websites, InsightSocial handles the social platforms where a dedicated extractor pays off. Both are free to install, so trying the combination costs nothing. ### Do I need to give InsightSocial my social media login? No. It works alongside the session already signed in to Chrome. You authenticate to InsightSocial with Google and never type your TikTok, LinkedIn or X password into the extension. ### Does InsightSocial support cloud scraping like Thunderbit? Not in the extension: scraping happens in your browser, so Chrome needs to be open, and scheduled runs fire from the browser rather than a server. For public data, the InsightSocial API runs server-side and you can call it from your own cron job or n8n workflow. If you want no-code cloud collection, that is a point in Thunderbit's favour. ### Which platforms does InsightSocial cover? TikTok, LinkedIn, X/Twitter, YouTube, Reddit and Pinterest, including posts, profiles, comments, followers, following, reactions and post likers depending on the platform. It also exports reviews and threads from Trustpilot, Google Maps, Amazon, Etsy, Steam, Product Hunt, Hacker News, Quora, Blind and Notion. --- # InsightSocial vs Bright Data Source: https://www.insightsocial.app/alternatives/bright-data, updated 2026-10-23 > Bright Data's Scraper API costs $1.50 per 1,000 records and proxies $8/GB. InsightSocial exports social data from your browser: 500 rows free, Pro $9.99. - **Web version**: https://www.insightsocial.app/alternatives/bright-data - **Compared against**: Bright Data (https://brightdata.com) - **Pricing verified**: 2026-10-18, source https://brightdata.com/pricing/web-scraper --- ## Summary Bright Data is enterprise scraping infrastructure: a Scraper API at $1.50 per 1,000 records (5,000 free a month) and residential proxies from $8 per GB. InsightSocial is a Chrome extension for social media exports, free for 500 rows a month and $9.99 for 10,000, plus an API for 22 platforms. Choose Bright Data for millions of records and compliance paperwork. Bright Data operates one of the largest residential proxy networks in the world. If you are collecting data at industrial scale with legal and compliance sign-off behind it, nothing on this page competes. But many people who land on a Bright Data pricing page wanted a few thousand TikTok profiles or a spreadsheet of a competitor's posts. InsightSocial is the other end of that spectrum: a browser extension billed per exported row, with no infrastructure to think about. ## Feature Comparison | Feature | InsightSocial | Bright Data | Advantage | | --- | --- | --- | --- | | Realistic entry cost | $0 free tier (500 exported rows), $9.99/mo Pro | Free 5K records, then $1.50/1K records or $499/mo plans | InsightSocial | | Billing model | Per exported row; scraping is free | Per GB of proxy traffic and per 1,000 records | InsightSocial | | Time to first export | Minutes: install and click | Create an account, pick a scraper, send URLs (KYC only for residential and mobile proxies) | InsightSocial | | Technical skill needed | None | API integration, or their no-code interface plus proxy config | InsightSocial | | Login-gated content (pages only your account sees, your own feed) | Yes: your own logged-in session | Restricted; their policy focuses on public data | InsightSocial | | Unblocking success at scale | Bounded by normal browsing from one machine | One of the largest residential networks, with CAPTCHA solving | Bright Data | | Volume ceiling | Thousands of rows per session | Effectively unlimited: millions of records | Bright Data | | Compliance and legal posture | Consumer tool; you are responsible for your own use | Enterprise compliance program, DPAs, KYC vetting | Bright Data | | Ready-made historical datasets | Not offered: you collect what you need | Large pre-collected social datasets for purchase | Bright Data | | Bio-link email + phone enrichment | On Pro: follows link-in-bio pages to find contacts | Not a packaged feature | InsightSocial | | Ask questions of your data in plain English | On Pro: AI chat over your scrapes (Ask your data) | Not included | InsightSocial | | Scraper API for public data | 22 platforms, a published credit price per endpoint, failed calls free | Ready-made scrapers for many sites, $1.50 per 1,000 records, proxies included | Bright Data | ## Pricing ### InsightSocial - **Free** · $0/mo: Unlimited scraping, 500 rows exported per month - **Pro monthly** · $9.99/mo: 10,000 rows exported per month, every supported site - **Pro yearly** · $7.99/mo: $95.88 billed yearly, 10,000 rows every month ### Bright Data - **Web Scraper API: free** · $0: 5,000 records per month - **Web Scraper API: pay as you go** · $1.50 / 1K records: No monthly commitment - **Web Scraper API: Scale** · $499/mo: 384,000 records, then $1.30 / 1K - **Residential proxies: pay as you go** · $8.00 / GB: List price; promo codes discount this - **Residential proxies: 141 GB plan** · $499/mo: $7.00 / GB list price Bright Data prices above are list prices taken from their own pricing pages. They frequently run promotions (a 50% residential proxy discount and a 25%-off Scraper API code were both live when we last checked) so your actual rate may be lower for an introductory period. We quote the undiscounted figure because that is what renews. Scraper API records and proxy gigabytes are separate products: a Scraper API job is billed per record only, with proxies, unblocking and parsing included. InsightSocial has one meter: exported rows. Scraping, and re-exporting a row you already paid for, cost nothing. ## Built for data teams, priced for them Bright Data's product is built for data teams buying collection capacity by the terabyte, with contracts, account managers and compliance review. That is a real market and they serve it very well. The mismatch shows up when an individual marketer, recruiter or researcher arrives wanting a spreadsheet of LinkedIn profiles and is quoted infrastructure pricing for it. - Meaningful plan tiers begin at $499 per month - Scraper API jobs are billed per record; proxies are a separate product billed per GB - Residential and mobile proxies need a KYC review before use - The free tier is 5,000 records a month, ten times InsightSocial's 500 exported rows, but only for public data through the API ## Why per-GB billing is hard to forecast Gigabytes are a proxy for effort, not for value. The same 1,000 profiles can cost very different amounts depending on how much media the pages pull down, how many retries the network needs, and whether the target served a challenge page. You find out afterwards. - Bandwidth consumed does not map cleanly to rows delivered - Retries and challenge pages consume traffic without producing data - Media-heavy social pages are expensive per useful record - Page weight, retries and proxy traffic never reach your bill: only exported rows do ## What you give up, and what you get back An extension cannot match a global residential network on raw throughput, and this page will not claim otherwise. What it does give you is access to material a public-data crawler cannot legitimately reach, at a price that does not require a budget approval. - Pages only your account can see, and your own feed, are visible because you are logged in - No proxy configuration, no CAPTCHA solving, no unblocking budget - TikTok, LinkedIn, X, YouTube, Reddit and Pinterest, plus 10 review and discussion sites - Export to CSV, Excel, JSON or Google Sheets ## When Bright Data is the better choice For a whole category of work, Bright Data is the correct answer and InsightSocial is not a substitute. Choose Bright Data when: - You need millions of records, or continuous collection at industrial scale - Your organisation requires DPAs, compliance review and vendor due diligence - You want to buy a pre-collected historical dataset rather than gather it yourself - You are scraping heavily protected targets that need serious unblocking - You need collection running continuously on servers, not on a laptop - Your scope goes well beyond social media: e-commerce, SERPs, travel, finance ## FAQ ### What is a cheaper alternative to Bright Data? For social media data specifically, InsightSocial is $9.99/month for 10,000 exported rows with a free tier of 500, versus Bright Data's $1.50 per 1,000 records pay-as-you-go or $499/month Scale plan. The comparison is only fair at modest volumes. If you need millions of records, Bright Data's per-record economics become far better than any extension can offer. ### Does Bright Data have a free tier? Yes, the Web Scraper API includes 5,000 records per month at no cost, and no credit card is required to start. That is ten times InsightSocial's free allowance, though only for public data through the API. InsightSocial's free tier is unlimited scraping plus 500 exported rows a month, so the allowance is spent only on rows you decide to keep. ### Do I need proxies to scrape TikTok or LinkedIn? Only if you are scraping from a server. Proxies exist so datacenter infrastructure can appear to be a residential user. A browser extension is already a residential user (the traffic comes from your IP, with your cookies, at the pace you scroll) so there is nothing to route and nothing to pay for. ### Is InsightSocial as reliable as Bright Data at avoiding blocks? At scale, no, and it would be dishonest to claim otherwise. Bright Data runs one of the largest residential networks, with CAPTCHA solving. InsightSocial avoids the problem rather than solving it: because requests are indistinguishable from your ordinary browsing, there is usually nothing to unblock. That works well at human scale and does not extend to millions of records. ### Can InsightSocial read pages only my account can see? Yes. Because it runs on your logged-in session it can read what you can read. Bright Data's Scraper APIs are oriented toward publicly accessible data, so this is one of the few areas where an extension genuinely reaches further. ### Does InsightSocial sell pre-collected datasets? No. Bright Data offers large historical social datasets you can buy outright, which is useful when you need backfill you could never gather in real time. InsightSocial only collects what you point it at, live. ### Which social platforms does InsightSocial support? TikTok, LinkedIn, X/Twitter, YouTube, Reddit and Pinterest, covering posts, profiles, comments, followers, following, reactions and post likers depending on the platform. It also exports reviews and threads from 10 review and discussion sites, such as Trustpilot, Google Maps and Amazon. ### Is scraping social media legal? It depends on the data, the jurisdiction and what you do with it, and nothing here is legal advice. Broadly, collecting publicly visible information is treated differently from personal data governed by GDPR or CCPA, and every platform's terms of service apply regardless. If you need contractual assurances and a compliance program behind your collection, that is a genuine reason to use an enterprise vendor like Bright Data instead. --- # InsightSocial vs PhantomBuster Source: https://www.insightsocial.app/alternatives/phantombuster, updated 2026-10-23 > PhantomBuster starts at $69/month and meters cloud execution time. InsightSocial scrapes in your own browser: unlimited scraping, 500 exported rows free. - **Web version**: https://www.insightsocial.app/alternatives/phantombuster - **Compared against**: PhantomBuster (https://phantombuster.com) - **Pricing verified**: 2026-10-18, source https://phantombuster.com/blog/ai-automation/phantombuster-pricing-explained --- ## Summary PhantomBuster automates outreach in the cloud: it scrapes a list, finds work emails and sends LinkedIn messages, from $69 a month (free plan: 30 minutes a month). InsightSocial only does the data step: a free Chrome extension that exports posts, comments, reactions, followers and profiles from 6 social platforms, with 500 exported rows a month free and $9.99 on Pro. If you want the whole loop on autopilot, with your browser closed, PhantomBuster is the stronger tool. Most people who search for an alternative only need the first step, the data. The InsightSocial extension exports it out of the tab you already have open, on your own logged-in session. Scraping is unlimited on every plan; you spend credits only on the rows you export, 500 a month free and 10,000 on Pro for $9.99. ## Feature Comparison | Feature | InsightSocial | PhantomBuster | Advantage | | --- | --- | --- | --- | | What you pay per month | $0 free (500 exported rows) or $9.99 Pro (10,000) | $69 Start, $159 Grow, $439 Scale ($56 / $128 / $352 billed yearly) | InsightSocial | | Free plan | Free forever: unlimited scraping, 500 exported rows a month, no credit card | Free plan: 30 minutes of execution time a month, 1 slot, exports capped at 10 rows. Plus a 14-day trial with 2 hours | InsightSocial | | What is metered | Exported rows only. Scraping and browsing results are unmetered | Execution time, automation slots, email credits, AI credits and URL-finder credits, each with its own monthly cap | InsightSocial | | Where the scrape runs | In your own Chrome, on your own IP and session, at the speed you scroll | On PhantomBuster's cloud servers, acting through your connected accounts | InsightSocial | | Setup before first export | Install the extension, open the page, click Scrape | Connect your account, pick a Phantom or Workflow, set its inputs, launch | InsightSocial | | Runs with your browser closed | The API does. Extension scrapes, scheduled ones included, need Chrome open | Yes, fully cloud-hosted | PhantomBuster | | Outreach: connection requests, messages, follow-ups | Not offered, by design. InsightSocial reads data and never acts on your account | Built in, chained with scraping in ready-made Workflows | PhantomBuster | | Work-email finding for B2B leads | Not offered. Pro follows link-in-bio pages for public emails and phones instead | Email credits on every plan (500 to 10,000 a month) | PhantomBuster | | CRM sync | Export to CSV, Excel, JSON or Google Sheets | HubSpot and other CRMs, plus n8n, Zapier and Make | PhantomBuster | | TikTok, X, YouTube, Reddit and Pinterest | A purpose-built extractor per platform, reading the fields its own app loads | LinkedIn-first; other platforms through individual Phantoms | InsightSocial | | Data behind your own login | Posts and comments your account can see, and your own feed, read in your own session | Your own LinkedIn connections and other account-bound lists, through the account you connect | Comparable | | Use from an AI assistant or n8n | MCP server, n8n community node and a REST API with published per-endpoint prices | MCP server, n8n, Zapier and Make | Comparable | | Ask questions of your data in plain English | On Pro: AI chat over your scrapes (Ask your data) | Not included | InsightSocial | ## Pricing ### InsightSocial - **Free** · $0/mo: Unlimited scraping, 500 rows exported per month - **Pro monthly** · $9.99/mo: 10,000 rows exported per month, every supported site - **Pro yearly** · $7.99/mo: $95.88 billed yearly, 10,000 rows every month ### PhantomBuster - **Free** · $0/mo: 30 min execution time a month, 1 slot, 50 MB storage, exports capped at 10 rows - **Trial** · $0 for 14 days: 2h execution time, 5 slots, 50 email credits, exports limited to 10 rows - **Start** · $69/mo: 20h execution time a month, 5 slots, 500 email credits ($56/mo billed yearly) - **Grow** · $159/mo: 80h execution time a month, 15 slots, 2,500 email credits ($128/mo billed yearly) - **Scale** · $439/mo: 300h execution time a month, 50 slots, 10,000 email credits ($352/mo billed yearly) PhantomBuster's plans are allowances of execution time: the minutes its cloud spends running your Phantoms, whether or not a run returns rows. Slow pages and rate limits consume it the same as productive runs. Its help center says that when the month's time runs out, automations pause until it resets or you move up a plan, with no automatic overage charge. Email, AI and URL-finder credits are separate allowances on top. The free plan gives 30 minutes of execution time a month, 1 slot and 50 MB of storage, with exports capped at 10 rows. InsightSocial meters one thing, rows you export, and shows the count before you spend anything; one-time credit packs cover a month that runs over. ## Moving off PhantomBuster from code - [LinkedIn scraper API](https://www.insightsocial.app/social-media-api/linkedin): Profiles, companies, posts and comments from code, with one key and a published price per call. ## Execution time is billed for running, not for results A PhantomBuster plan is a monthly budget of cloud running time. A Phantom spends it from the moment it launches, so a run that crawls slowly, waits out a rate limit or retries a blocked page spends the same hours as one that returns a full list. Two people running the same scrape can use very different amounts, and neither knows how much until it is done. - Start includes 20 hours a month, Grow 80, Scale 300 - Slots cap how many Phantoms run at once: 5, 15 or 50 - Email, AI and URL-finder credits are separate monthly caps - Run out of time and automations pause until the month resets - InsightSocial has no time meter: a slow scrape costs the same as a fast one, nothing until you export ## Your account, someone else's servers Phantoms run in PhantomBuster's cloud and act through the social accounts you connect to it, which is how they keep running after you close the laptop. It also means your LinkedIn or X account is active from servers that are not yours. The InsightSocial extension works the other way round: it reads the data the page has already loaded in your own Chrome, so the requests come from your IP, with your session, at the speed you scroll. No scraping method is free of risk, but this is the conservative end. - Nothing to connect: the extension uses the session you are already signed into - No password or cookie is ever sent to InsightSocial - No auto-connect or auto-message, which is the step that carries most of the account risk - Pages only your account can see, and your own feed, are reachable, because you can already see them ## If you only need the data half Many PhantomBuster workflows start with an extraction, then hand the list to outreach. If you do the outreach yourself, or in a tool you already use, the extraction is all you need, and InsightSocial covers it on 6 social platforms. - LinkedIn: people who liked or commented on a post, profiles, companies and posts - TikTok and X/Twitter: posts, comments and profiles; plus YouTube comments, Reddit posts and comments, and Pinterest search - Export to CSV, Excel, JSON or straight to Google Sheets ## If you want it to run unattended The extension's scheduled scrapes fire from your browser, so Chrome has to be open. For jobs that must run with the laptop closed, the InsightSocial API returns the same kinds of public data from a plain GET request: call it from your own cron, an n8n workflow or an AI agent. It runs on the same credit balance as exports. - One API key for 22 platforms, including TikTok, LinkedIn, X, YouTube, Reddit, Pinterest, Bluesky and Telegram - Every endpoint has a published price you can read before calling it - Calls that fail or find nothing cost nothing - MCP server for Claude, Cursor and Codex, and an n8n community node ## When PhantomBuster is the better choice PhantomBuster does things InsightSocial deliberately does not. Pick PhantomBuster when: - You want connection requests, messages and follow-ups sent for you, not just a list - You want scrape, enrich and outreach chained in one ready-made Workflow - You need B2B work emails found for LinkedIn leads - You want everything to run in the cloud with no code and your browser closed - You want leads pushed straight into HubSpot or another CRM - Your sources go beyond social platforms, such as Sales Navigator searches or Google Maps - You need your own LinkedIn connections. InsightSocial does not export them ## FAQ ### What is the best free PhantomBuster alternative? For social media data, InsightSocial: unlimited scraping and 500 exported rows a month, permanently, with no card. PhantomBuster's free plan gives 30 minutes of cloud time a month and caps exports at 10 rows; its 14-day trial gives 2 hours. If you need automated outreach, neither free option replaces PhantomBuster: InsightSocial does not send messages or connection requests. ### Is InsightSocial cheaper than PhantomBuster? For getting social data into a spreadsheet, yes. InsightSocial Pro is $9.99 a month for 10,000 exported rows, with scraping itself unmetered. PhantomBuster starts at $69 a month ($56 billed yearly) for 20 hours of execution time. The comparison is not like for like, though: PhantomBuster's price also buys outreach automation, cloud running and work-email credits, none of which InsightSocial offers. ### Can I export people who liked or commented on a LinkedIn post without PhantomBuster? Yes. Open the post in Chrome and the InsightSocial extension exports the people who reacted and the people who commented, with their names, headlines and profile links, to CSV, Excel or Google Sheets. It runs in your own logged-in session, so there is no account to connect and no Phantom to configure. ### Does InsightSocial send LinkedIn connection requests or messages? No, and it will not. InsightSocial only reads data you can already see; it never clicks, follows, connects or messages on your behalf. Automated outreach is the part of PhantomBuster that carries most of the account risk, and it is the main reason to stay on PhantomBuster if you need it. ### Is InsightSocial safer for my account than PhantomBuster? It works in a lower-risk way, though no scraping method is risk-free. PhantomBuster runs in its cloud and acts through the accounts you connect, so your account is active from servers that are not yours. InsightSocial runs inside your own Chrome, on your own IP and session, at the pace you scroll, and never takes actions on the account. For high volume, a secondary account is still sensible. ### What happens when I run out of PhantomBuster execution time? According to PhantomBuster's help center, your automations pause until the execution time resets or you move to a bigger plan, with no automatic overage charge. InsightSocial has no time meter at all: you can keep scraping and browsing results after your export credits run out, and buy a one-time credit pack if you need more rows that month. ### Can I export my LinkedIn connections? Not with InsightSocial. It exports profiles you open, and the people who reacted to or commented on a post. PhantomBuster has an automation that exports your own connections. ### Can InsightSocial run while my computer is off? Through the API, yes: call it from your own cron job, server or n8n workflow and nothing needs to be open. The Chrome extension, scheduled scrapes included, needs Chrome running. If you want unattended cloud runs without writing any code, PhantomBuster does that and InsightSocial does not. ### Can I use InsightSocial from an AI assistant or n8n, like PhantomBuster's MCP server? Yes. InsightSocial has an MCP server (npx -y insightsocial mcp) for Claude, Cursor, Codex and other MCP clients, an n8n community node (n8n-nodes-insightsocial), and a REST API whose public GET /v1/endpoints catalogue lists every path, parameter and price. New accounts get 10 free API calls. ### Which platforms does InsightSocial support? TikTok, LinkedIn, X/Twitter, YouTube, Reddit and Pinterest, each with a purpose-built extractor, plus reviews and threads from 10 review and discussion sites. PhantomBuster covers more automation sources and is strongest on LinkedIn, including Sales Navigator; for sources outside social media, such as Google Maps place searches, it is the broader option. ### Do I have to give InsightSocial my social media password or cookies? Never. The extension works alongside the session you are already signed into in Chrome. You sign in to InsightSocial itself with Google, and you never paste a password or session cookie anywhere. --- # InsightSocial vs Outscraper Source: https://www.insightsocial.app/alternatives/outscraper, updated 2026-10-23 > Outscraper bills Google Maps and Trustpilot reviews per 1,000. InsightSocial exports the place you have open: 500 rows free, $9.99 for 10,000. - **Web version**: https://www.insightsocial.app/alternatives/outscraper - **Compared against**: Outscraper (https://outscraper.com) - **Pricing verified**: 2026-06-17 (archived copy; live page blocks automated checks), source https://web.archive.org/web/20260617102855/https://outscraper.com/pricing/ --- ## Summary Outscraper is a cloud service that bills reviews per 1,000: Google Maps reviews are free for 500 a month, then $3 per 1,000. InsightSocial is a Chrome extension that exports the reviews of the one place, company or product you have open, at a flat $9.99 a month for 10,000 rows. Under about 3,800 reviews a month, Outscraper costs less. Outscraper's pricing page (as archived in June 2026) also lists $1 per 1,000 after 100,000, with bulk extraction, an API and Zapier. That makes it the right tool for review data across hundreds of places or a pipeline. InsightSocial covers the Trustpilot company, Google Maps place, Amazon product, Etsy shop or Steam game in front of you, metered per exported row: free up to 500 rows a month, Pro $9.99 for 10,000, Studio $49 for 150,000. It needs no task setup for a page you are already looking at; for bulk lists, an API or work that runs without your browser, Outscraper is the better buy. ## Feature Comparison | Feature | InsightSocial | Outscraper | Advantage | | --- | --- | --- | --- | | How it runs | Chrome extension, in your browser, on the page you open | Cloud service: submit a task in the web app or through the API | Comparable | | Billing | Flat monthly plan, metered per exported row; scraping is free | Pay as you go per 1,000 records, with a monthly free tier per product | Comparable | | Free tier | 500 exported rows a month, across every site | 500 Google Maps reviews and 500 Amazon reviews a month; 100 Trustpilot reviews (per its pricing pages) | Comparable | | Bulk input | One page per run | Bulk extraction across many places, searches or URLs | Outscraper | | API and integrations | None for review sites | API, Zapier and HubSpot | Outscraper | | Runs with your browser closed | No | Yes | Outscraper | | Review sites in common | Google Maps, Trustpilot, Amazon, Etsy, Product Hunt | Google Maps, Trustpilot, Amazon, Etsy, Product Hunt | Comparable | | Other sites | Steam, Hacker News, Quora, Blind, Notion, plus 6 social platforms | Google Play, Tripadvisor, Google Shopping, YouTube comments and more | Comparable | | Google Maps reviews | The place you open, up to 5,000 per run; Google sign-in, tab in front | Reviews of many places from a list or search | Outscraper | | Trustpilot past 200 reviews | Splits by language and stars to get past the 10-pages-per-filter limit; very large companies often stop short | Not published on a page we could read | Comparable | | Setup | Open the page, click Scrape | Create a task: place IDs, URLs or a search, limits, then download | InsightSocial | ## Pricing ### InsightSocial - **Free** · $0/mo: Unlimited scraping, 500 rows exported per month - **Pro monthly** · $9.99/mo: 10,000 rows exported per month - **Pro yearly** · $7.99/mo: $95.88 billed yearly, 10,000 rows every month - **Studio** · $49/mo: 150,000 rows exported per month ### Outscraper - **Google Maps Reviews, free tier** · $0: First 500 reviews a month - **Google Maps Reviews, medium tier** · $3 / 1,000: 501 to 100,000 reviews, API access - **Google Maps Reviews, business tier** · $1 / 1,000: After 100,000 reviews - **Amazon Reviews** · $0, then $2 / 1,000: First 500 free, $2 per 1,000 to 5,000, $1 per 1,000 after - **Trustpilot Reviews** · $0, then $3 / 1,000: First 100 free, $3 per 1,000 to 50,000, $1 per 1,000 after (December 2025 page) Outscraper's live site blocks automated visitors, so we could not read its pricing page directly in October 2026. The Outscraper prices above are from Outscraper's own pricing page as archived by the Internet Archive on 17 June 2026, and its Trustpilot page as archived on 10 December 2025; check outscraper.com/pricing for today's rates. What the comparison comes down to: at $3 per 1,000 after the free 500, 10,000 Google Maps reviews a month costs about $28.50 on Outscraper and $9.99 on InsightSocial Pro, and 150,000 costs about $348.50 on Outscraper (500 free, 99,500 at $3 per 1,000, 50,000 at $1 per 1,000) and $49 on Studio. Between 500 and about 3,800 reviews a month, Outscraper's per-review price is the cheaper of the two. On InsightSocial an owner reply is a row of its own, so a month's rows cover somewhat fewer reviews when you keep the replies. Outscraper's real advantage is not the price but the shape: it takes lists, runs in the cloud and has an API. InsightSocial also sells one-time packs, from 250 rows for $2 to 25,000 for $39, and a row you already exported is free to export again. ## Per review versus per month Outscraper charges for every review it returns, after a monthly free tier. That is fair and predictable when you know your volume. InsightSocial charges for rows you export, on a monthly allowance, and scraping or browsing results costs nothing. The difference shows up in two places: exploring (you can run a page, look at the results and export only what you need) and re-exporting (a row you already paid for is free to download again in another format). - Up to 500 reviews a month: free on both - Between 500 and about 3,800 a month: Outscraper's per-review price is lower than Pro's $9.99 - Around 10,000 Google Maps reviews a month: about $28.50 on Outscraper, $9.99 on Pro - Around 150,000 a month: about $348.50 on Outscraper, $49 on Studio - Millions of reviews across thousands of places: Outscraper's $1 per 1,000 tier and bulk input are the better fit ## The page you have open versus a task Outscraper is task-based: you give it place IDs, URLs or a search, it runs in the cloud, and you download the file. InsightSocial works on the page in front of you: open a Trustpilot company, a Google Maps place or an Amazon product, click Scrape, and the reviews land in your dashboard. For research where you are already browsing the pages, that removes the setup step; for a list of 400 locations, it is the wrong tool. - Google Maps: InsightSocial needs you signed in to Google and the tab in front, up to 5,000 reviews per place - Amazon: sign in to Amazon; up to about 1,200 reviews per product across star filters and sorts - Trustpilot: no account needed; filter splitting gets past the 200-review signed-out limit, though very large companies often stop short - Steam, Hacker News, Quora, Blind and Notion: covered by InsightSocial, not by Outscraper ## What InsightSocial does not do To save you a trial: InsightSocial has no list-of-URLs input for review sites, no API for them, no scheduling for them, and no Google Maps place search. It does not analyse sentiment. It does not cover Google Play, Tripadvisor, G2, Capterra, Yelp or Booking. If any of those is the job, Outscraper or another cloud service is the right choice. ## When Outscraper is the better choice Outscraper is built for volume and automation, and for those jobs it beats a browser extension. Choose Outscraper when: - You need reviews for many places, products or companies at once, from a list or a search - You want an API, or Zapier and HubSpot integrations, to move reviews into other systems - Jobs have to run in the cloud without your browser open - You pull hundreds of thousands of reviews a month, where its $1 per 1,000 tier applies - You need Google Play, Tripadvisor or other sites InsightSocial does not cover ## FAQ ### How much does Outscraper cost for Google Maps reviews? Outscraper's pricing page, as archived on 17 June 2026, lists Google Maps reviews free for the first 500 a month, $3 per 1,000 from 501 to 100,000, and $1 per 1,000 after that. Its live site blocks automated checks, so confirm today's rates on outscraper.com. ### Is there a cheaper Outscraper alternative for reviews? It depends on volume. Up to 500 reviews a month both are free, and between 500 and about 3,800 Outscraper's per-review price is lower. Above that, a flat plan costs less: InsightSocial Pro is $9.99 for 10,000 exported rows a month and Studio $49 for 150,000, covering Google Maps, Trustpilot, Amazon, Etsy, Steam and Product Hunt. For hundreds of thousands of reviews across many places from a list, Outscraper's bulk input and $1 per 1,000 tier are the better fit. ### Can InsightSocial scrape reviews for many Google Maps places at once? No. Each run reads the place you have open, up to 5,000 reviews, with you signed in to Google and the tab in front. For many places from a list or a search, use Outscraper or another cloud tool. ### Does InsightSocial have an API like Outscraper? Not for review sites. InsightSocial's API covers social platforms and Quora, not Google Maps, Trustpilot or Amazon reviews. ### Can I export more than 200 Trustpilot reviews? Signed out, Trustpilot shows 10 pages of 20 reviews per filter. InsightSocial goes through each language and star rating separately to reach further; in our runs in October 2026 a company with 20,624 reviews returned 4,994. Several Apify actors also say they get past the 200-review limit. ### Can I use InsightSocial's review scrapers today? Yes. Since version 4.7.0 the extension exports Trustpilot, Google Maps, Amazon, Etsy, Steam and Product Hunt reviews, plus Hacker News, Quora, Blind and Notion. --- # InsightSocial vs Instant Data Scraper Source: https://www.insightsocial.app/alternatives/instant-data-scraper, updated 2026-10-23 > Instant Data Scraper is free and exports any list to CSV. For reviews and comments, InsightSocial keeps stars, verified flags, owner replies and reply depth. - **Web version**: https://www.insightsocial.app/alternatives/instant-data-scraper - **Compared against**: Instant Data Scraper (https://chromewebstore.google.com/detail/ofaokhiedipichpaobibbnahnkdoiiah) - **Pricing verified**: 2026-10-17, source https://chromewebstore.google.com/detail/ofaokhiedipichpaobibbnahnkdoiiah --- ## Summary Instant Data Scraper is free, needs no account, and turns any repeating list on a page into a CSV or Excel file; for a one-off table it is hard to beat. On review and comment pages it reads what is rendered, so the columns are whatever its detection finds: a star rating drawn as an image has no text to capture, an owner reply sits inside the review it answers, and only the replies expanded on screen are there to read. InsightSocial is free up to 500 exported rows a month and reads 10 review and discussion sites with a fixed schema per site: rating, title, text, date, verified flag, helpful votes, the owner's reply as its own row, and depth and parent for threaded comments. The trade-off is scope: Instant Data Scraper works on any website, InsightSocial only on the sites it supports (those 10 plus 6 social platforms). ## Feature Comparison | Feature | InsightSocial | Instant Data Scraper | Advantage | | --- | --- | --- | --- | | Price | Free: 500 exported rows a month. Pro $9.99/mo for 10,000 | Free, no account | Instant Data Scraper | | Sites it works on | 6 social platforms, plus 10 review and discussion sites | Any website with a repeating list or table | Instant Data Scraper | | Review columns | Rating, title, text, date, verified flag, helpful votes, fixed per site | Columns detected automatically from the page markup | InsightSocial | | Owner, seller and developer replies | Their own rows, linked to the review they answer | Read as part of the review block it sits in, when it is on screen | InsightSocial | | Threaded comments (Hacker News, Quora, Product Hunt) | Depth and parent id on every row, including replies hidden behind "more" | Flattened to what is expanded on screen | InsightSocial | | Pagination and infinite scroll | Handled per site; most runs page over HTTP and keep going in a background tab | Supports pagination, automatic navigation to the next page and infinite scroll on the page you have open | Comparable | | Google Maps reviews | Opens the Reviews tab, sorts newest first and scrolls it (tab in front, Google sign-in, up to 5,000) | Works only as far as you can make the scrolling panel load | InsightSocial | | Where the data goes | Your InsightSocial dashboard, then CSV, Excel, JSON or Google Sheets | Straight to a CSV or XLSX download; nothing leaves your browser | Comparable | | Account needed | Sign in with Google | None | Instant Data Scraper | | Ask questions of the data | Ask your data (Pro): plain-English questions over a finished run | Not included | InsightSocial | ## Pricing ### InsightSocial - **Free** · $0/mo: Unlimited scraping, 500 rows exported per month - **Pro monthly** · $9.99/mo: 10,000 rows exported per month - **Pro yearly** · $7.99/mo: $95.88 billed yearly, 10,000 rows every month - **Studio** · $49/mo: 150,000 rows exported per month ### Instant Data Scraper - **Instant Data Scraper** · Free: Generic list and table detection, CSV and XLSX download, no account Instant Data Scraper is free, and that is a real advantage: if a free tool gives you the file you need, use it. Its Chrome Web Store listing showed 1,000,000 users and a 4.9-star rating from about 7,800 ratings when we checked in October 2026, and the listing names Flavr Technology, LP as its developer and says "This extension is completely FREE"; scraped data does not leave your browser. InsightSocial's free plan scrapes without limit and meters only exports: 500 rows a month, and a row you already exported is free to export again. Pro raises that to 10,000 rows a month. ## Why generic table scraping struggles with reviews Instant Data Scraper finds the biggest repeating block on a page and turns each repetition into a row, naming columns after the CSS classes it finds. That is exactly right for a product grid or a directory. A review is a different shape: the stars are usually an image or an aria-label rather than text, the date is often relative ("3 weeks ago"), and the business's reply sits inside the same block as the review it answers. A per-site extractor reads those as data. - Stars become a number from 1 to 5, not an empty cell or an icon class - Owner, seller and developer replies become their own rows, so you can count or exclude them - The verified-purchase or verified-reviewer flag gets a column of its own on Amazon and Trustpilot - The site's own date wording is kept next to the parsed date ## Threads are trees, not tables On Hacker News, Quora and Product Hunt launches, the reply structure is the point: who answered whom. A table scraper sees only the comments that are expanded on screen, in display order. InsightSocial reads the whole tree, including replies behind "more" links on Hacker News, and gives every row a depth and the id of the comment it answers. - Hacker News: the full comment tree, measured at 2,484 comments in 2 minutes 22 seconds (October 2026) - Quora: answers, then their comments one level deeper, up to about 3,000 rows - Product Hunt: launch comments with maker replies nested under the question ## What each tool can and cannot reach Neither tool gets past a site's own limits. Signed out, Trustpilot shows at most 10 pages of reviews per filter; InsightSocial goes through each language and star rating separately to reach further, but on very large companies it still often stops short of every review. Amazon shows signed-out visitors only a handful of reviews. Google Maps shows the full list only to signed-in visitors. Instant Data Scraper sees exactly what the page shows you, which is the same ceiling or lower. - Trustpilot: one company with 20,624 reviews returned 4,994 in our runs (October 2026) - Steam: the 10,000 newest reviews per game - Google Maps: up to 5,000 reviews of the place you open, with the tab in front - One page per run on every site. Neither tool takes a list of URLs for review sites ## When Instant Data Scraper is the better choice Instant Data Scraper is free, fast and works almost anywhere. Choose it when: - The site you need is not one of InsightSocial's supported sites (Yelp, G2, Capterra, TripAdvisor, app stores and so on) - You need a one-off table, not review fields, and do not want to create an account - You want nothing to leave your browser at all: no dashboard, no sync - You want a quick look at a product grid, directory or search-results page ## FAQ ### Is Instant Data Scraper free? Yes. It has no paid plan and needs no account. Its Chrome Web Store listing showed 1,000,000 users and a 4.9-star rating when we checked in October 2026. ### Can Instant Data Scraper export Google Maps reviews? Partly. It reads the reviews panel as far as you can get it to load, and the columns depend on Google's markup at the time. InsightSocial opens the Reviews tab, sorts it newest first and scrolls it for you, keeping owner replies as separate rows. It needs you signed in to Google and the tab in front, and stops at 5,000 reviews. ### What is the best Instant Data Scraper alternative for reviews? If your reviews are on Trustpilot, Amazon, Google Maps, Etsy, Steam or Product Hunt, a per-site exporter such as InsightSocial keeps the review fields Instant Data Scraper has to guess. If they are on Yelp, G2, Capterra or TripAdvisor, InsightSocial does not cover those sites; a cloud tool such as Outscraper or a site-specific extension is the better fit. ### Does InsightSocial work on any website like Instant Data Scraper? No. It works on 6 social platforms and 10 review and discussion sites: Trustpilot, Amazon, Google Maps, Etsy, Steam, Product Hunt, Hacker News, Quora, Blind and Notion. For any other site, Instant Data Scraper is the better tool. ### Can I use the review scrapers today? Yes. Since version 4.7.0 the extension exports Trustpilot, Google Maps, Amazon, Etsy, Steam and Product Hunt reviews, plus Hacker News, Quora, Blind and Notion. ### How much does InsightSocial cost compared with a free tool? Scraping and reading results in the dashboard are free on every plan. Exports use credits, one per row: the free plan includes 500 a month, Pro $9.99 a month includes 10,000, and a row you already exported is free to export again. --- # InsightSocial vs Adlicio Source: https://www.insightsocial.app/alternatives/adlicio, updated 2026-10-23 > Adlicio ranks reviews and comments into ad angles from $49/mo, billed per URL. InsightSocial exports the raw rows from $9.99/mo, billed per exported row. - **Web version**: https://www.insightsocial.app/alternatives/adlicio - **Compared against**: Adlicio (https://tryadlicio.com) - **Pricing verified**: 2026-10-18, source https://tryadlicio.com/pricing/credits --- ## Summary Adlicio turns reviews and comments into ranked ad angles and hooks, from $49 a month for 250 URL credits. InsightSocial exports the raw rows (rating, text, date, verified flag, owner reply, reply depth) to Excel or Google Sheets, free up to 500 rows a month and $9.99 for 10,000. The two read many of the same sites, but they sell different things. Adlicio is customer research for ad creative: it scrapes reviews and comments from more sources than we do (G2, TripAdvisor, the app stores, Shopify store reviews and more), then ranks them into angles, objections and hooks. InsightSocial exports the rows into CSV, Excel, JSON or Google Sheets, metered per exported row. If you want the AI-ranked angles, Adlicio does that and we do not. If you want the data in a spreadsheet, we cost less to start. ## Feature Comparison | Feature | InsightSocial | Adlicio | Advantage | | --- | --- | --- | --- | | What you get | Raw rows: each review or comment with its fields, ready to filter and export | Scraped comments plus AI ranking into ad angles, objections and hooks | Comparable | | Entry price | Free (500 exported rows/mo), Pro $9.99/mo | Free to start, no card; then Starter $49/mo | InsightSocial | | Billing unit | Per exported row; scraping is free; re-exporting a row is free | Credits per URL scraped, whatever the number of rows | Comparable | | Review sites | Trustpilot, Amazon, Google Maps, Etsy, Steam, Product Hunt | Trustpilot, Amazon, Google Maps, Etsy and Steam, plus G2, TripAdvisor, App Store, Google Play, Shopify store reviews, BBB, eBay, Walmart and more | Adlicio | | Discussion sites | Hacker News, Quora, Blind, Notion, Reddit | Hacker News, Quora, Blind, Notion, Reddit, Stack Exchange, Discourse, Disqus | Adlicio | | Social platforms | TikTok, LinkedIn, X, YouTube, Reddit, Pinterest: posts, profiles, comments, followers | Comments from TikTok, YouTube, Reddit, LinkedIn and other social platforms | InsightSocial | | Free sources | Every source: scraping is free, exports use the monthly allowance | Steam, Hacker News, Notion, App Store, Google Play, YouTube and more cost 0 credits | Comparable | | AI analysis | Ask your data (Pro): plain-English questions over a finished run | Ranked angles with verbatim quotes, Reddit Radar monitoring | Adlicio | | MCP, CLI, API | MCP and CLI for the social-data API; review sites are extension-only | Claude connector (MCP) and CLI from Starter, plus an export API | Adlicio | | Bulk and scheduling for review sites | One page per run, no scheduling for review sites | Research runs across many URLs (up to 100 URL scrapes an hour); Reddit Radar monitoring | Adlicio | ## Pricing ### InsightSocial - **Free** · $0/mo: Unlimited scraping, 500 rows exported per month - **Pro monthly** · $9.99/mo: 10,000 rows exported per month - **Pro yearly** · $7.99/mo: $95.88 billed yearly, 10,000 rows every month - **Studio** · $49/mo: 150,000 rows exported per month ### Adlicio - **Free** · $0: Free to start, no card needed - **Starter** · $49/mo: 250 credits a month, 3 brands, 1 Reddit Radar, CLI and MCP - **Growth** · $99/mo: 600 credits a month, 10 brands, 3 Radars - **Scale** · $199/mo: 1,200 credits a month, 3 seats, 25 brands, 5 Radars, top advertisers - **Credit packs** · From $9.99: 60 credits for $9.99, 200 for $29.99, 750 for $99.99 Adlicio's credits are charged per URL scraped, not per row, and the cost depends on the source: Steam, Hacker News, Notion, the App Store, Google Play, YouTube and Amazon reviews served from its archive or cache are free; Trustpilot, Quora, Blind, Etsy, Reddit and most comment sources cost 1 credit per URL; a live signed-in Amazon pull costs 2; Google Maps reviews cost 3 to 4 (its credit page describes the full pull as about 200 reviews). That makes Adlicio cheap per review on very large pages, and it is a fair model for research across many sources. InsightSocial meters exported rows instead: a 1,000-review Trustpilot company is 1,000 rows, inside Pro's 10,000 a month, and scraping or re-exporting the same rows costs nothing. One-time packs run from 250 rows for $2 to 25,000 for $39. Adlicio's figures were read on tryadlicio.com's pricing and credit pages on 18 October 2026; plans can also be billed quarterly (15% off) or yearly (33% off). Its sister site redditcommentscraper.com still lists an older price list ($9.99, $49.99 and $99.99 a month). ## Ad angles or raw rows Adlicio's core output is a ranked list of angles, objections and hooks with the customer quotes behind them, built for people writing ad creative. InsightSocial's output is the data: one row per review, comment or reply, with the fields the site provides. Which one you want depends on what happens next. If a model or a person is going to read the reviews anyway, the rows are what you need; if you want the reading done for you, Adlicio is built for that. - Rows with rating, title, text, date, verified flag and helpful votes on review sites - Owner, seller and developer replies as their own rows - Depth and parent on threaded comments (Hacker News, Quora, Product Hunt, Reddit) - CSV, Excel, JSON or a Google Sheets sync from your dashboard ## Per URL or per row: which is cheaper The two meters favour different jobs. Per URL is cheaper when you pull many large pages: a 5,000-review Trustpilot company costs Adlicio 1 credit, and costs InsightSocial 5,000 exported rows. Per row is cheaper when you work with a handful of pages a month, or when you scrape a lot and export only what you need, because InsightSocial does not charge for scraping at all. - A few companies or products a month: InsightSocial's free plan or Pro $9.99 - Hundreds of large pages a month: Adlicio's per-URL credits can cost less per review - Steam, Hacker News and Notion: free on Adlicio; on InsightSocial they use export rows like any other site - Re-downloading the same rows in another format: free on InsightSocial ## What InsightSocial does not do So you can rule it out quickly: InsightSocial reads one page per run on review sites, does not schedule review-site runs, does not rank or summarise reviews automatically, and covers 10 review and discussion sites, not G2, TripAdvisor or the app stores. On Pro, Ask your data answers plain-English questions about a finished run, but it is not an angle generator. ## When Adlicio is the better choice Adlicio covers more review sources and does analysis we do not. Choose Adlicio when: - You want reviews and comments ranked into ad angles, objections and hooks, not a spreadsheet - Your sources include G2, TripAdvisor, the App Store, Google Play, Shopify store reviews, BBB, eBay or Walmart - You pull many large pages, where per-URL credits cost less per review than per-row exports - You want ongoing Reddit monitoring (Reddit Radar) - You want a Claude connector, a CLI or an export API over review sources ## FAQ ### How much does Adlicio cost? When we checked tryadlicio.com/pricing on 18 October 2026: free to start with no card, then Starter $49 a month (250 credits), Growth $99 (600 credits) and Scale $199 (1,200 credits and 3 seats), plus credit packs from 60 for $9.99. Quarterly billing saves 15% and yearly 33%. Credits are charged per URL scraped: 0 for sources such as Steam, Hacker News and the app stores, 1 for Trustpilot, Etsy or Quora, and 3 or 4 for Google Maps reviews. ### Is redditcommentscraper.com part of Adlicio? Yes. redditcommentscraper.com (the Comment Exporter extension) states on its homepage that the extension also runs inside Adlicio, and both sites are published by the same company. ### What is the cheapest Adlicio alternative for exporting reviews? For raw exports, InsightSocial starts free (500 exported rows a month) and Pro is $9.99 a month for 10,000 rows, covering Trustpilot, Amazon, Google Maps, Etsy, Steam and Product Hunt. Other low-priced options are single-site Chrome extensions and reviewsextractor.com, from $9 a month for one site. ### Does InsightSocial generate ad angles like Adlicio? No. InsightSocial exports the reviews and comments. On Pro, Ask your data lets you ask plain-English questions of a finished run, but it does not rank angles or hooks. ### Which sites does Adlicio cover that InsightSocial does not? Among others: G2, TripAdvisor, the App Store, Google Play, Shopify store reviews (Yotpo, Loox, Judge.me), BBB, Reviews.io, Sephora, Ulta, eBay, Walmart, AliExpress, Stack Exchange, Discourse and Disqus. ### Can I use InsightSocial's review scrapers today? Yes. Since version 4.7.0 the extension exports Trustpilot, Google Maps, Amazon, Etsy, Steam and Product Hunt reviews, plus Hacker News, Quora, Blind and Notion. --- # Competitor Analysis Source: https://www.insightsocial.app/use-cases/competitor-analysis, updated 2026-10-23 > Export every post from competitors' TikTok, LinkedIn, X and YouTube accounts with dates and engagement, then compare them in Excel. Free. - **Web version**: https://www.insightsocial.app/use-cases/competitor-analysis --- ## A worked example: four coffee roasters on LinkedIn You run a small coffee roastery and want to see how four rivals use their LinkedIn company pages. 1. Open the first roaster's LinkedIn company page, open the InsightSocial side panel, choose **Posts** and pick 100. 2. Click **Scrape**. You get one row per post: date, text, post type, reactions, comments, reposts and the post link. 3. Repeat for the other three pages, then export all four runs to one Google Sheet. 4. Add a column that adds up reactions, comments and reposts, and sort by it. In one sheet you can now see who posts most often, which formats get the most comments, and which days each roaster posts on. To follow them over time, schedule the same runs weekly (Chrome must be open when a scheduled run fires). The same steps work on a TikTok profile, an X account or a YouTube channel. The free plan includes 500 exported rows a month, enough for four runs of 100 posts. For platform-specific guides, see [Twitter competitor analysis](/blog/twitter-competitor-analysis-guide) and [TikTok competitor analysis](/blog/tiktok-competitor-analysis-guide). --- ## Pain Points This Solves - Manually checking competitor pages wastes hours every week - No way to track historical content and engagement trends - Missing viral content opportunities your competitors capitalize on - Difficult to benchmark your performance against competitors ## How InsightSocial Helps - Automatically collect competitor posts and engagement data - Export to spreadsheets for trend analysis over time - Identify top-performing content to inspire your strategy - Compare engagement rates across multiple competitors ## Capabilities ### Post frequency Every post with its date, so you can count how often they post ### Engagement per post Likes and comments, plus shares and views where the platform shows them ### Content types Post type (image, video, document, article) on LinkedIn ### Posting times Every post's timestamp, so you can see when they post ### Follower counts A TikTok profile run records the follower count; re-run it weekly to see the change ### Post text and links The full caption or post text, hashtags and the post URL ## How to Get Started 1. **Identify Your Competitors**: List 3-5 direct competitors and 2-3 industry leaders whose social media strategy you want to analyze. 2. **Extract Competitor Data**: Open each competitor's TikTok profile, LinkedIn company page, X account or YouTube channel and run InsightSocial. Every post comes with its text, date and engagement counts. 3. **Export to Spreadsheet**: Download the data as CSV or Excel, or send it to Google Sheets. Keep one sheet per competitor for easy comparison. 4. **Analyze Patterns**: Look for trends in posting frequency, top-performing content types, and engagement rates across competitors. 5. **Apply Insights**: Use your findings to improve your own content strategy. Replicate what works, avoid what doesn't. ## FAQ ### How often should I run competitor analysis? Weekly works for most active competitors. You can set a recurring schedule in the extension; scheduled runs fire from your browser, so Chrome has to be open. ### How many competitors should I track? Start with 3-5 direct competitors and 2-3 industry leaders. Too many can be overwhelming; too few won't give you a complete picture. ### What metrics matter most for competitor analysis? Engagement per post (likes, comments and shares), engagement relative to follower count, posting frequency and which content formats get the most response. All of these come from the exported columns; you work them out in your spreadsheet. ### How do I export a competitor's LinkedIn posts to Excel? Open their LinkedIn company page, open the InsightSocial side panel, choose the page's posts and click Scrape. When the run finishes, export to CSV or Excel, or send it to Google Sheets. Each row is one post with its text, type, date, reactions and comments. ### Can I see a competitor's follower growth? Not as a history. A TikTok profile run records the follower count at the moment you run it. Schedule the same run weekly and compare the numbers over time. ### Can I track competitors across multiple platforms? Yes. InsightSocial works on TikTok, LinkedIn, X, YouTube, Reddit and Pinterest. Scrape each competitor where they are most active, then combine the exports in one spreadsheet. --- # Content Research Source: https://www.insightsocial.app/use-cases/content-research, updated 2026-10-23 > Export the videos on a TikTok hashtag, a subreddit or a creator's profile with engagement, then sort to see what worked. Free. - **Web version**: https://www.insightsocial.app/use-cases/content-research --- ## A worked example: the top posts on a TikTok hashtag You make short cooking videos and want to know what works on #mealprep. 1. Open the hashtag page on TikTok, open the InsightSocial side panel, choose **Videos** and pick 250. 2. Click **Scrape**. Each row is one video: creator, caption, music, views, likes, comments, shares, duration and upload date. 3. Export to Google Sheets and sort by views, or by likes divided by views to find videos that did well for their reach. 4. Read the top 20 captions and watch the videos. Note the hook, the length and the format each one uses. That list is your swipe file. Repeat it on a subreddit in your niche or a creator's profile to see whether the same patterns hold there. The free plan includes 500 exported rows a month; Pro is $9.99 a month for 10,000. --- ## Pain Points This Solves - Running out of content ideas that actually engage - No data to back up content decisions - Missing trending topics in your niche - Time wasted on content that doesn't perform ## How InsightSocial Helps - Extract top-performing posts from TikTok hashtags, subreddits and creator profiles - Sort by engagement to see which posts stood out - Build a swipe file of proven content formats - Plan your calendar from what you found, not from guesses ## Capabilities ### Engagement per post Likes and comments, plus views and shares on TikTok ### Post text and hashtags The caption or post text, with its hashtags and mentions ### Content formats Post type on LinkedIn, video duration on TikTok ### Post date and time When each post went up ### Creator Who posted it, with a link to the profile ### Post links A URL for every post, so you can open the originals ## How to Get Started 1. **Find Active Communities**: Pick the TikTok hashtags, subreddits and creator profiles in your niche where audiences engage most. 2. **Extract Top Posts**: Use InsightSocial to extract the posts, then sort the results by engagement and focus on the top 100. 3. **Analyze Patterns**: Look for common themes in a spreadsheet: hooks, content types, length and posting times. 4. **Build Your Swipe File**: Save the best examples as templates. Note what makes each post successful. 5. **Create & Test**: Apply insights to create new content. Track performance and iterate. ## FAQ ### How do I find the most engaging content? Sort the exported posts by total engagement (likes plus comments, plus shares where the platform gives them). Focus on posts with unusually high engagement compared to the average for that hashtag or account. ### Should I copy competitor content? Never copy directly. Use research for inspiration - understand what works and why, then create original content that applies those principles. ### How often should I do content research? Monthly research sessions work well for most creators. Trends change, so regular research keeps your content fresh and relevant. ### Which platforms can I research? TikTok, LinkedIn, X, YouTube, Reddit and Pinterest, plus discussions on Hacker News and Quora. --- # Audience Research Source: https://www.insightsocial.app/use-cases/audience-research, updated 2026-10-23 > Export the posts and comments of subreddits, hashtags, Hacker News stories and comment threads to understand interests, questions and conversation topics. - **Web version**: https://www.insightsocial.app/use-cases/audience-research --- ## A worked example: what a subreddit complains about You are building a budgeting app and want to know what people in r/personalfinance struggle with. 1. Open the subreddit on Reddit (signed in), open the InsightSocial side panel, choose **Posts** and pick 500. 2. Click **Scrape**. Each row is one post: title, body text, flair, author, score, upvote ratio, comment count and date. 3. Export to Google Sheets. Sort by comment count to find the questions that started the longest discussions. 4. Read the top 50 titles and tag each one with a theme in a new column, then count the themes. For the detail behind a theme, open one of those posts and run **Post and Comments**: you get every comment and reply with its depth, so you can see who answered whom. The same approach works on a TikTok hashtag, a YouTube video's comments or a Hacker News thread. The free plan includes 500 exported rows a month. On Pro, Ask your data answers plain-English questions about a finished run, such as "which complaints come up most?". --- ## Pain Points This Solves - Hard to study an audience without manually reading thousands of posts - No structured way to capture what a community is actually discussing - Trends and topics move faster than spreadsheets can track - Qualitative research stuck in screenshots and copy-paste ## How InsightSocial Helps - Capture posts and comments from subreddits, TikTok hashtags, Hacker News stories and comment threads in structured form - Spot recurring themes, questions and pain points across thousands of posts - Count topics and engagement in your spreadsheet, or ask questions of the data on Pro - Export structured datasets for analysis in your tools of choice ## Capabilities ### Community snapshots Capture a subreddit, hashtag or comment section in one run ### Comment threads Comments with their replies, author and date ### Engagement per post See which posts and questions get the most response ### Public profile data Name, handle and profile link of each author ### Repeat runs Re-run the same subreddit or hashtag later and compare the two exports ### CSV / Excel export Drop into your analysis or BI tool ## How to Get Started 1. **Pick the Community to Study**: Identify the subreddits, hashtags or comment threads where your research subjects discuss the topics you care about. 2. **Capture the Conversation**: Use InsightSocial to capture posts, comments, and engagement metrics into a structured dataset. 3. **Cluster by Topic**: Group posts by theme or keyword in your spreadsheet to see what the community actually talks about. On Pro, Ask your data can answer plain-English questions about the run. 4. **Quantify the Findings**: Measure topic frequency, engagement, and trend shifts over time. Turn impressions into evidence. 5. **Report**: Export to CSV or Excel for your analysis pipeline, slide deck, or research paper. ## FAQ ### Is this for marketing teams or for researchers? Both. Market researchers, journalists, academic researchers and product analysts all use the same workflow: capture a community, study what's there, report the findings. The extension only reads what your own account can already see on the platform. ### Can I use this for journalism or academic research? Yes, that's a primary use case. The structured exports make it straightforward to cite, share, and reproduce findings. Always follow your publication's or institution's ethical guidelines for working with social media data. ### What kinds of research questions does this answer? Examples: 'What problems does this community talk about most?', 'How has discussion of topic X changed since last quarter?' (re-run the same source and compare), 'Which formats and angles get the most engagement in this niche?', 'Which posts start the longest comment threads?' ### How do I keep the research ethical? Only work with publicly visible content, don't use the data for unsolicited outreach, respect platform terms, and follow applicable privacy regulations (GDPR, CCPA) when handling any data that could identify individuals. --- # Best Amazon Review Scrapers and Exporters (2026) Source: https://www.insightsocial.app/blog/best-amazon-review-scrapers, updated 2026-10-18 > Amazon review scrapers compared: Chrome extensions, Apify actors, Bright Data, Outscraper and open source. Prices per 1,000 reviews and the sign-in wall. - **Published**: 2026-10-17 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: amazon, reviews, comparison, scraping, tools, ecommerce - **Reading time**: 10 min read - **Web version**: https://www.insightsocial.app/blog/best-amazon-review-scrapers --- **The best Amazon review scraper depends on volume and on Amazon's sign-in wall: for one product at a time, a Chrome extension that uses your own signed-in Amazon session works best (InsightSocial reads up to about 1,200 reviews per product across star filters and sorts, free up to 500 exported rows a month; single-site exporters such as amazonreviews.cc start free at 10 reviews per click); for hundreds of ASINs, cloud tools such as Apify's Amazon Reviews Scraper ($6 per 1,000 reviews on Apify's free plan, down to $1) or Bright Data ($1.50 per 1,000 records) are the right shape.** Signed out, Amazon now shows only the dozen or so reviews on the product page, so any tool that does not sign in returns very few. *Updated October 2026. We make InsightSocial, so we are not neutral. This list includes the free and open-source options, names the single-site extensions that rank for these searches, and says where a cloud tool is the better fit. We have not benchmarked other tools; their prices, limits, user counts and ratings are what their own pages, Apify listings and Chrome Web Store listings said when we checked in October 2026.* ## Quick comparison | Tool | Type | Price (October 2026) | Free limit | Best for | |---|---|---|---|---| | InsightSocial | Chrome extension | Pro $9.99/mo for 10,000 rows | 500 exported rows a month | Reviews across star filters, 20 storefronts | | amazonreviews.cc (Amazon Reviews Exporter) | Chrome extension | $9.99/mo (shown as reduced from $19) | 10 reviews per click, images and Shopify CSV included | Review images, Shopify-import CSV | | Amazon Reviews Extractor | Chrome extension | Free basic, paid for more | Basic features | Quick extraction | | Amazon Reviews Exporter (CSV & Images) | Chrome extension | Pro for unlimited | CSV download | Images | | Amazon Review Scraper – Export to CSV | Chrome extension | Paid for unlimited | 35 reviews at a time | Small exports | | Product review export | Chrome extension | In-app purchases | Free tier | Amazon and Etsy | | Apify: junglee Amazon Reviews Scraper | Cloud actor | $6 per 1,000 on Apify's free plan, down to $1 | $5 of usage a month | Bulk ASINs | | Apify: Axesso | Cloud actor | $0.90 per 1,000 | $5 of usage a month | Cheaper bulk | | Outscraper | Cloud + API | $2 per 1,000 after 500 free (archived June 2026) | 500 reviews a month | API with a free tier | | Bright Data | Scraper API | $1.50 per 1,000 records | 5,000 records a month | Enterprise pipelines | | ExportComments | Web app | From $23 for 3 days | 100 per export | One-off exports | | Open-source scripts | Code | Free | — | Developers, with maintenance | ## Why Amazon review scraping changed Amazon now shows its full review pages only to signed-in shoppers. Signed out, you see the product page's few reviews: in our own runs in October 2026, 13 on a typical product, sometimes none on amazon.com. Many older tutorials and scripts were written before that, which is why they return almost nothing today. Signed in, there is still a ceiling: Amazon serves at most 10 pages of 10 reviews for each sort order and star filter. Tools that read each star rating under both "Top reviews" and "Most recent" reach well beyond 100 reviews, but not tens of thousands. Amazon may also limit review access for an account that reads many pages. ## How we put this list together We looked at the extensions that rank for "Amazon review scraper", "exporter", "extractor" and "downloader", the Apify actors with the most users, and the cloud APIs that publish Amazon review prices. For each we read its own listing or pricing page in October 2026. We did not run other vendors' tools, so this is not a ranking by completeness; where Chrome Web Store ratings are low, we say so, because that is what users report. ## InsightSocial: every star filter, 20 storefronts [InsightSocial's Amazon Review Scraper](/scraper/amazon-review-scraper) is a Chrome extension. Sign in to Amazon, open a product page, click Scrape. It reads the product page, then the review pages in 12 views: top and most recent unfiltered, then each star rating from 1 to 5 under both sorts, up to 10 pages each. That is up to about 1,200 reviews per product before duplicates are removed, within a 6-minute run, and it keeps going in a background tab. It works on 20 Amazon storefronts (amazon.com, .co.uk, .ca, .de, .fr, .it, .es, .nl, .se, .pl, .com.tr, .ae, .sa, .eg, .in, .co.jp, .com.au, .sg, .com.br and .com.mx), reading ratings, dates and helpful counts in each storefront's language. Each row has the rating, title, text, reviewer, date, country, verified-purchase flag, helpful votes and variant, and the original text when Amazon shows a translation. When Amazon's per-filter ceiling cuts a view short, or Amazon limits review access for the account, the panel says so and keeps what it collected. **Price:** scraping is free; exporting uses one credit per row. Free includes 500 rows a month, Pro $9.99 a month (or $7.99 billed yearly) includes 10,000, Studio $49 includes 150,000. Re-exporting a row is free. **Limits:** one product per run, no list of ASINs, no review images, no API or scheduling for Amazon. **Best for:** sellers and researchers comparing a handful of competitor products, who want the low-star reviews read in full and the same tool for other review sites. ## amazonreviews.cc (Amazon Reviews Exporter) A single-site extension with its own site. Free exports 10 reviews per click, with review images and videos, a CSV formatted for Shopify import and unlimited downloads; Pro, $9.99 a month (shown as reduced from $19), raises that to 100 per click (checked on its site, October 2026). **Best for:** dropshippers importing Amazon reviews with photos into a Shopify store. ## Amazon Reviews Extractor One of the most installed Amazon review extensions: its listing showed 20,000 users, a 2.6 rating from 24 ratings, and free basic features with a paid tier for more (October 2026). **Best for:** trying a free extraction quickly. Read the recent reviews on its listing first. ## Amazon Reviews Exporter (CSV & Images) Its listing showed 10,000 users and a 2.7 rating from 90 ratings: free CSV download, and a Pro plan for unlimited review downloads, images and filters. The listing was last updated in July 2025. **Best for:** exports that need review images. ## Amazon Review Scraper – Export to CSV Its listing showed 3,000 users and a 2.8 rating: it "extracts up to 35 reviews at a time", with a paid plan for unlimited reviews. **Best for:** small exports of a product's top reviews. ## Product review export Covers Amazon and Etsy; its listing showed about 5,000 users and a 4.1 rating from 25 ratings. Free with in-app purchases. **Best for:** sellers who work on both Amazon and Etsy. ## Apify actors: bulk ASINs in the cloud - **junglee, Amazon Reviews Scraper:** about 2,200 users in the last 30 days. $6 per 1,000 reviews on Apify's free plan, falling to $1 on Apify's top tier, with a date filter at extra cost. - **Axesso, Amazon Reviews Scraper:** about 700 users. A flat $0.90 per 1,000 reviews. - **web_wanderer, Amazon Reviews Extractor:** about 860 users. $1 per 1,000 on the free plan, down to $0.70. They take lists of products and run on Apify's schedules and API. Apify's free plan includes $5 of usage a month. **Best for:** brands and agencies tracking dozens or hundreds of ASINs. ## Outscraper Outscraper's pricing page, as archived in June 2026, lists Amazon reviews free for the first 500 a month, then $2 per 1,000 up to 5,000 and $1 per 1,000 after, with API access. The live site blocks automated visitors, so we could not re-check it in October 2026. **Best for:** teams already using Outscraper who want Amazon on the same account. See our [Outscraper comparison](/alternatives/outscraper). ## Bright Data Bright Data's Amazon reviews scraper API uses its Web Scraper API pricing: 5,000 records a month free, then $1.50 per 1,000 records pay as you go, or $499 a month with 384,000 records included (checked October 2026). **Best for:** enterprise collection across many products and marketplaces. ## ExportComments ExportComments exports Amazon reviews from a product URL in its web app: free up to 100 results per export and 50 exports a month, Personal $23 once for 3 days at up to 5,000 per export, Premium $45 a month at up to 50,000 (checked October 2026). **Best for:** an occasional one-off export. ## Open-source scripts GitHub has Amazon review scrapers such as philipperemy/amazon-reviews-scraper (about 130 stars, Apache-2.0). Most were written for signed-out pages; today they need a signed-in session, pacing and captcha handling to return more than a few reviews. **Best for:** developers who want to learn how the pages work and accept the maintenance. ## Detailed comparison | | InsightSocial | Single-site extensions | Apify actors | Outscraper | Bright Data | |---|---|---|---|---|---| | Runs | Your browser | Your browser | Cloud | Cloud | Cloud | | Signed-in session | Yours | Yours | Handled by the actor | Handled by the service | Handled by the service | | Many ASINs at once | No | Rarely | Yes | Yes | Yes | | Per product | Up to about 1,200 | Per click (10–100) or unlimited on paid plans | Configurable | Configurable | Configurable | | Storefronts | 20 | Varies | Varies by actor | Not checked | Not checked | | Review images | No | Some | Varies | Not checked | Not checked | | Price | 500 rows free, $9.99 for 10,000 | Free tier, then about $10/mo | $0.70–$6 per 1,000 | 500 free, then $2 per 1,000 | 5,000 free, then $1.50 per 1,000 | ## Which one should you pick? - **A few competitor products, low-star reviews in full, several storefronts:** InsightSocial. - **Reviews with photos for a Shopify store:** amazonreviews.cc or Amazon Reviews Exporter (CSV & Images). - **Hundreds of ASINs, recurring:** an Apify actor (Axesso for price, junglee for usage) or Outscraper. - **Enterprise pipelines:** Bright Data. - **One product, once, a few dozen reviews:** any single-site extension's free tier. ## FAQ **What is the best free Amazon review scraper?** In the cloud, Apify's free $5 a month and Outscraper's 500 free reviews a month (archived June 2026 pricing) are the free starting points. In the browser, single-site extensions have free tiers that cap reviews per click, and InsightSocial's free plan exports 500 rows a month. **Why does my Amazon review scraper only return a few reviews?** Amazon shows its full review pages only to signed-in shoppers. Sign in to Amazon in the browser, or use a cloud service that handles sign-in. **How many reviews can I scrape per Amazon product?** Amazon serves at most 100 reviews per sort and star filter. Reading every star rating under two sorts gives up to about 1,200; cloud tools may combine more filters. **Do Amazon review exporters include the Verified Purchase badge?** InsightSocial does, in a Verified column. For other tools, check a sample export before you rely on it. **Can I download Amazon reviews with images?** Some single-site extensions export review images (amazonreviews.cc, Amazon Reviews Exporter (CSV & Images)). InsightSocial exports text and fields only. **Is it safe to scrape Amazon reviews with my account?** A browser extension reads pages at browsing pace with your session. Amazon may still limit review access for an account that reads many pages; a careful tool stops at that notice. Related: [how to download Amazon reviews to Excel](/blog/how-to-download-amazon-reviews), [best free review scraper Chrome extensions](/blog/best-free-review-scraper-chrome-extensions), [how to export Etsy shop reviews](/blog/how-to-export-etsy-reviews). --- # Best Free Review Scraper Chrome Extensions (2026) Source: https://www.insightsocial.app/blog/best-free-review-scraper-chrome-extensions, updated 2026-10-18 > Free Chrome extensions that export reviews to CSV or Excel, compared: multi-site exporters, single-site Trustpilot, Amazon, Etsy and Steam tools. - **Published**: 2026-10-17 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: reviews, chrome extension, comparison, free tools, export - **Reading time**: 10 min read - **Web version**: https://www.insightsocial.app/blog/best-free-review-scraper-chrome-extensions --- **The best free review scraper Chrome extension depends on the site: for one site, a single-site exporter such as T-Reviews Scraper (Trustpilot) or Steam Review Scraper is the simplest; for several review sites in one tool, InsightSocial (10 review and discussion sites, free up to 500 exported rows a month) or Adlicio's extension (more sites, $49.99 a month for all of them) fit; and for any other site, the free Instant Data Scraper turns a visible list into a CSV but loses review structure.** Free tiers differ in shape: some cap reviews per click, some cap rows per month, and some are free outright. *Updated October 2026. We make InsightSocial, so we are not neutral; this list includes the free and official routes, and says where another tool is the better fit. We have not benchmarked the other extensions: the figures for them are what their own Chrome Web Store listings and pricing pages said when we checked in October 2026.* ## Quick comparison | Extension | Sites | Free tier | Paid from | Best for | |---|---|---|---|---| | InsightSocial | Trustpilot, Amazon, Google Maps, Etsy, Steam, Product Hunt, Hacker News, Quora, Blind, Notion (+ 6 social platforms) | 500 exported rows a month, scraping unlimited | $9.99/mo for 10,000 rows | Several review sites, replies kept as rows | | Instant Data Scraper | Any page with a list or table | Free, no account | — | Any site, one-off tables | | Adlicio (Reddit Comment Scraper) | Reddit, plus 30 sources on All Access | Free install | $9.99/mo for Reddit; $49.99/mo for all sources | Ad research across many sources | | reviewsextractor.com | Trustpilot, Amazon, Etsy, G2, Capterra, Shopify App Store and other B2B sites | 25 reviews per extraction, on G2, Trustpilot and Capterra | $9/mo for one site | B2B software reviews | | T-Reviews Scraper | Trustpilot | Free with in-app purchases | In-app | Trustpilot only | | Product review export | Amazon, Etsy | Free with in-app purchases | In-app | Amazon and Etsy | | Amazon Reviews Exporter (amazonreviews.cc) | Amazon | 10 reviews per click | $9.99/mo, 100 per click | Amazon reviews with images | | Etsy Reviews Extractor | Etsy | Free | — | Etsy only | | Steam Review Scraper | Steam | Free with in-app purchases | In-app | Steam only | ## How we picked We looked for Chrome extensions that export reviews (not just ratings) to a file, are listed on the Chrome Web Store or their own site, and have a free way to start. For each one we read its Chrome Web Store listing and pricing page in October 2026: the sites it supports, the free limit, the paid price and the user count. We did not run head-to-head tests of other extensions, so this list does not rank them on speed or completeness. Where a site has a free official route (Steam's public reviews endpoint, Trustpilot's export for business owners), we say so first. ## Free official routes to try first Before installing anything: - **Steam:** Steam's `GetAppReviews` Web API returns any game's reviews as JSON without a key. See [how to export Steam reviews](/blog/how-to-export-steam-reviews). - **Hacker News:** the Algolia and Firebase APIs return whole threads. See [how to download all comments from a Hacker News thread](/blog/how-to-export-hacker-news-comments). - **Trustpilot:** business owners can export their own company's reviews from Trustpilot Business. See [how to export Trustpilot reviews](/blog/how-to-export-trustpilot-reviews). - **Google:** owners can pull their own locations' reviews through the Business Profile API (needs a developer and Google's approval). See [how to export Google reviews](/blog/how-to-export-google-reviews). If the reviews are not yours, or you do not want to write code, an extension is the shortest route. ## InsightSocial: several review sites in one extension [InsightSocial](/scraper/reviews) exports reviews and comments from 10 review and discussion sites, alongside its six social platforms: [Trustpilot](/scraper/trustpilot-review-scraper), [Amazon](/scraper/amazon-review-scraper), [Google Maps](/scraper/google-maps-review-scraper), [Etsy](/scraper/etsy-review-scraper), [Steam](/scraper/steam-review-scraper), [Product Hunt](/scraper/product-hunt-scraper), [Hacker News](/scraper/hacker-news-comment-scraper), [Quora](/scraper/quora-scraper), Blind and Notion. Each site has its own extractor, so the columns are the site's real fields: rating, title, text, date, verified flag and helpful votes on review sites, and depth and parent on threaded comments. Owner, seller and developer replies are rows of their own under the review they answer. Most sites page over HTTP and keep going in a background tab; Google Maps needs its tab in front. **Free tier:** scraping and reading results in the dashboard are unlimited; exporting uses one credit per row, 500 a month free, and a row you already exported is free to export again. Pro is $9.99 a month (or $7.99 billed yearly) for 10,000 rows. **Limits:** one page per run (no list of URLs), no scheduling for review sites, and per-site caps: Trustpilot's 10-pages-per-filter limit is split by language and stars but very large companies often stop short; Amazon needs you signed in and serves at most about 1,200 reviews per product; Google Maps needs Google sign-in and stops at 5,000; Steam stops at the 10,000 newest. **Best for:** people who need reviews from more than one of these sites and want the replies and fields kept, without paying per review. ## Instant Data Scraper: free, any site [Instant Data Scraper](https://chromewebstore.google.com/detail/ofaokhiedipichpaobibbnahnkdoiiah) detects the biggest list or table on the page and downloads it as CSV or Excel. Its listing showed 1,000,000 users and a 4.9-star rating from about 7,800 ratings. It is free, needs no account, and works on sites no review-specific tool supports. **Limits:** it reads what is rendered, so star ratings (usually images) and owner replies (inside the review block) do not come out as clean columns, and nested replies are flattened. You point it at the "Next" button or let it scroll. **Best for:** a one-off table from a site no review extension covers. Our [Instant Data Scraper comparison](/alternatives/instant-data-scraper) goes deeper. ## Adlicio and Comment Exporter: the widest coverage Adlicio's extension (sold as Reddit Comment Scraper on redditcommentscraper.com) reads more review and comment sources than any other extension here, including Yelp, G2, TripAdvisor, the app stores and Shopify store reviews, and its web app ranks what it scrapes into ad angles, objections and hooks. The extension installs free; Pro is $9.99 a month for Reddit, and All Access is $49.99 a month for 250 credits across its 30 sources, charged per URL (checked on its site, October 2026). Its Chrome Web Store listing showed 7,000 users and a 4.6 rating from 43 ratings. **Best for:** marketers mining many review sources for ad copy. See our [Adlicio comparison](/alternatives/adlicio). ## reviewsextractor.com: B2B software reviews reviewsextractor.com exports reviews from 15+ sites: Trustpilot, Amazon and Etsy plus B2B software sites (G2, Capterra, the Shopify App Store, TrustRadius and others). Free extractions return 25 reviews, on G2, Trustpilot and Capterra only; Starter is $9 a month for one site at up to 2,500 reviews per extraction, $15 for all sites, $25 adds AI sentiment and themes, and $99 adds weekly monitoring. **Best for:** SaaS teams exporting G2 or Capterra reviews, which InsightSocial does not cover. ## T-Reviews Scraper: Trustpilot only [T-Reviews Scraper](https://chromewebstore.google.com/detail/mbokhiogfogcnhgllhcgmniobpcaedkn) exports Trustpilot reviews, companies and ratings. Its listing showed 478 users and a 4.2-star rating, free with in-app purchases. **Best for:** Trustpilot-only exports, if you do not need other sites. ## Product review export: Amazon and Etsy [Product review export](https://chromewebstore.google.com/detail/jilbpmenakjfpjclgjpppnflkiplmhjo) covers Amazon and Etsy and had about 5,000 users and a 4.1-star rating. Free with in-app purchases. **Best for:** Amazon and Etsy sellers who only need those two sites. ## Amazon Reviews Exporter (amazonreviews.cc): Amazon with images amazonreviews.cc's free tier exports 10 reviews per click, with review images and videos, a CSV formatted for Shopify import and unlimited downloads; Pro, $9.99 a month (shown as reduced from $19), exports 100 per click. **Best for:** dropshippers importing Amazon reviews with photos into a Shopify store. InsightSocial does not export review images. ## Etsy Reviews Extractor: Etsy only [Etsy Reviews Extractor](https://chromewebstore.google.com/detail/fbbobebaplnpchmkidpicipacnogcjpk) exports Etsy reviews to CSV and adds an AI summary. Its listing showed 679 users and a 4.0-star rating, free. **Best for:** a quick Etsy export with a summary. ## Steam Review Scraper: Steam only [Steam Review Scraper](https://chromewebstore.google.com/detail/gbabfbkjgollabnkkmolkbfjdbngongm) exports Steam reviews to Excel, CSV, JSON, HTML or XML. Its listing showed 141 users and a 5.0 rating from 2 ratings; it is free with in-app purchases and was last updated in August 2024. Steam's own GetAppReviews API is also free, if you can run a script. **Best for:** Steam reviews without code or an account. ## Detailed comparison | | InsightSocial | Instant Data Scraper | Adlicio | reviewsextractor | Single-site extensions | |---|---|---|---|---|---| | Review fields as columns | Yes, per site | Guessed from the page | Yes | Yes | Yes | | Owner replies as their own rows | Yes | No | Not checked | Not checked | Varies | | Threaded comments with depth | Yes (HN, Quora, Product Hunt, Reddit) | No | Not checked | Not checked | No | | Free tier | 500 rows a month | Free | Free start | 25 per extraction | Free, often capped | | Paid entry | $9.99/mo | — | $9.99/mo (Reddit), $49.99/mo (all sources) | $9/mo | In-app or ~$10/mo | | Billing unit | Exported row | — | URL | Site per month | Varies | | Sentiment or AI summary | No (Ask your data on Pro) | No | Ad angles | $25/mo tier | Some | | Bulk URLs or scheduling | No | No | Research runs, Reddit monitoring | $99/mo monitoring | Rarely | | Sites | 10 review and discussion + 6 social | Any | 30 | 15+ sites | One each | ## Which one should you pick? - **One review site, a few hundred reviews:** the single-site extension for that site, or the site's free official route. - **Several of Trustpilot, Amazon, Google Maps, Etsy, Steam and Product Hunt, with replies kept:** InsightSocial. - **Hacker News, Quora, Blind or Notion:** InsightSocial or Adlicio; almost nothing else covers them. - **G2, Capterra, Yelp, TripAdvisor or the app stores:** Adlicio, reviewsextractor.com or a single-site extension; InsightSocial does not cover them. - **Any other site, once:** Instant Data Scraper. - **Many companies or places on a schedule:** not an extension at all; use a cloud tool such as Outscraper or Apify. ## FAQ **Is there a free Chrome extension that scrapes reviews from multiple sites?** Yes. InsightSocial covers 10 review and discussion sites with a free tier of 500 exported rows a month. Instant Data Scraper is free and works on any site but does not understand review fields. **What is the best free Trustpilot review scraper extension?** For Trustpilot alone, T-Reviews Scraper is a dedicated free option. InsightSocial also splits Trustpilot's listing by language and star rating to get past its 10-pages-per-filter limit. Trustpilot Business owners can export their own reviews without any extension. **Can a Chrome extension scrape Google Maps reviews?** Yes, if you are signed in to Google: signed out, Maps shows only a few reviews. InsightSocial reads up to 5,000 reviews of the place you open, with the tab in front. **Are free review scrapers safe to use?** Check the permissions an extension asks for. InsightSocial asks Chrome for each review site only the first time you use it. Extensions that run in your own browser at browsing pace do not hand your session to a server. **Which review extensions do sentiment analysis?** reviewsextractor.com sells sentiment and themes from $25 a month, Adlicio ranks reviews into ad angles, and some single-site extensions add an AI summary. InsightSocial has no sentiment column in the export. On Pro, Ask your data answers sentiment and theme questions about a finished run. Related: [best Trustpilot review scrapers](/blog/best-trustpilot-review-scrapers), [best Google Maps review scrapers](/blog/best-google-maps-review-scrapers), [best Amazon review scrapers](/blog/best-amazon-review-scrapers). --- # Best Google Maps Review Scrapers (2026): Prices and Limits Source: https://www.insightsocial.app/blog/best-google-maps-review-scrapers, updated 2026-10-18 > Google Maps review scrapers compared: Google's APIs, Apify, Outscraper, SerpApi, open source and Chrome extensions. Prices per 1,000 reviews and limits. - **Published**: 2026-10-17 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: google maps, google reviews, comparison, scraping, tools - **Reading time**: 12 min read - **Web version**: https://www.insightsocial.app/blog/best-google-maps-review-scrapers --- **For Google Maps reviews of many places, cloud tools win: Apify's Google Maps Reviews Scraper costs $0.60 per 1,000 reviews on Apify's free plan, Outscraper listed 500 reviews a month free then $3 per 1,000 (archived June 2026 pricing), and the open-source gosom/google-maps-scraper is free on your own machine; for the reviews of one place you are looking at, a Chrome extension such as InsightSocial needs no setup (up to 5,000 reviews per run, though on very large places a run usually ends at a few hundred of the newest; free up to 500 exported rows a month); and Google's own Places API returns at most 5 reviews per place, so it is not an export route.** Owners can list their own locations' reviews through the Business Profile API, once Google approves their access. *Updated October 2026. We make InsightSocial, so we are not neutral. This list starts with Google's own routes, includes the open-source options, and says plainly that cloud tools are the better choice for bulk work. We have not benchmarked the other tools: their prices and limits are what their own pricing pages, Apify listings, GitHub repositories and Chrome Web Store listings said when we checked in October 2026.* ## Quick comparison | Tool | Type | Price (October 2026) | Many places at once | Best for | |---|---|---|---|---| | Business Profile API | Official API | Free, once Google approves access | Your own locations | Owners with a developer | | Places API | Official API | Per request | Yes | 5 reviews per place only | | Apify Google Maps Reviews Scraper | Cloud actor | $0.60 per 1,000 on Apify's free plan, down to $0.15 | Yes | Bulk at low cost | | Outscraper | Cloud + API | 500 free a month, then $3 per 1,000 (archived June 2026) | Yes | Bulk with Zapier and an API | | SerpApi Google Maps Reviews API | API | 250 free searches a month; $25 for 1,000 | Yes | Developers who already use SerpApi | | gosom/google-maps-scraper | Open source | Free | Yes, from searches | Self-hosted, ~300 reviews per place | | HasData | Scraper + API | Free 1,000 credits; from $49/mo | Yes | API with webhooks | | ScrapeHero Cloud | Cloud | 400 free credits once; from $5/mo | Yes | Cheap scheduled runs | | InsightSocial | Chrome extension | Free 500 rows/mo; Pro $9.99 for 10,000 | No, one place per run | The place you have open, replies as rows | | ExportComments | Web app | Free 100 per export; from $23 | One URL per export | Occasional one-off exports | | Adlicio | Extension + web app | Credits per URL; All Access $49.99/mo | Research runs | Ad research | | Instant Data Scraper | Generic extension | Free | No | Rough one-off grabs | Units differ: SerpApi bills per search of up to 20 reviews, and HasData per request. ## What makes Google reviews hard to export - **Sign-in.** Signed out, Google Maps shows only a handful of reviews per place. Signed in, it shows the full list. Browser tools need you signed in; cloud tools handle it on their side. - **Infinite scroll.** Reviews load as the panel scrolls, and the page slows down as the list grows. - **Relative dates.** Google shows "3 months ago", not a date. - **Star-only reviews.** Many reviews have no text. A tool that drops them skews your average. - **The official API's cap.** Google's Places API reference says: "A maximum of 5 reviews can be returned." ## How we put this list together We looked at the tools that rank for Google reviews export and scraper searches, the Apify actors with the most users, and the open-source projects with the most GitHub stars. For each we read its own pricing page, listing or README in October 2026. We did not run other vendors' tools, so this list does not rank them by speed or completeness. ## 1. Google's own routes: Business Profile API and Places API - **Business Profile API (owners).** Its `reviews.list` method returns the reviews of a location your Google account manages, up to 50 per request with a page token for the next page. It is free, but Google must approve your access request first (it asks for a verified profile active for at least 60 days), and you need a Google Cloud project and a developer. Google's Business Profile spreadsheet download covers business information, not reviews. - **Places API (any place).** Place details include reviews, but at most 5, sorted by relevance. Good for showing a few reviews on a website; not an export. **Best for:** owners of many locations with engineering help. Step-by-step options are in [how to export Google reviews](/blog/how-to-export-google-reviews). ## 2. Apify Google Maps Reviews Scraper The most used review actor on Apify (by compass), with about 7,900 users in the last 30 days when we checked. It takes place URLs or IDs and returns reviews with ratings, text, dates and owner responses. Pricing on its listing: $0.60 per 1,000 reviews on Apify's free plan, falling to $0.15 on Apify's top tier, plus a tiny per-run fee. Apify's free plan includes $5 of usage a month, which at that price covers several thousand reviews. **Best for:** bulk review pulls across many places, with runs you can schedule, monitor and call through Apify's API. ## 3. Outscraper A cloud service with a Google Maps Reviews Scraper and API. Its pricing page, as archived in June 2026, lists the first 500 reviews a month free, $3 per 1,000 from 501 to 100,000, and $1 per 1,000 after that, with API access on the paid tiers. Its pages also describe bulk extraction, Zapier and HubSpot integrations. The live site blocks automated visitors, so we could not re-read it in October 2026. **Best for:** agencies and lead-generation teams pulling places and their reviews in bulk. See our [Outscraper comparison](/alternatives/outscraper). ## 4. SerpApi Google Maps Reviews API SerpApi returns a place's reviews as JSON through its Google Maps Reviews API: 8 results on the first page, then up to 20 per page. Its free plan includes 250 searches a month; Starter is $25 a month for 1,000. Each request is a search, so a place with 2,000 reviews takes about 100 requests. **Best for:** developers who already use SerpApi for search results and want reviews from the same API. ## 5. gosom/google-maps-scraper (open source) The most starred open-source Google Maps scraper we found: about 6,500 stars on GitHub, MIT licence, updated in September 2026. It scrapes places from Google Maps searches on your own machine, and its extra-reviews option collects up to about 300 reviews per place. Other open-source options: gaspa93/googlemaps-scraper (about 530 stars, GPL-3.0) and georgekhananaev/google-reviews-scraper-pro (about 340 stars, MIT). **Best for:** developers who want a free, self-hosted bulk scraper and can run a command-line tool. ## 6. HasData HasData sells no-code scrapers and APIs, including a Google Maps Reviews API priced from $2.46 per 1,000 requests down to $0.69 at higher volumes, with plans from $49 a month (200,000 credits) and a free tier of 1,000 credits (checked October 2026). Its Google Maps reviews page mentions webhooks. **Best for:** developers who want a metered API with webhooks. ## 7. ScrapeHero Cloud ScrapeHero Cloud's Google Reviews scraper runs in the cloud with scheduled runs and delivery to Dropbox, S3 or Google Drive. The free plan gives 400 credits once (they do not renew), then plans start at $5 a month for 4,500 credits; its FAQ says 100 reviews of one listing use 11 page credits (checked October 2026). **Best for:** low-cost scheduled pulls with files delivered to cloud storage. ## 8. InsightSocial: the place you have open [InsightSocial's Google Maps Review Scraper](/scraper/google-maps-review-scraper) is a Chrome extension. Sign in to Google, open a place on google.com/maps, click Scrape, and the extension opens the Reviews tab, sorts it newest first and scrolls it for you, keeping each owner reply as its own row and star-only reviews as rows with empty text. In our own runs in October 2026, a place with 89 reviews returned all 89 plus 87 owner replies in 10 seconds; a very large place returned 640 to 720 reviews in two and a half minutes, because the Maps page slows as the list grows and the run stops at a time limit. The hard cap is 5,000 reviews per run. **Price:** scraping is free; exporting uses one credit per row. Free includes 500 rows a month, Pro $9.99 a month (or $7.99 billed yearly) includes 10,000, Studio $49 includes 150,000. Re-exporting a row is free. **Limits:** one place per run; no search across many places, no list of URLs, no API, no scheduling for Google Maps. It needs you signed in to Google, and the tab must stay in front while it runs, unlike most other sites it supports. **Best for:** checking the reviews of a few places you are already looking at (a competitor, a supplier, a location you might buy), with the owner's replies, in a spreadsheet. ## 9. ExportComments ExportComments has a Google reviews export in its web app: paste a place URL and download a file. Free returns up to 100 results per export and 50 exports a month; Personal is $23 once for 3 days at up to 5,000 per export; Premium is $45 a month at up to 50,000 per export (checked October 2026). **Best for:** an occasional export of one place. ## 10. Adlicio Adlicio pulls Google Maps reviews as part of its ad-research product, charged in credits per URL. Its All Access plan, which covers its review sources, is $49.99 a month for 250 credits (checked October 2026). **Best for:** marketers who want review quotes turned into ad angles. See our [Adlicio comparison](/alternatives/adlicio). ## 11. Instant Data Scraper and other generic extensions Instant Data Scraper (free, 1,000,000 users on its Chrome Web Store listing) can read the reviews panel as far as you get it to load, but it guesses columns from the page and does not know review fields. Lead-generation extensions such as Maps Scraper & Leads Extractor (100,000 users) are built for business listings; we did not confirm that they export review text. **Best for:** a rough grab when nothing else is set up. ## Detailed comparison | | Business Profile API | Apify | Outscraper | SerpApi | gosom (open source) | InsightSocial | ExportComments | |---|---|---|---|---|---|---|---| | Whose reviews | Your locations | Any | Any | Any | Any | The place you open | Any | | Bulk input | Your locations | Yes | Yes | Yes (code) | Yes (searches) | No | No | | Reviews per place | All | Configurable | Configurable | Paged, 20 per request | About 300 | Up to 5,000 | 100 to 250,000 by plan | | Needs Google sign-in | Owner account | No | No | No | No | Yes | No | | Owner replies | Yes | Yes | Not checked | Not checked | Not checked | Own rows | Not checked | | Schedules | Your code | Yes | Not checked | Your code | Your code | No | Premium and up | | Price | Free (approval needed) | From $0.60 per 1,000 | 500 free, then $3 per 1,000 (archived) | 250 searches free | Free | 500 rows free, $9.99 for 10,000 | 100 per export free | ## Which one should you pick? - **Your own locations:** the Business Profile API. - **Hundreds of places, recurring:** Apify or Outscraper; ScrapeHero for cheap scheduled files. - **Free and self-hosted:** gosom/google-maps-scraper. - **Reviews in an app you are building:** SerpApi or HasData. - **A few places you are looking at, with owner replies, no setup:** InsightSocial. - **One place, once:** ExportComments' free tier. ## FAQ **What is the best free Google Maps review scraper?** For bulk, the open-source gosom/google-maps-scraper is free on your own machine, and Apify's free $5 a month covers several thousand reviews with its Google Maps Reviews Scraper. For one place in your browser, InsightSocial's free plan exports 500 rows a month. **Is there a Chrome extension that scrapes Google Maps reviews?** Yes, but only signed in: Google Maps shows a handful of reviews to signed-out visitors. InsightSocial reads up to 5,000 reviews of the place you open, with the tab in front. Generic extensions such as Instant Data Scraper can grab what is loaded on screen. **Why does the Google Places API only return 5 reviews?** That is the API's documented limit. Owners use the Business Profile API for their own locations; everyone else uses a scraper. **Can I scrape Google reviews without signing in?** Cloud tools and APIs do not need your Google account. In a browser, Google Maps shows only a few reviews to signed-out visitors, so browser tools need you signed in. **Which tool is cheapest for a lot of Google reviews?** Among the hosted tools we checked, Apify's Google Maps Reviews Scraper, from $0.60 per 1,000 down to $0.15 on its top tier, and Outscraper's $1 per 1,000 after 100,000 reviews (archived June 2026 pricing). For up to 10,000 rows a month at a flat price, InsightSocial Pro is $9.99. Related: [how to export Google reviews](/blog/how-to-export-google-reviews), [best Trustpilot review scrapers](/blog/best-trustpilot-review-scrapers), [best free review scraper Chrome extensions](/blog/best-free-review-scraper-chrome-extensions). --- # Best Trustpilot Review Scrapers and Exporters in 2026 Source: https://www.insightsocial.app/blog/best-trustpilot-review-scrapers, updated 2026-10-18 > Trustpilot review scrapers compared: the official export, Apify actors, Outscraper, ExportComments and Chrome extensions. Prices and the 200-review limit. - **Published**: 2026-10-17 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: trustpilot, reviews, comparison, scraping, tools - **Reading time**: 13 min read - **Web version**: https://www.insightsocial.app/blog/best-trustpilot-review-scrapers --- **The best Trustpilot review scraper depends on whose reviews you need and how many companies: for your own company, Trustpilot Business's export (Premium and Enterprise plans) is the official route; for many companies on a pipeline, Apify actors from $0.14 to $0.75 per 1,000 reviews or Outscraper's pay-as-you-go plan fit; and for one company page at a time without code, a Chrome extension such as InsightSocial (free up to 500 exported rows a month) or T-Reviews Scraper is the shortest route.** Whatever you pick, check how it handles Trustpilot's signed-out limit of 10 pages per filter, about 200 reviews, which is why so many exports stop at 200. *Updated October 2026. We make InsightSocial, so we are not neutral: this list puts the official and open-source routes first, gives each tool a "best for", and says where another tool is the better fit. We have not benchmarked the other tools; their prices, limits and user counts are what their own pricing pages, Apify listings and Chrome Web Store listings said when we checked in October 2026.* ## Quick comparison | Tool | Type | Price (October 2026) | Gets past 200 reviews? | Best for | |---|---|---|---|---| | Trustpilot Business export | Official, in-app | Premium or Enterprise plan | Yes, your own company | Your own reviews | | InsightSocial | Chrome extension | Free 500 rows/mo; Pro $9.99 for 10,000 | Splits by language and stars; very large companies often stop short | One company page at a time, replies as rows | | Apify: Automation Lab | Cloud actor | $0.575 per 1,000 on Apify's free plan, down to $0.14 | Not stated on its listing | Cheap bulk pulls | | Apify: memo23 | Cloud actor | $0.75 per 1,000, down to $0.50 | Says yes ("past the ~200-review web cap") | All reviews, incremental syncs | | Apify: Black Falcon Data | Cloud actor | $0.25 per 1,000 flat | Says yes | Lowest per-review price we found | | Outscraper | Cloud + API | 100 free, then $3 per 1,000 (archived Dec 2025) | Not stated | Lists of companies, API | | ExportComments | Web app + API | Free 100 per export; $23 for 3 days; $45/mo | Up to 5,000–250,000 per export by plan | Occasional one-off exports | | reviewsextractor.com | Extension + web | Free 25 per extraction (G2, Trustpilot, Capterra); $9/mo | Up to 2,500 per extraction | Trustpilot plus B2B review sites | | T-Reviews Scraper | Chrome extension | Free with in-app purchases | Not stated | Trustpilot-only, batch URLs | | Adlicio | Extension + web app | All Access $49.99/mo for 250 credits | Not stated | Ad research from reviews | | Open-source Python scripts | Code | Free | Only as far as the public pages go | Developers | ## Why Trustpilot exports stop at 200 reviews Signed out, a Trustpilot company page lists 20 reviews a page and stops at page 10. We checked it in October 2026: page 10 of a large company's reviews loads, and page 11 redirects to Trustpilot's login page. That is 200 reviews per filter, and it is the wall behind threads such as r/scrapingtheweb's "Is it actually possible to scrape more than 200 Trustpilot reviews??" (September 2026). Because the limit is per filter, a tool can reach further by changing the filter: each language and each star rating is its own list of up to 10 pages. Some Apify actors say they get past the cap another way. Ask any tool how it handles the limit before you trust a total. ## How we put this list together We looked at the tools that rank for Trustpilot export searches, the Apify actors with the most users, and the Chrome Web Store extensions that name Trustpilot. For each we read its own page in October 2026: the price, the free tier, the limits it states and, for Apify and the Chrome Web Store, the user count. We did not run other vendors' tools, so this is not a ranking by speed or completeness; it is a map of what each tool says it does, at what price, with our own numbers only for InsightSocial. ## Trustpilot Business export: the official route for your own company If the company is yours, start here. Trustpilot's help centre says the review export "is included in the Premium and Enterprise plans": in Trustpilot Business, go to Manage reviews > Service reviews, open the inbox, click Export, pick a date range and download a CSV. **Limits:** only your own company, only on those plans, and Trustpilot limits how its reviews may be displayed on other platforms, so check its guidelines before you republish them. **Best for:** analysing your own reviews with Trustpilot's own data. Our step-by-step: [how to export Trustpilot reviews](/blog/how-to-export-trustpilot-reviews). ## InsightSocial: one company page at a time, replies kept [InsightSocial's Trustpilot Review Scraper](/scraper/trustpilot-review-scraper) is a Chrome extension: open any `trustpilot.com/review/` page (or a country site such as uk.trustpilot.com), click Scrape, and the reviews land in your dashboard, ready to export to CSV, Excel, JSON or Google Sheets. It reads the review pages over HTTP and keeps going in a background tab. To get past the 200-review limit it goes through each language and star rating separately. In our own runs in October 2026, a company with 83 reviews returned all 83 plus its 5 replies in 4 to 7 seconds, large companies came in at about 40 reviews a second, and a company with 20,624 reviews returned 4,994. That last number is the honest one: on very large companies it often does not reach every review. Each review comes with its rating, title, text, date, date of experience, reviewer country, language, verified flag and helpful votes; the company's replies are rows of their own; the page's TrustScore and star distribution come along. **Price:** scraping is free; exporting uses one credit per row. Free includes 500 rows a month, Pro is $9.99 a month (or $7.99 billed yearly) for 10,000, and a row you already exported is free to export again. **Limits:** one company per run (no list of URLs), no scheduling, no API for Trustpilot. No sentiment column in the export; on Pro, Ask your data answers sentiment and theme questions about a finished run. **Best for:** researchers and marketers who look at a few companies at a time and want the replies and fields kept, at a flat monthly price. ## Apify actors: per-review pricing, many companies, schedules The Apify Store has dozens of Trustpilot actors from independent developers. They run in Apify's cloud, take lists of companies, and can be scheduled or called from Apify's API. Three of the most used, with prices from their own listings (Apify's free plan includes $5 of usage a month; prices fall on paid tiers): - **Automation Lab, Trustpilot Reviews Scraper:** about 870 users in the last 30 days. $0.575 per 1,000 reviews on the free plan, down to $0.14, plus $0.005 per run. - **memo23, Trustpilot All Reviews Scraper:** about 690 users. $0.75 per 1,000 on the free plan, down to $0.50, plus a start fee. Its description says it exports "every Trustpilot review — past the ~200-review web cap", with an incremental mode for daily syncs and optional AI pain-point analysis at extra cost. - **Black Falcon Data, Trustpilot Reviews Scraper:** about 190 users. A flat $0.25 per 1,000 reviews, and it also says it gets past the 200-review limit. **Best for:** developers and data teams who need many companies, a schedule or an API. At these prices, cost is rarely the issue; setup and checking the output are. ## Outscraper: pay as you go, with an API Outscraper is a cloud scraping service with a Trustpilot reviews scraper and a Trustpilot Reviews API. Its Trustpilot page, as archived in December 2025, listed the first 100 reviews free, then $3 per 1,000 up to 50,000 and $1 per 1,000 beyond. Its live site blocks automated visitors, so we could not re-check those prices in October 2026. It takes lists of companies and integrates with Zapier. **Best for:** teams already using Outscraper for Google Maps data who want Trustpilot on the same bill. See our [Outscraper comparison](/alternatives/outscraper). ## ExportComments: paste a URL, get a file ExportComments exports Trustpilot reviews from a company URL in its web app. Its plans, read from its pricing page in October 2026: free up to 100 results per export and 50 exports a month; Personal $23 once for 3 days at up to 5,000 per export; Premium $45 a month at up to 50,000 per export, with scheduled exports; Business $199 a month at up to 250,000 per export with API access. **Best for:** an occasional export where a 3-day pass is cheaper than a subscription. More in our [ExportComments alternatives](/blog/exportcomments-alternatives) guide. ## reviewsextractor.com: Trustpilot and B2B review sites reviewsextractor.com runs a Trustpilot exporter (its Chrome Web Store listing, "Trustpilot Reviews Exporter", showed 134 users and a 4.5 rating) alongside G2, Capterra, TrustRadius and other software-review sites. Free extractions return 25 reviews, on G2, Trustpilot and Capterra only; Starter is $9 a month for one site at up to 2,500 reviews per extraction, $15 for all sites, $25 adds AI sentiment and themes, and $99 adds weekly competitor monitoring. **Best for:** SaaS teams who need Trustpilot and G2 or Capterra in one tool. InsightSocial does not cover G2 or Capterra. ## T-Reviews Scraper: a Trustpilot-only extension T-Reviews Scraper (by nifty.codes) exports Trustpilot reviews, companies and ratings to CSV, XLSX or JSON, with automatic pagination, batch URLs and monitoring, according to its listing, which showed 478 users and a 4.2 rating from 9 ratings. It is free with in-app purchases; the listing does not state the price. Other Trustpilot-only extensions on the Chrome Web Store include Trustpilot Reviews Downloader (244 users; free for the current page, paid for up to 300 pages) and Trustpilot Reviews Exporter by an independent developer (1,000 users and a 4.5 rating from 25 ratings, free with in-app purchases; its listing says it needs a Trustpilot login). **Best for:** Trustpilot-only work in the browser, including batch URLs, which InsightSocial does not take. ## Adlicio: reviews as ad research Adlicio scrapes reviews and comments from many sources and ranks them into ad angles, objections and hooks. It charges credits per URL; its All Access plan, which covers its review sources, is $49.99 a month for 250 credits (checked October 2026). **Best for:** ecommerce marketers who want angles, not a spreadsheet. See our [Adlicio comparison](/alternatives/adlicio). ## Bright Data: scraper API at enterprise scale Bright Data's Trustpilot Scraper API shares its Web Scraper API pricing: 5,000 records a month free, then $1.50 per 1,000 records pay as you go, or $499 a month with 384,000 records included (checked October 2026). **Best for:** companies that already run Bright Data for other collection and want Trustpilot in the same pipeline. ## Open-source scripts GitHub has small Trustpilot scrapers in Python, such as irfanalidv/trustpilot_scraper (22 stars, MIT licence, also on PyPI) and hakimkhalafi/trustpilot-scraper (29 stars, last updated in 2021). They read the public pages, so they inherit the 10-pages-per-filter limit unless you add filter splitting yourself, and Trustpilot's page structure changes over time. **Best for:** developers who want to own the code and accept maintaining it. ## Detailed comparison | | Official export | InsightSocial | Apify actors | Outscraper | ExportComments | Chrome extensions (single-site) | |---|---|---|---|---|---|---| | Whose reviews | Your company | Any company page | Any | Any | Any | Any | | Many companies in one go | No | No | Yes | Yes | One URL per export | Some (batch URLs) | | Schedules | No | No | Yes | Not checked | Premium and up | Some (monitoring) | | API | Trustpilot's business APIs | No | Yes | Yes | Business plan | No | | Company replies | Yes | Own rows | Varies by actor | Not checked | Not checked | Varies | | Free tier | No | 500 rows a month | $5 of usage a month | 100 reviews | 100 per export | Usually first page | | Billing | Plan | Exported row | Per review | Per review | Per export size | One-time or monthly | | Sentiment or AI | No | No column; Ask your data on Pro | memo23 add-on | No | Not checked | Some | ## Which one should you pick? - **Your own company, on Premium or Enterprise:** Trustpilot Business's export. - **A few competitor companies, in a spreadsheet, replies kept:** InsightSocial or T-Reviews Scraper. - **Dozens of companies, daily, into a database:** an Apify actor, or Outscraper if you already use it. - **Every review of a 20,000-review company:** one of the Apify actors that says it gets past the cap; check its output against the company's count. - **One export this month and nothing after:** ExportComments' 3-day pass. - **Trustpilot plus G2 or Capterra:** reviewsextractor.com. ## FAQ **What is the best free Trustpilot review scraper?** For a few hundred reviews, InsightSocial's free plan (500 exported rows a month) and the free tiers of Trustpilot-only extensions cover it. ExportComments' free tier returns up to 100 reviews per export, and Apify's free plan includes $5 of usage a month, enough for thousands of reviews at the per-review prices above. **Can any tool export all Trustpilot reviews of a big company?** Several Apify actors say they get past the 200-review limit. Filter-splitting tools such as InsightSocial reach far beyond 200 but often not every review on very large companies. Compare the exported count with the company's total before relying on it. **Is it legal to scrape Trustpilot reviews?** Reviews on company pages are public, but Trustpilot's terms and data-protection law apply to how you store and use them, particularly reviewer names. Check Trustpilot's guidelines before you display exported reviews elsewhere. **Does Trustpilot have an API for reviews?** Trustpilot offers APIs to its business customers for their own reviews. For other companies' reviews, people use scrapers. **Which Trustpilot scraper includes the company's replies?** InsightSocial puts each reply in its own row under the review it answers. For other tools, check a sample export: some return replies as a field, some leave them out. **Which tool is cheapest per review?** Among the tools we checked, Black Falcon Data's Apify actor at a flat $0.25 per 1,000 reviews. For a flat monthly price instead, InsightSocial Pro is $9.99 for 10,000 exported rows. Related: [how to export Trustpilot reviews](/blog/how-to-export-trustpilot-reviews), [best Google Maps review scrapers](/blog/best-google-maps-review-scrapers), [best free review scraper Chrome extensions](/blog/best-free-review-scraper-chrome-extensions). --- # How to Download Amazon Reviews to Excel or CSV (2026 Guide) Source: https://www.insightsocial.app/blog/how-to-download-amazon-reviews, updated 2026-10-18 > Download Amazon reviews to Excel, CSV or Google Sheets: why exports now stop at a dozen reviews, what signing in changes, and three ways to get them all. - **Published**: 2026-10-17 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: amazon, reviews, export, tutorial, ecommerce - **Reading time**: 10 min read - **Web version**: https://www.insightsocial.app/blog/how-to-download-amazon-reviews --- **To download Amazon reviews to Excel, sign in to Amazon first and use an exporter that pages through the product's review pages by star rating and sort order: signed out, Amazon now shows only the dozen or so reviews on the product page, and signed in it serves at most 10 pages of 10 reviews per sort and star filter.** The InsightSocial Chrome extension does this for the product you open, across 20 Amazon storefronts, collecting up to about 1,200 reviews per product (before duplicates are removed) with the verified-purchase flag, helpful votes and variant, exported to CSV, Excel, JSON or Google Sheets and free up to 500 rows a month. ## TL;DR: ways to download Amazon reviews | Method | Whose products | Cost | Limit | Skill | |---|---|---|---|---| | Chrome extension (InsightSocial and single-site exporters) | Any product you open | Free tiers, then about $10/month | What Amazon shows your account | None | | Cloud scrapers and scraper APIs (Apify, Bright Data, Outscraper) | Any product, many at once | Per 1,000 reviews | Varies by tool | Low to code | | Your own script | Any | Your time | Needs a signed-in session | Code | | Copy and paste | Any | Free | Your patience | None | ## Why most Amazon review exporters return 13 reviews now If an Amazon review tool used to give you hundreds of reviews and now gives you about a dozen, Amazon changed, not the tool. Amazon now shows its full review pages (`/product-reviews/…`) only to signed-in shoppers. A signed-out visitor sees the handful of reviews on the product page itself: in our own runs in October 2026, 13 on a typical product, and on amazon.com sometimes none at all. People started reporting the change in 2024, in threads such as r/learnpython's "Scrape Amazon Reviews". Two consequences: 1. **Sign in before you export.** Any tool that reads Amazon from your browser needs your Amazon session to see more than the product page. A cloud tool needs its own signed-in sessions or a reviews data source. 2. **Even signed in, there are ceilings.** Amazon serves at most 10 pages of 10 reviews for each sort order and star filter. A tool that reads every star rating (1 to 5) under both "Top reviews" and "Most recent" can reach far more than 100, but not an unlimited number on a product with 40,000 reviews. Amazon may also stop showing reviews to an account that reads a lot of pages, with a notice asking you to verify the account. A careful tool stops at that notice and keeps what it collected. ## What an Amazon reviews export includes One row per review, with: - **Rating**, 1 to 5 stars, read correctly on every storefront ("5,0 von 5 Sternen" becomes 5) - **Review title** and **text** - **Reviewer name** - **Date** and the **country** the review was written in ("Reviewed in Germany on 3 May 2026") - **Verified Purchase** flag - **Helpful votes** - **Variant** (size, colour, style) when Amazon shows it - **Permalink** to the review - The product's **title, brand, average rating and rating count** When Amazon shows a review translated, a good exporter keeps the original text too. Amazon reviews have no seller-reply rows: unlike Trustpilot or Google, sellers do not reply publicly under each review. ### What the rows look like *Illustrative rows: the shape of an export, with made-up names and text, not real reviewers.* | Rating | Title | Posted | Country | Verified | Helpful | Variant | |---|---|---|---|---|---|---| | 2 | Zip broke after a month | 2026-09-18 | United States | Yes | 41 | Colour: Black, Size: Large | | 5 | Exactly as described | 2026-09-12 | United States | Yes | 3 | Colour: Navy, Size: Medium | | 4 | Gutes Preis-Leistungs-Verhältnis | 2026-09-09 | Germany | Yes | 0 | Farbe: Schwarz | | 1 | Not the same as the photos | 2026-08-30 | United Kingdom | No | 12 | Colour: Grey | ## Can you export Amazon reviews directly? No. Amazon's product and review pages have no export button, so every method below reads the review pages for you, either in your own browser or from a cloud service. Competitor research is the most common reason to export Amazon reviews, and it is also the case no first-party tool covers. ## Method 1: A Chrome extension (any product you open) Browser extensions read Amazon with your own signed-in session, which is why they still work after the login change. The Chrome Web Store has many single-site Amazon exporters (search "Amazon review exporter"), usually with a free tier that caps reviews per click and a paid tier: amazonreviews.cc's Pro, for example, is $9.99 a month for 100 reviews per click. Here is how it works with [InsightSocial's Amazon Review Scraper](/scraper/amazon-review-scraper): 1. **Install InsightSocial** from the Chrome Web Store and sign in with Google. 2. **Sign in to Amazon in the same browser**, then open the product: any `/dp/…` page, or its `/product-reviews/…` page. 3. **Allow that Amazon storefront once.** Chrome asks you to let InsightSocial read it the first time; it asks for that one storefront, only when you use it. 4. **Click Scrape.** The extension reads the product page, then the review pages: two unfiltered views (top and most recent), then each star rating from 1 to 5 under both sorts, up to 10 pages each. It pauses between pages, removes duplicates, and keeps going if you switch to another tab. 5. **Export from your dashboard** to CSV, Excel, JSON or Google Sheets. **Storefronts:** amazon.com, .co.uk, .ca, .de, .fr, .it, .es, .nl, .se, .pl, .com.tr, .ae, .sa, .eg, .in, .co.jp, .com.au, .sg, .com.br and .com.mx. Dates, ratings and helpful counts are read in each storefront's own language. **How many reviews:** up to about 1,200 per product before duplicates are removed (12 views of up to 100 reviews), within a 6-minute run. The panel tells you when Amazon's per-filter ceiling cut a view short ("collected X of Y written reviews"), and stops cleanly if Amazon shows the review-access notice. **What it costs:** scraping and reading results in the dashboard are free on every plan; exporting uses one credit per row. Free includes 500 a month, Pro $9.99 a month (or $7.99 billed yearly) includes 10,000, Studio $49 includes 150,000, and one-time packs run from 250 rows for $2 to 25,000 for $39. A row you already exported is free to export again. Ten competitor products at about 800 reviews each is 8,000 rows: one month of Pro. **What it does not do:** one product per run, no list of ASINs, no review images or videos. ## Method 2: Cloud scrapers and APIs (many products, pipelines) For hundreds of ASINs, scheduled runs or an API, use a cloud service: - **Apify actors** such as junglee's Amazon Reviews Scraper (about 2,200 users in the last 30 days; $6 per 1,000 reviews on Apify's free plan, down to $1 on its top tier) and Axesso's ($0.90 per 1,000), which take lists of products (checked October 2026). - **Bright Data** sells an Amazon reviews scraper API: 5,000 records a month free, then $1.50 per 1,000 records pay as you go (checked October 2026). - **Outscraper** lists Amazon reviews free for the first 500 a month, then $2 per 1,000 up to 5,000 and $1 per 1,000 after (its pricing page as archived in June 2026). They cost more per review than a browser extension at small volumes, but they take lists of products and run without your browser open. ## Method 3: Write your own script Python tutorials for scraping Amazon reviews with `requests` and BeautifulSoup still circulate, but most predate the login change: run signed out, they return the product page's few reviews or a captcha. A script now needs a signed-in session, careful pacing and captcha handling, which is why most people who need more than a few products use a tool. ## Export formats: Excel, CSV, Google Sheets - **Excel (.xlsx):** dates stay dates and non-English text stays intact. The best choice for a one-off analysis. - **CSV:** universal. Open it in Excel through Data > From Text/CSV with UTF-8 selected, or German umlauts and Japanese text will break. - **Google Sheets:** InsightSocial syncs a run straight to a sheet, handy for sharing with a sourcing team or agency. - **JSON:** for scripts, databases and LLM pipelines. ## Working with a large Amazon review dataset - **Filter to verified purchases** for product-quality questions; keep the rest for marketing language. - **Group by variant.** Complaints often belong to one size or colour. - **Read the 1- to 3-star reviews in full.** That is where the defects, sizing problems and delivery issues are. - **Use the country column** when a product sells on several storefronts; expectations differ by market. - **Compare your export with the rating count.** Amazon's rating count includes star-only ratings, which have no review text, so your export will always have fewer rows than the number on the page. ## Troubleshooting **Only about 13 reviews came back.** You are signed out of Amazon in that browser, or Amazon is limiting your account. Sign in and run it again. **"Amazon is limiting review access for this account".** Amazon shows a button on its reviews page to verify the account. Once access is restored, run it again; the rows you already have stay in your dashboard. **A captcha appeared.** Reload the product page, solve it, then start again. **Fewer reviews than the product's ratings count.** Most Amazon ratings are star-only and have no text; the count on the page includes them. ## FAQ **Can I download Amazon reviews to Excel for free?** Yes, within free tiers. InsightSocial's free plan exports up to 500 rows a month, and most single-site Amazon exporters on the Chrome Web Store have a free tier that caps reviews per click. **Why do I need to sign in to Amazon to export reviews?** Amazon shows its full review pages only to signed-in shoppers. Signed out, you see only the dozen or so reviews on the product page. **How many Amazon reviews can I export per product?** Amazon serves at most 100 reviews per sort order and star filter. InsightSocial reads 12 such views, so up to about 1,200 per product before duplicates are removed. **Does the export include the Verified Purchase badge?** Yes, as a Verified column: yes when Amazon marks the review as a verified purchase. **Which Amazon countries are supported?** Twenty storefronts, from amazon.com and .co.uk to .co.jp, .in, .com.br and .com.mx. Chrome asks for permission the first time you use each one. **Can I export reviews for many ASINs at once?** Not with InsightSocial, which runs one product per run. Use a cloud scraper that takes a list of ASINs for that. **Does it download review images?** No. InsightSocial exports review text and fields, not images or videos. Related guides: [best Amazon review scrapers and exporters](/blog/best-amazon-review-scrapers), [how to export Etsy shop reviews](/blog/how-to-export-etsy-reviews), [how to export Trustpilot reviews](/blog/how-to-export-trustpilot-reviews), and all [review and comment scrapers](/scraper/reviews). --- # How to Export Etsy Shop Reviews to a Spreadsheet (2026) Source: https://www.insightsocial.app/blog/how-to-export-etsy-reviews, updated 2026-10-18 > Export any Etsy shop's or listing's reviews to CSV, Excel or Google Sheets, with seller replies, item names and photos: the Open API or a Chrome extension. - **Published**: 2026-10-17 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: etsy, reviews, export, tutorial, ecommerce - **Reading time**: 7 min read - **Web version**: https://www.insightsocial.app/blog/how-to-export-etsy-reviews --- **Etsy's shop and listing pages have no review export button; developers can pull any shop's or listing's reviews through the Etsy Open API v3, and without code a browser extension that replays Etsy's "View all reviews" panel exports the reviews with their rating, date, item and seller reply.** The InsightSocial Chrome extension does this for the Etsy listing or shop you open, newest first, up to 5,000 reviews per run, and exports to CSV, Excel, JSON or Google Sheets, free up to 500 rows a month. ## TL;DR | Method | Whose reviews | Cost | Limit | Skill | |---|---|---|---|---| | Etsy Open API v3 | Any shop or listing | Free API key (Etsy reviews the app) | 100 reviews per request, paged | Code | | Chrome extension (InsightSocial or single-site exporters) | Any shop or listing | Free tiers | 5,000 per run (InsightSocial) | None | | Cloud scrapers (Apify, Outscraper) | Any, many at once | Per 1,000 reviews | Varies | Low | ## Can you export Etsy reviews directly? Not as a file from the shop pages. Etsy's documented route to review data is its Open API v3: the `getReviewsByShop` and `getReviewsByListing` endpoints return a shop's or a listing's public reviews with an API key, up to 100 per request (checked on developers.etsy.com, October 2026). That needs a developer app and a script. That is why the question keeps coming up in r/Etsy: sellers want a clean sheet of their own reviews, for a website testimonial page, a product-photo shortlist or a complaint audit, and Etsy's own tools give them something else. ## What an Etsy review export includes - **Rating**, 1 to 5 stars - **Review text** (many Etsy reviews are star-only, keep them) - **Reviewer name** as Etsy shows it - **Date** - **Would recommend** answer, when the buyer gave one - **Item**: the listing title and link, on shop-wide exports - **Photo** link, when the buyer added a photo - **The seller's reply**, as its own row under the review it answers - The shop's or listing's **average rating and review count** Etsy reviews have no title and no "verified" badge (only buyers can leave a review on Etsy), so those columns stay empty. ### What the rows look like *Illustrative rows: the shape of an export, with made-up names and text, not real reviewers.* | Depth | Author | Rating | Posted | Text | Item | Would recommend | |---|---|---|---|---|---|---| | 0 | Buyer A | 5 | 2026-09-28 | Arrived quickly, the colour is exactly as pictured. | Linen apron, sage | Yes | | 1 | (seller) | | | Thank you, enjoy it! | | | | 0 | Buyer B | 3 | 2026-09-21 | Nice fabric but runs small. | Linen apron, rust | | | 0 | Buyer C | 5 | 2026-09-15 | | Linen napkins, set of 4 | Yes | The seller's reply is a row at depth 1 under the review it answers, and the star-only review stays as a row with an empty text cell. ## Method 1: The Etsy Open API (any shop, with code) 1. Create an app at developers.etsy.com to get an API key. Etsy reviews new apps before the key works beyond your own shop, which can take weeks. 2. Look up the shop's numeric `shop_id`. 3. Call `GET https://openapi.etsy.com/v3/application/shops/{shop_id}/reviews` with your key in the `x-api-key` header and `limit=100`, then raise `offset` by 100 until no more reviews come back. 4. Write the results to CSV. Check the fields it returns against what you need; it is built for developers, not for a spreadsheet. ## Method 2: A Chrome extension (any shop or listing) With [InsightSocial's Etsy Review Scraper](/scraper/etsy-review-scraper): 1. **Install InsightSocial** and sign in with Google. 2. **Open the listing or the shop:** any `etsy.com/listing/…` page for that item's reviews, or `etsy.com/shop/…` for the reviews across everything the shop sells. Country paths such as `/uk/` or `/de/` work too. No Etsy account is needed. 3. **Allow Etsy once** when Chrome asks. 4. **Click Scrape.** The extension reads the same data as Etsy's "View all reviews" panel, newest first, with a running count. The run keeps going if you switch tabs. 5. **Export** from your dashboard to CSV, Excel, JSON or Google Sheets. **How many and how fast:** in our own runs in October 2026, a listing returned 1,028 reviews and 403 seller replies in 41 seconds, with its tab in the background, and a shop run collected about 45 reviews a second. A run stops at 5,000 reviews or 3 minutes. On a very long shop run Etsy may ask the browser to prove it is human; the run ends there and keeps every review it collected. Finish the check on the page and run it again. **What it costs:** scraping is free; exporting uses one credit per row. Free includes 500 a month, Pro $9.99 a month includes 10,000, Studio $49 includes 150,000, and one-time packs start at 250 rows for $2. Re-exporting a row you already exported is free. ## Method 3: Cloud scrapers Apify has several third-party Etsy review actors, and Outscraper has an Etsy reviews page; they take lists of shops or listings and suit bulk jobs. On Apify, the two most used Etsy review actors cost $4 and $5 per 1,000 reviews when we checked in October 2026. ## Formats Excel keeps dates and accents intact; CSV is universal (open with UTF-8); Google Sheets is easiest to share; JSON suits a script. For a testimonials page, filter to 5 stars with text, then sort by date. ## Tips - **Shop runs for the big picture, listing runs for one product.** A shop export names the item on each row, so you can pivot reviews by product. - **Separate seller replies** before you count or average. - **Photos:** filter to rows with a photo link to find buyer images you can ask permission to reuse. - **Watch the trend.** Group by month; a sudden run of 3-star reviews often points to one listing or a supplier change. ## Troubleshooting **"Etsy's bot check stopped the run".** Reload the page, complete any check Etsy shows, then run it again. **Fewer reviews than the shop shows.** Long shops can stop at Etsy's bot check or the 5,000-review cap; the run says "Stopped at 5,000 reviews — Etsy lists N" when the cap is the reason. **The listing's count differs from the shop's.** A listing shows its own reviews; a shop shows reviews across all its items. ## FAQ **How do I download all my Etsy reviews?** Etsy's documented route is the Open API (a developer key and a script). Without code, open your shop page with InsightSocial and export up to 5,000 reviews per run, free up to 500 rows a month. **Can I export another shop's Etsy reviews?** Yes. Etsy reviews are public, and an extension reads the same reviews any visitor can see. **Are seller replies included?** Yes, each reply is its own row under the review it answers. Etsy does not show a date on seller replies. **Do I need an Etsy API key?** Not with a browser extension. The Etsy Open API needs a developer key and code. **Can I export reviews from many Etsy shops at once?** Not in one InsightSocial run; open each shop and run it. Cloud scrapers take lists. Related: [how to download Amazon reviews to Excel](/blog/how-to-download-amazon-reviews), [best free review scraper Chrome extensions](/blog/best-free-review-scraper-chrome-extensions), and all [review and comment scrapers](/scraper/reviews). --- # How to Export Google Reviews to Excel or Sheets (2026) Source: https://www.insightsocial.app/blog/how-to-export-google-reviews, updated 2026-10-18 > Export Google reviews to Excel, CSV or Google Sheets: the Business Profile API for your own places, the Places API's 5-review cap, and tools for any place. - **Published**: 2026-10-17 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: google maps, google reviews, reviews, export, tutorial - **Reading time**: 11 min read - **Web version**: https://www.insightsocial.app/blog/how-to-export-google-reviews --- **Google has no "export reviews" button: business owners can pull their own locations' reviews through the Business Profile API, while the Places API returns at most 5 reviews per place, so to export all reviews of any business into Excel or Google Sheets you need a tool that scrolls the place's Reviews tab for you.** The InsightSocial Chrome extension does that for the place you open in Google Maps, keeping each owner reply as its own row, up to 5,000 reviews per run, exported to CSV, Excel, JSON or Google Sheets and free up to 500 rows a month. ## TL;DR: ways to export Google reviews | Method | Whose reviews | Cost | Limit | Skill | |---|---|---|---|---| | Business Profile API | Locations you own or manage | Free API; needs Google's approval and a developer | 50 reviews per request, paged | Code | | Google Places API | Any place | Per request | **5 reviews per place** | Code | | Cloud scrapers and APIs (Outscraper, Apify, SerpApi) | Any place, many at once | Per 1,000 reviews or per search | Varies by tool | Low to code | | Open source (gosom/google-maps-scraper) | Any place, from searches | Free, your own machine | About 300 reviews per place | Command line | | Chrome extension (InsightSocial) | The place you open | Free up to 500 rows/month, Pro $9.99 for 10,000 | 5,000 reviews per run; Google sign-in | None | | Copy and paste | Any | Free | Your patience | None | ## Can you export Google reviews directly? Not from Google Maps or Search. A place's reviews are public, but nothing on the page downloads them. Google's official routes are built for business owners, plus one API that caps reviews at 5: - **Business Profile API.** Its `reviews.list` method returns the reviews of a location your Google account manages, up to 50 per request with a page token for the next page. Access is not automatic: you request it from Google, and Google asks for a verified profile that has been active for at least 60 days. - **Business Profile spreadsheet download.** Business Profile lets you download your profiles to a spreadsheet, but Google's help page describes that file as business information (names, addresses, hours, photos), not reviews. - **Places API.** For any place, the Places API returns place details including reviews, but Google's reference is explicit: "A maximum of 5 reviews can be returned." That is enough for a widget, not for an analysis. Some owner guides also describe requesting Business Profile data through Google Takeout, which arrives as JSON files. We could not find a Google help page that documents reviews in that export, so if you try it, check the count in the file against your listing. So the question splits in two. For **your own locations**, the Business Profile API gives you Google's own data. For **anyone else's place**, a competitor, a supplier, a location you are about to buy, you need a scraper. ## What data a Google reviews export includes From the public Reviews tab of a place, a good export gives you one row per review with: - **Rating**, 1 to 5 stars - **Review text**, when there is any. Many Google reviews are star-only; keep them as rows with an empty text cell, or your average rating will be wrong - **Reviewer name** as Google shows it - **Date**. Google shows relative dates ("3 months ago"); good tools keep that wording next to a parsed date - **The owner's reply**, ideally as its own row under the review it answers - **Permalink** to the review - The place's **name, address, average rating and total review count** Google reviews have no title field, so a "title" column in an export will be empty. Reviewer emails and phone numbers are never public. ### What the rows look like *Illustrative rows: the shape of an export, with made-up names and text, not real reviewers.* | Depth | Author | Rating | Posted (Google's wording) | Text | Likes | |---|---|---|---|---|---| | 0 | Visitor A | 5 | 2 weeks ago | Friendly staff and the best flat white in the area. | 3 | | 1 | (owner) | | 2 weeks ago | Thank you, see you soon! | | | 0 | Visitor B | 2 | a month ago | Waited 25 minutes for a table that was booked. | 7 | | 0 | Visitor C | 4 | 3 months ago | | 0 | The star-only review (Visitor C) stays as a row, so averages and counts match the place's own figures. ## Method 1: The Business Profile API (your own locations) If you manage your locations' Business Profiles, the Business Profile API lists each location's reviews, 50 at a time, and can keep a database up to date. It needs a Google Cloud project, API access that Google approves on request, and someone to write the code. It does not return other businesses' reviews. ## Method 2: Cloud scrapers and open source for many places Cloud tools take a list of places, or a search such as "dentists in Austin", and return the reviews of every place in a file or through an API. This is the right choice for bulk jobs, schedules and pipelines. - **Outscraper** lists Google Maps reviews free for the first 500 a month, then $3 per 1,000 up to 100,000 and $1 per 1,000 after that, with bulk extraction and an API (its pricing page as archived in June 2026; the live site blocks automated checks). See our [Outscraper comparison](/alternatives/outscraper). - **Apify's Google Maps Reviews Scraper** (by compass), the most used review actor on Apify with about 7,900 users in the last 30 days, cost $0.60 per 1,000 reviews on Apify's free plan when we checked in October 2026, falling to $0.15 on its top tier. Apify's free plan includes $5 of usage a month. - **SerpApi's Google Maps Reviews API** returns a place's reviews as JSON: 8 on the first page, then up to 20 per page. SerpApi's free plan includes 250 searches a month and Starter is $25 a month for 1,000; each request counts as a search. - **gosom/google-maps-scraper** is open source (MIT licence, about 6,500 stars on GitHub): it scrapes places from Google Maps searches on your own machine and, with its extra-reviews option, collects up to about 300 reviews per place. - **ExportComments** exports Google reviews from a place URL in its web app; its free tier returns up to 100 results per export, and paid plans 5,000 to 250,000 per export (from $23 one-off, checked October 2026). For one place at a time, cloud tools can be more setup than you need. ## Method 3: A Chrome extension for the place you open Here is how it works with [InsightSocial's Google Maps Review Scraper](/scraper/google-maps-review-scraper): 1. **Install InsightSocial** from the Chrome Web Store and sign in with Google. 2. **Sign in to Google in the same browser**, then open the place on google.com/maps. Signed out, Google Maps shows only a handful of reviews per place; signed in, it shows the full list, and that is what the extension reads. 3. **Allow Google Maps once.** The first time, Chrome asks you to let InsightSocial read google.com. It asks for that one site, only when you use it. 4. **Click Scrape and keep the tab in front.** The extension opens the Reviews tab, sorts it by newest and scrolls it the way a person would. Unlike most review sites, Google Maps only loads more reviews while its tab is visible, so leave the tab in front until the run finishes. 5. **Export from your dashboard** as CSV, Excel, JSON or Google Sheets. **How many reviews you get:** in our own runs in October 2026, a place with 89 reviews returned all 89, plus the owner's 87 replies, in 10 seconds. Large places take longer, because the Maps page itself slows down as the list grows, so a run stops at a time limit: a very large place returned 640 to 720 reviews in two and a half minutes. The hard cap is 5,000 reviews per run. Because the list is sorted newest first, a run that stops early still covers the most recent period completely. **What it costs:** scraping and reading results in the dashboard are free on every plan; exporting uses one credit per row. Free includes 500 a month, Pro $9.99 a month (or $7.99 billed yearly) includes 10,000, Studio $49 includes 150,000, and one-time packs run from 250 rows for $2 to 25,000 for $39. Re-exporting a row you already exported is free. **What it does not do:** it reads one place per run. It does not search Google Maps for many places, and it does not take a list of place URLs. For "all the reviews of every coffee shop in a city", use a cloud tool or the open-source scraper from Method 2. ## Exporting to Excel, CSV or Google Sheets - **Excel:** export as .xlsx to keep dates as dates and accents intact. - **CSV:** fine for any tool, but open it in Excel through Data > From Text/CSV with UTF-8 selected if names or reviews contain accents. - **Google Sheets:** InsightSocial syncs a run straight to a sheet in your Google Drive, which is the easiest way to share it or build a Looker Studio dashboard. - **JSON:** for scripts and databases. ## Tips for a large Google reviews dataset - **Separate owner replies before you average.** A reply is not a review. - **Keep star-only reviews.** They are a large share of Google reviews and drop your average if you lose them. - **Turn relative dates into months.** "2 years ago" is approximate; group by month or quarter rather than by day. - **Compare locations on the same date range.** Reviews per month says more than the all-time average. - **Track the reply rate.** Owner replies divided by reviews, by star rating, is a quick service-quality metric. ## Troubleshooting **Only a few reviews came back.** You are probably signed out of Google in that browser. Sign in, reload the place and run it again. **The run slowed down or stopped early.** The Maps page slows as the list grows, and the run stops at a time limit. Very large places will not finish in one run; you still have the newest reviews. **The tab was in the background.** Google Maps stops loading reviews in a hidden tab. Keep it in front. **Dates say "a year ago".** That is Google's own wording. Keep the parsed date for sorting and the original text for accuracy. ## FAQ **Can I export Google reviews to Excel for free?** For your own business, the Business Profile API is free but needs Google's approval and a developer. For any place, InsightSocial's free plan exports up to 500 rows a month. **Why does the Google Places API only return 5 reviews?** That is the API's limit: place details include at most 5 reviews. To get more, owners use the Business Profile API for their own locations, and everyone else uses a scraper. **Can I export a competitor's Google reviews?** Yes. Reviews on Google Maps are public, so a scraper can read them. Google's own exports cover only locations you manage. Check Google's terms and your data-protection obligations for how you store reviewer names. **Do I need a Google Maps API key?** Not with a browser extension: it reads the page you have open. You do need to be signed in to Google for Maps to show the full list of reviews. **Can I export reviews for many locations at once?** Not in one InsightSocial run; each run reads the place you open. For bulk lists of places, use Outscraper, Apify, SerpApi or gosom/google-maps-scraper. **Are owner replies included?** Yes, in InsightSocial each owner reply is its own row under the review it answers. Related guides: [best Google Maps review scrapers](/blog/best-google-maps-review-scrapers), [how to export Trustpilot reviews](/blog/how-to-export-trustpilot-reviews), [best free review scraper Chrome extensions](/blog/best-free-review-scraper-chrome-extensions), and all [review and comment scrapers](/scraper/reviews). --- # How to Download All Comments From a Hacker News Thread Source: https://www.insightsocial.app/blog/how-to-export-hacker-news-comments, updated 2026-10-18 > Download every comment in a Hacker News thread as CSV or Excel, replies hidden behind "more" included: a free web tool, the Algolia API, or an extension. - **Published**: 2026-10-17 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: hacker news, comments, export, tutorial - **Reading time**: 8 min read - **Web version**: https://www.insightsocial.app/blog/how-to-export-hacker-news-comments --- **To download every comment in a Hacker News thread, fetch `https://hn.algolia.com/api/v1/items/`, which returns the whole comment tree as nested JSON in one request, then flatten it to CSV with each comment's depth and parent; without code, paste the thread link into InsightSocial's free Hacker News Thread Exporter for a CSV, or export it from the thread page with the InsightSocial Chrome extension, which falls back to HN's official Firebase API when Algolia's tree is incomplete and exports to CSV, Excel, JSON or Google Sheets.** In our own runs in October 2026, a 71-comment thread took 6 seconds and a 2,484-comment thread took 2 minutes 22 seconds. ## TL;DR | Method | Output | Cost | Skill | |---|---|---|---| | Algolia HN API (`/api/v1/items/`) | Full nested tree as JSON, one request | Free, no key | A short script | | Official HN Firebase API (`/v0/item/.json`) | One item per request, follow `kids` | Free, no key | A script | | [InsightSocial's free HN Thread Exporter](/tools/hacker-news-thread-exporter) (web page) | Every comment as rows, CSV download | Free, no login | None | | Simon Willison's "Hacker News thread export" | The thread as plain text to copy | Free | None | | Chrome extension (InsightSocial) | Rows with depth, parent, links | Free up to 500 rows/month | None | ## Can you export Hacker News comments directly? There is no export button on news.ycombinator.com, and the page itself collapses long threads behind "more" links, so copying the page misses replies. But Hacker News is one of the most open sites on the web: two public APIs serve every story and comment, without a key. - **The official API** is a Firebase database (`hacker-news.firebaseio.com/v0/`), documented in the HackerNews/API repository on GitHub. Each item (a story or a comment) is one JSON object with a `kids` list of its replies' ids, so a thread of 2,000 comments is 2,000 requests. - **The Algolia HN Search API** (`hn.algolia.com/api`) returns a whole thread as one nested object from `/api/v1/items/`. It is the fast route, and the one most scripts use. ## What an HN comment export includes - **Comment id** and **permalink** - **Parent id** and **depth** (0 for a top-level comment, 1 for a reply, and so on), so you can rebuild the tree in a spreadsheet - **Author** username - **Text**, with HTML converted to plain text - **Links** written inside the comment, ideally in their own column - **Posted** time - The story's **title, URL, points and comment count** There is no score column: Hacker News keeps comment points private, so no tool can export them. ### What the rows look like *Illustrative rows: the shape of an export, with made-up names and text, not real reviewers.* | id | parent_id | depth | author | posted | text | links | |---|---|---|---|---|---|---| | 1001 | 1000 | 0 | user_a | 2026-10-02 14:03 | We switched to SQLite for this last year and never looked back. | | | 1004 | 1001 | 1 | user_b | 2026-10-02 14:20 | How did you handle concurrent writes? | | | 1009 | 1004 | 2 | user_a | 2026-10-02 14:41 | WAL mode, and one writer process. Write-up here: | https://example.com/post | | 1002 | 1000 | 0 | user_c | 2026-10-02 14:05 | The benchmark in the article is single-threaded. | | `parent_id` 1000 is the story itself, so depth-0 rows are top-level comments. ## Method 1: The Algolia API and a short Python script Take the number after `item?id=` in the thread's URL: ```python ITEM_ID = sys.argv[1] if len(sys.argv) > 1 else "8863" # the number after item?id= tree = requests.get(f"https://hn.algolia.com/api/v1/items/{ITEM_ID}", timeout=30).json() def plain(text): text = re.sub(r"

", "\n\n", text or "") return html.unescape(re.sub(r"<[^>]+>", "", text)).strip() rows = [] def walk(node, depth): for child in node.get("children", []): if child.get("type") == "comment" and child.get("author"): rows.append({"id": child["id"], "parent_id": child["parent_id"], "depth": depth, "author": child["author"], "created_at": child["created_at"], "text": plain(child.get("text"))}) walk(child, depth + 1) walk(tree, 0) with open(f"hn_{ITEM_ID}.csv", "w", newline="", encoding="utf-8-sig") as f: writer = csv.DictWriter(f, fieldnames=["id", "parent_id", "depth", "author", "created_at", "text"]) writer.writeheader() writer.writerows(rows) print(len(rows), "comments") ``` Run `python hn.py 8863` and you get `hn_8863.csv`, one row per comment. Deleted comments have no author and are skipped; their replies are kept, with a parent_id that points at the deleted comment. **One catch:** Algolia's tree can leave out some comments, notably replies under flagged or dead comments. Compare `len(rows)` with the story's `descendants` count from `https://hacker-news.firebaseio.com/v0/item/.json`. If it is short, walk the missing branches through the Firebase API item by item. ## Method 2: Copy the thread as text [Simon Willison's Hacker News thread export](https://tools.simonwillison.net/hacker-news-thread-export) takes a post id or URL and formats the whole thread as plain text you can copy, which is ideal for pasting into an LLM and asking it to summarise the discussion. It is not a spreadsheet: there are no columns to sort or filter. For a spreadsheet without code, [InsightSocial's free Hacker News Thread Exporter](/tools/hacker-news-thread-exporter) takes the thread link and downloads every comment as a CSV, with depth and parent, in your browser and without signing up. It reads Algolia's tree, so it shares Algolia's gaps described above. ## Method 3: A Chrome extension, no code With [InsightSocial's Hacker News Comment Scraper](/scraper/hacker-news-comment-scraper): 1. **Install InsightSocial** and sign in with Google. 2. **Open the thread**: any `news.ycombinator.com/item?id=…` page, a story, an Ask HN, a Show HN, or a single comment opened as its own page. No Hacker News account is needed. 3. **Allow Hacker News once** when Chrome asks. 4. **Click Scrape.** The extension reads the tree from Algolia, and when Algolia's count falls short of the story's, walks it item by item through the Firebase API, so replies hidden behind "more" and replies under flagged comments are included. It keeps running in a background tab. 5. **Export** to CSV, Excel, JSON or Google Sheets. **Speed:** 71 comments in 6 seconds and 2,484 in 2 minutes 22 seconds in our October 2026 runs. A run stops walking item by item after about 2.5 minutes and fills the rest from Algolia, which covers roughly 6,000 comments; the panel says so when that happens. **What it costs:** scraping is free; exporting uses one credit per row. The free plan's 500 rows a month covers most threads; Pro is $9.99 a month for 10,000. Re-exporting a row you already exported is free. ## What to do with an HN thread in a spreadsheet - **Collect every tool a thread recommends.** Filter the Links column, then count domains. "What do you use for X?" threads become a ranked list in a minute. - **Read only the top level.** Filter depth = 0 to see the distinct opinions before the arguments. - **Find the debates.** Sort parents by how many replies point to them. - **Launch feedback.** For a Show HN, filter to comments that are not yours and tag them as bug, feature request or praise. ## Troubleshooting **Fewer comments than the thread says.** The count on HN includes deleted and dead comments. Algolia can also miss replies under flagged comments; compare with the Firebase `descendants` count. **HTML in the text.** HN stores comment text as HTML (`

`, ``, `'`). Strip tags and unescape entities, as the script does. **Very large threads.** Algolia returns the whole tree in one response, which can be several megabytes. That is fine for a script; in a browser, give it a few seconds. ## FAQ **Is there an API for Hacker News comments?** Yes, two, both free and without a key: the official Firebase API (one item per request) and the Algolia HN Search API, whose `/api/v1/items/` returns a whole thread nested. **How do I export Hacker News comments to CSV without coding?** Paste the thread link into InsightSocial's free Hacker News Thread Exporter for a CSV, no login needed. Or use the InsightSocial browser extension: open the thread and click Scrape. Both keep depth and parent as columns. **Does it include replies hidden behind "more"?** Yes. The APIs return the whole tree regardless of what the page has expanded. **Can I get comment scores?** No. Hacker News does not publish comment points, so no tool can export them. **Do I need a Hacker News account?** No. Threads are public. **Can I export all comments by one Hacker News user?** Not with InsightSocial, which reads a thread. The Algolia search API can list a user's comments with `search_by_date?tags=comment,author_`. Related: [how to export Quora answers to a spreadsheet](/blog/how-to-export-quora-answers), [how to export Product Hunt reviews and comments](/blog/how-to-export-product-hunt-reviews), and all [review and comment scrapers](/scraper/reviews). --- # How to Export Product Hunt Reviews and Comments (2026) Source: https://www.insightsocial.app/blog/how-to-export-product-hunt-reviews, updated 2026-10-18 > Export a Product Hunt product's reviews or a launch's full comment thread to CSV, Excel or Google Sheets, with maker replies, upvotes and nesting. - **Published**: 2026-10-17 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: product hunt, reviews, comments, export, tutorial - **Reading time**: 6 min read - **Web version**: https://www.insightsocial.app/blog/how-to-export-product-hunt-reviews --- **Product Hunt has no export button; developers can read launches and comments through the official Product Hunt API (GraphQL, with a developer token, and not for commercial use without Product Hunt's permission), and without code the InsightSocial Chrome extension exports either a product's reviews (rating, text, helpful votes, the team's reply) or a launch's full comment thread (upvotes, maker flag, replies nested with depth and parent) to CSV, Excel, JSON or Google Sheets.** In our own runs in October 2026, a product returned 162 of its 162 reviews in 14 seconds, and a launch returned 212 of its 213 comments in 11 seconds. ## TL;DR | Method | What you get | Cost | Skill | |---|---|---|---| | Product Hunt API v2 (GraphQL) | Posts and comments, as JSON | Free token; not for commercial use without permission | Code | | Chrome extension (InsightSocial) | Reviews of a product, or every comment on a launch | Free up to 500 rows/month | None | | Cloud scrapers (Apify actors) | Launches and products, many at once | Per result | Low | ## Reviews or launch comments: which one you want Product Hunt has two kinds of feedback, on two kinds of page: - **Reviews** live on a product's reviews page (`producthunt.com/products//reviews`). They carry a star rating and, on many reviews, labelled answers to Product Hunt's prompts. They accumulate over the product's life. - **Launch comments** live on a launch (`producthunt.com/posts/`, or a product's launch page). They are the launch-day discussion: questions, feature requests, congratulations, and the maker's answers, nested as replies. Founders usually want the launch comments the week of a launch (to answer and tag feedback), and the reviews for testimonials and competitor research. ## Can you export them directly? Not from the site. Developers can use the Product Hunt API v2, a GraphQL API that needs a developer token. Its documentation is direct about one condition: "The Product Hunt API must not be used for commercial purposes. If you would like to use it for your business, please contact us at hello@producthunt.com." (checked October 2026). If you are a company analysing your own launch, check with Product Hunt before building on the API. ## What the export includes **Reviews:** rating, review text (with the labelled answers kept as sections), reviewer name, date, helpful votes, the review type, and the team's reply as its own row under the review. **Launch comments:** comment text, author, date, upvotes, whether the author is one of the makers, links written in the comment, and depth and parent so each reply sits under the comment it answers. Comments are read in Product Hunt's own vote order. ### What the rows look like *Illustrative rows: the shape of an export, with made-up names and text, not real reviewers.* | Depth | Parent | Author | Maker | Upvotes | Text | |---|---|---|---|---|---| | 0 | | User A | No | 14 | Does it work with self-hosted instances? | | 1 | User A's comment | Maker B | Yes | 6 | Yes, from version 2. There is a guide in the docs. | | 0 | | User C | No | 9 | Congrats on the launch! The onboarding is very smooth. | | 0 | | User D | No | 3 | Is there an annual plan? | For a product's reviews the columns are rating, text, helpful votes and date instead, with the team's reply as a row under the review. ## Method 1: The Product Hunt API Create an application in Product Hunt's API dashboard to get a developer token, then send GraphQL queries to `https://api.producthunt.com/v2/api/graphql` for a post and its comments, paging with the cursors the API returns, and write the CSV yourself. Keep the non-commercial condition above in mind. ## Method 2: A Chrome extension With [InsightSocial's Product Hunt Scraper](/scraper/product-hunt-scraper): 1. **Install InsightSocial** and sign in with Google. 2. **Open the page:** a product's reviews page for reviews, or a launch page for comments. The side panel says which one it found. No Product Hunt account is needed. 3. **Allow Product Hunt once** when Chrome asks. 4. **Click Scrape.** The extension reads the same data the page loads, including replies the page has not expanded, and keeps going in a background tab. 5. **Export** to CSV, Excel, JSON or Google Sheets. **Limits:** one product or launch per run; a run stops at 5,000 rows or 2 minutes, far above what almost any launch or product has. **What it costs:** scraping is free; exporting uses one credit per row. A launch with 300 comments fits inside the free plan's 500 rows a month; Pro is $9.99 a month for 10,000. Re-exporting rows you already exported is free. ## Method 3: Cloud scrapers Apify lists several third-party Product Hunt actors that collect launches by day or topic; the most used one cost $1.80 per 1,000 launches when we checked in October 2026. They suit tracking many launches over time rather than exporting one launch's discussion. ## What founders do with a launch export - **Answer everyone.** Filter to top-level comments with no maker reply. - **Tag feedback.** Add a column for bug, feature request, pricing question or praise, then count. - **Pull testimonials.** Sort reviews by rating and helpful votes, then ask reviewers for permission to quote. - **Benchmark competitors.** Export a competitor's launch and compare the questions people asked. ## Troubleshooting **"Product Hunt is showing a security check".** Reload the page, let it finish loading, then start again. **A comment or two short of the count.** The number Product Hunt shows can be slightly higher than the comments it serves; in our runs a launch returned 212 of its 213. **Wrong page type.** A product's main page and its reviews page both work for reviews; for comments, open the specific launch. ## FAQ **Can I export Product Hunt comments to CSV?** Yes. Open the launch with a browser extension such as InsightSocial, or call the Product Hunt API with a token and write the comments out yourself. **Are maker replies included?** Yes. Replies sit under the comment they answer, with a maker flag, so the thread reads the way it does on the page. **Are upvotes included?** On launch comments, yes. Reviews carry the reviewer's rating and helpful votes instead. **Do I need a Product Hunt API key?** Not with the extension. The official API needs a developer token. **Can I export every launch of the day?** Not with InsightSocial, which reads one launch or product per run. Use the API or a cloud actor for lists of launches. Related: [how to download all comments from a Hacker News thread](/blog/how-to-export-hacker-news-comments), [best free review scraper Chrome extensions](/blog/best-free-review-scraper-chrome-extensions), and all [review and comment scrapers](/scraper/reviews). --- # How to Export Quora Answers to a Spreadsheet (2026) Source: https://www.insightsocial.app/blog/how-to-export-quora-answers, updated 2026-10-18 > Quora has no export button and no public content API. How to get every answer to a question, with comments, upvotes and views, into CSV or Excel. - **Published**: 2026-10-17 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: quora, answers, export, tutorial - **Reading time**: 6 min read - **Web version**: https://www.insightsocial.app/blog/how-to-export-quora-answers --- **Quora has no export button and no public API for questions and answers, so to get a question's answers into a spreadsheet you need a tool that reads the question page for you: the InsightSocial Chrome extension collects each answer and then the comments and replies under it, with author, credential, upvotes, views and date, up to about 3,000 rows per question, and exports them to CSV, Excel, JSON or Google Sheets.** In our own runs in October 2026, a large question returned 3,024 rows (1,047 answers and 1,977 comments) in 2 minutes 26 seconds; smaller questions took 11 to 12 seconds. ## TL;DR | Method | What you get | Cost | Skill | |---|---|---|---| | Copy and paste | The answers you scroll to | Free | None | | Chrome extension (InsightSocial) | Every answer to one question, plus comments, as rows | Free up to 500 rows/month | None | | InsightSocial API (`/v1/quora/answers`) | Answers matching a keyword, as JSON | 50 credits a call | Code | | Cloud scrapers (Apify actors) | Questions and answers, many at once | Per 1,000 results | Low | ## Can you export Quora answers directly? No. Quora does not offer a public API for questions, answers or profiles; the only developer API it publishes is a Conversion API for advertisers in Quora Ads Manager. The question page is also hard to copy by hand. It loads answers as you scroll, collapses some of them, mixes in answers to related questions and, on many questions, an AI-generated answer. So "select all and paste" gives you a messy, partial page. ## What a Quora answers export includes - **Answer text**, line breaks kept, with **links** in their own column - **Author** name and **credential** (the "Software engineer at…" line) - **Upvotes**, **views** and **shares** - **Date** - **Comments and replies** under each answer, as rows one level deeper, with their own upvotes - **Depth and parent**, so you can tell an answer from a comment on it - The **question**: title and address A good export leaves out what is not an answer to this question: answers to related questions that Quora shows on the page, AI answers and deleted answers. ### What the rows look like *Illustrative rows: the shape of an export, with made-up names and text, not real reviewers.* | Depth | Author | Credential | Upvotes | Views | Text | |---|---|---|---|---|---| | 0 | Writer A | Physiotherapist, 12 years | 1,240 | 88,000 | Start with three short sessions a week, not seven long ones... | | 1 | Reader B | | 31 | | This is the advice my clinic gave me too. | | 0 | Writer C | Marathon runner | 410 | 21,500 | The mistake most beginners make is pace, not distance... | | 2 | Writer A | | 12 | | Agreed, and sleep matters more than people think. | Depth 0 is an answer, depth 1 a comment on it, depth 2 a reply to that comment. ## Method 1: A Chrome extension With [InsightSocial's Quora Scraper](/scraper/quora-scraper): 1. **Install InsightSocial** and sign in with Google. 2. **Open the question** on quora.com, or on a language site such as es.quora.com, de.quora.com or fr.quora.com. 3. **Allow Quora once** when Chrome asks. 4. **Click Scrape.** The extension collects each answer, then the comments and replies under it, and keeps going in a background tab. 5. **Export** to CSV, Excel, JSON or Google Sheets. **Limits:** one question per run, and a run stops at about 3,000 rows (answers plus comments) or 2.5 minutes, so the file stays workable. Quora sometimes shows a number of answers it does not actually list (collapsed, merged-in or AI answers); the panel tells you the gap when that happens. If Quora asks you to log in to see more, sign in to Quora in that browser and run it again. **What it costs:** scraping is free; exporting uses one credit per row. Free includes 500 a month, Pro $9.99 a month includes 10,000, and re-exporting a row you already exported is free. ## Method 2: Answers by keyword, through an API If you need answers about a topic across many questions rather than every answer to one question, the [InsightSocial Quora API](/social-media-api/quora) returns written answers matching a keyword, up to 10 per call, each with its text, author and credential, upvotes, views and the question it answers, as JSON. It costs 50 credits a call from the same balance as exports, and works today. ## Method 3: Cloud scrapers The Apify Store has third-party Quora actors that collect questions and answers by search or URL, billed per result; the most used, by fatihtahta (about 450 users in the last 30 days), cost $0.99 per 1,000 results when we checked in October 2026. They suit large, repeated collections; for one question, the extension is quicker. ## What people do with Quora answers in a spreadsheet - **Content research.** Sort by upvotes or views to see which answers to a question in your niche actually get read, then write the better answer. - **Product research.** Filter answers that mention your product or a competitor and read the objections. - **Find experts.** Filter by credential to see who answers with authority in a topic. - **Feed an LLM.** Paste the top 50 answers by upvotes, with credentials, into a model and ask what they agree on. ## Troubleshooting **Fewer answers than Quora's count.** Quora's count includes collapsed and merged answers and sometimes AI answers it does not list. The panel reports the gap. **"Quora wants you to log in".** Some questions show more to signed-in users. Sign in to Quora and run it again. **Security check.** Reload the page, let it finish loading, then start again. **Answers in other languages.** Each Quora language site has its own questions and answers. Open the question on that site. ## FAQ **Does Quora have an API?** Not for its content. Quora offers no public API for questions, answers or profiles; its Ads Manager has a Conversion API for advertisers. Third-party APIs, including InsightSocial's, read public Quora content. **How do I export all answers to a Quora question?** Open the question with a browser extension such as InsightSocial and click Scrape. It collects the answers and their comments, up to about 3,000 rows. **Are comments included?** Yes, as rows one level under the answer they belong to, with replies one level deeper again. **Can I export every question in a Quora topic or Space?** Not with the extension, which reads one question per run. The InsightSocial API finds answers, profiles and Spaces by keyword. **Can I export all the answers one Quora writer has written?** Not with the extension, which reads one question per run. Open each question you want to collect. **Does it work on Quora in other languages?** Yes, on Quora's language sites such as es.quora.com. Related: [how to download all comments from a Hacker News thread](/blog/how-to-export-hacker-news-comments), [how to export Product Hunt reviews and comments](/blog/how-to-export-product-hunt-reviews), and all [review and comment scrapers](/scraper/reviews). --- # How to Export Steam Reviews to CSV or Excel (2026) Source: https://www.insightsocial.app/blog/how-to-export-steam-reviews, updated 2026-10-18 > Export a Steam game's reviews to CSV or Excel: Steam's GetAppReviews API with Python, or a Chrome extension with no code. Playtime and replies included. - **Published**: 2026-10-17 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: steam, reviews, export, tutorial, gamedev - **Reading time**: 8 min read - **Web version**: https://www.insightsocial.app/blog/how-to-export-steam-reviews --- **Steam reviews can be exported with Steam's official Web API, `IUserReviewsService/GetAppReviews`, which returns up to 100 reviews per request with a cursor for the next page and needs no key, so a short script can write every review of a game to CSV; without code, the InsightSocial Chrome extension reads the reviews from the game's store page and exports the 10,000 newest in every language, with playtime, helpful votes and developer replies, to CSV, Excel, JSON or Google Sheets.** ## TL;DR | Method | Cost | Limit | Skill | |---|---|---|---| | Steam Web API (`GetAppReviews`) + script | Free, no key needed | 100 reviews per request, cursor paging | Python | | Chrome extension (InsightSocial) | Free up to 500 rows/month | 10,000 newest reviews per run | None | | Cloud scrapers (Apify actors) | Per 1,000 reviews | Varies | Low | ## Can you export Steam reviews directly? There is no download button on the store page, but Steam is unusually open: it documents a Web API method for reading any game's reviews, `GetAppReviews` in the `IUserReviewsService` interface (`partner.steamgames.com/doc/webapi/IUserReviewsService`). A key is optional; a publisher key associated with the game only raises the rate limit. It replaces the older `store.steampowered.com/appreviews/?json=1` endpoint, which Steam switches off on October 22, 2026, and takes the same filters: sort order, languages, review type, purchase type, a date range and a cursor. That makes Steam the easiest of the big review sites to export, as long as you are comfortable running a script. ## What a Steam review export includes - **Recommended** or not (Steam has thumbs up and down, not stars) - **Review text**, in the language it was written in - **Language** - **Date posted** and date last updated - **Helpful** and **funny** votes - **Playtime**: total, at the time of the review, and in the last two weeks - **Steam purchase** flag, **received for free**, **written during Early Access** - **Reviewer** Steam name and profile link, and how many games and reviews they have - **The developer's reply**, when there is one - The game's **name, review score description, total, positive and negative counts** Playtime at review is the field most other review sites cannot give you: a negative review after 2 hours reads differently from one after 200. ### What the rows look like *Illustrative rows: the shape of an export, with made-up names and text, not real reviewers.* | Recommended | Language | Posted | Playtime at review (h) | Helpful | Funny | Text | |---|---|---|---|---|---|---| | Yes | english | 2026-10-12 | 42 | 18 | 2 | The new patch fixed the stutter. Best co-op in years. | | No | schinese | 2026-10-11 | 3 | 5 | 0 | (review text in Chinese) | | No | english | 2026-10-10 | 210 | 64 | 1 | Loved it for 200 hours, but the latest update broke my saves. | | Yes | russian | 2026-10-09 | 15 | 0 | 0 | (review text in Russian) | A thumbs down after 210 hours of play says more than one after 3: it usually points at a specific change. ## Method 1: Steam's GetAppReviews API with Python Find the game's app ID in its store URL (`store.steampowered.com/app//...`). Then: ```python APP_ID = 620 # the number in the store URL URL = "https://api.steampowered.com/IUserReviewsService/GetAppReviews/v1/" rows, cursor, seen = [], "*", set() while cursor not in seen: seen.add(cursor) query = {"appid": APP_ID, "filter": 1, # 1 = most recently created "languages": ["all"], "purchase_type": 1, # 1 = all purchases, not only Steam "num_per_page": 100, "cursor": cursor} resp = requests.get(URL, params={"input_json": json.dumps(query)}, timeout=30) resp.raise_for_status() data = resp.json()["response"] reviews = data.get("reviews", []) if not reviews: break for r in reviews: rows.append({ "id": r["recommendationid"], "recommended": r["voted_up"], "language": r["language"], "created": r["timestamp_created"], "playtime_at_review_min": r["author"].get("playtime_at_review"), "votes_up": r["votes_up"], "text": r["review"], }) cursor = data.get("cursor", cursor) time.sleep(1) # be gentle; large games have thousands of pages with open(f"steam_{APP_ID}.csv", "w", newline="", encoding="utf-8-sig") as f: writer = csv.DictWriter(f, fieldnames=list(rows[0].keys())) writer.writeheader() writer.writerows(rows) print(len(rows), "reviews") ``` Notes: - Parameters go in one `input_json` parameter, and the sort and filters are numbers: `filter` 0 is most helpful, 1 most recent, 2 most recently updated, 3 funniest. Use 1 or 2 to page through every review; the helpful sort only looks back over a window of days. - `languages: ["all"]` gets every language; an empty list means English only. - `purchase_type` defaults to Steam purchases only; 1 includes reviews from keys bought elsewhere. - Off-topic "review bomb" reviews are filtered out by default. Add `"filter_offtopic_activity": false` to include them. - Pass the cursor back exactly as Steam returns it; the loop stops when a cursor repeats or a page comes back empty. - `encoding="utf-8-sig"` makes Excel read Chinese, Russian and accented text correctly. We ran this script against a real game while writing this guide (October 2026): it returned 100 reviews per page across languages. ## Method 2: A Chrome extension, no code With [InsightSocial's Steam Review Scraper](/scraper/steam-review-scraper): 1. **Install InsightSocial** and sign in with Google. 2. **Open the game's store page**, any `store.steampowered.com/app/…` address. You do not need to pass the age gate or sign in to Steam. 3. **Allow Steam once** when Chrome asks. 4. **Click Scrape.** The extension pages through Steam's public reviews feed, newest first, in every language and every purchase type, with a running count, and the run keeps going in a background tab. 5. **Export** to CSV, Excel, JSON or Google Sheets. **How many:** in our own runs in October 2026, a game with 78 reviews returned all 78 plus the developer's reply in 10 to 17 seconds. For the most-reviewed games a run stops at the 10,000 newest reviews (it also stops after 4 minutes, or earlier if Steam starts rate limiting). Newest first means a run that stops at the cap still covers the latest patches completely, which is usually the period you care about. **What it costs:** scraping is free; exporting is one credit per row. Free includes 500 a month; Pro $9.99 a month includes 10,000; Studio $49 includes 150,000. Re-exporting a row you already exported is free. ## Method 3: Cloud scrapers The Apify Store lists several third-party Steam review actors that take a list of app IDs and can run on Apify's schedules, billed per 1,000 reviews (the most used, Automation Lab's, cost $0.575 per 1,000 reviews on Apify's free plan when we checked in October 2026). They make sense if you track many games over time; for one game, Steam's own API is free. ## Large games: getting past 10,000 reviews For a game with 300,000 reviews, the extension's 10,000 newest is a sample of recent sentiment, not the whole history. If you need everything, use the script and let it run, pacing requests. Narrowing helps too: one language at a time, or a window of time with `date_range_start` and `date_range_end` (Unix timestamps; both must be set), for example the week after a patch. ## Troubleshooting **The script stops after a few pages.** You are being rate limited. Sleep between requests and resume from the last cursor. **Counts do not match the store page.** The store page's totals follow the filters shown on it, such as purchase type and off-topic review activity. The API defaults to Steam purchases only and filters out off-topic reviews; set `purchase_type` to 1 and `filter_offtopic_activity` to false to include everything. **Excel shows garbled text.** Save the CSV as UTF-8 with BOM, or export .xlsx. **Steam does not load.** Steam is blocked by some networks and countries. Try another connection. ## FAQ **Is there an official Steam reviews API?** Yes. `IUserReviewsService/GetAppReviews` in the Steam Web API returns any game's reviews as JSON, up to 100 per request with a cursor; a key is optional. It replaces the older `appreviews` endpoint, which Steam switches off on October 22, 2026. **How do I export Steam reviews without coding?** Use a browser extension. InsightSocial exports the 10,000 newest reviews of the game you open, free up to 500 rows a month. **Can I export Steam reviews in all languages?** Yes. Both the API (`languages: ["all"]`) and InsightSocial return reviews in the language they were written in. Nothing is translated. **Does the export include playtime?** Yes: playtime at the time of the review, total playtime and the last two weeks, in minutes. **Are developer replies included?** Yes. InsightSocial puts each developer reply in its own row under the review it answers. **Can I export reviews for several games at once?** Not in one InsightSocial run. Loop over app IDs in the script, or use a cloud scraper. Related: [how to download all comments from a Hacker News thread](/blog/how-to-export-hacker-news-comments), [best free review scraper Chrome extensions](/blog/best-free-review-scraper-chrome-extensions), and all [review and comment scrapers](/scraper/reviews). --- # How to Export Trustpilot Reviews to CSV or Excel (2026) Source: https://www.insightsocial.app/blog/how-to-export-trustpilot-reviews, updated 2026-10-18 > Export Trustpilot reviews to CSV or Excel: yours via Trustpilot Business, any company's with a Chrome extension. Why exports stop at 200, and the fix. - **Published**: 2026-10-17 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: trustpilot, reviews, export, tutorial - **Reading time**: 12 min read - **Web version**: https://www.insightsocial.app/blog/how-to-export-trustpilot-reviews --- **To export Trustpilot reviews, use Trustpilot Business's own export if the company is yours; for any other company page, use a scraper that pages through the reviews for you, because Trustpilot shows signed-out visitors at most 10 pages per filter (about 200 reviews at 20 per page) and has no public export button.** A filter-splitting tool such as the InsightSocial Chrome extension goes through each language and star rating separately to reach further, keeps the company's replies as separate rows, and exports to CSV, Excel, JSON or Google Sheets, free up to 500 rows a month. ## TL;DR: ways to export Trustpilot reviews | Method | Whose reviews | Cost | Cap | Skill needed | |---|---|---|---|---| | Trustpilot Business export | Your own company only | Premium or Enterprise plan | The date range you choose | None | | Trustpilot API | Your own company (business API) | Business plan + developer time | API limits | Code | | Cloud scrapers (Apify actors, Outscraper) | Any company, many at once | Per 1,000 reviews | Varies by tool | Low | | Chrome extension (InsightSocial) | Any company page you open | Free up to 500 rows/month, Pro $9.99 for 10,000 | Trustpilot's paging, split by language and stars | None | | Copy and paste | Any | Free | Your patience | None | If you only need your own reviews, start with Trustpilot's export. If you need a competitor's, read on. ## Can you export Trustpilot reviews directly? Only for your own company, and only on some plans. Trustpilot's help centre says the review export "is included in the Premium and Enterprise plans" of Trustpilot Business (checked October 2026). Trustpilot also limits how its reviews may be shown on other platforms, so treat the official export as a file for analysing your own reviews, and check Trustpilot's guidelines before you copy them onto your website. There is no export button on a public company page. Anyone can read `trustpilot.com/review/`, but nothing on it downloads the list, so for a competitor, a supplier or a whole category you need a tool that reads the pages for you. ## Why Trustpilot exports stop at around 200 reviews The most common complaint about Trustpilot scrapers is that they return about 200 reviews and stop, even when the company has 20,000. A September 2026 thread on r/scrapingtheweb ("Is it actually possible to scrape more than 200 Trustpilot reviews??") is exactly this: the poster tried two cloud tools and hit the same wall. The cause is Trustpilot itself. Signed out, a company's review list goes to at most **10 pages per filter**, at 20 reviews a page. Page 11 sends you to Trustpilot's login page instead (we checked in October 2026). Every tool that reads the public pages inherits that ceiling, unless it changes the filter. That is the trick: the 10-page limit applies **per filter**, so the same company viewed as "English, 1 star", "English, 2 stars", "German, 5 stars" and so on is a separate list of up to 10 pages each. A tool that walks every language and star rating separately reaches far more than 200 reviews, and then removes the duplicates. It still does not always reach every review. On a very large company, some combinations of language and rating hold more than 10 pages on their own. In our own runs in October 2026, a company with 83 reviews returned all 83 (plus its 5 replies) in 4 to 7 seconds, and a company with 20,624 reviews returned 4,994 of them. Be suspicious of any tool that promises "every review" from public pages. ## What data a Trustpilot export includes A good Trustpilot export gives you one row per review with: - **Rating**: 1 to 5 stars, as a number - **Title** and **review text**, line breaks kept - **Reviewer name** and **country** - **Date** of the review and, where shown, the date of the experience - **Verified** flag, when Trustpilot marks the review as verified - **Helpful** votes - **Language** of the review - **The company's reply**, ideally as its own row linked to the review it answers, so you can count or exclude replies - **Permalink** to the review At the page level you also want the **TrustScore**, the total review count and the **star distribution**, so you can compare what you exported with what Trustpilot reports. Fields Trustpilot does not show on the public page are not in any scraper's export. ### What the rows look like *Illustrative rows: the shape of an export, with made-up names and text, not real reviewers.* | Depth | Author | Country | Rating | Posted | Title | Verified | Language | |---|---|---|---|---|---|---|---| | 0 | Customer A | GB | 1 | 2026-10-03 | Refund still missing after 3 weeks | Yes | en | | 1 | (the company's reply) | | | 2026-10-04 | | | en | | 0 | Customer B | DE | 5 | 2026-10-02 | Schnelle Lieferung | No | de | | 0 | Customer C | US | 4 | 2026-09-30 | Good product, slow support | Yes | en | ## Method 1: Trustpilot Business export (your own company) If the company is yours and you are on the right plan, this is the cleanest route: it is Trustpilot's own file, filtered by date range. 1. Sign in to Trustpilot Business. 2. Go to **Manage reviews > Service reviews** and open the inbox. 3. Click **Export** and choose a date range. 4. Click **Download .csv**. On plans below Premium the option is not there, and you are back to the methods below. **When it is not enough:** it only covers companies you own and needs a Premium or Enterprise plan, so it cannot help with competitor research, and Trustpilot's guidelines limit republishing the exported reviews elsewhere. ## Method 2: The Trustpilot API Trustpilot offers developer APIs to its business customers, documented at developers.trustpilot.com, for working with your own company's reviews, invitations and widgets. Access comes through a Trustpilot Business account, so for pulling another company's reviews into a spreadsheet the API is not the practical route. ## Method 3: Cloud scrapers for many companies at once Cloud tools run on their own servers, take a list of company URLs and return a file or call your webhook. This is the right shape when you need dozens of companies, a schedule, or an API. - **Apify actors.** Several independent developers publish Trustpilot scrapers on the Apify Store, billed per review. On Apify's own listings in October 2026: Automation Lab's Trustpilot Reviews Scraper (about 870 users in the last 30 days) cost $0.575 per 1,000 reviews on Apify's free plan; memo23's Trustpilot All Reviews Scraper (about 690 users) $0.75 per 1,000, and it says it gets "past the ~200-review web cap"; Black Falcon Data's a flat $0.25 per 1,000, with the same claim. Prices fall on Apify's paid tiers, and the free plan includes $5 of usage a month. - **Outscraper.** Pay as you go. Its Trustpilot page, as archived in December 2025 (the live site blocks automated checks), listed the first 100 reviews free, then $3 per 1,000 up to 50,000 and $1 per 1,000 beyond, and it takes lists of companies through its web app and API. - **ExportComments.** Paste a company URL into the web app. Its Trustpilot page says the free tier returns up to 100 reviews per business, and the paid plans 5,000, 50,000 or 250,000 per export (Personal $23 one-off for 3 days, Premium $45/month, Business $199/month, checked October 2026). Check each tool's own output against the company's review count before you trust it. Trustpilot's per-filter limit applies to cloud tools reading public pages just as it does to anything else. ## Method 4: A Chrome extension for any company page If you want the reviews of one company at a time, without a cloud account or code, a browser extension is the shortest route. Here is how it works with [InsightSocial's Trustpilot Review Scraper](/scraper/trustpilot-review-scraper): 1. **Install InsightSocial** from the Chrome Web Store and sign in with Google. 2. **Open the company's review page**, any `trustpilot.com/review/` address, on trustpilot.com or a country site such as uk.trustpilot.com or de.trustpilot.com. The side panel names the company it found. 3. **Allow Trustpilot once.** The first time, Chrome asks you to let InsightSocial read trustpilot.com. It asks for that one site, only when you use it. 4. **Click Scrape.** The extension reads the review pages over HTTP, goes through each language and star rating to get past the 10-page limit, and counts as it goes. On large companies it collects about 40 reviews a second, and you can switch to another tab while it runs. Stop keeps everything collected so far. 5. **Export from your dashboard.** The run lands in your InsightSocial dashboard, where you can search and filter it, then export to CSV, Excel, JSON or Google Sheets. You do not need a Trustpilot account or an API key: the extension reads the same public pages any visitor sees. Signed in to Trustpilot, each filter goes deeper than 10 pages, so you get more of a large company. A run stops after about 3 minutes and keeps what it collected. Each run covers one company; open the next company and run it again. **What it costs:** scraping and reading results in the dashboard are free on every plan. Exporting uses one credit per row. The free plan includes 500 a month; Pro is $9.99 a month (or $7.99 a month billed yearly) for 10,000; Studio is $49 a month for 150,000; and one-time packs run from 250 rows for $2 to 25,000 for $39. A row you already exported is free to export again, so re-downloading the same company as Excel after CSV costs nothing. A company with 2,000 reviews and 300 company replies is 2,300 rows: inside Pro's monthly allowance, or a one-time pack. ## Export formats: CSV, Excel or Google Sheets - **CSV** opens anywhere and is what most analysis tools want. Make sure it is UTF-8, or reviews in German, French or Polish arrive with broken accents in Excel. - **Excel (.xlsx)** keeps dates as dates and avoids the encoding question entirely. - **Google Sheets** is the easiest to share with a team or connect to Looker Studio. - **JSON** suits a script or a database import. Whichever you choose, keep the company replies in their own rows, or filter them out before you average the ratings: a reply is not a review. ## Working with large Trustpilot datasets - **Split by star rating first.** One- and two-star reviews are usually what you want to read in full; five-star reviews are useful for counts and language. - **Use the language column.** Large companies collect reviews in many languages. Filter to the ones your team reads, or translate in bulk afterwards. - **Compare the count with the page.** The export's row count against Trustpilot's own total tells you how much of the company you have. - **De-duplicate on the permalink** if you merge runs from several days. - **Trend by month.** Group the review dates by month to see whether complaints are growing, not just what they say. ## Troubleshooting **The export stops at 200 reviews.** That is Trustpilot's 10-pages-per-filter limit for signed-out visitors. Sign in to Trustpilot, use a tool that splits the list by language and star rating, or accept that you have the newest 200. **Fewer reviews than the company's total.** Some reviews are hidden by Trustpilot (under investigation, reported, removed), and on very large companies even a filter-splitting run stops short. Check the star distribution in your export against the page. **Accents look broken in Excel.** Open the CSV through Excel's Data > From Text/CSV and pick UTF-8, or export as .xlsx. **Starting from a country site.** A company's page on uk.trustpilot.com or de.trustpilot.com works as the starting page, the same as on www.trustpilot.com. ## FAQ **Can I export Trustpilot reviews for free?** For your own company, Trustpilot Business includes an export on its Premium and Enterprise plans. For any company page, InsightSocial's free plan exports up to 500 rows a month, and ExportComments' free tier returns up to 100 reviews per business. **Is there a Trustpilot review limit of 200?** Yes, in practice. Signed out, Trustpilot shows at most 10 pages of reviews per filter, about 200 reviews. Tools that read the pages one filter at a time, by language and star rating, get past it, though not always to every review on very large companies. **Can I export a competitor's Trustpilot reviews?** Yes. Reviews on Trustpilot company pages are public, so a scraper can read them, but Trustpilot's own export only covers companies you own. Check Trustpilot's terms and your local data-protection rules for how you use reviewer names. **Are the company's replies included?** In InsightSocial, yes: each reply is its own row under the review it answers, labelled as an owner reply, and the run summary counts them apart. **Does signing in to Trustpilot get more reviews?** Yes. Signed in, each language and star filter pages past 10, so large companies return more. A run still stops after about 3 minutes. **Do I need a Trustpilot account or API key?** Not for public company pages. You need a Trustpilot Business account (Premium or Enterprise) only for the official export of your own reviews. **How do I export reviews from many Trustpilot companies at once?** Use a cloud tool that takes a list of URLs, such as an Apify actor or Outscraper. InsightSocial runs one company page at a time. **Does InsightSocial analyse sentiment?** No sentiment column in the export. On Pro, Ask your data answers sentiment and theme questions about a finished run, such as how many one-star reviews mention refunds. Related guides: [best Trustpilot review scrapers](/blog/best-trustpilot-review-scrapers), [how to export Google reviews](/blog/how-to-export-google-reviews), [how to download Amazon reviews to Excel](/blog/how-to-download-amazon-reviews), and the full list of [review and comment scrapers](/scraper/reviews). --- # Best LinkedIn Data APIs in 2026: Pricing Compared Source: https://www.insightsocial.app/blog/best-linkedin-data-apis-2026, updated 2026-10-18 > LinkedIn's official API vs Bright Data, Apify, PhantomBuster, Coresignal and InsightSocial: what each returns, what it costs, which job it fits. - **Published**: 2026-09-24 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: api, linkedin, developers, comparison, b2b-data - **Reading time**: 12 min read - **Web version**: https://www.insightsocial.app/blog/best-linkedin-data-apis-2026 --- **LinkedIn has no self-serve API for reading other people's profiles: its open permissions cover Sign In with LinkedIn and posting for the signed-in member, and everything else needs partner approval.** To read public profiles, companies, posts or jobs, developers use Bright Data ($1.50 per 1,000 records), Apify actors (priced per actor), Coresignal's B2B database (from $49 a month) or InsightSocial (50 credits per profile, about $0.05 on Pro). PhantomBuster automates your own LinkedIn account instead, from $69 a month. Picking a LinkedIn data API is less about features and more about how the data gets collected: through LinkedIn's own permissions, through your logged-in account, through a scraper that reads public pages, or from a database someone else built. That one choice decides your cost, your account risk, and how fresh the data is. This roundup covers LinkedIn's official programs and five third-party options, including ours. Where we quote a competitor's price, we checked it on that company's own website and marked it "as of October 2026", with a link to the page we read. Where we couldn't confirm a number, we describe the pricing model instead of guessing. *Prices checked 2026-10-18.* If you just want working code, skip to our [tutorial on scraping LinkedIn profiles and companies with Python](/blog/linkedin-scraping-api-guide-2026). ## The short version | Option | How data is collected | Pricing model | Best for | | --- | --- | --- | --- | | LinkedIn official APIs | Member consent (OAuth) | Free, but most access needs partner approval | Sign-in, posting, approved partner integrations | | Bright Data | Public-page scraping, managed | Per 1,000 records | High-volume profile and company pulls | | Apify | Public-page scrapers from a marketplace | Set by each scraper's developer | Trying many scrapers, custom workflows | | PhantomBuster | Your own LinkedIn session | Subscription | Sales automation around your own account | | Coresignal | Pre-collected B2B database | Monthly credit plans | Bulk firmographic and employee data | | InsightSocial | Public-page scraping, one API for 22 platforms | Credits per endpoint, free tier | Small to mid jobs, multi-platform products | ## Does LinkedIn have an official data API? Yes, but it's not a general data API. According to LinkedIn's developer documentation, only a few "open permissions" are self-serve: Sign In with LinkedIn using OpenID Connect (the logged-in member's name, headline, photo and email) and Share on LinkedIn (posting and commenting on that member's behalf). Everything else requires explicit approval: - **Marketing** (Advertising API and audiences) needs you to apply and be approved. - **Sales** access, including Sales Navigator profile matching, needs you to be an approved Sales Navigator Application Platform (SNAP) partner. - **Talent** integrations such as Recruiter System Connect and Apply Connect go through a separate partner application. - **Compliance** permissions are closed to new applicants. **Pick it when** your product needs "Sign in with LinkedIn", posts on a member's behalf, or you're a genuine ATS, CRM or ad-tech partner willing to go through review. **Skip it when** you need to look up arbitrary profiles, companies or posts. There's no self-serve endpoint for that. ## Bright Data Bright Data runs a managed Web Scraper API with dedicated LinkedIn scrapers. Its LinkedIn page lists five data types: people profiles, companies, jobs, posts and people search. You send URLs or search inputs and get structured records back. Because they manage the proxies and unblocking, you don't touch a LinkedIn account. Pricing (as of October 2026, from [Bright Data's pricing page](https://brightdata.com/pricing/web-scraper)): pay-as-you-go at **$1.50 per 1,000 records**, a free tier of **5,000 records per month**, and a Scale plan at **$499/month** that includes 384,000 records, with extra records at $1.30 per 1,000. **Strengths:** The lowest per-record price in this list at volume, broad LinkedIn coverage, and an enterprise-grade operation. **Trade-offs:** It's a large platform with many products, and the scraper model is built around batch jobs of records, not one quick call per lookup. If you need hundreds of thousands of LinkedIn profiles a month, start here. ## Apify Apify is a platform for running scrapers ("Actors"), and its store has many LinkedIn Actors from independent developers. You pick one, run it through the Apify API, and read the results from a dataset. Pricing has two layers. Apify's own plans (as of October 2026, from [apify.com/pricing](https://apify.com/pricing)) are Free ($0, with $5 of monthly platform usage), Starter ($19/month), Scale ($199/month) and Business ($999/month). On top of that, each Actor's price is set by its developer, using pay-per-event, pay-per-usage or a monthly rental, as Apify's documentation explains. So the real cost of a LinkedIn profile depends on which Actor you choose. **Strengths:** Lots of choice, a strong developer platform with scheduling, storage and integrations, and easy to prototype on the free tier. **Trade-offs:** Quality and upkeep vary by Actor, and when LinkedIn changes its pages, you depend on that one developer to fix theirs. Each Actor also has its own input and output format, so switching means rewriting your parser. We compare the two products in [InsightSocial vs Apify](/alternatives/apify). ## PhantomBuster PhantomBuster is an automation tool more than a data API. Its LinkedIn automations ("Phantoms") run through your own account. PhantomBuster's support docs describe connecting LinkedIn with your `li_at` session cookie and browser user agent, which it then uses to run your Phantoms. It has an API for launching Phantoms and fetching results, and it's popular for prospecting workflows like search exports, profile visits and connection requests. PhantomBuster's own [pricing explainer](https://phantombuster.com/blog/ai-automation/phantombuster-pricing-explained) lists Start at $69 a month, Grow at $159 and Scale at $439 (about 20% less billed yearly), plus a Free plan with 30 minutes of run time a month and exports capped at 10 rows (as of October 2026). Plans are priced by automation slots and run hours, not by record. We've written more about the trade-offs in [PhantomBuster alternatives](/blog/phantombuster-alternatives). **Strengths:** Great at actions, not just data, with a mature library of LinkedIn workflows. **Trade-offs:** Because it acts as you, your LinkedIn account carries the risk. LinkedIn's User Agreement prohibits bots and unauthorized automated access, and accounts that automate heavily can get restricted. Your volume is also limited by what one account can do safely. ## Coresignal Coresignal sells B2B data rather than live scraping on demand. Its site describes employee, company and job records, with employee data going back to 2016 (more than 900 million employee profiles and 70 million company records by its own count). You get it through Company, Employee and Jobs APIs or as bulk datasets, and it says multi-source company data is updated daily. Pricing (as of October 2026, from [Coresignal's pricing page](https://coresignal.com/pricing/)): a 7-day free trial with 2,000 credits, then monthly plans from **$49/month for 2,500 credits** up to $5,000/month. Its pricing page says a full employee or company record costs 20 credits and a job posting 1 credit. **Strengths:** Huge historical coverage, fast bulk queries, and no scraping to run yourself. Great for firmographics, talent analytics and market maps. **Trade-offs:** It's a database, so a record reflects the last time it was collected, not the page right now. Its APIs center on companies, employees and jobs. It also sells a separate social posts dataset on a custom agreement, so ask about post-level data such as comments or reactions before you commit. ## InsightSocial That's us. Our [LinkedIn scraper API](/social-media-api/linkedin) reads public LinkedIn pages on request and returns JSON in the same schema we use for 21 other platforms, including TikTok, X, YouTube, Reddit and Pinterest. The [LinkedIn endpoints](/docs/platforms/linkedin) (65+ of them) cover profiles and every profile section, company pages, company posts and headcount insights, posts, comments, reactions, reposts, people search with filters, post search, jobs, groups and the Ad Library. Pricing is per endpoint, in credits, and published in full at [endpoint pricing](/docs/endpoint-pricing): a member profile is 50 credits, a company page 50, a people-search page 100 to 500 (metered). The free plan has 500 credits a month, and your first 10 calls priced at 100 credits or less are free. Pro is $9.99/month for 10,000 credits, which works out to roughly $0.05 per LinkedIn profile. See [pricing](/pricing). A few billing rules that matter in practice (details in [Credits](/docs/credits)): - Failed calls and empty results cost 0. - A shared-cache hit costs 2 credits. - `GET /v1/endpoints` lists every price and needs no key. **Strengths:** One key and one schema across 22 platforms, a real free tier, pay-per-call pricing that suits small and bursty jobs, and no LinkedIn account involved. There's also a [Chrome extension](/scraper/linkedin) on the same credit balance for teammates who don't code. **Trade-offs, honestly:** Per LinkedIn profile we're more expensive than Bright Data's bulk rate, so if you're pulling hundreds of thousands of profiles a month, a per-record provider will cost less. We're also rate-limited to 60 requests a minute and 10 concurrent requests per key, which suits product features and research jobs better than massive batch crawls. ## How much does LinkedIn data cost through an API? LinkedIn's own API costs nothing, but it won't return other people's profiles unless you are an approved partner. Third-party prices, as of October 2026: | Option | What you pay | Roughly per profile | | --- | --- | --- | | Bright Data | $1.50 per 1,000 records pay-as-you-go; $499/month for 384,000 records | $0.0015, falling to about $0.0013 on Scale | | Apify | Set by each Actor's developer, on top of Apify's plan (free $5/month, Starter $19) | Depends on the Actor | | Coresignal | From $49/month for 2,500 credits; 20 credits per full employee or company record | About $0.39 on the entry plan | | PhantomBuster | From $69/month, priced by run hours, not records | Depends on how much your account can run | | InsightSocial | 50 credits per profile or company page, 100 to 500 per people-search page; 500 free credits a month, Pro $9.99 for 10,000 | About $0.05 on Pro | The pattern: per-record scrapers are cheapest when you need tens of thousands of profiles, a database such as Coresignal costs more per record but answers in bulk without scraping, and a per-call API such as ours costs more per profile but has no minimum and a free tier. Price your real job in each vendor's unit before choosing. ## What happened to Proxycurl? It's worth knowing before you commit to any vendor. Proxycurl was a popular LinkedIn profile API. After LinkedIn sued in January 2025, the company shut it down on July 4, 2025, and its founder wrote that there was no winning a fight against a company with Microsoft's resources. Every customer had to replace a dependency. The lesson isn't that every vendor will vanish. It's that you should keep your code loosely coupled. Put the provider behind one small client in your codebase, store the raw responses you depend on, and make sure you can swap vendors in a day, not a quarter. ## Which LinkedIn data API should you choose? - **You need "Sign in with LinkedIn" or to post for users:** the official API. - **You're a real CRM, ATS or ad-tech partner:** apply to the relevant LinkedIn partner program. - **Millions of profile or company records:** Bright Data for live pulls, Coresignal for a pre-built database. - **You want to try many scrapers or build custom workflows:** Apify. - **You want to automate your own LinkedIn outreach:** PhantomBuster, knowing the account risk. - **LinkedIn plus other platforms, or small, frequent lookups inside a product:** InsightSocial. Start with the [quickstart](/docs/quickstart), or hand the [AI agents page](/docs/ai-agents) to your coding agent. Whatever you pick, stick to public data, collect only what the job needs, and treat privacy law as applying even when a profile is public. ## FAQ ### What is the cheapest LinkedIn data API? At high volume, per-record providers are cheapest. Bright Data listed $1.50 per 1,000 records as of October 2026. For small jobs, free tiers matter more: Bright Data offers 5,000 records a month, Apify $5 of monthly usage, and InsightSocial 500 credits a month plus 10 free calls. ### Can I use LinkedIn's official API to look up any profile? No. Self-serve permissions only return data about the member who signed in to your app. Broader profile access runs through partner programs like SNAP, which LinkedIn approves case by case. ### Which options avoid using my LinkedIn account? Bright Data, Coresignal and InsightSocial don't ask for your LinkedIn login. On Apify it depends on the Actor, so read its input settings: some ask for a cookie. PhantomBuster's LinkedIn automations run through your session cookie by design. ### Is it legal to use a LinkedIn scraping API? It depends on where you are, what you collect and how you use it. Scraping public data isn't automatically illegal, but LinkedIn's User Agreement prohibits it and privacy laws like GDPR still apply. The Proxycurl case shows LinkedIn will sue. Get legal advice if LinkedIn data is core to your product. ### Can I get LinkedIn people search results through an API? Yes. Bright Data lists a people-search scraper, and InsightSocial's `/v1/linkedin/search/people` takes keywords plus title, company, school, industry and location filters, returning 10 people per page. ### How do I test an API before paying? Use the free tiers and run the same five or ten real inputs through each. Compare field coverage, how nulls are handled and how errors are billed. On InsightSocial, `GET /v1/endpoints` shows every price for free, and your first 10 qualifying calls cost nothing. --- # Best Social Media Scraping APIs in 2026: 7 Compared Source: https://www.insightsocial.app/blog/best-social-media-scraping-apis-2026, updated 2026-10-18 > Seven multi-platform social media scraping APIs for developers, compared on platforms, pricing model, free tier and auth. Prices checked October 2026. - **Published**: 2026-09-24 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: api, developers, comparison, scraping, social-media - **Reading time**: 11 min read - **Web version**: https://www.insightsocial.app/blog/best-social-media-scraping-apis-2026 --- **The main multi-platform social media scraping APIs in 2026 are InsightSocial (22 platforms, one schema, credits per endpoint, 500 free credits a month), Apify (a marketplace of scrapers, $5 free a month), Bright Data ($1.50 per 1,000 records, 5,000 free a month), ScrapeCreators (prepaid credits from $47), EnsembleData (from $100 a month), Data365 (from €300 a month) and Scrapfly (a general scraping API, 1,000 free credits).** They differ in what you pay for: per request, per record, per compute unit or per daily quota. If you need public data from TikTok, YouTube, Reddit and friends inside your own code, you have three broad choices: the official platform APIs, a general web-scraping service you point at social sites, or a purpose-built social data API that hands back parsed JSON. This roundup covers the second and third kind, the ones a developer can sign up for today and call from a script. We build one of them, so treat our entry with the skepticism you'd give any vendor writing a comparison. For every other tool, the prices and free tiers below were checked on that company's own website on October 18, 2026, and each section links to the pricing page we read. Where a vendor doesn't publish a number, we say so instead of guessing. *Prices checked 2026-10-18.* ## How do these APIs differ? Before the list, it helps to know the four axes that actually separate them: - **Shape of the product.** Some are marketplaces of individual scrapers (you pick one per job), some are scraping infrastructure (proxies plus parsing, you choose the target), and some are a single API with fixed endpoints per platform. - **How you're billed.** Per request, per record, per compute time, or per daily unit quota. - **Sync or async.** Some return data in the HTTP response. Others make you submit a job, poll, and fetch results later. Async is fine for batch pipelines and awkward for anything interactive. - **Schema consistency.** Whether a "post" from TikTok and a "post" from Reddit come back with the same field names, or whether you write one parser per platform. ## Comparison table | API | Type | Platforms (social) | Pricing model | Free tier | Auth | | --- | --- | --- | --- | --- | --- | | InsightSocial | Unified social data API | 22 | Credits per endpoint | 500 credits/mo + 10 free calls | `x-api-key` header | | Apify | Scraper marketplace + platform | Any, via Store Actors | Subscription + compute units or pay-per-event | $5/mo usage credit | Bearer token (or `token` param) | | Bright Data | Scraping infrastructure | 11 incl. Snapchat, Quora, Vimeo | Per 1K records | 5,000 records/mo | Bearer token | | ScrapeCreators | Social data API | 38+ APIs: the majors plus many niche platforms | Prepaid credits, ~1 per request | 100 credits (+ claimable bonus) | `x-api-key` header | | EnsembleData | Social data API | 8 | Monthly plan, daily unit quota | 50 units/day | `token` query param | | Data365 | Social data API (async) | 7 | Monthly plan, credits | 14-day trial | `access_token` query param | | Scrapfly | General web-scraping API | Any site you target | Credits, cost varies by features | 1,000 credits on signup | API key | All third-party figures are as of October 2026. ## 1. InsightSocial: one schema, 22 platforms, pay per endpoint **Disclosure: this is ours.** The [InsightSocial API](/social-media-api) covers [TikTok](/social-media-api/tiktok), [LinkedIn](/social-media-api/linkedin), [Twitter/X](/social-media-api/twitter), [YouTube](/social-media-api/youtube), [Reddit](/social-media-api/reddit) and [Pinterest](/social-media-api/pinterest), plus 16 more from [Bluesky](/social-media-api/bluesky), [Telegram](/social-media-api/telegram) and [Twitch](/social-media-api/twitch) to Douyin, Xiaohongshu and Weibo, through 230+ endpoints under `https://api.insightsocial.app/v1/`. Every response uses one envelope, and posts, comments and authors share one schema across all 22 platforms, so a parser written for TikTok reads Reddit too. ```bash curl "https://api.insightsocial.app/v1/tiktok/profile?handle=natgeo" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` **Pricing.** Each endpoint has its own credit price (a basic profile is 10 credits; heavier calls like LinkedIn people search are metered up to 500). You're never charged for failed or empty calls, and a shared-cache hit costs 2 credits. The free plan is 500 credits/month plus 10 free calls; Pro is $9.99/month for 10,000 credits. The balance is shared with our Chrome extension's exports. Full table: [Endpoint pricing](/docs/endpoint-pricing). **Good for:** developers who want synchronous JSON from the big social platforms without writing per-platform parsers, and AI agents (the endpoint catalogue at `/v1/endpoints` is public and free, so an agent can read real parameters and prices before spending anything; see [AI agents](/docs/ai-agents)). **Honest limits:** it's read-only. Each key is capped at 60 requests per minute and 10 concurrent, which suits most apps but not firehose-scale collection. There's no sandbox; test calls spend real credits (the free calls and `dry_run=1` are the cheap way to test). And it's a young product. ## 2. Apify: the biggest menu of scrapers Apify is a platform for running "Actors", packaged scrapers, many of them written by third-party developers and listed in the Apify Store. There are Actors for essentially every social platform, often several competing ones. **Pricing (as of October 2026, from [apify.com/pricing](https://apify.com/pricing)):** Free ($0, with $5 of monthly platform usage), Starter $19/month, Scale $199/month, Business $999/month. Usage is billed in compute units (1 CU = 1 GB of RAM for one hour, $0.20/CU on Free and Starter), or at a fixed price per event on Actors that use pay-per-event pricing. Auth is an API token, sent as `Authorization: Bearer ` (a `token` query parameter also works, but Apify recommends the header). **Good for:** breadth and odd targets. If a platform or page type exists, someone has probably published an Actor for it. **Watch out for:** every Actor has its own input and output format, quality varies by author, and compute-based billing makes costs harder to predict up front. Most runs are asynchronous. We compare the two products in [InsightSocial vs Apify](/alternatives/apify). ## 3. Bright Data: infrastructure at enterprise scale Bright Data's Social Media Scraper API bundles its proxy network, unblocking and parsing into per-record pricing. Its social page lists eleven networks, among them TikTok, X, LinkedIn, YouTube, Reddit, Pinterest, Quora, Vimeo and Snapchat. **Pricing (as of October 2026, from its [pricing page](https://brightdata.com/pricing/web-scraper)):** pay-as-you-go at $1.50 per 1,000 records, with proxies and parsing included, or $499/month for 384,000 records. The free tier is 5,000 records a month, no card required. Auth is a Bearer token. **Good for:** high-volume collection where you want per-record economics and a vendor with serious infrastructure behind it. **Watch out for:** it's a large product surface with many ways to buy, and it's built around datasets and collection jobs more than quick interactive lookups. ## 4. ScrapeCreators: wide coverage, simple credits ScrapeCreators is a social data API with a long list of platforms: the majors (TikTok, YouTube, Twitter, LinkedIn, Reddit, Pinterest and others) plus TikTok Shop, Telegram, Twitch, Bluesky, Truth Social, several ad libraries and link-in-bio tools. **Pricing (as of October 2026, from [scrapecreators.com](https://scrapecreators.com)):** prepaid credits where one credit is one request for most endpoints. Freelance is $47 for 25,000 credits; Business is $497 for 500,000; Enterprise is custom. Signup includes 100 free credits (and up to 7,000 more you can claim), and credits don't expire. Their site says results already in their cache cost 0 credits. Auth is an `x-api-key` header. **Good for:** teams that need niche platforms beyond the big ones and like flat, predictable per-request pricing. **Watch out for:** the entry purchase is a $47 pack rather than a low monthly plan, and with most endpoints at one credit, a light lookup and a heavy one usually cost the same. ## 5. EnsembleData: daily quotas for steady workloads EnsembleData covers eight networks, among them TikTok, YouTube, Reddit, Twitch, Twitter and Snapchat. **Pricing (as of October 2026, from its [pricing page](https://ensembledata.com/pricing)):** plans are sold by daily units. Wood is $100/month for 1,500 units/day, Bronze $200 for 5,000, Silver $400 for 11,000, Gold $800 for 25,000 and Platinum $1,400 for 50,000; Diamond is custom. The free trial is 50 units a day with no card. Endpoints cost from 1 unit upward, with some priced by how many posts or replies they return. Auth is a `token` query parameter. **Good for:** products that make a steady, predictable number of calls every day. **Watch out for:** daily quotas don't roll over, so bursty workloads (a big backfill, then quiet weeks) fit this model poorly. Tokens in query strings also end up in logs more easily than headers. ## 6. Data365: async collection for research pipelines Data365 offers APIs for seven networks, among them Twitter/X, TikTok, Reddit and Pinterest. **Pricing (as of October 2026, from its [pricing page](https://data365.co/pricing)):** Basic is €300/month for one social network and 500,000 credits; Standard is €850/month for three networks and 1,000,000 credits; Custom goes up to seven networks. Their examples price one post at 1 credit, a post with comments at 5, a search request at 7 and a profile with info at 9. There's a 14-day free trial, requested through a form. Auth is an `access_token` query parameter. **Good for:** research and monitoring pipelines that collect in batches and can tolerate latency. **Watch out for:** requests are asynchronous (a `POST` to start collection, a status check, then a `GET` for results), plans are priced per network, and access starts with a sales form. ## 7. Scrapfly: general scraping you aim at social sites Scrapfly isn't a social API. It's a web-scraping API (proxies, headless browsers, anti-bot handling) that you can point at any site, social platforms included. You get raw pages or extracted data, and the parsing is your job. **Pricing (as of October 2026, from its [pricing page](https://scrapfly.io/pricing)):** Free with 1,000 API credits on signup, then Discovery $30/month, Pro $100, Startup $250, Enterprise $500, and custom tiers above. One key and one credit balance cover all its products; a request's cost depends on features you enable, such as JavaScript rendering and proxy type. **Good for:** teams already scraping other websites who want one tool for everything, and targets no social API covers. **Watch out for:** you own the parsers and their maintenance every time a platform changes its markup. ## What about the official platform APIs? Where an official API gives you what you need, it's the most stable option and the one the platform explicitly permits. The catch is that they differ enormously: separate apps, review processes, OAuth flows, terms and pricing per platform, and many are designed for managing your own accounts rather than reading public data at large. Check each platform's current developer terms directly; they change often, and we'd rather not quote numbers from memory. ## How should you choose? - **You want parsed JSON from the big platforms, synchronously, with one parser:** a unified social API such as [InsightSocial](/social-media-api), or ScrapeCreators if you need niche platforms too. - **You need scale measured in millions of records:** Bright Data. - **You need a weird target or a one-off scraper:** Apify's Store. - **You have a steady daily call volume:** EnsembleData's quota model. - **Batch research pipelines that can wait for results:** Data365. - **You're scraping plenty of non-social sites as well:** Scrapfly. Whatever you pick, test it on your real workload before committing. Pull the same five profiles and one busy comment thread from each candidate, then compare field coverage, failure rate and what you were actually billed. ## FAQ ### What is a social media scraping API? A hosted service that collects public data from social platforms (profiles, posts, comments, search results) and returns it to your code, usually as JSON, so you don't run browsers, proxies or parsers yourself. ### Which social media scraping API has the best free tier? It depends on what you're testing. Bright Data gives 5,000 records a month, Scrapfly 1,000 credits on signup, Apify $5 of monthly usage, EnsembleData 50 units a day, ScrapeCreators 100 credits on signup, and InsightSocial 500 credits a month plus 10 free calls (as of October 2026). Compare on the calls you'll actually make, since a credit means something different at each. ### Is scraping public social media data legal? Collecting publicly available data is generally treated differently from accessing private data, but the answer depends on your jurisdiction, the platform's terms and what you do with personal data afterwards. Talk to a lawyer for anything commercial. ### Which is cheapest? There's no single answer, because the billing models differ: per request, per record, per compute unit, per daily unit. Estimate your monthly job (for example, 10,000 profiles and 500 comment threads) and price it on each site. For InsightSocial, every endpoint's price is on [Endpoint pricing](/docs/endpoint-pricing), and `dry_run=1` on any endpoint quotes a call for free. ### Is there a no-code option? Yes. If you'd rather click than code, the [InsightSocial Chrome extension](/scraper) scrapes six of these platforms (TikTok, X, LinkedIn, YouTube, Reddit and Pinterest), plus review sites, in your browser and exports to CSV or Excel. See [Pricing](/pricing). --- # Best TikTok Data APIs in 2026: Pricing Compared Source: https://www.insightsocial.app/blog/best-tiktok-data-apis-2026, updated 2026-10-18 > TikTok's official Research and Display APIs versus six third-party TikTok data APIs: who can use them, what they return, how they charge, and which fits. - **Published**: 2026-09-24 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: api, tiktok, developers, comparison, scraping - **Reading time**: 11 min read - **Web version**: https://www.insightsocial.app/blog/best-tiktok-data-apis-2026 --- Picking a TikTok data API comes down to three questions. Are you allowed to use it? Does it return the data you need (profiles, videos, comments, search, transcripts)? And does its pricing model match the shape of your workload? A tool that is cheap per record at a million rows a month can be the wrong choice for a side project that makes 300 calls, and the other way round. This roundup covers TikTok's two official APIs and six third-party options, InsightSocial included. We sell one of them, so we've tried to be straight about where others beat us. Every competitor price below comes from that company's own pricing page, checked on October 18, 2026, and each one links to that page below. Prices change, so confirm before you commit. *Prices checked 2026-10-18.* ## Can you use the official TikTok API? TikTok has two developer products that matter here, and both are narrow. **The Research API** gives access to public accounts, videos, comments and follower lists, but only to qualifying researchers. TikTok's product page opens it to academic institutions in the US, EEA, UK, Canada and Switzerland, to non-profit research organizations in the EU (in beta), and in Brazil only to institutions studying online youth safety. Applicants must be independent of commercial interests. Approved projects get 1,000 requests per day, up to 100,000 records a day (as of October 2026). If you're a university researcher, apply. If you're a company, it isn't open to you. **The Display API** lets your app show a TikTok user's own profile and videos after they sign in with TikTok and grant permission. Its user info endpoint returns data about the authorized user only. It's the right tool for "connect your TikTok" features in a creator app, and useless for reading creators who haven't connected to you. Everything else, meaning reading public creators, videos, comments and search results you don't own, means a third-party API. ## Which TikTok data APIs are worth a look? | API | Pricing model | Free tier (as of Oct 2026) | Best for | | --- | --- | --- | --- | | TikTok Research API | Free, quota per day | Free if approved | Non-commercial academic research | | TikTok Display API | Free | Free | Showing a signed-in user's own content | | Apify TikTok Scraper | Pay per result | $5 platform credit per month | Batch jobs, dataset exports | | Bright Data TikTok Scraper | Per 1,000 records | 5,000 records per month | High-volume pipelines, enterprise delivery | | EnsembleData | Monthly plan, units per day | 50 units per day | Steady daily TikTok volume | | ScrapeCreators | Prepaid credits that don't expire | 100 credits, more on request | Pay-as-you-go, bursty usage | | TikAPI | Monthly plans | Trial offered | Acting on a connected TikTok account | | InsightSocial | Credits per endpoint, one balance | 500 credits/month + 10 free calls | Multi-platform apps, low-to-mid volume, AI agents | ### Apify TikTok Scraper Apify is a marketplace of scrapers ("actors") that you run on its platform. Its [TikTok Scraper actor](https://apify.com/clockworks/tiktok-scraper) (by clockworks) lists **$1.70 per 1,000 results** on a pay-per-event model, with discounts on higher Apify plans, and Apify's [free plan](https://apify.com/pricing) includes **$5 of usage a month** (as of October 2026). It covers profiles, video metrics, hashtags, music, comments and follower lists, and can download media and subtitles. The model is "start a run, collect a dataset": you submit input, wait for the run, then fetch results. That's great for batch exports and less natural for request-response app code. Because different actors come from different authors, output shapes differ between them. We compare the two products in [InsightSocial vs Apify](/alternatives/apify). ### Bright Data TikTok Scraper API Bright Data is the heavyweight: **$1.50 per 1,000 records** pay-as-you-go on its [pricing page](https://brightdata.com/pricing/web-scraper), a **$499/month** Scale plan with 384,000 records included, and a free tier of **5,000 records a month** with no card (all as of October 2026). It covers profiles, posts, comments and TikTok Shop products, and can deliver to webhooks, S3, Google Cloud Storage, Azure, Snowflake or SFTP in JSON, NDJSON or CSV. If you're moving hundreds of thousands of records a month into a warehouse, it's hard to beat on unit price and delivery options. For a small app, the platform is more than you need. ### EnsembleData EnsembleData sells a daily allowance of "units." [Plans](https://ensembledata.com/pricing) start at **$100/month for 1,500 units a day**, and the free trial gives **50 units a day** with no card (as of October 2026). On its pricing page a TikTok user-info call costs 1 unit, a page of a user's posts costs 1 unit for 10 posts, and a page of comments costs 1 unit for 30. Failed requests caused by its own errors aren't charged. The daily reset suits a pipeline that runs every day at a steady rate. It's a worse fit for spiky workloads, because unused units don't roll over to the day you actually need them. ### ScrapeCreators [ScrapeCreators](https://scrapecreators.com) sells prepaid credits that **never expire**: **$47 for 25,000** or **$497 for 500,000**, with **100 free credits** on signup and up to 7,000 more you can claim (as of October 2026). It lists more than 20 TikTok endpoints, including profiles, videos, transcripts, comments and replies, following lists, live details and audience demographics. If your usage comes in bursts (a big research sprint, then nothing for a month), credits that don't expire are a real advantage over a monthly plan. ### TikAPI TikAPI's distinguishing feature is **OAuth account-level access**: your users can connect their own TikTok accounts, and your app can act on their behalf, beyond reading public data. It sells monthly plans with request limits and offers a trial. We couldn't read current plan prices from its public site, so check them on [tikapi.io](https://tikapi.io) directly. Pick TikAPI when you need that connected-account capability. For reading public data only, the other options are simpler. ### InsightSocial Our [TikTok scraper API](/social-media-api/tiktok) reads public TikTok data through 35+ endpoints under `https://api.insightsocial.app/v1/tiktok/...`: profiles, videos, single posts, comments and replies, keyword, hashtag, user and top search, followers and following, transcripts, on-screen text, sounds, playlists, trending and popular boards, and the TikTok Ad Library. The same key reads 21 other platforms, and every post, comment and profile comes back in one shared shape, so one parser handles all of them. Pricing is per endpoint in credits. A profile is 10 credits, a transcript is 100, and metered endpoints like comments (10–30) are charged for what the call actually read. The full list is on the [TikTok platform page](/docs/platforms/tiktok). Pro is $9.99/month for 10,000 credits, which works out to roughly one cent for a 10-credit call. Where we fit and where we don't, honestly: - **At high volume we cost more per record** than Bright Data, Apify or ScrapeCreators' larger packs. If you're pulling millions of rows a month, one of them is the better deal. - **We're built for low-to-mid volume and for apps that span platforms.** Failed and empty calls cost 0. A result someone else recently fetched costs 2 credits from the shared cache. Your first 10 calls priced at 100 credits or less are free. - **We're easy for AI agents to use.** `GET /v1/endpoints` is public, free and needs no key. It lists every path, parameter and price, so an agent can plan a job and quote its cost before spending anything. See [using an AI agent](/docs/ai-agents). - **Limits are 60 requests per minute and 10 concurrent per key**, which suits apps and scheduled jobs but isn't meant for bulk firehose extraction. - **The balance is shared with our Chrome extension**, so a team that exports TikTok data by hand and calls the API from code pays from one pool. A worked example with code and a real cost breakdown is in our [tutorial on scraping TikTok with Python, Node and cURL](/blog/tiktok-scraping-api-guide-2026). ## How much does a TikTok API cost? TikTok's own Research and Display APIs are free, but neither is open to commercial reading of other accounts. Third-party TikTok APIs cost about $1.50 to $1.70 per 1,000 records (Bright Data, Apify), from $47 for 25,000 requests (ScrapeCreators), or from $100 a month for 1,500 units a day (EnsembleData), as of October 2026. On InsightSocial a TikTok profile is 10 credits and a transcript 100; the free plan includes 500 credits a month, and Pro is $9.99 for 10,000. | Job | Bright Data | Apify | ScrapeCreators (smallest pack) | InsightSocial (Pro) | | --- | --- | --- | --- | --- | | 1,000 profiles | about $1.50 | about $1.70 | about $1.88 | 10,000 credits | | One video's first 30 comments | about $0.05 (30 records) | about $0.05 (30 results) | about $0.002 (1 request) | 10 to 30 credits, about $0.01 to $0.03 | Per record at volume, the per-record vendors win. Per small lookup, a per-call API is often cheaper, because one call returns a whole page. ## How do the pricing models compare in practice? The headline numbers aren't directly comparable, because each vendor counts a different unit: - **Per result or per record** (Apify, Bright Data): you pay for each video, comment or profile returned. Predictable for bulk exports. - **Per request** (ScrapeCreators, InsightSocial, EnsembleData's units): you pay per call, and one call can return a whole page of rows. At a flat per-call price, a page of 30 comments costs the same as a page of 3. Some of our endpoints, TikTok comments among them, are metered: the price moves within a range depending on what the call read. - **Per day** (EnsembleData, the Research API quota): capacity resets daily whether you used it or not. So work out your job in the vendor's unit before comparing. "10,000 comments across 500 videos" is 10,000 records at a per-record vendor, but around 500 or more page requests at a per-request vendor, depending on how many pages each video needs. ## Which TikTok data API should you choose? - **Academic, non-commercial research:** apply for the TikTok Research API first. - **"Connect your TikTok" features:** the TikTok Display API, or TikAPI if you need to do more than display. - **Millions of records into a data warehouse:** Bright Data or Apify. - **Steady daily TikTok volume on a fixed budget:** EnsembleData. - **Bursty usage where you hate losing unused credit:** ScrapeCreators. - **An app or agent that reads TikTok alongside YouTube, X, LinkedIn and others, at modest volume:** InsightSocial. Start with the [quickstart](/docs/quickstart) or the [social media API overview](/social-media-api). And if you don't write code at all, skip APIs entirely: the [InsightSocial Chrome extension](/scraper/tiktok) exports TikTok profiles, videos and comments to CSV from your browser. ## FAQ ### What is the best TikTok API in 2026? It depends on volume and use case. For commercial reads of public data at scale, Bright Data, Apify, EnsembleData and ScrapeCreators' larger packs are the cheapest per record. For multi-platform apps and AI agents at modest volume, InsightSocial's per-endpoint pricing, free calls and free failed calls tend to work out simpler. For research, TikTok's own Research API. ### Is the official TikTok API free? The Research API and Display API don't charge, but the Research API is only open to qualifying non-commercial researchers in certain regions, and the Display API only reads accounts whose owners have authorized your app. ### Can I get TikTok transcripts through an API? Yes. InsightSocial's `/v1/tiktok/post/transcript` returns the spoken text for 100 credits, with an optional AI fallback when a video has no captions. ScrapeCreators also lists a TikTok transcript endpoint. ### Which TikTok API gives account-level access? TikTok's own Display API (for reading a signed-in user's content) and TikAPI, which advertises OAuth access to connected accounts. The others, including ours, read public data only. ### What's the cheapest way to try a TikTok data API? Use the free tiers: Bright Data's 5,000 monthly records, Apify's $5 monthly credit, EnsembleData's 50 daily units, ScrapeCreators' 100 credits, or InsightSocial's 10 free calls plus 500 monthly credits. Our endpoint catalogue at `/v1/endpoints` also lets you price a job before making a single paid call. Plans are on the [pricing page](/pricing), and credit rules are in [credits](/docs/credits). --- # Best Twitter/X Data APIs in 2026: 6 Options Compared Source: https://www.insightsocial.app/blog/best-twitter-x-data-apis-2026, updated 2026-10-18 > The official X API against five third-party Twitter/X data APIs: prices checked on each vendor's own page in October 2026, strengths, and which one fits. - **Published**: 2026-09-24 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: api, twitter, developers, x, comparison, data - **Reading time**: 11 min read - **Web version**: https://www.insightsocial.app/blog/best-twitter-x-data-apis-2026 --- Reading public data from X used to mean picking an official tier you could afford. In 2026 X has moved to pay-per-use billing, and a handful of third-party APIs return the same public tweets, profiles and follower lists at very different prices and with very different trade-offs. This roundup compares six options for developers who need to read X data programmatically. We built one of them (InsightSocial), so we've tried to be straight about where it's the right pick and where it isn't. Every competitor price below was checked on the vendor's own pricing page on October 18, 2026, and each section links to that page. *Prices checked 2026-10-18.* If you don't write code and just want a spreadsheet of tweets or profiles, skip the APIs entirely: our [free Twitter/X Chrome extension](/scraper/twitter) exports from the page you're viewing. ## Which Twitter/X data APIs are worth considering? | API | Pricing model | Headline read price (Oct 2026) | Free option | Other platforms | Best for | | --- | --- | --- | --- | --- | --- | | Official X API | Prepaid, pay per resource | $0.005 per post, $0.010 per user | No free tier; $20 in credits after your first purchase | No | Posting, DMs, your own account's data | | InsightSocial | Credits per endpoint | 10 credits per profile, 10 per timeline page | 500 credits/month + 10 free calls | 24 more | Multi-platform projects, AI agents, small to mid volume | | twitterapi.io | Pay as you go | $0.15 per 1K tweets; profiles $0.18 per 1K in small batches, $0.01 per 1K in bulk | Up to $1 in free credits, no card | No | Cheapest bulk tweet reads | | Apify (Tweet Scraper V2) | Pay per result | $0.40 per 1,000 tweets | Demo mode: 5 runs a month, 10 items each | Via other actors | Batch jobs inside an existing Apify workflow | | Bright Data | Pay per record or monthly plan | $1.50 per 1K records | 5,000 records/month | Many | Enterprise volume and procurement | | ScrapeCreators | Credits, never expire | $1.88 per 1K requests (smallest pack) | 100 credits, more on request | Many | Occasional use, credits you don't want to lose | These units aren't directly comparable: some bill per tweet, some per request, some per record. ## 1. Official X API **What it is.** X's own API, the only option that can write: post, reply, send DMs, like and follow on behalf of an authenticated user. **Pricing (as of October 2026).** The old monthly Basic and Pro subscriptions are gone from [X's pricing documentation](https://docs.x.com/x-api/getting-started/pricing). Access is now pay per use from credits you buy upfront in the Developer Console. There is no free tier, but new accounts get $20 in credits after their first purchase, plus a matched auto-recharge of up to $50. Reads are priced per resource returned: $0.005 per post, $0.010 per user, $0.010 per follower or following record, and $0.001 for likes. Reading your own account's data ("owned reads") is $0.001 per resource. Writes are per request: $0.015 to create a post, $0.200 for a post that contains a URL. The same resource requested twice within the same UTC day is charged once, and standard accounts are capped at 3 million post reads per billing cycle, beyond which X points you to Enterprise. **Strengths.** It's first-party. It's the only route for write actions, and the owned-read price is hard to beat for analytics on your own account. You can set spending limits. **Weaknesses.** At $5 per 1,000 posts and $10 per 1,000 user records, reading other people's public data adds up fast. It's X-only, and you still need a developer app, OAuth for user-context calls, and your own handling of X's data model. **Choose it if** you need to post or act as a user, or you mainly analyze your own account. ## 2. InsightSocial **What it is.** Our [Twitter/X scraper API](/social-media-api/twitter), a REST API for public social data across 22 platforms, among them Twitter/X, TikTok, LinkedIn, YouTube, Reddit, Bluesky and Truth Social. On X it covers [15 endpoints](/docs/platforms/twitter): profiles, user timelines and media, single tweets, replies, retweeters, followers and following, tweet and user search, communities, video transcripts, and a one-call profile summary (the profile plus recent tweets). Read-only. **Pricing.** Every endpoint has its own credit price, listed publicly at [endpoint pricing](/docs/endpoint-pricing) and at `GET /v1/endpoints` (no key needed). On X: 10 credits for a profile, a single tweet, or a page of followers, following or retweeters; 10 credits per page of about 20 timeline tweets; 10–50 per page of search; 10 per page of replies; 50 for the full profile summary; 100 for a video transcript. Metered endpoints reserve the ceiling and charge what the call actually read. Credits come from the same balance as our extension exports: the free plan includes 500 a month, Pro gives 10,000 a month for $9.99 (or $7.99 billed yearly), and one-time packs never expire. Your first 10 calls priced at 100 credits or less are free. To put that in dollars on Pro: a profile is about $0.01, and 1,000 timeline tweets (roughly 50 pages at 10 credits) costs about $0.50. **What makes the bill smaller.** Failed calls and empty results cost 0. Every call is charged, including a repeat, so store what you fetch. If the same public data was fetched recently by anyone, you pay 2 credits instead of the full price. See [credits](/docs/credits) and [caching](/docs/caching). **Strengths.** One key, one `x-api-key` header, and one response shape across all 22 platforms, so a tweet, a TikTok video and a Reddit post share the same [post object](/docs/schema/post). Timelines support `since` and `stop_at_id` for incremental polling. Responses are plain data: no sentiment or other model labels, so classification runs on your side. There's a [guide for AI agents](/docs/ai-agents), and an `ai-search` endpoint that answers a plain-English question about X with cited posts. **Weaknesses.** Be honest with yourself about volume. For raw bulk tweets, twitterapi.io ($0.15 per 1,000) and Apify's Tweet Scraper ($0.40 per 1,000) are cheaper per tweet than our roughly $0.50. For X user profiles specifically, 10 credits is about $0.01 on Pro, the same as the official API's $0.010 per user. Each key allows 60 requests a minute and 10 concurrent requests, and there are no write endpoints. **Choose it if** your project touches more than one platform, you're building an agent or a pipeline and want one schema, or your volume sits in the thousands to tens of thousands of records a month. Our [tutorial on scraping tweets with Python and Node.js](/blog/twitter-x-scraping-api-guide-2026) has working Python, Node and cURL code. ## 3. twitterapi.io **What it is.** A dedicated third-party X data API with a wide set of read endpoints. **Pricing (as of October 2026, from its [pricing page](https://twitterapi.io/pricing)).** Pay as you go with no minimum spend: $0.15 per 1,000 tweets. User profiles cost $0.18 per 1,000 when a call returns fewer than 100, and $0.01 per 1,000 in bulk. There's a minimum charge of $0.00015 per request. Recharged credits don't expire; the bonus credits that come with a recharge last 31 days. New accounts get up to $1 in free credits with no card. **Strengths.** On price per tweet, it's the cheapest option in this list by a wide margin. **Weaknesses.** X only. If you later add TikTok or LinkedIn, that's a second vendor and a second data model. **Choose it if** you're doing high-volume, X-only reads and cost per tweet is your deciding factor. ## 4. Apify (Tweet Scraper V2) **What it is.** An actor published by a third-party developer on Apify's scraping platform. You configure a run (search terms, handles, lists), it executes in Apify's cloud, and you collect a dataset. **Pricing (as of October 2026).** The [actor page](https://apify.com/apidojo/tweet-scraper) lists $0.40 per 1,000 tweets, with a minimum of 50 tweets returned per query. Free-plan users are limited to demo mode: 5 runs a month of up to 10 items each. **Strengths.** Good for scheduled batch jobs, and if your team already uses Apify for other sites, it slots into the same scheduler, storage and integrations. **Weaknesses.** It's a run-and-collect job model rather than a request-response API, which is awkward for live lookups or agent tool calls. The 50-tweet minimum per query makes lots of small lookups inefficient, and actors are maintained by individual publishers, so quality varies across the store. Apify's plans are on [apify.com/pricing](https://apify.com/pricing), and we compare the two products in [InsightSocial vs Apify](/alternatives/apify). **Choose it if** you want scheduled bulk tweet collection and already live in the Apify ecosystem. ## 5. Bright Data **What it is.** A large web-data company whose Twitter/X Scraper API is one of many prebuilt scrapers, backed by its own proxy network. **Pricing (as of October 2026, from its [pricing page](https://brightdata.com/pricing/web-scraper)).** $1.50 per 1,000 records on the pay-as-you-go plan, a $499/month Scale plan that includes 384,000 records (then $1.30 per 1,000), and custom Enterprise pricing. There's a free tier of 5,000 records a month with no card required. **Strengths.** Scale, and on its Enterprise plan the premium SLA, account manager and paperwork large companies need for procurement. **Weaknesses.** More expensive per record than the X-specialist APIs for plain tweet reads, and the product surface is large, which means a steeper learning curve for a small team. **Choose it if** you're an enterprise team that needs contracts, SLAs and very high volume. ## 6. ScrapeCreators **What it is.** A credit-based API covering a long list of social platforms, X among them. **Pricing (as of October 2026, from [scrapecreators.com](https://scrapecreators.com)).** Credits never expire and there are no subscriptions. One credit is one request for most endpoints. Packs run from $47 for 25,000 credits ($1.88 per 1,000 requests) to $497 for 500,000 ($0.99 per 1,000), with custom Enterprise pricing above that. New accounts start with 100 free credits and can claim up to 7,000 more. **Strengths.** Simple per-request pricing and no expiry, which suits bursty or occasional workloads. **Weaknesses.** Its X coverage is narrower than a dedicated X API; its site lists 7 Twitter endpoints. Check that the endpoints you need exist before buying a pack. **Choose it if** you use social data occasionally and hate losing unused credits. ## How do you choose a Twitter/X data API? Start from the job, not the price list: - **You need to post, reply or DM.** Only the official X API can do it. - **You're analyzing your own account.** The official API's owned-read price is the cheapest route. - **Millions of tweets, X only.** twitterapi.io on price per tweet. - **Scheduled batch jobs in an existing scraping stack.** Apify. - **Enterprise procurement, SLAs, huge volume.** Bright Data. - **More than one platform, or an AI agent calling tools.** InsightSocial, for one key and one schema across 22 platforms. Start with the [quickstart](/docs/quickstart) or the [social media API overview](/social-media-api). Whichever you pick, test your real workload on a small sample first: per-unit prices hide how many items a request actually returns. ## FAQ ### How much does the official X API cost in 2026? As of October 2026, X bills pay per use from prepaid credits. There is no free tier; new accounts get $20 in credits after their first purchase. Reading a post costs $0.005, reading a user costs $0.010, and creating a post costs $0.015 ($0.200 if it contains a URL). Standard accounts are capped at 3 million post reads per billing cycle. ### Is there a free Twitter/X API? Not from X itself any more. Several third-party APIs have free allowances: InsightSocial includes 500 credits a month plus 10 free calls, Bright Data offers 5,000 records a month, twitterapi.io gives up to $1 in credits, and ScrapeCreators gives 100 starting credits. ### What is the cheapest way to get tweets at scale? For X-only bulk reads, twitterapi.io had the lowest per-tweet price we found in October 2026, at $0.15 per 1,000 tweets. If you also need other platforms, weigh that against running a second integration. ### Can third-party APIs post to X? The read-focused APIs in this list don't. For posting, replying or sending DMs, use the official X API. ### Do these APIs need an X account or login? The third-party options here don't require an X account for public data. The official API requires a developer account, and user-context calls need OAuth. ### Is using a third-party X data API legal? These APIs return publicly visible data, but the law depends on your jurisdiction and how you use the data, especially if it includes personal information. Review X's terms and data-protection rules such as GDPR, and get legal advice for commercial use. --- # LinkedIn Scraping API Tutorial: Python, Node & cURL (2026) Source: https://www.insightsocial.app/blog/linkedin-scraping-api-guide-2026, updated 2026-10-18 > Call a LinkedIn scraping API from Python, Node or cURL: profiles, company pages, posts and filtered people search, with pagination and real costs. - **Published**: 2026-09-24 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: api, linkedin, developers, python, nodejs, scraping - **Reading time**: 12 min read - **Web version**: https://www.insightsocial.app/blog/linkedin-scraping-api-guide-2026 --- This tutorial shows how to call a LinkedIn scraping API from Python, Node or cURL. If you want LinkedIn data inside your own code, you have two realistic paths: apply to one of LinkedIn's partner programs, or call a third-party API that reads public pages for you. This guide takes the second path, using our [LinkedIn scraper API](/social-media-api/linkedin). By the end you will have code that reads a member profile, a company page and its posts, runs a filtered people search, walks the pages of a result, and tells you what the whole job cost before you run it. Not a developer? You don't need any of this. The [InsightSocial Chrome extension](/scraper/linkedin) exports LinkedIn data straight to CSV from the page you're looking at, and our [step-by-step guide to scraping LinkedIn profiles](/blog/how-to-scrape-linkedin-profiles) walks through it with no code. ## Why not just use LinkedIn's official API? Because it isn't built for reading other people's data. LinkedIn's self-serve permissions (Sign In with LinkedIn using OpenID Connect, and Share on LinkedIn) let your app read the name, headline, photo and email of the member who logged in, and post on their behalf. That's it. Anything broader, such as advertising data, Sales Navigator profile matching or recruiting integrations, sits behind partner programs that LinkedIn approves case by case. That's the right design for a login button. It's the wrong tool if you need to look up 200 prospects, benchmark five competitors' company pages, or monitor posts about a keyword. For those jobs, developers use a data API that returns public LinkedIn pages as JSON. We compare the options in [Best LinkedIn data APIs for developers](/blog/best-linkedin-data-apis-2026). ## What can you pull from LinkedIn with an API? The [LinkedIn API reference](/docs/platforms/linkedin) lists 67 endpoints. These are the ones most jobs start with: | What you want | Endpoint | Key parameter | Credits | | --- | --- | --- | --- | | A member's public profile | `/v1/linkedin/profile` | `url` | 50 | | Their whole background in one call | `/v1/linkedin/profile/complete` | `url` | 100 | | Posts a member published | `/v1/linkedin/profile/posts` | `url` | 50–2,000 | | A company page | `/v1/linkedin/company` | `url` | 50 | | A company from its website | `/v1/linkedin/company/by-domain` | `domain` | 50 | | A company's recent posts | `/v1/linkedin/company/posts` | `company_id` | 50 | | Company + recent posts | `/v1/linkedin/profile/full` | `url` (company page) | 50 | | Comments on a post | `/v1/linkedin/post/comments` | `url` | 50 | | People search with filters | `/v1/linkedin/search/people` | `query` | 100–500 | | Keyword search over posts | `/v1/linkedin/search/posts` | `query` | 10–480 | Prices come from the [endpoint pricing table](/docs/endpoint-pricing). A range means the endpoint is metered: we hold the top of the range while the call runs and charge what it actually read. See [Credits](/docs/credits) for how that works. ## How do I set up the API key? Sign up, open the API section of the portal, and copy your key. It starts with `isk_live_`. Keys are stored hashed and encrypted, and you can reveal yours again in the dashboard whenever you need it. Every request sends it in one header, `x-api-key`. There's no OAuth dance and nothing to configure per platform. The [quickstart](/docs/quickstart) has the full walkthrough. ```bash ``` The free plan gives you 500 credits a month, and your first 10 calls priced at 100 credits or less cost nothing. That covers the profile, company and post calls below. People search is the exception: it is not covered by free calls, and a metered call reserves its ceiling before it runs, so `search/people` with `include=profile` holds 500 credits while it runs, which can be more than a free month's 500. Pro or a credit pack covers it, and you're only charged what it actually reads. ## How do I scrape a LinkedIn profile? Pass the full profile URL. Here is the same call in all three languages. ```bash curl -G "https://api.insightsocial.app/v1/linkedin/profile" \ --data-urlencode "url=https://www.linkedin.com/in/satyanadella/" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python BASE = "https://api.insightsocial.app/v1" HEADERS = {"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]} body = requests.get( f"{BASE}/linkedin/profile", params={"url": "https://www.linkedin.com/in/satyanadella/"}, headers=HEADERS, timeout=60, ).json() if body["success"]: author = body["data"]["author"] print(author["display_name"], author["followers"], author["url"]) print("cost:", body["credits_used"], "left:", body["credits_remaining"]) else: print(body["error"]["type"], body["error"]["message"]) ``` ```javascript const BASE = "https://api.insightsocial.app/v1"; const headers = { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY }; const url = new URL(`${BASE}/linkedin/profile`); url.searchParams.set("url", "https://www.linkedin.com/in/satyanadella/"); const body = await (await fetch(url, { headers })).json(); if (body.success) { const { display_name, followers } = body.data.author; console.log(display_name, followers, "cost", body.credits_used); } else { console.log(body.error.type, body.error.message); } ``` Every response uses the same envelope: the payload sits under `data`, and `credits_used`, `credits_remaining` and `charge_reason` tell you what the call cost and why. `schema_version` is `"2"`, and `unavailable` lists any field LinkedIn normally shows that this response could not fill (usually none). The field names in `data.author` are shared across all 22 platforms we cover, so a parser written for LinkedIn also works for TikTok or X. On a member profile, `author.id` is the vanity slug from the URL; on a company page it's the numeric company id. Both are strings. The [response schema](/docs/response-schema) lists every field. Two cheaper habits worth building early: - **Cache on your side.** Every repeat of a call is charged, so store profiles you've fetched instead of re-requesting them. For retries after a timeout, send an `Idempotency-Key`: a replay costs 0. - **Pick the right depth.** `/profile` gives you identity and counts. If you also need experience, education and skills, `/profile/complete` returns them in one 100-credit call instead of four separate 50-credit calls. It's a beta endpoint: the fields keep LinkedIn's own structure, with string ids, ISO times and snake_case keys. ## How do I get a company page and its posts? Company endpoints other than `/company` itself take a numeric `company_id`, which you can't read off the page URL. Resolve it once with `/company` (it comes back as `data.author.id`), store it, and reuse it. ```python def get(path, **params): return requests.get(f"{BASE}/{path}", params=params, headers=HEADERS, timeout=60).json() company = get("linkedin/company", url="https://www.linkedin.com/company/hubspot/") company_id = company["data"]["author"]["id"] print(company["data"]["author"]["display_name"], "id", company_id) posts = get("linkedin/company/posts", company_id=company_id, sort_by="recent") for item in posts["data"]["items"]: post = item["post"] likes = post["engagement"]["likes"] print(post["published_at"], likes, post["url"]) ``` That's two calls and 100 credits. If all you need is a snapshot for a dashboard, `/v1/linkedin/profile/full` (beta) does both in one 50-credit call. Despite the name, it takes a company page URL and returns the company and its recent posts together. Set `posts` from 1 to 100 (default 25); LinkedIn serves company posts 10 at a time, so pass the returned `posts_cursor` back as `cursor` for the next batch. It doesn't compute engagement figures: divide each post's likes, comments and shares by the company's follower count yourself. LinkedIn doesn't publish view counts on posts, so `engagement.views` is always `null`. For a company you only know by its website, `/v1/linkedin/company/by-domain?domain=hubspot.com` returns the same record, including the `company_id`. ## How do I search LinkedIn people through an API? `/v1/linkedin/search/people` takes a keyword plus optional filters. The filters want LinkedIn's own ids, and there are cheap lookup endpoints for each one: | Filter | Where the id comes from | Lookup cost | | --- | --- | --- | | `current_company`, `past_company` | `/v1/linkedin/company` (`author.id`) | 50 | | `geocode_location` | `/v1/linkedin/search/location` | 10 | | `school` | `/v1/linkedin/search/schools` | 10 | | `industry` | `/v1/linkedin/search/industry` | 10 | | `title` | Free text, no lookup | 0 | A search page returns up to 10 people and costs 100 credits. By default the follower figure on each row is LinkedIn's rounded display number, and `author.followers_approximate` is `true`. Add `include=profile` to join each row to that member's full profile in the same call. That adds 40 credits per row it fills, and the page is capped at 500 credits. Use `limit` (1 to 10) to cap both the rows and the extra cost. ```javascript const search = new URL(`${BASE}/linkedin/search/people`); search.searchParams.set("query", "growth marketing"); search.searchParams.set("title", "Head of Growth"); search.searchParams.set("geocode_location", "103644278"); // from /search/location const page = await (await fetch(search, { headers })).json(); for (const row of page.data.items) { console.log(row.author.display_name, row.author.url); } console.log("cost", page.credits_used); ``` ## How does pagination work? List endpoints return a `pagination` object next to `data`. Send `pagination.next_cursor` back as the `cursor` parameter exactly as you got it (it starts with `v2c.` and works with the same parameters for 24 hours), and stop when `has_more` is `false`. Don't judge completeness by an empty page or a total count. The [pagination docs](/docs/pagination) cover the details. This helper walks any LinkedIn list and stops at a page cap, so a large result can't quietly eat your balance: ```python def walk(path, max_pages=5, **params): cursor, spent = None, 0 for _ in range(max_pages): query = dict(params, **({"cursor": cursor} if cursor else {})) res = requests.get(f"{BASE}/{path}", params=query, headers=HEADERS, timeout=120) if res.status_code in (429, 503): time.sleep(float(res.headers.get("Retry-After", 2))) continue # retry the same cursor body = res.json() if not body["success"]: raise RuntimeError(f'{body["error"]["type"]} {body["request_id"]}') spent += body["credits_used"] yield from body["data"]["items"] page = body.get("pagination") or {} if not page.get("has_more"): break cursor = page["next_cursor"] print(f"{path}: {spent} credits") people = list(walk("linkedin/search/people", max_pages=3, query="data engineer", current_company=company_id)) ``` Each key allows 60 requests a minute and 10 in flight. Going over returns a `429` with a `Retry-After` header, and a rejected request costs nothing. Pages of one list are sequential because each needs the previous cursor, but you can walk several lists in parallel. The [rate limits page](/docs/rate-limits) explains how to size a job. ## What does a real LinkedIn job cost? Here is a realistic B2B research job, costed from the published prices: 1. Snapshot 5 competitor company pages with their latest posts: 5 × `/profile/full` at 50 = **250** 2. Resolve those 5 companies' `company_id` for filtering: 5 × `/company` at 50 = **250** 3. Find decision-makers: 5 people-search pages (50 rows), no join, at 100 = **500** 4. Pull the full profile for the 25 best matches: 25 × `/profile` at 50 = **1,250** 5. Read the comments on 5 of the competitors' top posts: 5 × `/post/comments` at 50 = **250** **Total: 2,500 credits.** That fits inside one month of the Pro plan (10,000 credits for $9.99/month), with room to run it three more times. On the free plan's 500 credits you'd get through steps 1 and 2, or about 10 profile lookups. Four things bring the real number down: - **Failed and empty calls cost 0.** A private or deleted profile doesn't charge you. - **Make reruns resumable.** Every call is charged, including a repeat, so have your script skip profiles it already stored. - **Shared-cache hits cost 2 credits.** If someone recently fetched the same public page, you get it from our cache. - **Metered calls settle at actual usage.** Search pages often come in under their ceiling. You can check prices without spending anything: `GET /v1/endpoints` is public, needs no key, and returns every endpoint's price and cache window as JSON. Every data endpoint also accepts `dry_run=1`, which returns the price range in `data.dry_run` (`credits_min`, `credits_max`) for 0 credits. Your balance is shared with extension exports, and `GET /v1/credits` shows both kinds of usage. Plans are on the [pricing page](/pricing). ## How do I scrape LinkedIn responsibly? A few rules we'd follow even if nobody enforced them: - **Stick to public data.** These endpoints return public profiles, pages and posts. There's no endpoint for private messages or anyone's inbox, and you never hand over a LinkedIn login. - **Know the platform's terms.** LinkedIn's User Agreement bans scraping and unauthorized automated access to its services. Using a third-party API means you aren't logging in with your own account, but it doesn't make privacy law go away. - **Collect what the job needs.** If you only need job titles for a market map, don't store phone numbers. GDPR and similar laws apply to personal data even when it's public. - **Give people a way out.** If you use the data for outreach, honor opt-outs and delete records you no longer need. This is general guidance, not legal advice. If LinkedIn data is central to your product, talk to a lawyer. ## Can an AI agent write this integration? Yes. The API is plain REST with one header, so coding agents handle it well. Point Claude, Cursor or another agent at the [AI agents page](/docs/ai-agents), which lists what to hand it. For the broader picture across platforms, see the [social media API overview](/social-media-api). ## FAQ ### Do I need a LinkedIn account to use the API? No. You authenticate with your InsightSocial API key only. Your own LinkedIn account is never connected, so it can't be flagged for automation. ### Is there a LinkedIn people search API? Yes. `/v1/linkedin/search/people` takes a keyword plus title, company, school, industry and location filters, and returns up to 10 people per page for 100 credits. Add `include=profile` to join each row to the full profile, at 40 credits more per row and at most 500 credits a page. ### Can I get email addresses from LinkedIn profiles? Only what a member chooses to show publicly. `/v1/linkedin/profile/contact` returns the contact details on the profile, such as websites, phone numbers and a Twitter handle. Most members don't publish an email, and we don't guess one. ### How many LinkedIn profiles can I pull per month? At 50 credits per profile, the free plan's 500 credits covers about 10 (plus your 10 free calls), and Pro's 10,000 covers about 200. For more, buy credit packs, which never expire. Rate limits allow 60 requests per minute per key. ### Why does people search return rounded follower counts? Search rows carry the figure LinkedIn displays in results, which is rounded. Add `include=profile` to get the exact count on each row. `author.followers_approximate` tells you which kind you have. ### What happens when a call fails? You aren't charged. The response has `success: false`, `credits_used: 0` and an `error.type` to branch on. Retry only transient types such as `RATE_LIMITED` or `SERVICE_UNAVAILABLE`. The rest fail the same way until you change the request. ### Is this the same data as the Chrome extension? It's the same LinkedIn and the same credit balance, but a different way in. The extension captures what's on your screen as you browse. The API fetches public pages on request from your server. Use the [extension](/scraper/linkedin) for one-off exports and the API for anything scheduled or built into a product. --- # How to Scrape Reddit Posts and Comments with Python (2026) Source: https://www.insightsocial.app/blog/reddit-scraping-api-guide-2026, updated 2026-10-18 > Tutorial: scrape subreddit posts, keyword search, full comment trees and user profiles from Reddit with Python, Node.js or cURL, and what it costs. - **Published**: 2026-09-24 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: api, reddit, developers, scraping, python, nodejs - **Reading time**: 12 min read - **Web version**: https://www.insightsocial.app/blog/reddit-scraping-api-guide-2026 --- This tutorial shows how to scrape Reddit posts and comments with Python. Reddit is where people say what they actually think about a product, a job, a framework or a brand, usually in long threads with the replies nested five levels deep. That makes it one of the most useful sources for market research, support mining and brand monitoring, and one of the more annoying ones to collect programmatically. This guide shows how to get Reddit data out as clean JSON with our [Reddit scraper API](/social-media-api/reddit): a subreddit's feed, a keyword search across all of Reddit, the complete comment tree under a post, and a user's profile and history. Every example is a plain HTTPS `GET`, so it works from any language. If you don't write code, skip to the end for the no-code route. ## What Reddit data can you get from the API? The Reddit section of the API has 14 endpoints, all under `https://api.insightsocial.app/v1/reddit/`. These are the ones this guide uses: | Endpoint | What you get | Credits | | --- | --- | --- | | `/subreddit` | Posts from one subreddit: title, body, score, comment count, author, permalink, timestamp | 10 | | `/subreddit/details` | Subscribers, active users, description, rules, creation date | 10 | | `/search` | Posts matching a keyword across all of Reddit, with bodies included | 10–300 | | `/subreddit/search` | Posts matching a keyword inside one subreddit | 10–260 | | `/post` | One post by URL, with body and engagement | 10 | | `/post/comments` | The full nested comment tree for a post | 50 | | `/search/comments` | Comments matching a phrase, with the parent post inline | 10 | | `/profile` | A user's karma split, cake day, bio, avatar, trophies | 10 | | `/profile/posts` | A user's submissions, newest first | 10 | | `/profile/comments` | A user's comment history | 20–2,000 | A range means the endpoint is **metered**: we hold the top of the range when the call starts and charge what the call actually read. The full list, including `/subreddits/search`, `/search/media`, `/post/transcript` and `/omni-search`, is on the [Reddit platform page](/docs/platforms/reddit), and every price is on [Endpoint pricing](/docs/endpoint-pricing). ## How do I get set up? You need one thing: an API key. Sign up, open the API section of the portal, and create a key. Keys start with `isk_live_` and go in the `x-api-key` header. There is no Reddit app to register and no OAuth flow to run. ```bash ``` Sanity-check it with the free balance endpoint: ```bash curl "https://api.insightsocial.app/v1/credits" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` The free plan gives you 500 credits a month, and your first 10 calls priced at 100 credits or less cost nothing at all. That covers the subreddit, post and comment examples below. Search is the exception: a metered call reserves its ceiling before it runs, and `/search` with `max_pages=2` holds 600 credits, more than the free plan's 500. Run it with Pro or a credit pack, or drop `max_pages` for a single page. You're only charged what the call actually reads. The [quickstart](/docs/quickstart) covers the same steps in more detail. Every response uses the same envelope: `success`, `schema_version` (`"2"`), `data`, `unavailable`, `credits_used`, `credits_remaining`, and on list endpoints a `pagination` object. Rows live in `data.items`, and each item wraps either a `post` or a `comment`. Ids are strings and times are ISO 8601 in UTC. ## How do I scrape a subreddit's posts? Start with the community itself. `/subreddit/details` is a cheap way to confirm the name is right (it's case-sensitive here) and see how big the community is: ```bash curl "https://api.insightsocial.app/v1/reddit/subreddit/details?subreddit=dataengineering" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` Then pull the feed. `/subreddit` takes `sort` (`best`, `hot`, `new`, `top`, `rising`) and, with `sort=top`, a `timeframe` of `day`, `week`, `month`, `year` or `all`. This Python script walks three pages of the month's top posts in r/dataengineering and writes them to a CSV: ```python KEY = os.environ["INSIGHTSOCIAL_API_KEY"] URL = "https://api.insightsocial.app/v1/reddit/subreddit" params = {"subreddit": "dataengineering", "sort": "top", "timeframe": "month"} rows, spent = [], 0 for page in range(3): body = requests.get(URL, params=params, headers={"x-api-key": KEY}, timeout=60).json() if not body["success"]: print(body["error"]["type"], body["error"]["message"]) break spent += body["credits_used"] for item in body["data"]["items"]: post = item["post"] ext = post["ext"] or {} eng = post["engagement"] rows.append({ "title": ext.get("title"), "author": post["author"]["username"], "score": eng.get("likes"), "comments": eng.get("comments"), "flair": ext.get("flair"), "url": post["url"], "published_at": post["published_at"], }) pagination = body.get("pagination") or {} if not pagination.get("has_more"): break params["cursor"] = pagination["next_cursor"] with open("dataengineering_top_month.csv", "w", newline="") as f: writer = csv.DictWriter(f, fieldnames=rows[0].keys() if rows else ["title"]) writer.writeheader() writer.writerows(rows) print(f"{len(rows)} posts, {spent} credits") ``` Two details worth knowing. First, the pagination rule is the same on every list endpoint: send `pagination.next_cursor` back as `cursor`, and stop when `has_more` is `false`. Don't stop on an empty page or a row count. Cursors start with `v2c.` and are opaque, so pass them back untouched, with the same parameters, within 24 hours. Second, read `unavailable` on each page. It lists fields Reddit normally shows that this page could not fill on any row. On subreddit feeds it usually holds `items[].post.author.id`: Reddit post lists carry the author's username but not their account id, so key authors on `author.username`. Reddit has no public view count either, so `engagement.views` is always `null`. The [pagination guide](/docs/pagination) covers both. ## How do I search Reddit by keyword? `/search` looks across all of Reddit and returns post bodies at `ext.selftext` at no extra cost. It takes `sort` (`relevance`, `new`, `top`, `comment_count`; this is Reddit's own search ranking) and `timeframe`, plus two filters that save you post-processing: `max_age_days` keeps only recent rows, and `max_pages` (1 to 5) walks several pages in a single request. Here it is in Node.js, looking for a week of discussion about a product category: ```javascript const KEY = process.env.INSIGHTSOCIAL_API_KEY; const url = new URL("https://api.insightsocial.app/v1/reddit/search"); url.searchParams.set("query", "self-hosted analytics"); url.searchParams.set("sort", "new"); url.searchParams.set("max_age_days", "7"); url.searchParams.set("max_pages", "2"); const res = await fetch(url, { headers: { "x-api-key": KEY } }); const body = await res.json(); if (!body.success) { console.error(body.error.type, body.error.message); process.exit(1); } for (const { post } of body.data.items) { const sub = post.ext?.subreddit; const title = post.ext?.title ?? post.content.text?.slice(0, 80); console.log(`r/${sub} ${post.engagement.likes ?? 0} pts ${title}`); console.log(` ${post.url}`); } console.log(`credits used: ${body.credits_used}`); ``` To search inside one community, you have two options. `/subreddit/search` does it directly, but that source sends no post body unless you add `include_body`, which costs extra. The cheaper habit is to call `/search` with `query=subreddit:dataengineering your terms`, which returns bodies for free. When the phrase you care about lives in replies rather than titles, use `/search/comments` instead. It's a flat 10 credits and every hit carries its parent post inline (`ext.post_title`, `ext.subreddit`, `ext.post_url`), so you don't need a second call to know what thread a comment came from. ## How do I scrape the comments on a Reddit post? Give `/post/comments` a post URL and it returns the whole discussion as a tree for 50 credits: each comment has `text`, `author`, `engagement.likes` (the score), `engagement.replies`, `parent_id`, `ext.depth` and its own `replies[]` array. A top-level comment has `parent_id: null`; a reply carries its parent comment's id. A comment whose score is below zero has `engagement.likes: null` and the score in `ext.score`. ```bash curl "https://api.insightsocial.app/v1/reddit/post/comments?url=https://www.reddit.com/r/Python/comments/POST_ID/slug/" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` Most analysis wants a flat table, so flatten the tree yourself. This keeps the depth and the parent so you can rebuild the thread later: ```python def flatten(comments, parent=None, out=None): out = [] if out is None else out for c in comments: ext = c["ext"] or {} out.append({ "id": c["id"], "parent": c["parent_id"] or parent, "depth": ext.get("depth"), "author": c["author"]["username"], "score": c["engagement"]["likes"] if c["engagement"]["likes"] is not None else ext.get("score"), "text": c["text"], }) flatten(c["replies"] or [], c["id"], out) return out top_level = [item["comment"] for item in body["data"]["items"]] table = flatten(top_level) ``` On big threads, watch `data.truncated`. If it's `true`, Reddit cut the thread short, so keep paging with `pagination.next_cursor` while `has_more` is `true`. Removed comments come back with `text: null` rather than the literal `[deleted]`, which keeps them from polluting sentiment counts. The API returns comments as written and doesn't score sentiment. If you need it, run your own classifier or model over `text`; `language` tells you which model to send each comment to. ## How do I get a Reddit user's profile and history? Three endpoints cover a user. `/profile` is the account itself: ```bash curl "https://api.insightsocial.app/v1/reddit/profile?handle=spez" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` The karma split is at `data.author.ext.post_karma`, `comment_karma` and `awardee_karma`. Note that `author.followers` is `null` on purpose: Reddit doesn't publish a public follower count, so karma is the reach signal you get. `/profile/posts` returns their submissions across every subreddit (with `sort` and `timeframe`), at 10 credits a page. `/profile/comments` returns their comment history; its `limit` (1 to 100, default 25) controls how deep one call reads, and `before=YYYY-MM-DD` walks further back. It's metered from 20 up to 2,000 credits, so keep `limit` modest until you know you need the full history. One gotcha: an account with no posts and an account that doesn't exist both return an empty list from `/profile/posts`. Call `/profile` first if you need to tell them apart. ## What does it cost to scrape Reddit? Pricing is per endpoint in credits, and the rules are designed so you don't pay for nothing: - **Failed and empty calls cost 0.** Errors, `404`s and searches with no results are never charged. - **Repeats are charged.** Re-running the same call is billed again, so store the results you need. - **Shared-cache hits cost 2 credits.** If someone recently fetched the same public data, you pay 2 instead of the full price, and `cached: true` tells you so. - **Metered calls settle below the ceiling.** You're charged what the call read, never more than the top of the range. A rough budget: 10 subreddits, three pages of top posts each, is 30 calls at 10 credits apiece, 300 credits. Add `/post/comments` on the 20 busiest threads at 50 each and you're at 1,300 credits for a solid week of research. The free plan covers exploration; Pro is $9.99/month for 10,000 credits. Details on [Credits](/docs/credits) and [Pricing](/pricing). Before a large job, add `dry_run=1` to any endpoint, such as `/search` or `/post/comments`. It returns the price range in `data.dry_run` (`credits_min`, `credits_max`) and costs nothing. ## How do I handle rate limits and errors? Each key allows 60 requests per minute and 10 in flight at once. Over either limit you get a `429` with a `Retry-After` header, and nothing is charged. Branch on `error.type`, retry only the transient ones (`RATE_LIMITED`, `CONCURRENCY_LIMIT`, `SERVICE_UNAVAILABLE`, `UPSTREAM_ERROR`, `INTERNAL_ERROR`), and when paginating, retry the **same** cursor rather than skipping ahead. Adding an `Idempotency-Key` header makes a retried call free if the first attempt actually succeeded. The [errors reference](/docs/errors) lists every type. ## What about Reddit's official API? Reddit runs its own Data API, which requires registering an app, authenticating with OAuth, and accepting Reddit's developer terms. If you're building something that posts, votes or moderates, or you need Reddit's blessing for a commercial product, that's the route to evaluate, and you should read Reddit's current terms and rate limits directly on their developer pages, since they have changed over the years. If you only need to read public posts, comments and profiles as JSON, a data API like this one skips the app registration and gives you the same response shape you'd get for 21 other platforms. ## Can I do this without writing code? Yes. The [InsightSocial Chrome extension](/scraper/reddit) scrapes Reddit posts, search results, subreddits and a user's comments from inside your own browser and exports them to CSV or Excel. It draws on the same credit balance as the API, so you can mix the two. And if you're wiring Reddit data into an AI agent, point it at the free, keyless catalogue at `GET /v1/endpoints?platform=reddit` so it plans calls from real parameters and prices. The [AI agents guide](/docs/ai-agents) has a paste-in prompt. ## FAQ ### Do I need a Reddit account or developer app to use this? No. You need an InsightSocial API key in the `x-api-key` header. There's no Reddit app, client ID or OAuth token involved. ### Can I get every comment on a large thread? Yes, with paging. `/post/comments` returns the tree and flags `data.truncated` when it's incomplete; keep following `pagination.next_cursor` while `has_more` is `true`. ### How far back can I search? `/search` and `/subreddit` accept `timeframe` values up to `all`, and `/profile/comments` walks back with `before=YYYY-MM-DD`. How much history exists depends on what Reddit itself still serves. ### Is there a free tier? Yes. The free plan includes 500 credits per month, and your first 10 calls priced at 100 credits or less are free. Failed and empty calls never cost anything. ### How do I scrape a Reddit user's posts and comments? Call `/v1/reddit/profile/posts` (10 credits a page) for their submissions and `/v1/reddit/profile/comments` (20 to 2,000 credits, metered; set `limit`) for their comments. Without code, the InsightSocial extension exports a user's comments from their profile page. ### Does the same code work for other platforms? Mostly. The envelope, pagination rule, error types and the post and comment schemas are shared across all 22 platforms, so switching from `/v1/reddit/search` to another platform's search is usually a path change. See the [platform docs](/docs/platforms/reddit) and the [API overview](/social-media-api). ### Why did a call cost less than the listed price? Check `charge_reason` in the response: `shared_cache` costs 2 credits, `replay` costs 0, and on metered endpoints `miss` charges only what the call read. --- # How to Scrape TikTok with Python, Node and cURL (2026) Source: https://www.insightsocial.app/blog/tiktok-scraping-api-guide-2026, updated 2026-10-18 > Tutorial: scrape TikTok profiles, videos, comments, search results and transcripts with Python, Node.js or cURL, plus pagination and real costs. - **Published**: 2026-09-24 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: api, tiktok, developers, python, node, scraping - **Reading time**: 11 min read - **Web version**: https://www.insightsocial.app/blog/tiktok-scraping-api-guide-2026 --- Not a developer? The free [InsightSocial Chrome extension](/scraper/tiktok) exports a TikTok profile's videos, comments and followers to Excel from the page you're on. For code, read on. This tutorial shows how to scrape TikTok with Python, Node and cURL using our [TikTok scraper API](/social-media-api/tiktok): profiles, videos, comments, search results and transcripts, with code you can paste. It's for people who write code. If you just want a spreadsheet of a creator's videos, you don't need any of this: our [TikTok profile scraping walkthrough](/blog/how-to-scrape-tiktok-profiles) uses the free Chrome extension and takes two minutes, and the [TikTok scraper page](/scraper/tiktok) covers everything else it can export. If you're building something (a creator database, a brand monitor, a trend dashboard, an AI agent that needs TikTok context), read on. By the end you'll have working code for every common TikTok read, a pagination loop you can reuse, and a way to price a job before you run it. ## Why not just use TikTok's official API? Because for most developers it isn't an option. TikTok offers two relevant products, and neither fits a commercial "read public data" use case: - **The Research API** is limited to qualifying academic and non-profit researchers in specific regions, and applicants must be independent of commercial interests. Approved projects get a daily quota (1,000 requests per day, as of October 2026). - **The Display API** only reads the account of a user who has signed in with TikTok and granted your app permission. It cannot look up an arbitrary public creator. So if you need to read public accounts you don't control, you either run your own scraper or call a third-party API. Running your own means headless browsers, rotating residential proxies, request signing that TikTok changes without notice, and a parser you'll rewrite every few months. We compare the API options in [Best TikTok data APIs for developers](/blog/best-tiktok-data-apis-2026). This post shows the InsightSocial route. ## What do you need before the first call? One key and nothing else. Sign in, open the API section of the portal, and your first key is created automatically. Keys start with `isk_live_`. We store them hashed and encrypted, and you can reveal a key again in the dashboard whenever you need it. Put it in an environment variable: ```bash ``` Every request is a `GET` to `https://api.insightsocial.app/v1/...` with an `x-api-key` header. There's no OAuth dance and no per-platform setup. The full walkthrough is in the [quickstart](/docs/quickstart). You also get your first 10 calls free (any call priced at 100 credits or less), and the free plan includes 500 credits a month. That's enough to run every example in this post. ## How do you scrape a TikTok profile? `GET /v1/tiktok/profile` takes a `handle` (no `@`) or a numeric `user_id` and costs 10 credits. ```bash curl "https://api.insightsocial.app/v1/tiktok/profile?handle=nasa" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` The payload sits under `data.author`: display name, bio, follower count, likes, verification and user id (`author.id`, always a string). Store the id and send it back as `user_id`. It survives username changes, and the docs note it gives faster responses. A link in the bio is in `author.external_url`; `author.url` is the TikTok profile itself. If you want the profile and its latest videos in one shot, `GET /v1/tiktok/profile/full` (50 credits, beta) returns both. It doesn't compute engagement rates for you; with the follower count and each video's `engagement` you have everything you need, as the next section shows. ## How do you get a creator's videos? `GET /v1/tiktok/profile/videos` returns a page of recent public videos with caption, views, likes, comments, shares and a thumbnail. It costs 10 credits per page. Here's a Python helper we'll reuse for the rest of the post: ```python BASE = "https://api.insightsocial.app/v1" HEADERS = {"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]} def get(path, **params): body = requests.get(f"{BASE}/{path}", params=params, headers=HEADERS, timeout=120).json() if not body["success"]: raise RuntimeError(f'{body["error"]["type"]}: {body["error"]["message"]}') return body page = get("tiktok/profile/videos", handle="nasa") for item in page["data"]["items"]: post = item["post"] eng = post["engagement"] followers = (post["ext"] or {}).get("author_followers") interactions = sum(eng[k] or 0 for k in ("likes", "comments", "shares")) rate = interactions / followers if followers else None # engagement rate by followers print(post["kind"], eng["views"], rate, post["url"]) print("cost:", page["credits_used"], "left:", page["credits_remaining"]) ``` Every post comes back in the same [unified post shape](/docs/schema/post) regardless of platform: `content.text` for the caption, `engagement.views/likes/comments/shares/saves`, `published_at` as ISO 8601 UTC, `kind` (`short` for a TikTok video) and `author.id`. TikTok extras live under `ext`, including `ext.music_id` (feed it to `/v1/tiktok/song/videos`) and `ext.author_followers`, which is what the engagement rate above divides by. For a single video you already have a link to, `GET /v1/tiktok/post?url=...` (10 credits) returns it in full, including any on-screen text the creator typed with TikTok's text tool. ## How does pagination work? Every list endpoint uses the same rule: send `pagination.next_cursor` back as the `cursor` parameter, unchanged, and stop when `pagination.has_more` is `false`. Cursors are opaque strings starting with `v2c.`. Don't decode or edit them, send them with the same parameters as the first call, and use them within 24 hours. Details are on the [pagination page](/docs/pagination). In Node: ```javascript const BASE = "https://api.insightsocial.app/v1"; async function* paginate(path, params, maxPages = 5) { let cursor = null; for (let n = 0; n < maxPages; n++) { const url = new URL(`${BASE}/${path}`); for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v); if (cursor) url.searchParams.set("cursor", cursor); const res = await fetch(url, { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY }, }); const body = await res.json(); if (!body.success) throw new Error(`${body.error.type}: ${body.request_id}`); yield* body.data.items; if (!body.pagination?.has_more) return; cursor = body.pagination.next_cursor; } } for await (const item of paginate("tiktok/profile/videos", { handle: "nasa" }, 3)) { console.log(item.post.engagement.views, item.post.url); } ``` Note the `maxPages` cap. Every page is billed as its own call, so an uncapped walk of a prolific creator can cost more than you meant to spend. For a daily poll, `profile/videos` also takes `since` (a date or ISO timestamp) and `stop_at_id` (the newest video you already hold). The walk ends as soon as it reaches known territory, so a creator who posted once yesterday costs you one page, not ten. ## How do you scrape TikTok comments and replies? `GET /v1/tiktok/post/comments?url=...` returns a page of comments with the commenter's username, text, like count, reply count and timestamp, metered at 10–30 credits per page. Add `sort=recent` for newest first, and `scan_pages` (1 to 3) to read several pages and drop duplicates in one request. ```python comments = get( "tiktok/post/comments", url="https://www.tiktok.com/@nasa/video/", sort="recent", ) for item in comments["data"]["items"]: c = item["comment"] print(c["engagement"]["likes"], c["language"], c["text"]) ``` The API returns comments as written, without sentiment or other labels, so run your own classifier over `text` if you need one. Top-level comments have `parent_id: null`. Replies to a specific comment come from `GET /v1/tiktok/video/comment/replies` with `comment_id` and the video `url`. ## How do you search TikTok by keyword or hashtag? Four search endpoints cover most discovery work: | Endpoint | Finds | Credits | | --- | --- | --- | | `/v1/tiktok/search/top` | Videos TikTok ranks highest for a keyword | 10 | | `/v1/tiktok/search` | Videos for a keyword, with date and sort filters | 10–370 | | `/v1/tiktok/search/hashtag` | Videos under a hashtag | 10 | | `/v1/tiktok/search/users` | Accounts matching a term | 10–1,310 | The video searches accept filters that run on our side: `min_views`, `max_age_days` and `sort_rows=views`, plus `country` on `/search` and `/search/top` (keep videos registered to, say, `US,GB`; `/search/hashtag` takes `region` instead). They also take `max_pages` (1 to 5), which walks several pages in one request and uses only one slot of your rate limit. ```bash curl -G "https://api.insightsocial.app/v1/tiktok/search/hashtag" \ --data-urlencode "hashtag=skincare" \ --data-urlencode "min_views=100000" \ --data-urlencode "max_pages=2" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` Each page walked is billed as one call, so with `max_pages=2` on this 10-credit endpoint the call costs at most 20 credits. The ceiling is always the listed maximum times `max_pages`. ## Can you get a TikTok video's transcript? Yes. `GET /v1/tiktok/post/transcript?url=...` returns the spoken text in `data.transcript`, for 100 credits: `text` holds the whole transcript as one string, `language` the caption track's language, and `segments` the timed cues when TikTok has them (otherwise `null`). It reads the video's captions, and `use_ai_as_fallback=true` switches to AI transcription when there are none. Pass `language=es` (or another two-letter code) to pick a caption track. ```bash curl -G "https://api.insightsocial.app/v1/tiktok/post/transcript" \ --data-urlencode "url=https://www.tiktok.com/@nasa/video/" \ --data-urlencode "use_ai_as_fallback=true" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` If the text you care about is burned into the video rather than spoken, `GET /v1/tiktok/video/screen-text` (50 credits) returns native text stickers plus OCR of the cover frame. Our [video transcription recipe](/docs/recipes/video-transcription-api) covers the same idea across platforms. ## What does a real TikTok job cost? Say you're vetting 10 creators for an influencer campaign. For each one you want the profile, one page of recent videos, the comments on their three best videos, and a transcript of their top video so you can check how they talk about sponsors. | Step | Calls | Credits per call | Credits | | --- | --- | --- | --- | | Profiles | 10 | 10 | 100 | | Recent videos (1 page each) | 10 | 10 | 100 | | Comments (1 page, top 3 videos each) | 30 | 10–30 | 300–900 | | Transcripts (top video each) | 10 | 100 | 1,000 | | **Total** | **60** | | **1,500–2,100** | Metered endpoints are billed on what the call actually read, so the real number lands somewhere in that range. Before the call runs we hold the ceiling against your balance, then settle the actual and release the rest. You never pay more than the ceiling. On the Pro plan ($9.99/month for 10,000 credits), the worst case for that job is under half a month's credits. On the free plan's 500 credits you could run the profiles and a few video pages. A few things make it cheaper in practice: - **Failed or empty calls cost 0.** A deleted video or a typo'd handle is free. - **Store what you fetch.** Every repeat of a call is charged, so keep responses you'll need again instead of re-requesting them. - **Shared-cache hits cost 2 credits.** If someone recently requested the same public data, you get it for 2 instead of the full price. - **`dry_run=1`** on any data endpoint returns the price range in `data.dry_run` (`credits_min`, `credits_max`) without charging anything. Every endpoint's price is on the [TikTok platform page](/docs/platforms/tiktok) and the full [endpoint pricing](/docs/endpoint-pricing) table. `GET /v1/endpoints?platform=tiktok` returns the same catalogue as JSON, needs no key, and costs nothing, which makes it the right thing to hand an [AI coding agent](/docs/ai-agents) before it writes your integration. ## What are the rate limits? Each key gets 60 requests per minute and 10 in flight at once. Over either limit you get a `429` with a `Retry-After` header, and a rejected request is never charged. On a `429` or `503`, wait and retry the same cursor. Don't skip ahead past a page you didn't read. If one key isn't enough, you can create up to 25 on an account; they share one credit balance. See [rate limits](/docs/rate-limits). Add an `Idempotency-Key` header with a fresh UUID per logical request. A retry after a timeout then comes back as a replay at 0 credits instead of a second charge. ## FAQ ### Is scraping TikTok legal? Reading publicly visible data is generally treated differently from accessing private accounts or bypassing a login, but the rules depend on your jurisdiction and what you do with the data, especially personal data under laws like GDPR. Don't collect more personal data than you need, and get legal advice for anything sensitive. ### Do I need a TikTok account or TikTok's approval? No. You need an InsightSocial API key. You don't log in to TikTok, connect an account, or apply to TikTok for access. ### Which language should I use? Any language that can send an HTTP GET with a header. The examples here are Python, Node and cURL because they cover most teams, but there's no SDK to install. ### How do I get all of a creator's videos? Walk `/v1/tiktok/profile/videos` with the cursor loop above until `has_more` is `false`. For recurring jobs, pass `since` or `stop_at_id` so you only pay for pages with new videos. ### Can I use the same key for other platforms? Yes. The same key and the same credit balance cover 22 platforms, including YouTube, X, LinkedIn, Reddit and Pinterest, and posts come back in the same shape on every platform. See the [social media API overview](/social-media-api). ### How do I start for free? Create an account and get a key. Your first 10 calls (priced 100 credits or less) are free, and the free plan adds 500 credits every month. For more, see Pro and credit packs on the [pricing page](/pricing). --- # How to Scrape Tweets Without an X Developer Account (2026) Source: https://www.insightsocial.app/blog/twitter-x-scraping-api-guide-2026, updated 2026-10-18 > Tutorial: scrape tweets, profiles, search results and replies with Python, Node.js or cURL, no X developer account needed. Pagination and costs. - **Published**: 2026-09-24 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: api, twitter, developers, x, python, node, tutorial - **Reading time**: 12 min read - **Web version**: https://www.insightsocial.app/blog/twitter-x-scraping-api-guide-2026 --- This tutorial shows how to scrape tweets with Python and Node.js, without applying for an X developer account. If you need public X data in a script, a pipeline or an agent, you have three realistic options: pay for the official X API, maintain your own headless-browser scraper, or call a data API that has already done the scraping work. This guide covers the third route with our [Twitter/X scraper API](/social-media-api/twitter): how to read a profile, walk an account's timeline, search tweets, pull the replies under a post, and work out what the whole job will cost before you run it. Not a developer? You don't need any of this. The [InsightSocial Chrome extension](/scraper/twitter) exports profiles and tweets straight from the page you're looking at, and our [step-by-step guide to scraping Twitter profiles without code](/blog/how-to-scrape-twitter-profiles) walks through it. ## Why not just use the official X API? You can, and for some jobs you should (posting, DMs, reading your own account's data). For reading other people's public data it has two drawbacks. First, it's billed per resource: as of September 2026, X's own pricing page lists $0.005 per post read and $0.010 per user read, paid from prepaid credits, with no free tier. Second, it's X-only. If your project also touches TikTok, LinkedIn or Reddit, you end up with a separate integration, auth scheme and data model for every platform. A scraping API gives you the public side of X, returned in the same response shape as the 21 other platforms the API covers. We compare the options side by side in [the best Twitter/X data APIs in 2026](/blog/best-twitter-x-data-apis-2026). ## Why not build your own scraper? For a weekend project it's a fine way to learn. In production, X's logged-out surface shifts often, the internal GraphQL query IDs rotate, and the rate limits on guest traffic are strict. You'd spend more time maintaining the scraper than using the data it collects. Expect to budget for proxies, blocked sessions, and regular parser rewrites. ## How do you get set up? Sign in, open the API section of your dashboard, and copy the key that's created for you. Keys start with `isk_live_`. We store them hashed and encrypted, and you can reveal yours again in the dashboard whenever you need it. Put it in an environment variable: ```bash ``` Every request is a plain `GET` with one header, `x-api-key`. There's no OAuth dance and no app review. The [quickstart](/docs/quickstart) covers the response envelope in detail; the short version is that the payload sits under `data`, and every response tells you what it cost (`credits_used`) and what you have left (`credits_remaining`). Your first 10 calls priced at 100 credits or less are free, and the free plan includes 500 credits a month. That covers every example in this post, the three-page search included: a metered call holds what it can cost before it runs, and the search with `max_pages=3` holds 150 credits (50 per page at most) and is charged what it actually reads (`dry_run=1` shows the hold for free). ## How do you scrape a Twitter/X profile? `GET /v1/twitter/profile` takes a `handle` (no `@`) and returns followers, following, tweet count, bio, avatar and banner URLs, and verification status. It costs 10 credits. ```bash curl "https://api.insightsocial.app/v1/twitter/profile?handle=natgeo" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python BASE = "https://api.insightsocial.app/v1" HEADERS = {"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]} body = requests.get(f"{BASE}/twitter/profile", params={"handle": "natgeo"}, headers=HEADERS).json() if body["success"]: author = body["data"]["author"] print(author["username"], author["followers"], author["posts_count"]) print("cost:", body["credits_used"], "left:", body["credits_remaining"]) else: print(body["error"]["type"], body["error"]["message"]) ``` If you want the profile and its recent tweets in one call, `GET /v1/twitter/profile/full` (50 credits, beta) returns both. It returns the raw numbers, not computed metrics: engagement rate, posting cadence and top post are a few lines of your own code over `engagement` and `published_at`, as the next section shows. ## How do you scrape tweets from a user's timeline? `GET /v1/twitter/user/tweets` returns an account's recent tweets, newest first, about 20 per page, with full text, likes, retweets, replies, bookmarks, views, media and timestamp. It costs 10 credits per page. Here is the Node version, collecting the last three pages from National Geographic's timeline: ```javascript const KEY = process.env.INSIGHTSOCIAL_API_KEY; const url = new URL("https://api.insightsocial.app/v1/twitter/user/tweets"); url.searchParams.set("handle", "natgeo"); const tweets = []; let spent = 0; for (let page = 1; page <= 3; page++) { const body = await (await fetch(url, { headers: { "x-api-key": KEY } })).json(); if (!body.success) { console.error(body.error.type, body.error.message); break; } spent += body.credits_used; for (const item of body.data.items) { tweets.push({ url: item.post.url, text: item.post.content.text, likes: item.post.engagement.likes, views: item.post.engagement.views, published_at: item.post.published_at, // Engagement rate by followers, computed here: the API does not compute it. rate: item.post.ext?.author_followers ? ((item.post.engagement.likes ?? 0) + (item.post.engagement.comments ?? 0) + (item.post.engagement.shares ?? 0)) / item.post.ext.author_followers : null, }); } if (!body.pagination?.has_more) break; url.searchParams.set("cursor", body.pagination.next_cursor); } console.log(`${tweets.length} tweets, ${spent} credits`); ``` Every tweet uses the same unified [post object](/docs/schema/post) as posts from the other platforms, so `post.engagement.likes` means the same thing on X as it does on TikTok. X-specific extras live under `post.ext`, for example `ext.retweeted_post` for the original behind a retweet, `ext.quote_count`, and `ext.author_followers`, the follower count the rate above divides by. On a retweet X reports `likes: 0` for the retweet itself; the original's numbers are in `ext.retweeted_post.engagement`. Two things to expect on X: `post.language` is X's own language tag, and `author.id` is `null`, which the response lists in `unavailable` as `items[].post.author.id`. Key accounts on `author.username`. ### Polling a timeline without paying twice If you poll an account every day, don't re-walk pages you already have. `user/tweets` accepts `since` (a date or ISO timestamp) and `stop_at_id` (the id or URL of the newest tweet you stored). The walk ends at that boundary, `pagination.stopped_at` tells you which one ended it, and you only pay for the pages you actually fetched. Pinned tweets are out of date order and never end the walk, so don't store one as your "newest". ## How do you search tweets by keyword? `GET /v1/twitter/search/tweets` takes a `query` and an optional `sort` (`latest`, the default, or `top`). Filter by date with the `since`, `until` or `max_age_days` parameters, or put X's own operators inside the query string: `since:2026-09-01`, `until:`, `from:handle`, `min_faves:20`, `filter:images` and quoted phrases all work. ```bash curl -G "https://api.insightsocial.app/v1/twitter/search/tweets" \ --data-urlencode 'query="heat pump" since:2026-09-01 min_faves:50' \ --data-urlencode "sort=top" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` One thing to know about `sort=top`: it ranks by engagement, not relevance, so an unquoted multi-word query can return popular posts that match none of your words. Quote the phrase or add an operator. Search is metered at 10–50 credits per page. If you want several pages in a single request, add `max_pages` (1 to 5). The walk still counts as one request against your rate limit, each page is billed as one call, and the most it can cost is the listed maximum times `max_pages`. Search also has some filters we apply on our side, after each page arrives: `min_views`, `max_age_days` and `sort_rows=views`. See the [Twitter/X platform docs](/docs/platforms/twitter) for the full parameter list. ## How do you scrape replies to a tweet? `GET /v1/twitter/tweet/replies` takes the tweet's full `url` and returns the replies (not the tweet itself), each with text, author, likes, reply count and timestamp. It costs 10 credits per page and pages with the same `cursor` loop. This Python example chains two endpoints: take National Geographic's most recent tweet from the timeline, then read the conversation under it. ```python BASE = "https://api.insightsocial.app/v1" HEADERS = {"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]} def get(path, **params): body = requests.get(f"{BASE}/{path}", params=params, headers=HEADERS, timeout=120).json() if not body["success"]: raise RuntimeError(f'{body["error"]["type"]}: {body["request_id"]}') return body def paginate(path, max_pages=5, **params): cursor = None for _ in range(max_pages): query = dict(params, **({"cursor": cursor} if cursor else {})) body = get(path, **query) yield from body["data"]["items"] page = body.get("pagination") or {} if not page.get("has_more"): return cursor = page["next_cursor"] # pass it back unchanged timeline = get("twitter/user/tweets", handle="natgeo") latest = timeline["data"]["items"][0]["post"]["url"] for item in paginate("twitter/tweet/replies", url=latest, max_pages=3): c = item["comment"] print(c["author"]["username"], c["engagement"]["likes"], (c["text"] or "")[:80]) ``` A tweet with no replies returns an empty list, and an empty result costs nothing. Replies use the unified [comment object](/docs/schema/comment), so the same parser handles YouTube or Reddit comments too. A direct reply to the tweet has `parent_id: null` and `post_id` set to the tweet's id; a reply to a reply carries its parent comment's id. The API returns replies as written. It doesn't label tone or sentiment, so if you need that, run your own classifier or model over `comment.text` and `comment.language`. ## How does pagination work? The rule is the same on every list endpoint. Send `pagination.next_cursor` back as the `cursor` parameter, byte for byte, and stop when `pagination.has_more` is `false`. Don't stop on an empty page or a count, and don't decode the cursor (it's an opaque string that starts `v2c.`, valid for 24 hours with the same parameters). If a page fails with a `429` or `503`, retry the same cursor rather than skipping ahead. The full loop is in the [pagination docs](/docs/pagination). Other Twitter/X lists work the same way: `user/followers`, `user/following`, `tweet/retweeters`, `user/media` and `search/users` are 10 credits per page. ## What are the rate limits? Each key allows 60 requests per sliding minute and 10 requests in flight at once. Go over either and you get a `429` with a `Retry-After` header, and the rejected request costs nothing. There's no daily request quota: past those two ceilings, your credit balance is what limits volume. For a bulk job, that means up to 10 workers per key and roughly one request a second on average. ## What does a real Twitter/X job cost? Take a common brief: size up a brand's presence on X before a campaign. One profile, its recent timeline, a week of mentions, and the replies under its five latest tweets. Here's the budget from our published prices, with the floor and ceiling for the metered endpoints: | Step | Calls | Credits per call | Floor | Ceiling | | --- | --- | --- | --- | --- | | Profile | 1 | 10 | 10 | 10 | | Timeline, about 100 tweets | 5 pages | 10 | 50 | 50 | | Keyword search, `max_pages=3` | 3 pages | 10–50 | 30 | 150 | | Replies under 5 tweets | 5 | 10 | 50 | 50 | | **Total** | | | **140** | **260** | The actual bill lands somewhere between those two numbers, depending on how much each metered call reads. That's why the call reserves the ceiling and settles the actual, and why `credits_used` is often well below the top of the range. At the ceiling it's 260 credits, which fits in the free plan's 500 a month, because each metered call only has to cover its own ceiling when it starts. On Pro's 10,000 credits a month ($9.99, or $7.99 billed yearly) it's a small slice. Three things push the real cost down: - **Repeats are charged.** Every call is billed, including the same call twice, so store what you fetch. - **Shared-cache hits cost 2 credits.** If someone else recently fetched the same public data, you pay 2 instead of the full price. The response says `cached: true`. - **Failures and empty results cost nothing.** A handle that doesn't exist or a tweet with no replies doesn't touch your balance. To see prices without spending anything, `GET /v1/endpoints` is public, free and needs no key. The full table is at [endpoint pricing](/docs/endpoint-pricing), and the [credits docs](/docs/credits) explain metering and what is free. ## Can an AI agent use this? Yes. Every endpoint is a plain GET with one header, and the response always carries the same envelope, which suits tool-calling agents. The [AI agents guide](/docs/ai-agents) lists what to hand Claude, Cursor or another agent so it writes the integration correctly. There's also `GET /v1/twitter/ai-search` (50 credits), which answers a plain-English question about X and returns the posts it cited. ## FAQ ### Is it legal to scrape Twitter/X? Collecting publicly visible data is generally treated differently from accessing content behind a login, but the rules depend on your jurisdiction and what you do with the data. Our API returns only data anyone can see without logging in. If you process personal data, you are responsible for complying with laws such as GDPR. When in doubt, ask a lawyer. ### Can I scrape tweets without an X account or login? Yes. You don't need an X account, a developer app or cookies. The only credential is your InsightSocial API key. ### Can I get a user's full tweet history? `user/tweets` pages back through the timeline about 20 tweets at a time, as far as X shows the account's public timeline. For older material on a specific topic, `search/tweets` with `from:handle` and `since:`/`until:` operators is often the better route. ### Which programming language works best? Use what your stack already runs. Anything that can send an HTTP GET and parse JSON will do, from a Python script to a Node service to a cron job calling cURL. There's no SDK to install. ### Does this also cover other platforms? Yes. The same key and response format cover 22 platforms, including TikTok, LinkedIn, YouTube, Reddit and Pinterest. See the [social media API overview](/social-media-api). ### What happens when I run out of credits? A call that your balance can't cover is refused with a `402 INSUFFICIENT_CREDITS` before it runs, and nothing is charged. Pro and one-time packs (which never expire) are on the [pricing page](/pricing). --- # 6 Best ExportComments Alternatives for Comment Export (2026) Source: https://www.insightsocial.app/blog/exportcomments-alternatives, updated 2026-10-18 > ExportComments caps results per export. Six alternatives for exporting TikTok, YouTube, X and Reddit comments, compared on price and limits. - **Published**: 2026-07-21 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: comparison, alternatives, comments, scraping, tools - **Reading time**: 14 min read - **Web version**: https://www.insightsocial.app/blog/exportcomments-alternatives --- **The main ExportComments alternatives are InsightSocial (a Chrome extension: scraping is free, 500 exported rows a month, comment threads with replies on 6 social platforms), Apify's comment scrapers (cloud, pay per result, $5 free a month), PhantomBuster (comment-to-outreach automation, from $69 a month), Instant Data Scraper (free, generic), the YouTube Data API (free quota, YouTube only) and Thunderbit (AI scraping, from $15 a month).** ExportComments still fits one-off exports and the review sites only it covers, such as Yelp and TripAdvisor. We make InsightSocial, so we are not neutral. Prices for the other tools were checked on their own pages on October 18, 2026. ExportComments is simple: paste a post URL, get the comments back as a spreadsheet. For a single viral post, that is what you want. When comment export becomes recurring work (giveaway picking, audience research, UGC rights requests), the per-export caps start to matter. This guide covers where ExportComments pinches, then compares six alternatives with notes on where each falls short. ## Why People Look for ExportComments Alternatives The same complaints come up repeatedly from people shopping for a replacement: ### 1. The free tier is a demo, not a plan The free tier caps out at 100 results per export and 50 exports a month (checked October 2026). That's enough to confirm the tool works, and not enough for any real analysis of a post with an active comment section. ### 2. Per-export caps mean big threads get truncated Paid plans raise the cap per export (into the thousands, then tens of thousands on higher tiers), but the cap is still per export, per link. A genuinely viral post can blow past your tier's limit, and the comments beyond it simply don't come back. ### 3. One link at a time The core workflow is paste-a-URL, wait in the queue, download, repeat. ExportComments now lists automated workflows that chain exports together, but there is no one-click "export comments from this creator's last 30 posts": you paste those links one by one and merge the files. ### 4. Pricing climbs fast for what it is Premium-level plans run around $45/month and business tiers around $199/month. ExportComments covers more than comments (posts, X replies, followers, reviews), but if comments are all you need, multi-platform extensions cost the same or less. If several of these resonate, one of the tools below will probably fit you better. ## Quick Comparison | Tool | Type | Starting Price | Bulk (multi-post) Export | Best For | |------|------|---------------|--------------------------|----------| | InsightSocial | Chrome extension | Free (Pro $9.99/mo) | Yes: subreddit runs, schedulable | Social comments + posts to Excel | | Apify comment Actors | Cloud platform | $5 free credit, then usage | Yes, with setup | Developers piping comments into systems | | PhantomBuster | Cloud automation | $69/mo | Yes, scheduled | Teams chaining comments into outreach | | Instant Data Scraper | Chrome extension | Free | No | Quick one-off table grabs | | YouTube Data API | Official API | Free quota | Yes, with code | YouTube-only, developer on hand | | Thunderbit | Chrome extension (AI) | ~$15/mo | Partially | Mixed scraping across many sites | ## 1. InsightSocial: Comments and the Posts Above Them, in One Run [InsightSocial](https://chromewebstore.google.com/detail/insightsocial-free-social/cddgiejchlkeedmhjeodlcjdiddlcdld) is our Chrome extension. It exports comments (with replies, likes, timestamps, and commenter usernames) from [TikTok](/scraper/tiktok-comments-scraper), [YouTube](/scraper/youtube-comments-scraper), [X replies](/scraper/twitter-replies-scraper), [LinkedIn](/scraper/linkedin-posts-scraper) and [Reddit](/scraper/reddit-comments-scraper), directly in your browser. The workflow difference from ExportComments is that one run can cover many posts. Open a single post and scrape its thread, or open a subreddit and choose Posts and Comments: it collects a number of posts *and then visits each one* to extract its comments. One run, one export. **Pricing** meters only what you export, at 1 credit per exported row. Scraping a thread and reading it in the dashboard is free and unlimited, so you see the comment count before you spend anything. How many comments a run takes depends on the platform: up to the number you pick on TikTok (50, 100 or 250 top-level comments, with their replies) and YouTube (100, 250 or 500). Free plan: 500 export credits a month. Pro: $9.99/month for 10,000 export credits, or $95.88/year ($7.99/month). **Setup** is install → open the post or profile → click Scrape → export to Excel, CSV, JSON or Google Sheets from your results page. Because it runs inside your own logged-in browser session, the platform sees ordinary browsing from your usual IP: no queue, no third-party server touching the post. **Pros:** - Scraping a full thread is free: you only spend credits on the rows you export - Bulk mode: posts *and* their comments from a subreddit in one session - Replies keep their parent-comment link, not flattened - Also exports the posts themselves (engagement, timestamps, authors), not just comments - Free tier: unlimited scraping and 500 export rows a month - Schedulable: a creator's scrape can re-run daily or weekly on its own; you export from the results page **Cons:** - Chrome has to be open for a run, including scheduled ones; the paste-a-URL web tool covers one TikTok video's first 50 comments, nothing more - TikTok and YouTube runs stop at the comment count you pick (presets of 50 to 250 on TikTok, 100 to 500 on YouTube), so a huge thread is not collected in full by default - Comments-plus-posts runs exist on subreddits, not on TikTok, YouTube or X accounts - Very large threads take real time in your browser **Best for:** marketers, community managers, and researchers who export comments regularly and want threads complete, structured, and free to collect before deciding what to keep. ## 2. Apify Comment Actors: For Developers Piping Comments Somewhere Apify's marketplace has dedicated comment-scraper Actors for TikTok, YouTube and other major networks. They run in the cloud, output JSON or CSV, and can be scheduled or triggered by API, which makes them the right shape if comments need to land in a database rather than a spreadsheet. **Pricing** stacks a plan fee, compute units, and per-result Actor fees, which makes costs hard to predict. We've broken this down in detail in our [Apify alternatives guide](/alternatives/apify). **Pros:** - API-first: pipe comments straight into your own systems - Scheduling, webhooks, and storage built in - Handles very large jobs if you're willing to pay for them **Cons:** - Per-result pricing re-creates ExportComments' metering problem, with extra layers - Actor quality varies; datacenter IPs get challenged by social platforms - Real setup work for non-developers **Best for:** engineering-adjacent teams who need comments delivered to systems, not spreadsheets. ## 3. PhantomBuster: Comments as a Step in an Outreach Chain PhantomBuster's Phantoms can extract commenters from social posts and then feed them into follow-up automations: auto-follows, DMs, enrichment. If the reason you're exporting comments is to *contact the commenters*, that chaining is the draw. **Pricing**: a Free plan with 30 minutes of run time a month and 10-row exports, then $69/month (Start), per [its own pricing post](https://phantombuster.com/blog/ai-automation/phantombuster-pricing-explained). **Pros:** - Scrape-then-outreach workflows in one product - Cloud scheduling: runs while your laptop is closed - Mature ecosystem of pre-built automations **Cons:** - Expensive if you only want the export half - Runs with your session cookies from cloud IPs: account-risk trade-offs are real (see our [PhantomBuster alternatives guide](/blog/phantombuster-alternatives)) - Comment output is geared to lead lists, not complete threaded archives **Best for:** sales and growth teams who treat commenters as leads and accept the account risk. ## 4. Instant Data Scraper: Free, Generic, One Page at a Time Instant Data Scraper is a free Chrome extension that detects tables and lists on whatever page you're on and exports them. Point it at a visible comment section and it will often grab usernames and comment text serviceably. **Pros:** - Completely free, no account - Works on many sites, not just social platforms **Cons:** - No understanding of comment structure: nested replies, like counts, and timestamps are flattened or missed - Infinite-scroll comment sections load unreliably; you babysit the scroll - One page at a time, no bulk mode, no post metadata **Best for:** a quick one-off grab where "usernames and text in a CSV" is good enough. ## 5. YouTube Data API: Free and Official, for One Platform For YouTube specifically, the official Data API's `commentThreads` endpoint is genuinely good: complete threads, reply structure, like counts, and a free daily quota that covers most channels' needs. It's the rare official social API that actually serves this use case. **Pros:** - Free quota is generous for comment reading - Official and stable: no scraping fragility - Full thread structure including replies **Cons:** - YouTube only: nothing for TikTok, X or Reddit - You write code (or wrangle scripts) to use it; output is JSON - Quota accounting becomes a real constraint at large scale **Best for:** developers with a YouTube-only requirement. If that's you, start here before paying anyone. ## 6. Thunderbit: AI Scraping That Includes Comment Sections Thunderbit's AI-driven extraction works on almost any page, comment sections included. As with Instant Data Scraper, the generalist approach cuts both ways: it extracts *something* nearly everywhere, but social-specific structure is shallower than a dedicated tool's output, a trade-off we cover in our [Thunderbit alternatives guide](/alternatives/thunderbit). **Pricing**: one credit per output row. The free plan covers about 6 pages; Starter is $15/month for 500 credits, so a 2,000-comment thread needs a bigger plan. **Pros:** - One tool for comments today, product listings tomorrow - AI field detection: no templates to build **Cons:** - Long comment threads use credits fast, one per row - Nested reply structure and per-comment metadata are hit-or-miss **Best for:** people whose comment exports are occasional and who scrape many other kinds of pages. ## Exporting Reviews Instead of Comments ExportComments is not only a comment tool. It also exports reviews, with an `/export-{site}-reviews` page for about 20 review sites: Trustpilot, Amazon, Google, Etsy, Steam, Product Hunt, Yelp, TripAdvisor, the App Store, Airbnb, AliExpress, Best Buy, the Chrome Web Store, Expedia, Flipkart, IMDb, Lazada, Shopee and Walmart, among others (counted from its sitemap, October 2026). It also lists sentiment analysis of exported comments as a use case. InsightSocial covers fewer review sites: 10. Six overlap with ExportComments; four are discussion sites ExportComments has no page for. | Site | ExportComments | InsightSocial | |------|----------------|----------------------| | Trustpilot | Yes | Yes: splits by language and stars to get past the 10-pages-per-filter limit | | Amazon | Yes | Yes: 20 storefronts, up to about 1,200 reviews per product, sign in to Amazon | | Google Maps / Google reviews | Yes | Yes: up to 5,000 per place, Google sign-in, tab in front | | Etsy | Yes | Yes: listing or whole shop, seller replies as rows | | Steam | Yes | Yes: the 10,000 newest, all languages, playtime | | Product Hunt | Yes (reviews and comments) | Yes (reviews and launch comments) | | Hacker News | No | Yes: the full comment tree | | Quora | No | Yes: answers and their comments | | Blind | No | Yes: a post's comments | | Notion | No | Yes: public pages and databases | | Yelp, TripAdvisor, App Store, Airbnb, Walmart and the other review sites above | Yes | No | | Sentiment | Listed as a use case | No sentiment column in the export. On Pro, Ask your data answers sentiment and theme questions about a finished run | The pricing models differ the same way they do for comments. ExportComments caps results **per export**: the free tier returns up to 100 results per export, Personal is $23 once for 3 days at up to 5,000 per export, Premium $45 a month at up to 50,000, and Business $199 a month at up to 250,000 with API access (checked October 2026). InsightSocial meters **rows per month**: scraping is free, the free plan exports 500 rows a month, Pro $9.99 exports 10,000 and Studio $49 exports 150,000, and a row you already exported is free to export again. InsightSocial is also one page per run on review sites: there is no list-of-URLs input and no scheduling for them. If you need dozens of companies on a schedule, or one of the review sites it does not cover, ExportComments' Premium plan or a cloud tool is the better fit. The how-to guides for each site: [Trustpilot](/blog/how-to-export-trustpilot-reviews), [Google reviews](/blog/how-to-export-google-reviews), [Amazon](/blog/how-to-download-amazon-reviews), [Etsy](/blog/how-to-export-etsy-reviews), [Steam](/blog/how-to-export-steam-reviews), [Product Hunt](/blog/how-to-export-product-hunt-reviews), [Hacker News](/blog/how-to-export-hacker-news-comments) and [Quora](/blog/how-to-export-quora-answers), and the full list of [review scrapers](/scraper/reviews). ## Which Should You Choose? - **Regular comment exports, complete threads, nothing charged for scraping** → InsightSocial - **Comments flowing into a database or pipeline** → Apify comment Actors - **Exporting commenters to contact them** → PhantomBuster - **A free one-off grab, structure optional** → Instant Data Scraper - **YouTube only, developer available** → YouTube Data API - **Occasional comments plus lots of non-social scraping** → Thunderbit - **One viral post, once, under the free cap** → honestly, ExportComments is fine The dividing line is frequency. If you export comments once a quarter, a per-export tool is tolerable. If it's part of your workflow, per-export pricing and per-link caps are exactly the wrong model: you want a tool that collects the whole thread for free and only charges for the rows you decide to keep. ## FAQ **Is there a free way to export all comments from a post?** InsightSocial's free plan scrapes threads for free (up to the count you pick on TikTok and YouTube) and gives you 500 export rows a month, so you see the conversation before spending anything. ExportComments' free tier stops around 100 comments per post, and Instant Data Scraper is free but loses thread structure. For YouTube alone, the official API's free quota also works if you can code. **Can I export comments from multiple posts at once?** With InsightSocial, yes: Posts and Comments mode on a [subreddit](/scraper/reddit-subreddit-scraper) collects a number of posts and then each post's comments in one run. TikTok and YouTube accounts don't have that mode. ExportComments' automated workflows chain exports; check which plan includes them. **Do these tools capture nested replies?** InsightSocial and the YouTube Data API preserve reply structure (parent-comment relationships, reply counts). Generic scrapers like Instant Data Scraper typically flatten or miss replies. On ExportComments, reply coverage varies by platform. **Is exporting comments legal?** Comments on public posts are publicly visible data, and collecting them for analysis is broadly accepted, but personal-data rules apply to what you do afterwards, especially if you contact commenters. Platform terms also apply. Talk to a lawyer before building anything commercial on commenters' personal data. **Why did my export come back with fewer comments than the post shows?** On per-export tools, you likely hit your tier's cap for that link. Platforms also hide some comments (spam-filtered, restricted, or deleted), so no tool returns the exact on-screen count. If the gap is large and consistent, the cap is the usual culprit. **Which ExportComments alternative also exports reviews?** InsightSocial exports reviews from 10 review and discussion sites: Trustpilot, Amazon, Google Maps, Etsy, Steam, Product Hunt, Hacker News, Quora, Blind and Notion. ExportComments covers about 20 review sites, including Yelp, TripAdvisor and the App Store, which InsightSocial does not. For many companies on a schedule, cloud tools such as Outscraper or Apify fit better. **Does exporting comments risk my account?** Browser-extension scraping happens in your own logged-in session at browsing pace, which is the conservative end of the spectrum. Cloud tools access posts from datacenter IPs, which platforms flag more readily. No method is entirely risk-free; pace and volume moderation matter with any of them. [Install InsightSocial free](https://chromewebstore.google.com/detail/insightsocial-free-social/cddgiejchlkeedmhjeodlcjdiddlcdld) and export your first comment thread: unlimited scraping and 500 free export rows every month. --- # 7 Best PhantomBuster Alternatives in 2026 (Free & Paid) Source: https://www.insightsocial.app/blog/phantombuster-alternatives, updated 2026-10-18 > PhantomBuster's paid plans start at $69/month and run on your session cookies. 7 alternatives for social media scraping: price, account risk, who fits. - **Published**: 2026-07-18 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: comparison, alternatives, scraping, tools - **Reading time**: 12 min read - **Web version**: https://www.insightsocial.app/blog/phantombuster-alternatives --- The best PhantomBuster alternative depends on which half of it you use. For social media data in a spreadsheet, InsightSocial is a free Chrome extension that scrapes 6 social platforms in your own browser, with no cookies handed to a cloud (500 free export rows a month, Pro $9.99). For general websites, Thunderbit or Octoparse. For developer pipelines, Apify. For LinkedIn invitation and message campaigns, Waalaxy, or stay on PhantomBuster. PhantomBuster is the best-known name in social media automation: cloud "Phantoms" that scrape LinkedIn searches, enrich profiles, and chain into outreach. For growth teams running always-on lead pipelines, it earned its reputation. This guide covers what it costs and risks in practice, then compares seven alternatives, with notes on where each one falls short. We make InsightSocial, so we are not neutral; prices for the other tools were checked on their own pages and blogs on October 18, 2026. For a side-by-side of the two pricing models, see [InsightSocial vs PhantomBuster](/alternatives/phantombuster). ## Why People Look for PhantomBuster Alternatives Talk to people shopping for a replacement and the same four complaints come up: ### 1. Real use starts at $69/month PhantomBuster's paid plans run $69/month (Start), $159/month (Grow) and $439/month (Scale), or $56, $128 and $352 a month billed yearly, according to its own pricing explainer (July 2026). There is a Free plan, but it is small: 30 minutes of execution time a month, 1 slot, and exports capped at 10 rows. The 14-day trial gives 2 run hours, also with 10-row exports. If you scrape a competitor's followers once a month or pull a hashtag before a campaign, you're paying enterprise-adjacent money for occasional use. ### 2. You hand your session cookies to someone else's cloud Phantoms don't run in your browser. They run on PhantomBuster's servers, authenticated as *you* via session cookies you copy over. That means a third-party datacenter is operating your LinkedIn or X account. Platforms actively look for exactly this pattern: your account, suddenly active from an IP range that isn't yours. Restrictions and checkpoint challenges are the predictable result, and every experienced PhantomBuster user has a story about one. ### 3. You pay for execution time, not results Plans meter execution hours (plus separate pools of email, AI and other credits): compute time, not rows delivered. A run that crawls slowly, hits rate limits, or retries burns your monthly budget without producing more data. Like Apify's compute units, it turns every month into a usage-dashboard-watching exercise, and two people running "the same scrape" can consume wildly different amounts. ### 4. It's real maintenance work Session cookies expire and need re-pasting. Multi-step workflows mean chaining Phantoms whose outputs must line up. Rate limits need per-Phantom tuning to stay under the platforms' radar. None of this is hard for a growth engineer; all of it is friction for a marketer or recruiter who just wants a lead list. If several of these resonate, one of the tools below will probably fit you better. ## Quick Comparison | Tool | Type | Starting Price | Coding Needed | Best For | |------|------|---------------|---------------|----------| | InsightSocial | Chrome extension | Free (Pro $9.99/mo) | None | Social media data to Excel | | Waalaxy | Chrome extension + cloud | From €19/mo | None | LinkedIn invitation and message campaigns | | Apify | Cloud platform | Free $5/mo usage; Starter $19/mo | Some | Developers and custom pipelines | | Thunderbit | Chrome extension (AI) | Free 6 pages; $15/mo | None | General-purpose page scraping | | Browse AI | Cloud robots | ~$19/mo | None | Monitoring site changes | | Octoparse | Desktop app | Free plan; from $69/mo | None (visual) | Regular websites at volume | | Bright Data | Enterprise platform | Usage-based | Yes | Massive-scale data collection | ## 1. InsightSocial: The Data Half, in Your Own Browser [InsightSocial](https://chromewebstore.google.com/detail/insightsocial-free-social/cddgiejchlkeedmhjeodlcjdiddlcdld) is a Chrome extension that scrapes [TikTok](/scraper/tiktok), [X](/scraper/twitter), [LinkedIn](/scraper/linkedin), [YouTube](/scraper/youtube), [Reddit](/scraper/reddit) and [Pinterest](/scraper/pinterest), plus reviews on [Trustpilot, Google Maps, Amazon and seven more sites](/scraper/reviews), directly in your browser. The architectural difference from PhantomBuster is the whole point: scraping happens inside your normal logged-in session, on your usual IP, at browsing pace. There are no session cookies to copy and no third-party cloud acting as you. That keeps the account risk low, though it is still your account under each platform's terms. **Pricing** meters only what you export, at 1 credit per exported row. Scraping a 5,000-post hashtag and reading it in the dashboard costs nothing. Free plan: 500 export credits a month, no credit card. Pro: $9.99/month for 10,000 export credits, or $95.88/year ($7.99/month). There are no execution hours to budget. **Setup** is install → open a profile, hashtag, or post → click scrape → export to CSV, Excel, or JSON. Pro also includes Ask your data, a chat box that answers questions about your scraped rows ("which posts got the most engagement last week?"). Need runs while your laptop is off? The [InsightSocial API](/social-media-api) reads public profiles, posts and comments on 22 platforms from your server, with no account or cookie, on the same credit balance. **Pros:** - Low cost for social data (free, or $9.99/month on Pro) - No session-cookie handover: runs in your own browser, on your own IP - One tool covers 6 social platforms and 10 review sites with the same export formats - Nothing to configure: no cookies to refresh, no chains to maintain - Built-in scheduler: re-scrape a page hourly, daily or weekly **Cons:** - Scraping only: it deliberately doesn't auto-follow, auto-connect, or auto-message - Scheduled runs need Chrome open on your machine; it is not a 3 a.m. cloud job - Ask your data is Pro-only - Social and review sites only; it won't scrape arbitrary websites **Best for:** marketers, researchers and founders who want the *data* half of PhantomBuster without the price or the maintenance. ## 2. Waalaxy: LinkedIn Campaigns From a Chrome Extension If the part of PhantomBuster you use is LinkedIn outreach (invitations, message sequences, finding emails), Waalaxy is a focused alternative. You run it from a Chrome extension and manage campaigns in its web app. Its pricing page lists plans from €19 a month, with a 14-day trial; plans differ by monthly invitations and email-finder credits. (TexAu, often listed here as the cheaper PhantomBuster look-alike, now sells itself as a GTM enrichment spreadsheet, with paid plans from $99 a month.) **Pros:** - Built for one job: LinkedIn prospecting campaigns - Lower entry price than PhantomBuster's Start plan - Combines LinkedIn and email steps on higher plans **Cons:** - LinkedIn only: no TikTok, X or YouTube data - Automated invitations and messages are what LinkedIn restricts accounts for, whichever tool sends them - Campaign tool, not a data export tool **Best for:** sales teams whose PhantomBuster use is mostly LinkedIn invitation and message sequences. ## 3. Apify: For Developers Who Want Full Control Apify is a cloud platform with thousands of pre-built "Actors," including social media scrapers. Where PhantomBuster is packaged for growth marketers, Apify is packaged for engineers: SDK, storage APIs, webhooks, custom code. **Pricing**: the Free plan includes $5 of usage a month; Starter is $19/month with $19 of usage included, at $0.20 per compute unit. Many popular social Actors charge per result on top. Predicting a real workload's cost takes effort. We break the model down in our [Apify alternatives](/alternatives/apify) guide. **Pros:** - Enormous Actor marketplace; almost everything has a pre-built scraper - Scriptable end to end: real pipelines, not just workflows - Strong scheduling, storage, and API infrastructure **Cons:** - Three-layer pricing (plan + compute + Actor fees) is hard to forecast - Datacenter IPs get blocked on social platforms; proxies cost extra - Overkill if your destination is a spreadsheet **Best for:** engineering teams building data pipelines who want more control than PhantomBuster's fixed Phantoms offer. ## 4. Thunderbit: AI Scraping for Any Website Thunderbit is also a Chrome extension, but a generalist: its AI looks at whatever page you're on and suggests fields to extract. For conventional websites (directories, listings, e-commerce catalogs), it works impressively well with zero configuration. **Pricing**: the free plan covers 6 pages a month; Starter is $15/month for 500 credits, at one credit per output row (two for a row enriched from a subpage). A 1,000-post hashtag run needs a paid plan; [we compare the two in detail](/alternatives/thunderbit). **Pros:** - Works on almost any website, not just social platforms - AI field detection: no selectors, templates, or Phantom configuration - Browser extension, so it shares the same anti-block advantage as InsightSocial **Cons:** - Per-row credits add up on large social exports - Social-specific structures (nested comments, follower lists) are shallower than a dedicated tool's output - No outreach or automation features at all **Best for:** people who scrape many different kinds of websites and want one flexible tool. ## 5. Browse AI: Point, Click, Monitor Browse AI lets you train a "robot" by clicking the data you want on a page; the robot re-runs on a schedule and alerts you when values change. It's the strongest option here for *monitoring*: prices, job postings, competitor pages. **Pricing** starts around $19/month billed annually, credit-based. **Pros:** - Easiest training flow of the visual tools - Excellent for change-monitoring use cases - Prebuilt robots for common sites **Cons:** - Login-walled social platforms are largely out of reach for its cloud robots - Credit model penalizes large one-off extractions **Best for:** monitoring public web pages for changes over time, not a social scraping replacement. ## 6. Octoparse: Visual Workflows on the Desktop Octoparse is a desktop app with a point-and-click workflow designer that handles pagination, loops, and scheduling on conventional websites. It's been around for years and is genuinely capable on structured, public sites at volume. **Pros:** - Powerful visual workflow builder: the closest no-code equivalent to writing a real scraper - Handles large, multi-page extraction jobs well - Free plan (10 tasks, local runs); cloud execution on paid plans, from $69/month **Cons:** - Social platforms' login walls and anti-bot systems are its weak spot - The workflow designer has a real learning curve despite being "no-code" **Best for:** regular websites at volume, where you'd otherwise write a custom scraper. ## 7. Bright Data: When You Truly Need Scale If your requirement is millions of records, Bright Data's proxy networks, scraper APIs, and prebuilt datasets are industry-standard, with usage-based pricing and KYC checks for some proxy products. **Pros:** - Unmatched proxy infrastructure and scale - Prebuilt datasets can skip scraping entirely - Serious compliance posture for enterprise procurement **Cons:** - Enterprise pricing; costs are usage-based and substantial - Developer-oriented: far more platform than PhantomBuster, not less **Best for:** enterprise-scale data collection with engineering support. Below that scale, it's overkill. ## Which Should You Choose? - **Social media data, no account risk, minimal cost** → InsightSocial - **LinkedIn invitation and message campaigns, cheaper** → Waalaxy - **Custom pipelines, engineering team** → Apify - **Arbitrary websites, no engineers** → Thunderbit or Octoparse - **Watching pages for changes** → Browse AI - **Enterprise-scale datasets** → Bright Data - **Scraping chained directly into automated outreach, and the price is fine** → stay on PhantomBuster A useful rule of thumb: if what you need is the *data*, a browser extension gets it cheaper and safer. If what you need is the *automation* (the auto-connects and drip sequences), you're choosing between PhantomBuster and a campaign tool such as Waalaxy, and accepting the account risk that comes with automated invitations either way. ## FAQ **Is there a truly free PhantomBuster alternative?** For social media data, InsightSocial's free plan: unlimited scraping and 500 export rows a month, no credit card. Octoparse has a free plan for regular websites, Apify's $5 monthly credit covers light testing, and Thunderbit's free plan covers 6 pages. PhantomBuster's own Free plan exports 10 rows at a time. **Will I get my account banned using these tools?** No method is entirely risk-free, but the spectrum is real. Cloud tools that run on your session cookies operate your account from someone else's servers: an easy pattern for platforms to flag. Browser extensions like InsightSocial work inside your normal logged-in session at browsing pace, which is the lower-risk end. Automated invitations and messages carry the most risk, whatever sends them. **Can I replicate PhantomBuster's LinkedIn lead flows?** Partly. InsightSocial exports [LinkedIn profiles, company posts, and the people who react to or comment on a post](/scraper/linkedin). It can't export LinkedIn search results, Sales Navigator lists or connections, and email comes only for your 1st-degree connections. The outreach half (auto-connect, auto-message) is deliberately not something it does. Our [LinkedIn prospecting guide](/blog/linkedin-sales-prospecting-guide) shows the research workflow. **Why does execution-hours pricing end up expensive?** Because you pay for time, not output. Slow pages, rate limits, and retries all consume hours without delivering rows. Per-row export pricing (you see the exact row count before you spend anything) or per-result pricing is predictable; per-hour pricing is not. **Do these alternatives export to Excel?** InsightSocial, Thunderbit, and Octoparse export directly to Excel/CSV. Apify and Bright Data return structured data (JSON/datasets) you can convert. **What about scraping legality?** Reading public data is not a crime in the US, but platform terms still bind logged-in users, and personal-data rules apply to what you keep and how you use it. Talk to a lawyer before building anything commercial on scraped personal data. To try the browser-based approach, [install InsightSocial free](https://chromewebstore.google.com/detail/insightsocial-free-social/cddgiejchlkeedmhjeodlcjdiddlcdld): unlimited scraping and 500 free export rows every month, no credit card. --- # How to Extract Data from LinkedIn for Free (No API, 2026) Source: https://www.insightsocial.app/blog/how-to-extract-linkedin-data-free, updated 2026-10-18 > Export LinkedIn posts, author titles and post reactors to Excel for free with a Chrome extension. No API key, no code. Step-by-step, 2026. - **Published**: 2026-07-04 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: linkedin, scraping, tutorial, free tools, data extraction - **Reading time**: 8 min read - **Web version**: https://www.insightsocial.app/blog/how-to-extract-linkedin-data-free --- You can extract LinkedIn data for free with the InsightSocial Chrome extension. Open a company page, a profile, or a single post, click the extension, and export posts (text, author name and headline, reactions, comments, reposts, date) or the people who reacted or commented, to Excel, CSV, JSON or Google Sheets. Scraping is unlimited; exports are free up to 500 rows a month. ## Introduction You need LinkedIn data in a spreadsheet: post authors with their titles and companies, engagement numbers on competitor content, or the people posting about your industry. The official LinkedIn API is locked behind partner approval, and most scraping tools charge per row before you've even validated the idea. The good news: if the data is visible in your browser, you can extract it for free. This guide walks through every free method, then shows step-by-step how to export LinkedIn posts, profiles, and company page posts to Excel using a free Chrome extension: no API key, no coding, no credit card. ## What Counts as "LinkedIn Data"? Before picking a method, be specific about what you're extracting: | Data type | Examples | Typical use | |-----------|----------|-------------| | Posts | Content, author name, author title, company, reactions, comments, shares, date | Content research, social selling, trend analysis | | Profiles | Name, headline, location, experience | Recruiting, prospect research | | Company pages | Posts, engagement, activity | Competitor monitoring | | Engagement | Who reacts and comments, how often | Lead generation, audience research | The most underrated of these is **post data**. Every LinkedIn post carries the author's name, professional title, and company, which means a feed or company page is effectively a self-updating list of people in your market, complete with job titles, sorted by how actively they engage. Engagement data goes one level deeper: the [LinkedIn Post Likers Scraper](/scraper/linkedin-post-likers-scraper) exports everyone who reacted to a specific post (name, headline, connection degree, and reaction type), and the [comments scraper](/scraper/linkedin-comments-scraper) exports the comment thread. Together they show who engages with a topic and what roles they hold. ## Your Free Options, Compared ### Option 1: Manual copy-paste Free, but the math is brutal. Copying 100 posts with author details into a spreadsheet takes hours, formats inconsistently, and you'll do it all again next month. Fine for 5 rows, unworkable for 500. ### Option 2: The official LinkedIn API LinkedIn's API is free in theory but gated behind the Partner Program. Individual developers and small teams are rarely approved, and even approved apps get narrow scopes. For ad-hoc research, this path is a dead end. ### Option 3: Paid cloud scrapers Tools like PhantomBuster or Apify run in the cloud and often ask you to hand over your LinkedIn session cookie, meaning a third-party server logs in as you. Pricing is per-result or per-minute, which adds up fast. We've compared them in detail in our [PhantomBuster alternatives](/blog/phantombuster-alternatives) and [Apify alternatives](/alternatives/apify) guides. ### Option 4: A free browser extension (this guide) A Chrome extension reads the data LinkedIn already renders in *your* browser, in *your* session. Nothing to code, no cookie to share, and the free tier is genuinely free. [InsightSocial](/scraper/linkedin) lets you scrape and read unlimited posts, and includes 500 export rows per month. ## Step-by-Step: Extract LinkedIn Data to Excel for Free ### Step 1: Install the extension Add [InsightSocial from the Chrome Web Store](https://chromewebstore.google.com/detail/insightsocial-free-social/cddgiejchlkeedmhjeodlcjdiddlcdld). It takes one click and works on Chrome, Edge, Brave, and other Chromium browsers. ### Step 2: Open LinkedIn where your data lives The extension detects these LinkedIn page types automatically: - **Company pages** (`linkedin.com/company/...`): everything a company publishes - **Profiles** (`linkedin.com/in/...`): the person's posts, or their profile details (headline, experience, education, skills) - **Single posts** (`linkedin.com/feed/update/...` or `linkedin.com/posts/...`): everyone who reacted, or the comment thread - **Your home feed** (`linkedin.com/feed`): works only on the older feed layout. LinkedIn has moved part of its users to a new home feed that carries no post links, and that feed can't be collected yet. Search results, groups, hashtag feeds and your connections list can't be scraped. Open the page and the extension recognizes it. ### Step 3: Start the scrape Click the InsightSocial icon to open the side panel, choose how many posts you want (50, 100 or 250 per run), and click Scrape. The extension scrolls the page like a reader would and captures each post as it loads. On a single post, choose Reactions or Comments instead (50, 100 or 500) and keep that tab in front until the run ends. ### Step 4: Export to Excel, CSV, or JSON When the session finishes, export in one click. Every post row includes: | Field | What you get | |-------|--------------| | Post Content | Full text of the post | | Author Name | Who posted it | | Author Title | Their professional headline (usually includes where they work) | | Reactions | Total reaction count | | Comments | Comment count | | Reposts | Repost count | | Post Date | When it was published | | Post URL | Direct link to the post | | Media URLs | Attached images or video | | Post Type | Text, image, video, article, document or poll | That **Author Name + Author Title** combination is the one people usually pay for. From a scrape of an industry leader's or a company's posts you see who is active in that space and what roles they hold. Results also sync to your web dashboard, so you can filter, search, and re-export later from any device. ## Three Free Workflows to Steal ### 1. Map who engages with a competitor's posts Scrape a competitor's company page posts, export to Excel, and sort by engagement. Then export the reactors and commenters of their top posts: their headlines show which roles and companies the content reaches. More in the [LinkedIn Sales Prospecting Guide](/blog/linkedin-sales-prospecting-guide). ### 2. Reverse-engineer content that works in your niche Scrape 250 posts from a company page or an industry voice's profile, sort by reactions, and read the top 20. Patterns in hooks, length, format, and posting time appear immediately. Data beats guessing. ### 3. Track competitor publishing cadence Scrape each competitor's company page monthly. Post frequency, formats, engagement trends: all in a spreadsheet you control, at no cost. ## Is Extracting LinkedIn Data Legal? The short version: - **Public data, viewed in your own browser, for legitimate research** is the defensible end of the spectrum. In *hiQ v. LinkedIn* the court found scraping public profiles was not "unauthorized access" under US computer-crime law, but hiQ was still found to have broken LinkedIn's User Agreement and settled in 2022. - **LinkedIn's Terms of Service** prohibit automated data collection, so use judgment: scrape at reading speed, in your own session, for research, not mass harvesting. - **Personal data rules still apply.** If you're subject to GDPR or similar, exporting people's data for outreach carries obligations regardless of how you collected it. InsightSocial only captures what your logged-in session can already see, never accesses private data, and performs no actions on your behalf: no auto-connecting, liking, or messaging. Keep volumes reasonable and use the data respectfully. ## Free vs Paid: What Do You Actually Get for $0? Scraping and reading your results are unlimited on the free plan. Only exporting is metered, at **1 credit per exported row, with 500 free credits a month**. For most research workflows (a few competitor checks a month) that's enough to never pay. If you outgrow it, Pro is $95.88/year ($7.99/month) or $9.99/month, with 10,000 export credits a month. ## FAQ **Can I export LinkedIn search results?** No. LinkedIn search pages can't be scraped with the extension. Open each profile you shortlisted instead, or use the [LinkedIn API](/social-media-api/linkedin), which has a people search endpoint. **Can I export my connections?** No. The connections list isn't a supported page. You can export people who react to or comment on a post, and the posts on a profile or company page. **Can I get emails from LinkedIn?** Only from your own 1st-degree connections. The Profile export includes email, phone and address when LinkedIn shows them to you, which it does only for people you are connected with. **Will my LinkedIn account get banned?** The extension reads what your own session shows, at reading pace, and never connects, likes or messages. That keeps the risk low, but LinkedIn's terms prohibit automated collection, so keep volumes modest and don't run scrapes all day. ## What's Next? - [LinkedIn Scrapers overview](/scraper/linkedin): all LinkedIn tools in one place - [LinkedIn Posts Scraper](/scraper/linkedin-posts-scraper): the tool used in this guide - [LinkedIn Company Scraper](/scraper/linkedin-company-scraper): company page extraction - [How to Scrape LinkedIn Profiles](/blog/how-to-scrape-linkedin-profiles): profile-focused walkthrough ## Conclusion You don't need API approval or a paid scraping subscription to get LinkedIn data into a spreadsheet. A free Chrome extension, your own browser session, and ten minutes will export posts with author names, titles, and engagement metrics. Install the [free extension](https://chromewebstore.google.com/detail/insightsocial-free-social/cddgiejchlkeedmhjeodlcjdiddlcdld), open a competitor's LinkedIn company page, and run your first export. --- # Ask Your Data: Chat With Your Scraped Social Media Data Source: https://www.insightsocial.app/blog/ask-ai-analyze-social-media-data, updated 2026-10-18 > Ask questions about your scraped posts, comments, profiles or reviews in plain English. Answers come from your own rows. Included in InsightSocial Pro. - **Published**: 2026-06-12 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: feature, ai, analytics, data - **Reading time**: 4 min read - **Web version**: https://www.insightsocial.app/blog/ask-ai-analyze-social-media-data --- **Ask your data is a chat box on every InsightSocial results page: ask a question in plain English about the rows you scraped, and it answers from those rows, with counts and rankings computed, not guessed.** It works on posts, comments and profiles from [TikTok](/scraper/tiktok), [X](/scraper/twitter), [LinkedIn](/scraper/linkedin), [YouTube](/scraper/youtube), [Reddit](/scraper/reddit) and [Pinterest](/scraper/pinterest), and on [reviews](/scraper/reviews) from the 10 review and discussion sites. It is part of Pro ($9.99 a month), with 500 questions a month. ## What You Can Ask Ask your data answers from the rows in your session: posts, profiles, comments, engagement numbers. Some questions it handles well: **Finding what matters** - *"Show me the top 10 rows by engagement."* - *"Which of these rows stand out most by engagement, and why?"* - *"Which rows have an email, phone, or website link?"* **Finding out why** - *"What patterns do the top-performing rows share? Look at bios, captions, hashtags."* - *"Which topics or content formats get the most engagement in this session?"* - *"Summarize this session: how many rows, average engagement, which rows stand out."* **Comment analysis** (after scraping a post's comments) - *"What is the overall sentiment of the comments: positive, negative, mixed?"* - *"What themes or opinions come up most across the comments?"* - *"Which comments got the most likes? Quote the top 3."* **Acting on it** - *"Draft a personalized 2-sentence opener for each row in my shortlist."* - *"Score each of my shortlisted profiles 1–10 for fit, then explain the scores."* Answers that involve rows come back as tables inside the chat, and every reply suggests follow-up questions, so "show top performers" naturally chains into "what do they have in common?" without you composing the next prompt. ## Why This Beats Exporting to a Spreadsheet You can still export everything to Excel. That workflow isn't going anywhere. But for the questions you ask most, chat is simply faster: | Task | Spreadsheet | Ask your data | |------|-------------|--------| | Top 10 by engagement | Sort, eyeball, handle ties | One question | | "What do winners have in common?" | Manual reading, gut feel | Pattern analysis across captions, bios, hashtags | | Comment sentiment | Read 800 comments | One question | | Outreach drafts | Write each one | Drafted per row from real bio data | The pattern questions are where it earns its place. A spreadsheet tells you *which* post got 40k likes; Ask your data reads the captions, bios, and hashtags across your winners and tells you *what they're doing differently*. ## How to Use It 1. **Scrape something.** Any source works: a competitor's [TikTok](/scraper/tiktok-profile-scraper), a [TikTok hashtag](/scraper/tiktok-hashtag-scraper), a LinkedIn feed, using the [InsightSocial extension](https://chromewebstore.google.com/detail/insightsocial-free-social/cddgiejchlkeedmhjeodlcjdiddlcdld). 2. **Open the session in your dashboard** and click **Ask your data**. 3. **Start with a suggested prompt** or type your own: "Ask anything about this session." 4. **Drill down with follow-ups,** shortlist the rows that matter, and export when you're done. ## Three Workflows It Speeds Up **Competitor research:** scrape a competitor's profile, then ask what content formats get their best engagement and what their top posts share. That's a [content strategy audit](/blog/tiktok-competitor-analysis-guide) in three questions. **Lead qualification:** scrape a hashtag's authors, ask which rows have contact info, then score the shortlist for fit before you reach out. **Launch feedback:** scrape the comments on a launch post and ask for sentiment, themes, and the most-liked criticisms. Useful for your launches; more fun on competitors'. ## FAQ **Does it see all my data?** It answers from the scrape session you opened it on: your data, scoped to the question at hand. It doesn't browse the internet or other people's sessions. **Can it be wrong?** Counts and rankings are computed from your rows, not estimated. Interpretive answers (patterns, sentiment) are the model's reading of real data. The suggested follow-ups make it easy to ask "show me the rows behind that" and check. **Is it included in my plan?** Only in Pro: 500 questions a month for $9.99. On the free plan you can still scrape, read and export your sessions. See [pricing](/pricing). The fastest way to get it: [install InsightSocial](https://chromewebstore.google.com/detail/insightsocial-free-social/cddgiejchlkeedmhjeodlcjdiddlcdld), scrape any page you care about, and ask your data the question you actually have. --- # How to Scrape LinkedIn Profiles in 2026 (Step-by-Step Guide) Source: https://www.insightsocial.app/blog/how-to-scrape-linkedin-profiles, updated 2026-10-18 > Export a LinkedIn profile's headline, experience, education, skills and certifications to Excel with a free Chrome extension, and what it can't get. - **Published**: 2026-01-18 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: linkedin, scraping, tutorial, recruiting, sales - **Reading time**: 4 min read - **Web version**: https://www.insightsocial.app/blog/how-to-scrape-linkedin-profiles --- To scrape a LinkedIn profile, open linkedin.com/in/username in Chrome while logged in, click the [InsightSocial extension](/scraper/linkedin-profile-scraper), choose **Profile** and click Scrape. In a few seconds you get the name, headline, location, about, follower and connection counts, and the experience, education, skills and certifications shown on the profile, exported to Excel, CSV, JSON or Google Sheets. Contact details come only for your 1st-degree connections. Exports are free up to 500 rows a month. ## What data can you extract? The Profile export reads the profile page as it first loads. LinkedIn shows only the top few entries of each section there, so that is what you get; the full lists behind "Show all" are not fetched. | Data | What it contains | |------|------------------| | Identity | Name, headline, profile URL, profile picture, country and location | | Reach | Connection count, follower count | | About | The profile summary | | Experience | Title, company, employment type, dates and location for the entries shown on the profile | | Education | School, degree and dates for the entries shown | | Skills | The skills listed on the profile (no endorsement counts) | | Certifications and volunteering | Name, issuer, dates, credential link; role, organization, cause | | Badges | Creator, Top Voice, Premium and Influencer flags | | Contact info | Email, phone and address only if you are a 1st-degree connection; websites and other handles the person lists | The same profile page also offers **Posts**: that is a separate run that exports the person's posts (text, reactions, comments, reposts, date) instead of the profile. ## Step-by-step: how to scrape a LinkedIn profile ### Step 1: Add InsightSocial to Chrome Install the [free Chrome extension](https://chromewebstore.google.com/detail/insightsocial-free-social/cddgiejchlkeedmhjeodlcjdiddlcdld) and pin its icon to the toolbar. ### Step 2: Log in to LinkedIn InsightSocial reads what your own logged-in session can see. Signed out, LinkedIn hides most of a profile. ### Step 3: Open the profile Go to the profile you want: ``` https://www.linkedin.com/in/username ``` Any profile you can open works: 1st-degree, 2nd-degree or out of network. ### Step 4: Click Scrape Click the InsightSocial icon. The side panel detects the profile. Choose **Profile** and click Scrape. The run takes a few seconds. ### Step 5: Export Open the results page and export to Excel, CSV, JSON or Google Sheets. ## Tips ### Search results and Sales Navigator pages can't be scraped The extension doesn't read LinkedIn search results or Sales Navigator. Open each profile you shortlisted and run it, or use the [LinkedIn API](/social-media-api/linkedin), whose people search takes keyword, title, company and location filters. ### To find people, start from a post The fastest way to a list of relevant people is a post in your field. The [LinkedIn Post Likers Scraper](/scraper/linkedin-post-likers-scraper) exports everyone who reacted to a post, with name, headline, profile URL and connection degree. Then open the profiles that matter. ### Keep data fresh People change jobs. Re-run the profiles you rely on every few months. ## Legal considerations LinkedIn's User Agreement restricts automated collection, and using the extension means using your own account under those terms. Keep runs small and focused, don't use the data for spam, and handle personal data the way GDPR and similar laws require. To read many profiles from a server without your account, use the [LinkedIn API](/social-media-api/linkedin) instead. ## FAQ **Can I scrape emails from LinkedIn profiles?** Only from your 1st-degree connections. LinkedIn shows email, phone and address in Contact info to connections only, so for everyone else the export has no email. Websites and other handles a person lists publicly are included. **Can I export LinkedIn search results?** No. LinkedIn search and Sales Navigator pages can't be scraped with the extension. Open each profile, or use the people search in the [LinkedIn API](/social-media-api/linkedin). **Do I get the full work history?** You get the experience, education and skills entries shown on the profile as it loads. LinkedIn truncates long lists there, and the full lists behind "Show all" are not fetched. **Can I scrape many profiles at once?** Not in one extension run: the Profile export reads one profile per run. For hundreds of profiles, the [LinkedIn API](/social-media-api/linkedin) reads profiles from your server, priced per call. **Is it allowed?** Reading public profile data is not a crime in the US after *hiQ v. LinkedIn*, but LinkedIn's User Agreement bans automated collection, and hiQ was found to have broken it. Your account is the one at risk, so scrape what you need, at a normal pace. ## Related - [LinkedIn Profile Scraper](/scraper/linkedin-profile-scraper): what the profile export contains - [LinkedIn Post Likers Scraper](/scraper/linkedin-post-likers-scraper): people who reacted to a post - [LinkedIn Company Scraper](/scraper/linkedin-company-scraper): a company page's posts - [LinkedIn Posts Scraper](/scraper/linkedin-posts-scraper): posts from a profile or company --- # How to Scrape TikTok Profiles in 2026 (Step-by-Step Guide) Source: https://www.insightsocial.app/blog/how-to-scrape-tiktok-profiles, updated 2026-10-18 > Export a TikTok account's videos (views, likes, comments, shares, caption, music, date) or its followers to Excel or CSV with a free Chrome extension. - **Published**: 2026-01-18 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: tiktok, scraping, tutorial, social media - **Reading time**: 5 min read - **Web version**: https://www.insightsocial.app/blog/how-to-scrape-tiktok-profiles --- To scrape a TikTok profile, open tiktok.com/@username in Chrome, click the InsightSocial extension, choose **Videos**, set how many (50, 100 or 250 per run) and Latest or Popular, and click Scrape. Each row has the caption, views, likes, comments, shares, music, duration and date. You can also export the account's followers or following. Export to Excel, CSV, JSON or Google Sheets; exports are free up to 500 rows a month. ## Introduction TikTok profile data can show: - Influencer reach and engagement - Content trends and viral patterns - Competitor strategies - Audience behavior In this guide, you'll learn how to extract TikTok profile data using InsightSocial, a free Chrome extension that requires no coding or API access. ## Why Scrape TikTok Profiles? ### Influencer Marketing Research Before partnering with a TikTok creator, you need data: - Follower count and growth trends - Average engagement rates - Content themes and quality - Posting frequency Manually collecting this takes hours. Scraping automates the process. ### Competitive Analysis Track what competitors are doing on TikTok: - What content formats work for them - Which hashtags they use - How often they post - Their engagement benchmarks ### Content Research Find inspiration by analyzing successful accounts: - What makes videos go viral - Trending sounds and effects - Caption strategies - Optimal video lengths ## What Data Can You Extract? On a profile, InsightSocial's [TikTok Profile Scraper](/scraper/tiktok-profile-scraper) offers three choices, one per run: | Choice | One row per | Fields | |--------|-------------|--------| | **Videos** | video | Video ID and URL, caption (with its hashtags), music title and author, views, likes, comments, shares, duration, upload time, and the creator's username, display name, avatar and verified badge | | **Followers** | follower | Username, display name, bio, avatar, follower count, total likes, verified badge | | **Following** | followed account | The same fields as Followers | ## Step-by-Step: How to Scrape TikTok Profiles ### Step 1: Install InsightSocial [Add the extension to Chrome](https://chromewebstore.google.com/detail/insightsocial-free-social/cddgiejchlkeedmhjeodlcjdiddlcdld) and pin its icon to the toolbar. ### Step 2: Navigate to a TikTok Profile Go to TikTok.com and visit any profile: ``` https://www.tiktok.com/@username ``` The extension works with any public profile: creators, brands, or personal accounts. Private accounts show nothing to scrape unless you follow them. ### Step 3: Open InsightSocial Click the InsightSocial icon in your toolbar. The sidebar opens on the right side of your screen. InsightSocial automatically detects you're on a TikTok profile and shows TikTok-specific options. ### Step 4: Configure Your Extraction Choose **Videos**, then how many: 50, 100 or 250 per run. Pick the sort order, the same two tabs TikTok shows on the profile: - **Latest**: most recent videos first - **Popular**: the videos TikTok ranks as most popular ### Step 5: Start Scraping Click **Scrape**. The extension scrolls the video grid and the panel shows videos as they are captured. Depending on the count, a run takes a few minutes. ### Step 6: Export Your Data When the run finishes, open it on your results page and export to Excel, CSV, JSON or Google Sheets. ## Tips for Better TikTok Scraping ### Start with Popular Sort When researching a new account, start with "Popular" sort to see their best-performing content first. ### Export Regularly TikTok metrics change constantly. Export data periodically to track trends over time. ### Combine with Spreadsheet Analysis After export: 1. Calculate engagement rate: (Likes + Comments + Shares) / Views 2. Identify top hashtags with pivot tables 3. Chart posting frequency over time ## Legal Considerations Scraping publicly available TikTok data is generally permitted for: - Research and analysis - Competitive intelligence - Legitimate business purposes However: - Review TikTok's Terms of Service - Don't scrape private or restricted content - Use data responsibly - Consult legal counsel for commercial use ## FAQ **Can I scrape a private TikTok account?** Only if you follow it and TikTok shows you its videos. The extension reads what your own browser session sees; it cannot open content TikTok hides from you. **Can I get a creator's email?** Not from this export. The Followers and Following exports include each account's bio, so an email a creator writes in the bio comes through as text. **How many videos can I export?** Pick 50, 100 or 250 per run. Very old videos on a large account can take a while to load, so start with 100. **Can I export all of an account's followers?** TikTok often serves only the first few dozen accounts of a followers list, however far you scroll. Treat a follower export as a sample of the audience. ## What's Next? Now that you can scrape TikTok profiles, explore these related guides: - [TikTok Competitor Analysis Guide](/blog/tiktok-competitor-analysis-guide): Compare multiple accounts - [Competitor Analysis Use Case](/use-cases/competitor-analysis): Strategic frameworks - [TikTok Video Scraper](/scraper/tiktok-video-scraper): Deep dive into video data ## Conclusion With InsightSocial you can export a TikTok account's videos with their metrics, or its followers, without code. Start by installing the [free Chrome extension](https://chromewebstore.google.com/detail/insightsocial-free-social/cddgiejchlkeedmhjeodlcjdiddlcdld) and scraping your first TikTok profile today. --- *Have questions about TikTok scraping? [email our support team](mailto:support@insightsocial.app).* --- # How to Export an X (Twitter) Account's Posts and Followers Source: https://www.insightsocial.app/blog/how-to-scrape-twitter-profiles, updated 2026-10-18 > Export any X (Twitter) account's posts, followers and following to Excel or CSV with a free Chrome extension. No API, no code. Step-by-step, 2026. - **Published**: 2026-01-18 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: twitter, x, scraping, tutorial, social media - **Reading time**: 4 min read - **Web version**: https://www.insightsocial.app/blog/how-to-scrape-twitter-profiles --- To export an X (Twitter) account's posts, open x.com/username in Chrome, click the InsightSocial extension, choose **Posts**, set how many (50, 100 or 300 per run) and click Scrape. Each row has the text, likes, reposts, replies, quotes, views, bookmarks, media and date. Followers and Following lists export the same way. Export to Excel, CSV, JSON or Google Sheets; exports are free up to 500 rows a month. ## What you can export from an X profile On a profile page, the InsightSocial panel offers four choices, one per run: | Choice | What you get | |--------|--------------| | **Posts** | One row per post: text, post type, media URLs, quoted-post preview, likes, reposts, replies, quotes, views, bookmarks, post URL, timestamp, and the author's username, display name and verified flags | | **Followers** | The accounts that follow this one: username, display name, avatar, bio, verified flags and follower count | | **Following** | The accounts this one follows, with the same fields | | **Liked Posts** | Posts the account liked. X hides the Likes tab on other people's profiles, so this works on your own profile only | A separate profile-details export (bio, join date, website, follower totals as one row) is coming. Today the posts export carries each author's name, handle and verified flags, and the followers export carries each follower's bio and follower count. ## Step-by-step: export an X account's posts ### Step 1: Install InsightSocial [Add the extension to Chrome](https://chromewebstore.google.com/detail/insightsocial-free-social/cddgiejchlkeedmhjeodlcjdiddlcdld) and pin its icon to the toolbar. Make sure you are logged in to X in the same browser; X shows little to signed-out visitors. ### Step 2: Open the profile Go to the account's page: ``` https://x.com/username ``` ### Step 3: Open the panel and choose Posts Click the InsightSocial icon. The side panel detects the profile. Choose **Posts**, pick how many (50, 100 or 300), and click **Scrape**. The panel shows posts as they come in. ### Step 4: Export When the run finishes, open it on your results page and export to Excel, CSV, JSON or Google Sheets. ## Tips ### Spot accounts with weak engagement Sort the export by views or likes per post. A large account whose posts get few replies or views is worth a second look before you pay it for a promotion. ### Track an account over time Export the same account once a month. Comparing posts per week, median views and engagement per post shows whether its strategy changed. ### Combine with other exports - [Twitter Posts Scraper](/scraper/twitter-posts-scraper): posts from a profile, list or search - [Twitter Followers Scraper](/scraper/twitter-followers-scraper): an account's followers - [Twitter Replies Scraper](/scraper/twitter-replies-scraper): every reply to a single post ## FAQ **How many followers can I export?** For many accounts, X stops serving the followers list after about 50 to 70 accounts, however far you scroll. That is X's limit, not the extension's. Treat a follower export as a sample of the audience, not the full list. **Do I need to be logged in to X?** Yes. The extension reads what your own logged-in session shows. Signed out, X shows almost nothing to scrape. **Can I scrape X search results?** Yes. Open a search or hashtag page and choose Posts. Search runs pause when the tab is hidden, so keep that tab in front until the run ends. **Can I export the profile details (bio, join date, website)?** Not as a separate export yet; it is coming. The followers export includes each follower's bio and follower count. **Is it legal to scrape X?** Reading public posts is generally lawful, but X's Terms of Service restrict automated collection, and personal data in your export is covered by privacy laws such as GDPR. Don't scrape protected accounts, and use the data for research and analysis. ## What's next - [Twitter Competitor Analysis Guide](/blog/twitter-competitor-analysis-guide): compare rivals with exported data - [Twitter Profile Scraper](/scraper/twitter-profile-scraper) *Questions about X scraping? [Email our support team](mailto:support@insightsocial.app).* --- # LinkedIn Prospecting: Start From Post Engagement (2026) Source: https://www.insightsocial.app/blog/linkedin-sales-prospecting-guide, updated 2026-10-18 > B2B prospecting on LinkedIn with real data: export who reacts to and comments on posts in your field, research the best-fit accounts, then write to them. - **Published**: 2026-01-18 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: linkedin, sales, prospecting, B2B, lead generation - **Reading time**: 5 min read - **Web version**: https://www.insightsocial.app/blog/linkedin-sales-prospecting-guide --- Data-driven LinkedIn prospecting starts with public engagement: who reacts to and comments on posts about the problem you solve. Export those reactors and commenters (name, headline, profile URL, connection degree), sort them by title and company to find the accounts that fit, research those profiles and company pages, and write a first message about their business, not a template. The [InsightSocial Chrome extension](/scraper/linkedin) exports post reactors, post commenters, profiles and company posts to Excel. LinkedIn search results and connection lists can't be exported. ## Step 1: Define who you are looking for Write down your ideal customer before you collect anything: - **Industry**: where your best customers work - **Company size**: employee or revenue range - **Region**: the markets you sell in - **Role and seniority**: who decides, and who uses the product This keeps the list short and keeps you from collecting data you have no use for. ## Step 2: Find accounts through post engagement Posts are where LinkedIn shows public interest in a topic. A competitor's launch post, an industry analyst's post or a thread about a problem your product solves all collect reactions and comments from people who work on that problem. With the [LinkedIn Post Likers Scraper](/scraper/linkedin-post-likers-scraper), open the post, click InsightSocial, choose **Reactions** and click Scrape. You get one row per person: name, headline, profile URL, connection degree and reaction type, 50, 100 or 500 per run. Choose **Comments** instead for the [comment thread](/scraper/linkedin-comments-scraper): name, headline, text, likes and replies. In the spreadsheet, filter the headlines by title and company. Most rows won't fit your profile. The ones that do are accounts whose people already engage with your topic in public, which is a better starting point than a cold search. ## Step 3: Research the best fits For each account that fits, open the person's profile and run the [LinkedIn Profile Scraper](/scraper/linkedin-profile-scraper). The export has their headline, location, about, and the experience, education, skills and certifications shown on the profile. | Field | What it tells you | |-------|-------------------| | Current role | What they are responsible for | | Experience dates | How long they have been in the role | | Past companies | Background you may share | | Education, certifications | Shared schools, technical depth | | Skills | Whether your product fits their work | The profile export doesn't include the person's posts; choose **Posts** on the same profile for that, as a separate run. Email and phone are only included for your 1st-degree connections. Then export the company's recent posts with the [LinkedIn Company Scraper](/scraper/linkedin-company-scraper): text, date, reactions, comments and links. They show what the company is launching and hiring for. Company size and industry are not part of the export; read them on the company page. ## Step 4: Write a first message about their business Reference something specific and public: a post their company published, a launch, a role they are hiring for. Keep the first message to three or four sentences with one clear ask. **Generic:** > "Hi John, I help companies improve their sales process. Want to chat?" **Specific:** > "Hi John, I saw Acme's post about moving support onto a new inbox. We helped a team of a similar size cut onboarding time on that kind of switch. Would a 15-minute comparison be useful?" Follow up a few times at most, then stop. Honor every opt-out, and delete records you no longer need. ## Step 5: Keep it in a CRM or a sheet Export to CSV and import into Salesforce, HubSpot or Pipedrive, or keep a simple sheet: | Name | Company | Title | LinkedIn | What you referenced | Status | Last contact | |------|---------|-------|----------|---------------------|--------|--------------| ## Ground rules - **Use your own account at a normal pace.** The extension reads what your logged-in session shows. LinkedIn's User Agreement restricts automated collection, so keep runs small and focused. - **Collect what the job needs.** GDPR and similar laws apply to personal data even when it's public. A title and company is usually enough. - **Contact people in their professional role, about their business.** Don't add people to sequences they never asked for. ## FAQ **Can I export my LinkedIn connections?** No. Connection lists aren't supported, and neither are LinkedIn search results or Sales Navigator. Post reactors and commenters, profiles and company posts can be exported. **Can I get prospects' email addresses?** Only for your 1st-degree connections, where LinkedIn shows Contact info. For everyone else, the profile export has no email. **How many people can I export from one post?** Choose 50, 100 or 500 reactors per run. Comments export the same way, with replies. **Does the profile export include the person's posts?** No. Posts are a separate run on the same profile page. ## Related - [How to scrape LinkedIn profiles](/blog/how-to-scrape-linkedin-profiles): the profile export step by step - [LinkedIn API](/social-media-api/linkedin): people search with title, company and location filters, from your own code --- # How to Analyze TikTok Competitors With Exported Data Source: https://www.insightsocial.app/blog/tiktok-competitor-analysis-guide, updated 2026-10-18 > Export rivals' TikTok videos with a free Chrome extension, then compare median views, engagement rate and posting pace in a spreadsheet. Step by step. - **Published**: 2026-01-18 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: tiktok, competitor analysis, marketing, strategy - **Reading time**: 5 min read - **Web version**: https://www.insightsocial.app/blog/tiktok-competitor-analysis-guide --- To analyze TikTok competitors, export each rival's last 100 videos with the InsightSocial Chrome extension (views, likes, comments, shares, caption, music, date), then compare three numbers per account in a spreadsheet: median views per video, engagement rate ((likes + comments + shares) ÷ views), and videos per week. Read the captions and sounds of each account's top 10 videos to see what drives the outliers. ## Introduction Your competitors are on TikTok. They're posting content, building audiences, and engaging with potential customers. The question is: do you know what's working for them? TikTok competitor analysis isn't about copying. It's about understanding: - What content resonates in your niche - How often successful accounts post - Which trends they're leveraging - Where the gaps are that you can fill In this guide, you'll learn how to systematically analyze TikTok competitors using data extraction tools. ## Why Competitor Analysis on TikTok Matters ### The TikTok Opportunity TikTok's algorithm gives every video a chance to go viral, regardless of follower count. This means: - New accounts can compete with established ones - Content quality matters more than audience size - Understanding what works is crucial for growth ### What You'll Learn from Competitors Analyzing competitor accounts reveals: | Insight | Business Value | |---------|---------------| | Posting frequency | Optimal content cadence | | Content themes | What topics resonate | | Hashtag strategy | Discovery opportunities | | Engagement rates | Performance benchmarks | | Sound usage | Trending audio to leverage | | Video formats | What styles work | ## How to Run a TikTok Competitor Analysis ### Step 1: Identify Your Competitors List 5-10 accounts to analyze: - **Direct competitors**: Same product/service - **Indirect competitors**: Same audience, different offering - **Aspirational accounts**: Where you want to be - **Niche leaders**: Top performers in your space ### Step 2: Extract Their Data Open each competitor's profile, click the InsightSocial icon, choose **Videos**, pick 50, 100 or 250 and Latest or Popular, and click Scrape. [InsightSocial's TikTok scrapers](/scraper/tiktok) give you: 1. Video data (views, likes, comments, shares per video) 2. Content details (captions with their hashtags, music, duration, upload date) Note each account's follower count from its profile page by hand; the video export doesn't include it. Export each competitor's data to separate spreadsheets. ### Step 3: Calculate Key Metrics For each competitor, calculate: **Engagement Rate:** ``` (Likes + Comments + Shares) / Views x 100 ``` **Average Views:** ``` Total Views / Number of Videos ``` **Posting Frequency:** ``` Videos per Week = Videos in Last 30 Days / 4 ``` ### Step 4: Analyze Content Patterns Look for patterns in top-performing videos: - What topics get the most engagement? - Are certain video lengths more successful? - Which hashtags appear in viral content? - What sounds/music correlate with views? ### Step 5: Identify Gaps and Opportunities Compare competitors to find: - Topics they're missing - Formats no one is using - Hashtags with low competition - Audience questions not being answered ## Building Your Competitor Dashboard Create a spreadsheet with these columns (the rows below are an illustration, not real accounts): | Competitor | Followers | Avg Views | Eng Rate | Posts/Week | Top Hashtags | Notes | |------------|-----------|-----------|----------|------------|--------------|-------| | @competitor1 | 50K | 10K | 5.2% | 4 | #niche #trend | Strong hooks | | @competitor2 | 25K | 15K | 8.1% | 7 | #topic #viral | High frequency | Update monthly to track changes. ## Turning Insights into Action ### Content Strategy Based on competitor analysis: 1. **Double down on what works**: If educational content performs well across competitors, create your version 2. **Fill the gaps**: Topics competitors miss are opportunities 3. **Improve on weakness**: Where competitors have low engagement, you can do better ### Posting Schedule If top competitors post 5x per week, aim for similar frequency. Consistency matters on TikTok. ### Hashtag Strategy Build a hashtag list from competitor data: - High-volume hashtags for reach - Niche hashtags for targeting - Branded hashtags for recognition ## Tools You'll Need 1. **[TikTok Profile Scraper](/scraper/tiktok-profile-scraper)**: Extract competitor profiles 2. **[TikTok Video Scraper](/scraper/tiktok-video-scraper)**: Get video-level data 3. **[TikTok Comments Scraper](/scraper/tiktok-comments-scraper)**: See how audiences react to competitor content 4. **[TikTok Analytics Scraper](/scraper/tiktok-analytics-scraper)**: Pull engagement metrics for benchmarking 5. **Spreadsheet**: Google Sheets or Excel for analysis 6. **Optional: Data visualization** · Charts for presentations ## Common Mistakes to Avoid ### Copying Instead of Learning Don't recreate competitor videos. Understand *why* they work and apply principles to original content. ### Analyzing Too Few Competitors 5-10 accounts give you patterns. 1-2 accounts give you bias. ### One-Time Analysis TikTok moves fast. Update your analysis monthly to stay current. ### Ignoring Small Accounts High-engagement small accounts often have the best content strategies. Don't only look at follower counts. ## Case Study: Finding Your Content Edge Here is a hypothetical example of how the analysis plays out: **Scenario:** A fitness brand wants to grow on TikTok. **Analysis:** 1. Scraped 10 fitness competitor accounts 2. Found that workout tutorials had high views but low engagement 3. Found that "day in the life" content had a clearly higher engagement rate 4. Noticed a gap: no competitors were doing "nutrition myth-busting" **Result:** The brand focused on lifestyle content and myth-busting, differentiating from competitors while targeting proven engagement patterns. ## Conclusion TikTok competitor analysis is your shortcut to understanding what works. By extracting data, calculating metrics, and identifying patterns, you can build a content strategy based on evidence, not guesswork. Start with [InsightSocial's TikTok scrapers](/scraper/tiktok) to extract your first competitor's data today. --- *Ready to analyze competitors? [Install InsightSocial free](https://chromewebstore.google.com/detail/insightsocial-free-social/cddgiejchlkeedmhjeodlcjdiddlcdld).* --- # How to Analyze Twitter (X) Competitors With Data Source: https://www.insightsocial.app/blog/twitter-competitor-analysis-guide, updated 2026-10-18 > Export rivals' X posts with a free Chrome extension, then compare posts per week, median views and engagement per post in a spreadsheet. - **Published**: 2026-01-18 - **Updated**: 2026-10-18 - **Author**: InsightSocial Team - **Tags**: twitter, x, competitor analysis, strategy, social media - **Reading time**: 6 min read - **Web version**: https://www.insightsocial.app/blog/twitter-competitor-analysis-guide --- To track competitors on X, export each rival's last 100 to 300 posts with the InsightSocial Chrome extension (likes, reposts, replies, quotes, views, bookmarks, date) and compare posts per week, median views and engagement per post in a spreadsheet. Re-export monthly to see what changed. X shows follower lists only partially, so treat follower exports as a sample. ## Introduction Your competitors are on Twitter. They're building audiences, engaging customers, and establishing thought leadership. The question isn't whether to track them. It's how to do it systematically. This guide provides a complete framework for Twitter competitor analysis, from identifying who to monitor to turning insights into action. ## Why Twitter Competitor Analysis Matters Twitter is uniquely valuable for competitive intelligence because: - **Real-time**: Competitors share news and updates immediately - **Public**: Most content is visible without following - **Engaging**: Replies and quotes reveal audience sentiment - **Measurable**: Engagement metrics are visible on every tweet Done well, competitor analysis helps you: - Identify content gaps to exploit - Benchmark your performance - Spot emerging trends early - Learn from competitor successes and failures ## Building Your Competitor Set ### Direct Competitors Start with companies selling to your same audience: - Same industry and category - Similar product/service offerings - Overlapping target markets ### Aspirational Competitors Include brands you want to emulate: - Market leaders in your space - Companies known for excellent Twitter presence - Innovators in content strategy ### Adjacent Competitors Don't forget near-competitors: - Different products, same audience - Same products, different markets - Potential future competitors **Recommended**: Track 5-10 competitors actively, with quarterly reviews to add/remove. ## Metrics That Matter ### Audience Metrics | Metric | What It Shows | |--------|---------------| | Followers | Reach potential | | Growth Rate | Momentum | | Follower Quality | Audience authenticity | ### Content Metrics | Metric | What It Shows | |--------|---------------| | Tweet Frequency | Content investment | | Content Mix | Strategy focus | | Engagement Rate | Content resonance | ### Engagement Metrics Collect these with the [Twitter posts scraper](/scraper/twitter-posts-scraper). Each exported post carries its likes, reposts, replies, quotes and views: | Metric | Calculation | |--------|-------------| | Engagement Rate | (Likes + Reposts + Replies) / Views | | Reply Rate | Replies / Total Engagements | | Share Rate | Retweets / Total Engagements | ## Data Collection with InsightSocial ### Step 1: Note the headline numbers Write down each competitor's follower and post counts from their profile page. A one-row profile-details export is coming to the extension but is not available yet. ### Step 2: Export recent posts Export each competitor's recent posts with the [Twitter posts scraper](/scraper/twitter-posts-scraper): ``` 1. Open the competitor's profile on x.com 2. Click the InsightSocial icon and choose Posts 3. Pick 100 or 300 posts and click Scrape 4. Export to Excel, CSV or Google Sheets ``` ### Step 3: Sample the audience The [Twitter followers scraper](/scraper/twitter-followers-scraper) exports an account's followers with bio and follower count. For many accounts X stops serving the list after about 50 to 70 followers, so read it as a sample, not the full audience. The Liked Posts option only works on your own profile: X hides the Likes tab on other accounts. ## Analysis Framework ### Content Audit Categorize competitor tweets by type: - **Promotional**: Product announcements, sales - **Educational**: Tips, how-tos, insights - **Engagement**: Questions, polls, replies - **News**: Industry updates, trends - **Culture**: Behind-the-scenes, team content Calculate the percentage of each type. Compare to your own mix. ### Performance Benchmarking Create a comparison table. The numbers below are an illustration, not real accounts: | Competitor | Followers | Tweets/Week | Avg. Engagement | |------------|-----------|-------------|-----------------| | You | 10,000 | 14 | 1.2% | | Competitor A | 25,000 | 21 | 1.8% | | Competitor B | 15,000 | 10 | 2.1% | Identify where you're underperforming. ### Content Gap Analysis Find what competitors are doing that you're not: - Topics they cover, you don't - Formats they use (threads, polls, media) - Hashtags driving engagement - Posting times and frequency ### Opportunity Identification Look for competitor weaknesses: - Topics they ignore that matter to audience - Poor engagement on certain content types - Audience complaints or requests - Gaps in their content calendar ## Turning Insights Into Action ### Quick Wins Immediate actions from analysis: 1. Match competitors' posting frequency if they outperform 2. Test content formats driving their engagement 3. Use successful hashtags they've validated 4. Address topics they're missing ### Strategic Initiatives Longer-term improvements: 1. Build content calendar informed by competitor gaps 2. Develop unique voice/angle competitors lack 3. Invest in content types you're under-serving 4. Create competitive positioning strategy ### Ongoing Monitoring Set up regular tracking: - **Weekly**: Check competitor content themes - **Monthly**: Extract fresh data, update benchmarks - **Quarterly**: Full competitive review, adjust strategy ## Tools for Automation InsightSocial exports to Excel, CSV, JSON or Google Sheets, so you can use them in: - **Google Sheets**: a shared competitive dashboard - **Excel**: pivot table analysis - **Notion or Airtable**: import the CSV as a competitor database - **Looker Studio**: connect it to the Google Sheet for charts ## Example: Competitive Dashboard Build a simple dashboard tracking: 1. **Your metrics** vs. **top 3 competitors** 2. Week-over-week changes 3. Best-performing content by competitor 4. Content calendar comparison Update monthly with fresh InsightSocial exports. ## Common Mistakes to Avoid ### Vanity Metric Focus Don't obsess over follower counts. A competitor with 50K followers and 0.5% engagement is less successful than one with 15K and 3% engagement. ### Copying Without Context Understand why competitor content works before replicating. Their audience may differ from yours. ### Analysis Paralysis Don't track so many competitors or metrics that you never act. Start with 3-5 competitors and 5 key metrics. ### One-Time Analysis Competitor strategies evolve. Schedule regular check-ins, not one-off reports. ## Conclusion Twitter competitor analysis isn't about copying. It's about understanding the landscape and finding your opportunities. With InsightSocial, you can collect the data. This framework helps you turn data into strategy. **Start today:** 1. Install [InsightSocial](https://chromewebstore.google.com/detail/insightsocial-free-social/cddgiejchlkeedmhjeodlcjdiddlcdld) 2. Extract data from your top 3 competitors 3. Build your first competitive benchmark --- *Want more Twitter/X insights? Read how to [export an X account's posts and followers](/blog/how-to-scrape-twitter-profiles).* --- # InsightSocial API documentation # Using an AI agent (/docs/ai-agents) Point Claude, ChatGPT, Cursor or any coding agent at the InsightSocial API with one paste-in prompt and the free endpoint catalogue, so it reads the real paths, parameters and prices instead of guessing. You do not have to read the rest of these docs before you start. Paste the prompt below into your agent and it will read the free endpoint catalogue, check your key and make the first calls for you. Everything happens over plain HTTPS: one base URL, one header, one JSON envelope, so there is nothing you have to install. If your agent supports MCP or Agent Skills, one command sets up both instead: `npx -y insightsocial init`. See [MCP server, CLI and agent skills](/docs/mcp). For workflows in n8n, see [n8n](/docs/n8n). ## Why the catalogue matters [#why-the-catalogue-matters] `GET https://api.insightsocial.app/v1/endpoints` is public and free, and it needs no key. It lists every endpoint with its description, every parameter (name, type, whether it is required, allowed values, an example) and its price in credits. An agent that reads it before planning a call never invents a path or a parameter, and it can tell you what a job will cost before it spends anything. ```bash title="cURL" # Every endpoint on one platform curl "https://api.insightsocial.app/v1/endpoints?platform=tiktok" ``` ```json title="Response (one entry, trimmed)" { "path": "/v1/tiktok/profile", "method": "GET", "platform": "tiktok", "description": "Returns a TikTok account's public profile: display name, bio, follower count ...", "credits": 10, "paginates": false, "cache_ttl_seconds": 86400, "params": [ { "name": "handle", "required": false, "in": "query", "type": "string", "example": "charlidamelio", "one_of_group": "handle|user_id" }, { "name": "user_id", "required": false, "in": "query", "type": "string", "one_of_group": "handle|user_id" } ], "available": true } ``` A few fields worth knowing: | Field | Meaning | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `credits` | A number for a fixed price, or `{ "min", "max" }` for a metered endpoint. A metered call holds the most it can cost with your parameters and is charged what it actually used. | | `params[].one_of_group` | Parameters in the same group are alternatives: send at least one of them. | | `paginates` | `true` when the endpoint returns a cursor for the next page. | | `cache_ttl_seconds` | Kept for compatibility. It does not change the price: every repeat is charged. | | `available` | Only call endpoints where this is `true`. | `?platform=` takes one platform id, such as `tiktok`, `youtube`, `bluesky` or `weibo` (the full list is under [UNKNOWN\_PLATFORM](/docs/errors#unknown_platform)). Leave it off to get all 22 platforms at once. If your tooling generates clients or agent tools from OpenAPI, the same surface is published as an OpenAPI 3.1 spec at `GET https://api.insightsocial.app/v1/openapi.json`, also free and keyless. ## Give it the docs as Markdown [#give-it-the-docs-as-markdown] The quickest start is one link: `https://www.insightsocial.app/docs/api-reference.md` lists every endpoint with its path, a one-line description and its required parameters, and links to each endpoint's full page. Give it to your assistant together with your key and say what data you want. Every page of these docs is also plain Markdown: add `.md` to its URL, for example `https://www.insightsocial.app/docs/pagination.md`. Two more files cover the whole site: * `https://www.insightsocial.app/docs/llms.txt` lists every page, one line each. * `https://www.insightsocial.app/docs/llms-full.txt` is every page in one file. Paste either into a chat, or let an agent that can fetch URLs read them itself. ## Copy the prompt [#copy-the-prompt] Put your key in the environment first, so it never appears in the chat: ```bash title="Terminal" export INSIGHTSOCIAL_API_KEY=isk_live_... ``` Then paste this into your agent: ```text title="Prompt" Set up the InsightSocial API in this project and make a first successful call. Facts you can rely on: - Base URL: https://api.insightsocial.app/v1 - Auth: send the header `x-api-key: $INSIGHTSOCIAL_API_KEY` on every request. Read the key from the environment. Never print it, put it in a URL, or commit it. Authorization: Bearer is refused. - All data endpoints are GET with query parameters. - Success responses look like: { success: true, platform, endpoint, schema_version: "2", data, pagination?, unavailable, credits_used, credits_remaining, request_id, cached, idempotent_replay, charge_reason, free_call }. List responses put rows in data.items (each { post }, { author } or { comment }) and add pagination { next_cursor, has_more }. unavailable lists fields (paths into data) this response could not fill. - Ids are strings, times are ISO 8601 UTC. null means unknown, never zero. - Responses carry data only: no engagement rate, labels or relevance scores. Compute what you need from the raw counts. Parameters that ask for analysis (label, relevance, relevant_to, judgments, fit, brand, ...) are refused with 400 UNSUPPORTED_PARAMETER and error.param. - Error responses look like: { success: false, error: { type, message, param? }, request_id, credits_used, credits_remaining }. - Prices are per endpoint, in credits. Failed calls, empty results and dry_run=1 calls are never charged. Repeating a call is charged again, so store responses you need twice. Before writing any call, read the reference instead of guessing paths or parameters: https://www.insightsocial.app/docs/api-reference.md For prices and allowed values, read the catalogue. It is free and needs no key: GET https://api.insightsocial.app/v1/endpoints GET https://api.insightsocial.app/v1/endpoints?platform= Use only endpoints where available is true, only parameters listed for that endpoint, and tell me the price (credits, or min-max for metered) before any call over 50 credits. Then, in order: 1. Verify the key with GET https://api.insightsocial.app/v1/credits (free) and print credits_remaining. 2. Call GET https://api.insightsocial.app/v1/tiktok/profile?handle=khaby.lame and print data.author.followers and credits_used. 3. Read the same kind of account on tiktok/profile (handle=natgeo), youtube/channel (handle=mkbhd) and twitter/profile (handle=nasa). Print one line per platform. 4. Pick one list endpoint from the catalogue whose paginates is true, and read two pages by sending pagination.next_cursor back as ?cursor= while has_more is true. Send cursor values back unchanged, with the same other parameters as page 1. Rules: - Check `success` before using `data`. Branch on error.type, never on the message text. - Retry only on HTTP 429, HTTP 503, IDEMPOTENCY_IN_PROGRESS and INTERNAL_ERROR. On a 400, read error.param and fix or remove that parameter before trying again. Wait for the Retry-After header when present, then back off with jitter. Never retry other 4xx errors. - On INSUFFICIENT_CREDITS, stop and tell me. Do not retry. - Stay under 60 requests per minute and 10 requests in flight. - Stop and ask me before spending more than 500 credits in total. ``` The prompt pins down the three things an agent must not guess (the base URL, the header and the response shape), sends it to the catalogue before it writes a call, and gives it four concrete tasks that end with accounts read on four platforms. The whole exercise costs roughly 60 to 100 credits, and on a new account the 10 free calls cover most of it. ## What the agent will do first [#what-the-agent-will-do-first] A good agent run starts the same way every time, and you can ask for these steps by name: **Read the catalogue.** `GET /v1/endpoints?platform=` to find the endpoint and its parameters. Free, no key. **Check the key.** `GET /v1/credits` confirms the key works and returns your balance, the monthly allowance, pack credits and your remaining free calls. Free. **Run a single paid request,** then swap the platform segment of the path and run it again to see how another network answers. ```bash title="cURL" curl "https://api.insightsocial.app/v1/credits" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Wiring the API into your own agent [#wiring-the-api-into-your-own-agent] When you build the agent yourself, one generic HTTP tool is enough: the model picks the path and parameters from the catalogue, and your tool makes the call. Keep the key in your code, not in the model's context. ```python title="Python" import os import requests KEY = os.environ["INSIGHTSOCIAL_API_KEY"] BASE = "https://api.insightsocial.app/v1" # Give the model this catalogue once, as reference text or a second tool. CATALOGUE = requests.get(f"{BASE}/endpoints", timeout=30).json() def insightsocial_get(path: str, params: dict) -> dict: """Tool: call one InsightSocial endpoint, e.g. path='tiktok/profile'.""" res = requests.get(f"{BASE}/{path.removeprefix('/v1/').lstrip('/')}", params=params, headers={"x-api-key": KEY}, timeout=120) body = res.json() if not body["success"]: # Hand the model a short instruction, not a raw error envelope. retry = res.headers.get("Retry-After") return {"error": body["error"]["type"], "message": body["error"]["message"], "retry_after_seconds": retry} return {"data": body["data"], "pagination": body.get("pagination"), "credits_used": body["credits_used"], "credits_remaining": body["credits_remaining"]} ``` Describe the tool to the model with two parameters, `path` (string, for example `tiktok/profile`) and `params` (object of query parameters). This works with Claude tool use, OpenAI function calling or any agent framework, because it is only an HTTP request. Three habits keep an agent loop cheap and correct: * **Return a short error, not the envelope.** A model given a raw `success: false` body tends to reason around it. Hand it the `error.type` and let your code decide whether to retry. * **Watch the budget.** Every response carries `credits_used` and `credits_remaining`. Stop the loop on a budget you set, and cap the number of tool steps. * **Price before you call.** On a metered endpoint the hold depends on your parameters and never exceeds the catalogue's `max`. `dry_run=1` returns our quote in `data.dry_run` (`credits_min`, `credits_max`) with `charge_reason: "dry_run"`, and is never charged. ## Troubleshooting [#troubleshooting] **The agent gets `MISSING_API_KEY`.** It is almost certainly putting the key in `Authorization: Bearer`. That header is ignored: the API looks for the key in `x-api-key` and nowhere else, so a Bearer-only request arrives with no key at all. `INVALID_API_KEY` is different: the `x-api-key` header is present but its value is wrong, such as a token that does not start with `isk_` or a key that does not exist. **It invents parameters.** A parameter the endpoint does not have is refused with `400 UNSUPPORTED_PARAMETER`, and `error.param` names it. Nothing is charged, but it wastes a round trip. Tell the agent to read `GET /v1/endpoints?platform=` first and use only the listed `params`. **It gets `UNSUPPORTED_PARAMETER`.** The agent sent a parameter that asks for analysis, such as `relevance`, `relevant_to` or `label`, often copied from older examples. `error.param` names it. Have the agent drop it and filter or score the rows itself; see [Schema 2](/docs/schema-2). **It gets `CURSOR_INVALID` on page 2.** It changed a parameter between pages, sent the cursor under another name, or reused a cursor from the previous schema. A cursor works only as `cursor`, with the first page's parameters, for 24 hours. See [Pagination](/docs/pagination#bad-or-stale-cursors). **It hits `RATE_LIMITED` or `CONCURRENCY_LIMIT`.** Each key allows 60 requests per minute and 10 in flight. Have the agent honour `Retry-After` and run fewer calls in parallel. See [Rate limits](/docs/rate-limits). **It gets `INSUFFICIENT_CREDITS` on a call that should be cheap.** A metered call holds the most it can cost with your parameters before it runs, so the balance has to cover that hold, not the final charge. `dry_run=1` shows the hold for free. The error carries `top_up_url`, a checkout link already tied to your account; have the agent show it to you. API credits share one balance with your InsightSocial export credits, and they are non-refundable. Calls that fail or return nothing are simply never charged. **It keeps paying for the same data.** Every repeat of a call is charged. Have the agent keep the responses it already has instead of calling again, and make sure it is not adding `fresh=1` or `Cache-Control: no-cache`, which skip the 2-credit shared cache and force a full-price fetch. ## Next steps [#next-steps] One command to connect Claude Code, Cursor, Codex or Gemini CLI. The same first calls, step by step, by hand. Creating, naming and revoking keys. Every error type and whether to retry. End-to-end builds an agent can adapt. --- # Authentication (/docs/authentication) Create, send, rotate and revoke InsightSocial API keys with the x-api-key header. Every request carries your key in the `x-api-key` header. The key is all you need to authenticate. You do not sign in, trade it for a token or keep a session alive. ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/profile?handle=natgeo" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## What a key looks like [#what-a-key-looks-like] A key is `isk_live_` followed by 43 URL-safe characters (32 random bytes). You may also come across keys starting `isk_test_`. They are accepted the same way and draw on the same credits. The full key is shown in the dialog that opens right after you create it. It is stored encrypted, so you can show or copy it again later from the dashboard. Keep it in your secret store, not in source code. ## Create a key [#create-a-key] 1. Sign in at [insightsocial.app](https://www.insightsocial.app). 2. Open the [API dashboard](https://www.insightsocial.app/portal/api). The first time you open it, a first key is created for you, and you can copy it from [API keys](https://www.insightsocial.app/portal/api/keys). 3. To add another, click create and give it a name that says where it runs, such as `production` or `local-dev`. A name is required and can be up to 64 characters. 4. Copy the key from the dialog. ## Send the key [#send-the-key] ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/profile?handle=natgeo" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python title="Python" import os import requests res = requests.get( "https://api.insightsocial.app/v1/tiktok/profile", params={"handle": "natgeo"}, headers={"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]}, ) ``` ```ts title="Node.js" const res = await fetch( "https://api.insightsocial.app/v1/tiktok/profile?handle=natgeo", { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY! } }, ); ``` The API does not read the `Authorization` header. A key sent as `Authorization: Bearer ...` is treated as no key at all and returns `MISSING_API_KEY`. Never put the key in a query string. Anything in a URL can be recorded by browsers, proxies and the sites you link to. ## Authentication errors [#authentication-errors] Authentication runs before anything else, so these failures never cost credits and do not count against your rate limit. `credits_remaining` is `null` on all of them. | `error.type` | Status | What happened | Fix | | --------------------- | ------ | ----------------------------------------------------------------------------------------- | ------------------------------------------------- | | `MISSING_API_KEY` | 401 | No `x-api-key` header reached the API | Add the header, and check that no proxy strips it | | `INVALID_API_KEY` | 401 | The value is not an InsightSocial key (for example a session token), or no key matches it | Copy the key again from the dashboard | | `API_KEY_REVOKED` | 401 | The key was revoked | Create a new key | | `SERVICE_UNAVAILABLE` | 503 | We could not verify the key right now | Retry shortly | ```json title="Response" { "success": false, "error": { "type": "API_KEY_REVOKED", "message": "This API key has been revoked. Create a new one at https://www.insightsocial.app/portal/api/keys" }, "request_id": "req_1a2b3c4d5e6f", "credits_used": 0, "credits_remaining": null } ``` The 401s are not worth retrying: the same key fails the same way until you change it. Running out of credits is a different problem and returns `402 INSUFFICIENT_CREDITS`; see [Errors](/docs/errors). ## Key management [#key-management] | Rule | Value | | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Keys per account | Up to 25 | | Name | Required, up to 64 characters | | Scope | Every key can call every `/v1` endpoint | | Balance | All keys draw on your one account balance | | Storage | Verified against a hash; the key itself is kept encrypted so you can show or copy it again from the dashboard. Keys created before 2026-09-23 cannot be shown again | | Revocation | Takes effect on the next request, which returns `401 API_KEY_REVOKED` | | Rate limits | Counted per key. See [Rate limits](/docs/rate-limits) | ### Rotate a key [#rotate-a-key] Issue the new key, roll it out, check that requests now use it, and only then revoke the old one from the dashboard. Revoking first causes downtime, because the old key stops working on its very next request. If a key has leaked, revoke it at once and accept the downtime. Anyone holding a live key can spend your credits. ## Security guidance [#security-guidance] * **Never ship a key in client-side code.** Anyone can unpack a web or mobile app and pull the key out, and you pay for every call made with it. Put a server route in front of the API. * **Use one key per environment.** That way you can revoke a test key without breaking live traffic. * **Store keys in a secret manager** or encrypted environment variables, never in git. * **Revoke keys you no longer use**, including ones issued to contractors or short-lived jobs. ## Next steps [#next-steps] Your first authenticated call in about a minute. Every error type and whether to retry it. What calls cost and how the shared balance works. Per-key request and concurrency limits. --- # Caching (/docs/caching) How cached answers are flagged and priced, and how to force a fresh fetch. One thing can make a call cheaper than its listed price: a recent answer to the same request may already sit in our shared cache, which costs 2 credits instead of the full price. It needs no setup and is reported on every response. Repeating a call is charged like the first time. A repeat can return newer data, so it is a new call. ## Reading the signals [#reading-the-signals] | Field | Meaning | | --------------- | ---------------------------------------------------------------------------------------------- | | `cached` | `true` when the answer came from our shared cache instead of a new fetch | | `charge_reason` | Why you were charged what you were: `miss`, `shared_cache`, `replay`, `no_result` or `dry_run` | | `credits_used` | What this call cost. Also in the `X-Credits-Used` header | Rely on the body fields. There is no `X-Cache` header. ## What each case costs [#what-each-case-costs] | Case | `cached` | `charge_reason` | Credits | | ---------------------------- | -------- | --------------- | -------------------------------------------- | | New fetch | `false` | `miss` | The endpoint's price (metered: what it used) | | Served from the shared cache | `true` | `shared_cache` | 2 | | Nothing found | `false` | `no_result` | 0 | The shared cache is not tied to your account. Public data is the same for everyone, so a request someone else made moments ago can answer yours. That is why a shared-cache answer is cheap but not free. If you need the same data more than once, store the first response on your side instead of calling again. ## Force a fresh fetch [#force-a-fresh-fetch] When you need data as it is right now, send `Cache-Control: no-cache`, or add `fresh=1` to the query string. Either skips the shared cache, so the call is always charged at the endpoint's normal price. ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/profile?handle=khaby.lame" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" \ -H "Cache-Control: no-cache" ``` ```python title="Python" import os import requests res = requests.get( "https://api.insightsocial.app/v1/tiktok/profile", params={"handle": "khaby.lame"}, headers={ "x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"], "Cache-Control": "no-cache", }, ) body = res.json() print(body["cached"], body["charge_reason"], body["credits_used"]) ``` ```ts title="Node.js" const res = await fetch( "https://api.insightsocial.app/v1/tiktok/profile?handle=khaby.lame", { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY!, "Cache-Control": "no-cache", }, }, ); const body = await res.json(); console.log(body.cached, body.charge_reason, body.credits_used); ``` The same request with the query-string form: ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/profile?handle=khaby.lame&fresh=1" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` `fresh=1` (or `fresh=true`) is read by us and not passed on as an endpoint parameter. Either form affects only the request it is on. ## When should I force a fresh fetch? [#when-should-i-force-a-fresh-fetch] Leave it off for most work. A shared-cache answer is far cheaper than a new fetch. Force it only when stale data would be wrong, for example: * a reconciliation or audit that must reflect the platform at the moment of the call; * reading a post or profile straight after it changed; * comparing a cached answer against a live one while debugging. ## Next steps [#next-steps] Every charge reason, free calls, and where your balance comes from. Prices for every endpoint. Retries, idempotency and logging before launch. --- # Changelog (/docs/changelog) Every change to the InsightSocial API that affects what you send, what comes back, or what a call costs. Newest first. Changes that affect your integration are listed here with the date they took effect. Anything that changes what a call costs is marked **Billing**. ## October 23, 2026 [#october-23-2026] **Breaking: three platforms withdrawn.** Their endpoints are out of the catalogue, the reference and the MCP tools, and calls to them return an error. Failed calls cost nothing. The API now covers 22 platforms; every current endpoint is in [Endpoint pricing](/docs/endpoint-pricing). ## October 18, 2026 [#october-18-2026] **Running out of credits gives you a checkout link.** An `INSUFFICIENT_CREDITS` error (HTTP 402) now carries `error.top_up_url`, which opens the checkout for the smallest credit pack that covers what the call was short, already tied to your account. The same link ends `error.message`, so a script or AI agent that shows the message shows the link too. The message used to say "Top up at /pricing", a page that did not know who you were. See [Errors](/docs/errors). **One email the first time your account runs out of credits.** The first time a call is refused for credits, the account's email address gets one message with the same checkout link, so a script that keeps failing in the background does not go unnoticed. It is sent once per account, never again, and never delays the 402. **Docs: price tables corrected.** The price tables in [Pagination](/docs/pagination) and the [recipes](/docs/recipes) still showed prices from before October 5, double what calls cost. They are now built from the same spec the API charges from, and a test fails the build if they drift. What calls are charged did not change. ## October 14, 2026 [#october-14-2026] **How-to guides.** [How-to guides](/docs/how-to) cover one job each that most data APIs do not document, with the endpoint, cURL, Python and Node.js code, a real response and the price: [the TikTok videos a user liked](/docs/how-to/tiktok-videos-a-user-liked), [LinkedIn company employees](/docs/how-to/linkedin-company-employees), [a YouTube channel's business email](/docs/how-to/youtube-channel-email), [Reddit comment search](/docs/how-to/reddit-comment-search), [Xiaohongshu (RedNote) search](/docs/how-to/xiaohongshu-rednote-search) and more. Each endpoint's reference page links the guides that use it. **Every docs and API page as Markdown.** Pages under `/docs`, `/social-media-api` and `/mcp` answer a request sent with `Accept: text/markdown` with a Markdown version of the same page, and the HTML names it in a `Link: <…>; rel="alternate"; type="text/markdown"` header. Adding `.md` to the URL works too. An endpoint page is about 4 KB as Markdown, against more than 1 MB as HTML, which is what an AI agent reading the docs wants. **Docs: a shared-cache answer costs 2 credits.** [Caching](/docs/caching) and [Credits](/docs/credits) still said 5, the price before October 5. The charge itself has been 2 since then. **Date filters on 112 more endpoints.** Lists of posts and comments across the platforms now take `until` (on or before) and, where they did not have it already, `since` (on or after), as `YYYY-MM-DD` or an ISO 8601 timestamp. On lists that are not in date order they filter each page and the walk continues, and a page is charged even when every row on it was filtered out. See [Pagination](/docs/pagination#date-filters-on-other-lists). **`GET /v1/linkedin/search/hashtag` is switched off.** It has returned no posts for any hashtag since at least October 3, so every call came back as a free, empty result that read as "nobody posts under this tag". Calls answer `503 ENDPOINT_UNAVAILABLE` with `Retry-After: 3600` and are never charged, and the endpoint is out of the catalogue until it works again. `GET /v1/linkedin/search/posts` with `query=#hiring` returns recent posts that carry the tag. ## October 8, 2026 [#october-8-2026] **16 more platforms.** Bluesky, Truth Social, Snapchat, Telegram, Twitch, Kick, Rumble, Kwai, Douyin, Xiaohongshu (RedNote), Quora, TikTok Shop, Weibo, Zhihu, Substack and Nextdoor are now on the API, with the same key, response envelope and credit balance. Their endpoints and prices are in [Endpoint pricing](/docs/endpoint-pricing), and each platform has its own page, such as [Bluesky](/docs/platforms/bluesky). ## October 5, 2026 [#october-5-2026] **Billing: every endpoint costs half what it did.** A standard call is 10 credits (was 20), and a 100-credit call is now 50. Metered endpoints halve at both ends of their range, and so does what a metered call holds. An answer served from the shared cache costs 2 credits (was 5). The free plan's 500 credits a month now cover 50 standard calls instead of 25. The 10 free calls a new account gets now cover calls priced at up to 100 credits, which is the same set of endpoints as before. Failed calls, empty results, `dry_run=1` and `Idempotency-Key` replays are still free. Credits you already hold are worth twice as many calls. Every current price is in [Endpoint pricing](/docs/endpoint-pricing). Changelog entries below this one quote the prices of their own date. ## October 4, 2026 [#october-4-2026] **New: a hosted MCP server at `https://api.insightsocial.app/mcp`.** Claude (desktop, claude.ai, Cowork), ChatGPT and any MCP client that supports sign-in connect by URL: add a connector, sign in to InsightSocial and click Allow, with no key to paste. Each app gets its own key, listed under Connected apps on [API keys](https://www.insightsocial.app/portal/api/keys), where you can disconnect it. Clients that cannot sign in send an API key as a Bearer token. The hosted server has the same tools as the local one plus `quote_endpoint` and `send_feedback`, and `call_endpoint` is marked as spending credits so clients ask first. See [MCP](/docs/mcp). **The CLI signs in through your browser.** `npx -y insightsocial init` (or `insightsocial login`) opens a sign-in page and prints a short code: type it on the page and click Allow, and the CLI prints which account it signed into. `login --api-key` still takes a key you already have. **Breaking: a LinkedIn person has one id everywhere, the member URN.** `author.id` on a LinkedIn person is now the URN (`ACoAA…`) on every endpoint that has one: profiles, search, similar, reactors, and the authors of posts. It used to be the vanity slug on profiles and a numeric member id on posts and reactors, so the same person had different ids. The slug is in `username` (it was sometimes the URN there), the numeric id in `ext.member_id` on profiles and `ext.author_member_id` on posts and comments. Comment authors have no URN at the source, so their `author.id` is `null` and listed in `unavailable`; join on `username`. On `/v1/linkedin/search/people/by-url`, where the source gives no URN, `id` stays the slug. Companies keep their numeric id. **Breaking: `GET /v1/tiktok/profile/region` returns a record, not a profile.** The source sent the handle as the profile's `id`. `data` is now `{ region, username, display_name, followers, … , url }` with no `id` and no `author` wrapper, and the endpoint is marked beta. **LinkedIn companies have one id everywhere.** `/v1/linkedin/search/companies` and `/v1/linkedin/company/also-viewed` now return the numeric company id in `author.id` (for example `"1035"`), the same id `/v1/linkedin/company` returns and `/v1/linkedin/company/posts` takes as `company_id`. The slug (`"microsoft"`) stays in `author.username`. **X replies to a retweet no longer include the original tweet as a reply.** A row whose `id` equals its `post_id` was the post itself; it is dropped, so the page holds replies only. **`Retry-After` on `UPSTREAM_ERROR` and `UPSTREAM_INVALID` is now at least 30 seconds** (was 5), longer when the platform asks for more. By the time you see one we have already retried, so 5 seconds met the same outage. **Reddit comment trees: `data.truncated` is `null` instead of `false`** when we cannot tell whether Reddit left branches out, and `true` when the tree reaches Reddit's depth limit. A thread was served 329 of its 602 comments while saying `false`. **Billing: a metered call holds what it can cost, not the top of the range.** The hold before a call is now worked out from the parameters you send. For example, a metered list called without `limit` now holds the price of one page instead of the top of its range. What a call is charged did not change. `dry_run=1` quotes the same hold. **The previous response shape is no longer served.** `InsightSocial-Version: legacy` is ignored and `/v1/openapi-legacy.json` is gone. No key was still using it. **Breaking: every key now gets schema 2.** One response shape per entity on every platform; analysis fields (`computed`, `labels`, `relevance`) are gone, cursors are `v2c.…`, and analysis parameters answer `400 UNSUPPORTED_PARAMETER`. Everything that changed is on [Schema 2](/docs/schema-2). **Billing: lower ceilings under schema 2.** A metered call no longer holds credits for labels, which schema 2 does not produce, so the ceiling held at the start of a call dropped on 24 endpoints. What a call is charged did not change: it was already what the call used. * Now one price, 20 credits a call: `GET /v1/tiktok/profile/videos`, `/v1/tiktok/video/comment/replies`, `/v1/tiktok/search/hashtag`, `/v1/youtube/video/comments`, `/v1/youtube/video/comment/replies`, `/v1/twitter/user/tweets`, `/v1/twitter/tweet/replies` and `/v1/reddit/subreddit`. * Now one price, 100 credits a call: `GET /v1/reddit/post/comments`. * Still metered, with a lower top: for example `GET /v1/tiktok/post/comments` is 20–60 and `/v1/twitter/search/tweets` 20–100. `GET /v1/tiktok/search/users` goes the other way, to 20–2,620, because its old ceiling was below what a call can use. Every current price is in [Endpoint pricing](/docs/endpoint-pricing). ## October 1, 2026 [#october-1-2026] **New endpoint.** `GET /v1/tiktok/similar` returns accounts similar to a TikTok creator, 100 credits a call. ## September 26, 2026 [#september-26-2026] **Billing: repeat calls are now charged.** Repeating a call you had already paid for used to be free for a while afterwards. A repeat is now charged like the first call, because it can return newer data. Store responses you need again on your side. Retries with the same `Idempotency-Key` still cost 0 and come back with `charge_reason: "replay"`. `owned` is no longer a `charge_reason`; you will still see it on Activity Log rows from before this date. See [Credits](/docs/credits#repeating-a-call). **The whole reference on one page.** [`/docs/api-reference.md`](https://www.insightsocial.app/docs/api-reference.md) lists every endpoint with its path, a one-line description and its required parameters. Give it to an AI assistant along with your key. See [AI agents](/docs/ai-agents). ## September 24, 2026 [#september-24-2026] **Not-found errors no longer read like outages.** A 404 sometimes ended with an extra sentence saying the endpoint was temporarily unavailable. It now says only that nothing exists at that identifier, and that you were not charged. ## September 23, 2026 [#september-23-2026] **The API is live** at `https://api.insightsocial.app/v1`. Public social media data, authenticated with one `x-api-key` header and paid from the same credit balance as InsightSocial exports. Every account gets 10 free calls. Start with the [Quickstart](/docs/quickstart), or run a call without code in the [Explorer](https://www.insightsocial.app/portal/api/explorer). **Pagination on every list endpoint.** List responses return a `pagination` block (`next_cursor`, `has_more`, `page_size`) next to `data`. See [Pagination](/docs/pagination). --- # Which endpoint should I use? (/docs/choosing-endpoints) Side-by-side decision tables for the endpoints that look alike, with the credit price of each so you pick the one that returns what you need for the least. Several endpoints overlap. Two of them may return the same account, one cheaply and one with extras, or the same comments as one page or as a whole thread. Picking the wrong one either costs more than it should or leaves you making a second call. Each section below takes one of those "these look the same" questions and puts the options next to each other with their prices. Every price here comes from the live catalogue at `GET https://api.insightsocial.app/v1/endpoints` (free, no key needed). A few pricing rules to keep in mind while you read: * **Fixed endpoints** show one number, and that is the charge for a successful call. * **Metered endpoints** show a range. The top of the range is held when the call starts, and when it finishes you are charged what the call actually used, never more than the ceiling. Plan your balance around the top of the range. * **Nothing found costs nothing.** Failed calls, empty results and `dry_run=1` calls are never charged. API credits are non-refundable, so this is how "you only pay for data" works: an unanswered call is simply never billed. * **Repeats are charged.** Calling the same endpoint again with the same parameters is a new call, because the data may have changed. A response served from the shared cache costs 2 credits. Store what you need to reuse. See [Credits](/docs/credits) for the full rules and [Endpoint pricing](/docs/endpoint-pricing) for every price in one table. ## Start here [#start-here] | What you are trying to do | Section | | -------------------------------------------------------- | ----------------------------------------------------------------- | | Account numbers alone, or together with its latest posts | [Profile, or profile plus posts?](#profile-or-profile-plus-posts) | | Know what `limit` does on a call | [What `limit` means](#what-limit-means-depends-on-the-endpoint) | | Fetch only what is new since your last run | [Only what is new](#only-what-is-new) | | Find posts or accounts by keyword | [Which search?](#which-search) | | Get what was said in a video | [Getting a transcript](#getting-a-transcript) | | Read the comments on a post | [Which comment endpoint?](#which-comment-endpoint) | | Track hiring and job postings | [Hiring and job postings](#hiring-and-job-postings) | | See what a brand runs as paid advertising | [Ad libraries](#ad-libraries) | ## Profile, or profile plus posts? [#profile-or-profile-plus-posts] `profile` returns the account and nothing else. `profile/full` returns the same account and its latest page of posts in one call, so you skip the follow-up list request. `profile/full` is a **beta** endpoint, but its two main parts are typed: `data.profile` is a [profile](/docs/schema/author), and each `data.posts[].post` is a [post](/docs/schema/post), the same shapes `profile` and the posts list return. Anything else under `data` keeps the source's own structure under our naming rules (snake\_case keys, string ids, ISO times where the source gives a timestamp) and may change. Under [schema 2](/docs/schema-2) it no longer carries computed metrics such as engagement rate or posting cadence; compute those from the posts it returns. | Your goal | Endpoint | Credits | | ----------------------------------------- | --------------------------------------------------------------------------------- | ------- | | Just the account | `/v1/tiktok/profile`, `/v1/twitter/profile`, `/v1/youtube/channel` | 10 | | Just the account, LinkedIn member | `/v1/linkedin/profile` | 50 | | Account + recent posts (beta) | `/v1/tiktok/profile/full`, `/v1/twitter/profile/full`, `/v1/youtube/profile/full` | 50 | | LinkedIn company + latest 10 posts (beta) | `/v1/linkedin/profile/full` | 50 | If you only need follower counts, use plain `profile`. When you fetch a profile and then always ask for its latest posts, `profile/full` replaces those two calls with one. On TikTok, for example, `profile` plus one page of `profile/videos` costs 20 credits, while `profile/full` is a flat 50 for the same profile and posts. Prefer the pair when cost matters; prefer `profile/full` when one round trip matters more. How many posts one `profile/full` call reads depends on the platform's page size: 10 on TikTok, up to 30 on YouTube, about 10 to 20 on X and 10 on a LinkedIn company. To read further back, send `pagination.next_cursor` back to `profile/full` as `cursor`: each further page is another 50-credit call. Paging the platform's posts list (for example `/v1/tiktok/profile/videos`) is usually cheaper. `/v1/linkedin/profile/full` takes a company page URL and replaces a `/v1/linkedin/company` plus `/v1/linkedin/company/posts` pair (100 credits) with one 50-credit call. For a person, use `/v1/linkedin/profile`. The fields that get filled vary by platform. Check the platform's page under [Platforms](/docs/platforms/tiktok) before you rely on one. ## What `limit` means depends on the endpoint [#what-limit-means-depends-on-the-endpoint] `limit` does two different jobs on this API. Read the endpoint's parameter description before you rely on one. * **Bigger single page.** On `/v1/tiktok/search`, `limit` returns one bulk page of up to 120 videos (rounded up to a multiple of 30). On `/v1/linkedin/search/posts` it returns up to 200 posts in one call. * **Keep the top N.** On `/v1/tiktok/search/users`, `/v1/pinterest/search`, and `/v1/reddit/subreddits/search`, `limit` trims the page after the search has run. It is not a page size, and the next cursor still moves past the whole page. Separately, eight search endpoints take `max_pages` (1 to 5), which walks that many pages in one call. Each page is billed as one call, and the hold is multiplied by the page count before the call starts. ## Only what is new [#only-what-is-new] When you poll the same account on a schedule, most list endpoints can stop at what you already hold instead of returning it again. | Parameter | What it does | | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `since` | Leaves off posts published before a date (`YYYY-MM-DD` or ISO 8601). The page that reaches an older post ends the walk, and `pagination.stopped_at` is `since`. | | `stop_at_id` | Pass the id or URL of the newest post you already have. The page stops just before it, and `pagination.stopped_at` is `known_id`. | | `max_age_days` | On search endpoints, keeps only rows published within N days. The filter runs after each page is fetched, so every page walked is still billed. | `since` and `stop_at_id` work on `/v1/tiktok/profile/videos`, `/v1/twitter/user/tweets`, `/v1/youtube/channel/videos` and `/v1/youtube/channel/shorts`. See [Pagination](/docs/pagination). ## Which search? [#which-search] Every platform has its own keyword search. Pick the one for the platform you care about, and run several in parallel when you want more than one. | Your goal | Endpoint | Credits | | ------------------------------------------------------------------ | ----------------------------- | ------- | | TikTok videos by keyword | `/v1/tiktok/search` | 10–370 | | TikTok's Top tab for a keyword | `/v1/tiktok/search/top` | 10 | | YouTube videos, channels, playlists and Shorts | `/v1/youtube/search` | 10–150 | | YouTube videos with date, license and country filters | `/v1/youtube/search/advanced` | 10–110 | | X posts, with X search operators in the query | `/v1/twitter/search/tweets` | 10–50 | | A written answer about X, with the posts it cites | `/v1/twitter/ai-search` | 50 | | Reddit posts, site-wide | `/v1/reddit/search` | 10–300 | | Reddit posts inside one subreddit | `/v1/reddit/subreddit/search` | 10–260 | | Reddit threads with their top comments and a per-subreddit roll-up | `/v1/reddit/omni-search` | 50–90 | | LinkedIn posts and articles | `/v1/linkedin/search/posts` | 10–480 | | Pinterest pins | `/v1/pinterest/search` | 10–260 | Search results are the platform's own matches. When your keyword is also a common word or someone else's brand, filter the rows on your side: check `post.content.text` for the terms that must appear and the ones that must not, and use `post.language` where the platform states one. To find **accounts** rather than posts: | Your goal | Endpoint | Credits | | ------------------------------------------------- | ---------------------------------------------- | -------- | | TikTok creators, with bio and region on every row | `/v1/tiktok/search/users?include=profile` | 10–1,310 | | X accounts | `/v1/twitter/search/users` | 10 | | Reddit communities, with activity and rules | `/v1/reddit/subreddits/search?include=details` | 10–260 | | LinkedIn people | `/v1/linkedin/search/people` | 100–500 | An `include=profile` search replaces a user search plus one profile call per row. You pay per row actually filled. `/v1/reddit/subreddits/search` is usually the step before the other Reddit searches: `author.id` on each row is the `subreddit` value the rest of the platform takes. `/v1/reddit/omni-search` is never the cheap option, because it runs the search and expands the top threads' comments in the same call. Choose it when you want what people are saying rather than a list of links. Its `threads` parameter (1 to 8) is what moves the price. ## Getting a transcript [#getting-a-transcript] YouTube has two cheap options. Every other platform has one transcript endpoint at 100 credits. | Your goal | Endpoint | Credits | | ---------------------------------------------------- | ------------------------------ | ------- | | YouTube caption files to download and parse yourself | `/v1/youtube/video/subtitles` | 10 | | YouTube transcript as timed segments with language | `/v1/youtube/video/transcript` | 30 | | TikTok video | `/v1/tiktok/post/transcript` | 100 | | X video post | `/v1/twitter/tweet/transcript` | 100 | | Reddit video post | `/v1/reddit/post/transcript` | 100 | | LinkedIn video post | `/v1/linkedin/post/transcript` | 100 | On YouTube, take `subtitles` if you can parse caption files, and `transcript` if you want the words already split into segments. A video with no captions or no speech comes back as a `404` and is not charged. The [Video transcription recipe](/docs/recipes/video-transcription-api) wraps all of these in one function. ## Which comment endpoint? [#which-comment-endpoint] Each platform has a comment list, and a few have a way to look up one comment directly. | Your goal | Endpoint | Credits | | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ---------------- | | A page of comments on a TikTok video | `/v1/tiktok/post/comments` | 10–30 | | A page of comments on a YouTube video | `/v1/youtube/video/comments` | 10 | | Replies to a tweet | `/v1/twitter/tweet/replies` | 10 | | Top-level comments on a LinkedIn post | `/v1/linkedin/post/comments` | 50 | | A Reddit post's whole comment tree, replies nested | `/v1/reddit/post/comments` | 50 | | One thread of replies | `/v1/tiktok/video/comment/replies`, `/v1/youtube/video/comment/replies`, `/v1/linkedin/post/comments/replies` | 10 (LinkedIn 50) | | Re-check one known TikTok comment | `/v1/tiktok/comment` | 20–60 | Comments come back as text with their counts, author and `language` where the platform states one. Classifying them (sentiment, questions, complaints) is up to you; the [Sentiment analysis recipe](/docs/recipes/sentiment-analysis) shows one way. `/v1/reddit/post/comments` costs more because it returns the whole discussion with nested replies expanded under each comment's `replies`, which replaces a paging loop you would otherwise write. `/v1/tiktok/post/comments` takes `scan_pages` to read several pages in one call. TikTok has no native "read one comment" route, so `/v1/tiktok/comment` scans for the target and stops as soon as it finds it. `deep_scan=true` widens the scan and is what reaches the top of the range. A comment that is not found is not charged. ## Hiring and job postings [#hiring-and-job-postings] Job data lives on LinkedIn. The choice is a keyword search, one company's openings, or just the count. | Your goal | Endpoint | Identifier | Credits | | --------------------------------- | -------------------------------- | ------------ | ------- | | Postings by keyword | `/v1/linkedin/search/jobs` | `query` | 100 | | Every opening at one company | `/v1/linkedin/company/jobs` | `company_id` | 100 | | How many roles a company has open | `/v1/linkedin/company/job-count` | `company_id` | 50 | | One posting in full | `/v1/linkedin/job` | `id` | 50 | To track hiring across a set of competitors, poll `company/job-count` on a schedule and spend the 100 on `company/jobs` only when the count moves. LinkedIn company endpoints need a numeric `company_id`, and you cannot read it from the page URL. Get it from `/v1/linkedin/company` (50 credits) with the page `url`, then store it. ## Ad libraries [#ad-libraries] Each network's ad library has a keyword door and an advertiser door. Use the keyword door when you only know a brand name. Use the advertiser door for a complete run once you have its id. | Your goal | Endpoint | Credits | | ------------------------------------------------------- | ----------------------------- | -------- | | LinkedIn ads by company, keyword or country | `/v1/linkedin/ads/search` | 50 | | One LinkedIn ad in full | `/v1/linkedin/ad` | 50 | | TikTok ads by keyword or advertiser name | `/v1/tiktok/adlibrary/search` | 50–170 | | One TikTok ad in full | `/v1/tiktok/adlibrary/ad` | 50 | | TikTok's leaderboard of top-performing ads for a market | `/v1/tiktok/ads/top` | 100–1000 | ## Still unsure? [#still-unsure] Ask the catalogue. `GET https://api.insightsocial.app/v1/endpoints?platform=tiktok` lists every TikTok endpoint with its description, parameters and price, and needs no key. To try a call before you write code, use the [Playground](https://www.insightsocial.app/portal/api/explorer) in your dashboard. Every endpoint and its credit price in one table. Holds, metered charges, repeats and what is free. Working builds that chain these endpoints together. Getting past the first page of any list. --- # Computed fields (/docs/computed-fields) The computed block (engagement rate, language, category, estimated reach) was removed in schema 2. How to get the same numbers from the fields every response carries. Responses used to carry a `computed` block: `engagement_rate`, `language`, `content_category`, `estimated_reach` and `vs_creator`. Schema 2, which every key gets from October 4, 2026, removed it on every endpoint. Responses now carry the platform's data only. What changed is on [Schema 2](/docs/schema-2). ## What to use instead [#what-to-use-instead] | Was | Now | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `engagement_rate` | Compute it from `post.engagement` and the author's follower count. See below. | | `language` | `post.language` and `comment.language`: the language the platform itself states, such as `en`. `null` when the platform gives none. We do not detect languages. | | `content_category` | No replacement. Classify `post.content.text` yourself. | | `estimated_reach` | No replacement. Use `post.engagement.views` where the platform shows views. | | `vs_creator` | Compare a post with the author's other posts yourself, from a page of `/profile/posts` results. | ## Engagement rate [#engagement-rate] Engagement rate is engagement divided by followers. Every post carries the counts in `engagement`. The follower count comes from the author's profile (`data.author.followers` on the platform's profile endpoint). On Twitter/X and TikTok post rows it is also in `post.ext.author_followers`, a snapshot taken with the row. ```python title="engagement_rate.py" def engagement_rate(post, followers): """(likes + comments + shares) / followers. None when it cannot be computed.""" e = post["engagement"] counts = [e["likes"], e["comments"], e["shares"]] if not followers or all(c is None for c in counts): return None return sum(c for c in counts if c is not None) / followers ``` A count is `null` when the platform hides it or does not show it, so leave it out of the sum rather than reading it as zero. YouTube does not show share counts, so a YouTube rate is usually (likes + comments) / views. Say which counts you used when you compare platforms. A full worked example is in [Creator engagement scoring](/docs/recipes/creator-engagement-scoring). Every field of a post is described on [Post](/docs/schema/post). --- # Credits (/docs/credits) What a call costs, how metered calls are held and settled, what is free, and where your balance comes from. Every call is priced per endpoint in credits. A fixed endpoint always costs the same; a metered endpoint quotes a range and charges what the call actually used. Calls that fail or find nothing cost nothing. Your balance is the same one you use for InsightSocial exports. ## What does a call cost? [#what-does-a-call-cost] Each endpoint has its own price, listed on its reference page and in the full table at [Endpoint pricing](/docs/endpoint-pricing). There are two kinds. **Fixed.** One number, charged on every successful call. | Endpoint | Credits | | -------------------------------- | ------- | | `GET /v1/tiktok/profile` | 10 | | `GET /v1/linkedin/profile` | 50 | | `GET /v1/tiktok/post/transcript` | 100 | | `GET /v1/youtube/channel/about` | 250 | **Metered.** A range. What you pay depends on how much the call reads, for example how many pages of comments it walked. | Endpoint | Credits | | --------------------------------- | -------- | | `GET /v1/youtube/channel/videos` | 10–20 | | `GET /v1/tiktok/search` | 10–370 | | `GET /v1/linkedin/search/people` | 100–500 | | `GET /v1/reddit/profile/comments` | 20–2,000 | `GET /v1/endpoints` returns the same prices as JSON: `credits` is a number for a fixed endpoint and `{ "min", "max" }` for a metered one. It needs no key and costs nothing. ### Reserve the ceiling, settle the actual [#reserve-the-ceiling-settle-the-actual] Before a call runs, we hold the most it can cost against your balance: the fixed price, or, on a metered endpoint, the most that call can use with the parameters you sent. A call without `limit` or `include` holds one plain page, not the top of the range; asking for more rows or a join holds more. When the call finishes, we charge what it really used and release the rest. On a metered endpoint `credits_used` is often below the hold. You never pay more than the ceiling. If you send `max_pages` (see [Pagination](/docs/pagination)), the ceiling is the listed maximum multiplied by `max_pages`, and that product is the most the call can cost. If your balance cannot cover the ceiling, the call is refused before it starts: ```json title="Response" { "success": false, "error": { "type": "INSUFFICIENT_CREDITS", "message": "This call needs up to 130 credits and 120 remain. Add credits: https://www.insightsocial.app/api/top-up?need=10&u=6f1c2b7e-0d4a-4c8e-9b21-3a5f7d9e1c40&via=api_402", "top_up_url": "https://www.insightsocial.app/api/top-up?need=10&u=6f1c2b7e-0d4a-4c8e-9b21-3a5f7d9e1c40&via=api_402" }, "request_id": "req_1a2b3c4d5e6f", "credits_used": 0, "credits_remaining": 120 } ``` The status is `402` and nothing is charged. ## Why a call cost what it did [#why-a-call-cost-what-it-did] Every successful response carries `charge_reason`, so you can tell why `credits_used` has the value it has. | `charge_reason` | What happened | Credits | | --------------- | ------------------------------------------------------ | -------------------------------------------- | | `miss` | We fetched the data for you | The endpoint's price (metered: what it used) | | `shared_cache` | The answer came from our shared cache (`cached: true`) | 2 | | `replay` | A retry with the same `Idempotency-Key` | 0 | | `no_result` | Nothing was found | 0 | | `dry_run` | You asked for a price quote with `dry_run=1` | 0 | Errors are never charged either: every error response has `credits_used: 0`. That includes a request refused with `400 UNSUPPORTED_PARAMETER` because it sent an analysis parameter that schema 2 does not accept; see [Errors](/docs/errors#unsupported_parameter). ### Repeating a call [#repeating-a-call] Repeating a call is charged like the first time, because a repeat can return newer data. Store responses you need again on your side. A retry with the same `Idempotency-Key` is the exception: it returns the recorded outcome and costs 0 (`replay`). See [Caching](/docs/caching). ### Price a call without running it [#price-a-call-without-running-it] Add `dry_run=1` to any data endpoint to get our price quote instead of the data. Nothing is fetched and nothing is charged: ```bash title="cURL" curl "https://api.insightsocial.app/v1/youtube/channel/videos?handle=nasa&dry_run=1" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```json title="Response" { "success": true, "platform": "youtube", "endpoint": "/v1/youtube/channel/videos", "schema_version": "2", "data": { "dry_run": { "credits_min": 10, "credits_max": 20 } }, "unavailable": [], "credits_used": 0, "credits_remaining": 9980, "request_id": "req_2ac2c2b769ef", "cached": false, "idempotent_replay": false, "charge_reason": "dry_run", "free_call": false } ``` `credits_min` is the least the call can cost and `credits_max` is what we would hold for those exact parameters, including the `max_pages` you sent. A quote never uses a free call. ### Prices under schema 2 [#prices-under-schema-2] Prices did not change with schema 2. A few metered endpoints hold less of your balance while they run, because the analysis they used to do, and could be charged for, is gone. The charge is still what the call actually used. ## Free calls [#free-calls] Every account gets **10 free calls**, once, for its lifetime. A free call is any call that would have been charged (a `miss` or a `shared_cache`) whose ceiling is 100 credits or less. It comes back with `free_call: true` and `credits_used: 0`. Calls above 100 credits are charged normally even while free calls remain. Empty results, errors and replays of a call we already answered never use one up. The one replay that can use a free call is a replay of a call we never answered successfully, because that replay is charged; see [Production checklist](/docs/production-checklist#make-retries-safe). ## Where your credits come from [#where-your-credits-come-from] | Source | Credits | Expires | | ---------------------------------------------------- | ---------------- | ------------------------------------- | | Free plan | 500 per month | Resets on the 1st of each month (UTC) | | Pro plan ($9.99/month, or $7.99/month billed yearly) | 10,000 per month | Resets monthly | | Credit packs (one-time purchase) | Pack size | Never | The monthly grant is spent first and pack credits second. Referral bonuses are added to your pack credits. This is **one balance**, shared with InsightSocial exports. Credits you spend on the API reduce what you can export, and the other way round. Buy a plan or a pack at [insightsocial.app/pricing](https://www.insightsocial.app/pricing). API credits are non-refundable. Failed calls, empty results and `dry_run` calls are simply never charged in the first place. ## How do I check my balance? [#how-do-i-check-my-balance] 1. **On every response.** The body has `credits_remaining`, and the `X-Credits-Remaining` header carries the same number. The header is left out when the balance could not be read. 2. **With `GET /v1/credits`.** Needs your key, costs 0 credits. 3. **In the dashboard.** The API section of your portal shows balance, usage and an activity log. ```bash title="cURL" curl "https://api.insightsocial.app/v1/credits" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```json title="Response" { "success": true, "credits_used": 0, "credits_remaining": 9180, "plan": { "tier": "pro", "credits_per_month": 10000, "resets_at": "2026-10-01T00:00:00.000Z" }, "usage": { "window_start": "2026-09-01T00:00:00.000Z", "used": 1320, "used_export": 400, "used_api": 920 }, "pack_credits": 500, "free_calls": { "remaining": 0, "total": 10 }, "key": { "id": "3f6c2a8e-7b41-4d0f-9a52-1c8e5d7b9f20", "name": "production" }, "request_id": "req_1a2b3c4d5e6f" } ``` ## Retries with an Idempotency-Key are not charged twice [#retries-with-an-idempotency-key-are-not-charged-twice] Send an `Idempotency-Key` header and retry with the same value. A replay of a call we already answered comes back with `idempotent_replay: true`, `charge_reason: "replay"` and `credits_used: 0`. See [Production checklist](/docs/production-checklist#make-retries-safe) for the key format and the edge cases. ## Next steps [#next-steps] The price of every endpoint. Shared-cache hits and forcing a fresh fetch. What a full walk costs, and how `max_pages` changes the ceiling. Checks that cost nothing. ## Endpoints billed per item [#endpoints-billed-per-item] `/v1/linkedin/profile/all` and `/v1/pinterest/url-stats` take a list in `urls` and are billed per item: the listed price is for one URL, and a call with three URLs costs three times as much. The hold and the `dry_run` quote count the URLs the same way. --- # Data availability (/docs/data-availability) How to read values, nulls, absent fields, the unavailable list and cache state in a response, and which fields each platform never shows. A successful response tells you what one endpoint returned for one request. It is not proof that nothing else exists on the source platform. The excerpt below is trimmed from a real `GET /v1/twitter/user/tweets` response. It contains each state your parser needs to handle: ```json title="Response" { "success": true, "platform": "twitter", "endpoint": "/v1/twitter/user/tweets", "schema_version": "2", "data": { "items": [ { "post": { "id": "2106502020849127865", "kind": null, "content": { "text": "RT @Astro_Jessica: Room with a view…", "media_urls": null }, "author": { "id": null, "username": "NASA", "display_name": "NASA" }, "engagement": { "views": 40169, "likes": 0, "comments": 0, "shares": 572, "saves": 0 }, "published_at": "2026-10-03T21:49:53.000Z", "language": "en", "ext": { "author_followers": 92378243, "quote_count": 0 } } } ], "total": null, "truncated": null }, "pagination": { "next_cursor": "v2c.M-GEP84JXNZPqhQ0NlEOubhbuFGG…", "has_more": true, "page_size": 19 }, "unavailable": ["items[].post.author.id"], "credits_used": 10, "credits_remaining": 9490, "request_id": "req_161a29ec13ca", "cached": false, "idempotent_replay": false, "charge_reason": "miss", "free_call": false } ``` In this row, `post.id` and `post.content.text` hold values. `post.kind` is `null` because the platform did not say what format the post is. `post.author.id` is `null` on every row of the page, so the envelope lists it in `unavailable`. `ext.author_followers` is a platform-specific extra: present here, absent on other platforms. ## Public data only [#public-data-only] InsightSocial returns data that anyone can see on the platform without logging in. Private accounts and content behind a login are out of scope. What is public changes over time. A post can be edited or deleted, an account can go private, and a platform can stop showing a field. A successful call describes what the chosen endpoint could see at that moment, in that cache state. ## Four states to tell apart [#four-states-to-tell-apart] | State | What it means | What to do | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------- | | Value | The field is there and its value matches the documented type. | Use it as documented. | | `null` | The field belongs to the schema, but no trustworthy value was available: the platform hides it on this item, does not show it at all, or this response could not fill it. | Keep the `null`. Never turn it into `0`, `""` or an estimate. A real zero is sent as `0`. | | Absent | Only `ext` keys and a few envelope fields (`pagination`, `pagination.stopped_at`) can be absent. Every field of the [unified schema](/docs/schema/post) is always present, as a value or `null`. | Treat `ext` keys as optional. Absent is not the same as `null` or `0`. | | Listed in `unavailable` | The platform normally exposes this field, but this response could not fill it on any item. | Keep the response. Log the path, and do not read the field from this endpoint until it fills again. | `unavailable` never turns a success into an error. For the envelope itself see [Response schema](/docs/response-schema). ## `unavailable` [#unavailable] `unavailable` is a list of paths into `data`, such as `"post.author.id"` for a single entity or `"items[].post.author.id"` for a page. It is `[]` when nothing is missing. A path is listed only when all three hold: 1. **The field is one we judge.** These are the fields every entity has once a platform exposes them: ids, author identity, counts, URLs and times. A `null` bio, `external_url`, `content.text` or `duration_seconds` usually means the profile has no link or the post is a photo, so those are never listed. 2. **The platform exposes it.** Fields a platform never shows are in the table below, once, instead of in every response. 3. **It is `null` on every item of the page.** One filled row shows the endpoint can fill it; a `null` on a single row is the platform hiding it on that item (a hidden like count, for example). An empty page lists nothing: an empty search is not a missing field. Fields judged per entity. `kind` is not judged on posts: it is `null` whenever the source does not say what format a post is, which on some endpoints is every row. | Entity | Judged fields | | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Post | `url`, `author.id`, `author.username`, `author.display_name`, `author.avatar_url`, `engagement.views`, `engagement.likes`, `engagement.comments`, `engagement.shares`, `engagement.saves`, `published_at` | | Comment | `url`, `post_id`, `author.id`, `author.username`, `author.display_name`, `author.avatar_url`, `engagement.likes`, `engagement.replies`, `published_at` | | Profile | `username`, `display_name`, `avatar_url`, `verified`, `followers`, `following`, `posts_count`, `likes_count`, `url`, `private`, `joined_at` | | Transcript | `text` | Beta endpoints, which return the platform's own structure, always send `unavailable: []`. ## Fields a platform never shows [#fields-a-platform-never-shows] These fields are `null` on every response from that platform. They are never listed in `unavailable`, because nothing can fill them. | Platform | Posts | Comments | Profiles | | --------------------- | ----------------------------------------------------------------------------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------- | | TikTok | — | `url` | `joined_at` | | Twitter/X | — | — | — | | YouTube | `engagement.shares`, `engagement.saves` | — | `following`, `likes_count`, `private` | | Reddit | `engagement.views`, `engagement.saves`, `engagement.shares`, `author.display_name` | `author.display_name` | `following`, `posts_count`, `likes_count`, `verified` | | LinkedIn | `engagement.views`, `engagement.saves` | — | `posts_count`, `likes_count`, `private` | | Pinterest | `engagement.views` | — | — | | Bluesky | `engagement.views`, `engagement.saves` | — | `likes_count`, `private` | | Truth Social | `author.id`, `engagement.views`, `engagement.saves` | — | `likes_count` | | Snapchat | — | `url` | `following`, `posts_count`, `likes_count` | | Telegram | `author.id`, `engagement.comments`, `engagement.shares`, `engagement.saves` | — | `following`, `posts_count`, `likes_count`, `private`, `joined_at` | | Twitch | `author.id`, `engagement.likes`, `engagement.comments`, `engagement.shares`, `engagement.saves` | — | `following`, `posts_count`, `likes_count`, `private` | | Rumble | `author.id`, `engagement.shares`, `engagement.saves` | `url` | — | | Kwai | `author.id` | — | `joined_at` | | Douyin | `engagement.views` | `url` | `private`, `joined_at` | | Xiaohongshu (RedNote) | `engagement.views` | `url` | `private`, `joined_at` | | Quora | `engagement.saves` | — | `verified`, `following`, `posts_count`, `likes_count`, `private`, `joined_at` | | Weibo | `author.username`, `engagement.views`, `engagement.saves` | `url`, `author.username` | `likes_count`, `private`, `joined_at` | | Zhihu | `engagement.shares` | — | `verified`, `following`, `posts_count`, `likes_count`, `private`, `joined_at` | | Substack | `author.id`, `engagement.views`, `engagement.saves` | — | — | | Nextdoor | — | — | `avatar_url`, `verified`, `followers`, `following`, `posts_count`, `likes_count`, `private`, `joined_at` | Kick and TikTok Shop have no fields on this list. The table is checked against live traffic, and it changes when a platform changes what it shows publicly. ## One page is not the whole set [#one-page-is-not-the-whole-set] A list page only proves what is on that page. A row the platform sends without an id is left out of `items` and does not count toward `page_size`, but the page is still charged at its price: the platform returned it and we paid for it. Only when every row on a page lacks an id is the call refused instead, with `503 UPSTREAM_INVALID`, and nothing is charged. Follow the top-level `pagination` object if the response has one. Pass `pagination.next_cursor` back exactly as you received it (it starts with `v2c.`) in the `cursor` parameter, with the same parameters as the first page, and stop when `pagination.has_more` is `false`. Do not stop based on `data.total`, which is the platform's own total and not a page count. The full loop is in [Pagination](/docs/pagination). Reaching the last page means you have every page the endpoint offered. It does not guarantee full history: endpoint depth, deletions and access restrictions can still leave gaps. When the platform itself cuts a list short, `data.truncated` is `true`. ## Order is not stable [#order-is-not-stable] A platform can return records in a different order from one request to the next. Do not use a row's position as an identifier, and do not assume page one always spans the same time window. When an endpoint offers a sort parameter, use it. Store the IDs and timestamps from each row, and deduplicate across pages and runs when your workflow needs it. ## Region, language and date filters [#region-language-and-date-filters] Filters and depth differ per endpoint. A `region`, language or date parameter on one search endpoint says nothing about any other endpoint on the same platform. Check the endpoint's parameters before you design a query. If a filter is not listed, assume it is not applied. When you filter on your side, do it only on fields that are present and fit the decision. For example, read the [TikTok profile videos reference](/docs/api-reference/tiktok/profile-videos) before you build on `/v1/tiktok/profile/videos`. It lists the parameters that endpoint accepts and the fields it returns. ## Freshness and cache state [#freshness-and-cache-state] The body field `cached` tells you whether the response came from a recent fetch rather than a new one. A cached response costs 2 credits. A cache hit is never guaranteed. When your decision needs a new fetch, send `Cache-Control: no-cache` or add `fresh=1`. The call is then charged at the endpoint's normal price. Details are in [Caching](/docs/caching). A new fetch is fresher, not more complete. It still reflects only what the platform shows at that moment. An empty result is never charged. See [Credits](/docs/credits). ## Provenance and extension fields [#provenance-and-extension-fields] Store `platform`, `endpoint` and `request_id` alongside the IDs and URLs you keep. They let you trace any stored record back to the call that produced it. Fields under `ext.*` carry platform-specific details and the IDs you need to chain one endpoint into another. Their keys are snake\_case. Treat every `ext` field as optional, and check the [unified schema](/docs/schema/post) for which platforms fill it. Values that every platform can mean the same way live in the core instead: the author's id is `author.id`, the content language is `language`, and a bio link is `external_url`. Endpoints marked **beta** on their reference page (metrics and some lists) return the source's own structure under our naming rules: snake\_case keys, string ids, and ISO times where the source gives a timestamp. Some carry the source's own figures and date text. Expect their shape to differ by platform, and their fields to change. `profile/full` is beta as well, but its `data.profile` is a typed profile and its `data.posts[].post` are typed posts; only its other keys follow these beta rules. New optional fields can appear in responses. Ignore fields you do not recognize instead of rejecting the response, and validate only the fields you actually use. ## Pick the endpoint that fits the question [#pick-the-endpoint-that-fits-the-question] The endpoint you choose sets what you can see. A profile lookup, a post list, a keyword search and a comment list answer different questions, with different filters and depth. Start from the question, then use [Choosing endpoints](/docs/choosing-endpoints) to find the narrowest endpoint that returns the object, coverage and controls you need. ## Checklist [#checklist] Before relying on an endpoint, confirm that: * It returns the object and fields your question needs. * The records you expect are public. * Its region, language, date, ordering and depth controls are documented for that endpoint. * Your loop sends `pagination.next_cursor` back unchanged and stops on `pagination.has_more`. * You log `unavailable` on every response and know which fields the platform never shows. * Your parser treats a value, `null` and an absent field as three different cases. * Your freshness policy reads `cached` and budgets for fresh fetches at the normal price. * Stored records keep their IDs plus `request_id`, `platform` and `endpoint`. * Unknown fields are ignored, and the fields you use are validated. Match the question to the endpoint with the right scope. The envelope, what sits inside data, and unavailable. Walk every page with the cursor and the stop signal. Read cache state and decide when to pay for a fresh fetch. --- # Endpoint pricing (/docs/endpoint-pricing) The price of every endpoint, in credits. 231 endpoints across 22 platforms. Prices are per call and per endpoint. A range means the endpoint is **metered**: we hold the top of the range when the call starts and charge what it actually read when it finishes. Empty results, failed calls and `dry_run=1` cost nothing. How charging works: [Credits](/docs/credits). ## Bluesky [#bluesky] | Endpoint | Credits | Paginates | | ------------------------------------------------------------------ | ------- | --------- | | [`/v1/bluesky/profile`](/docs/api-reference/bluesky/profile) | 10 | — | | [`/v1/bluesky/user/posts`](/docs/api-reference/bluesky/user-posts) | 10 | — | | [`/v1/bluesky/post`](/docs/api-reference/bluesky/post) | 10 | — | | [`/v1/bluesky/search`](/docs/api-reference/bluesky/search) | 10 | — | ## Douyin [#douyin] | Endpoint | Credits | Paginates | | -------------------------------------------------------------------------- | ------- | --------- | | [`/v1/douyin/search`](/docs/api-reference/douyin/search) | 50–1250 | — | | [`/v1/douyin/profile`](/docs/api-reference/douyin/profile) | 60 | — | | [`/v1/douyin/profile/posts`](/docs/api-reference/douyin/profile-posts) | 50–1250 | — | | [`/v1/douyin/post`](/docs/api-reference/douyin/post) | 100 | — | | [`/v1/douyin/post/comments`](/docs/api-reference/douyin/post-comments) | 20–1000 | — | | [`/v1/douyin/comment/replies`](/docs/api-reference/douyin/comment-replies) | 50–2500 | Yes | | [`/v1/douyin/search/users`](/docs/api-reference/douyin/search-users) | 50–1250 | Yes | | [`/v1/douyin/trending`](/docs/api-reference/douyin/trending) | 250 | — | ## Kick [#kick] | Endpoint | Credits | Paginates | | ------------------------------------------------ | ------- | --------- | | [`/v1/kick/clip`](/docs/api-reference/kick/clip) | 10 | — | ## Kwai [#kwai] | Endpoint | Credits | Paginates | | ------------------------------------------------------------ | ------- | --------- | | [`/v1/kwai/profile`](/docs/api-reference/kwai/profile) | 10 | — | | [`/v1/kwai/user/posts`](/docs/api-reference/kwai/user-posts) | 10 | Yes | | [`/v1/kwai/post`](/docs/api-reference/kwai/post) | 10 | — | ## LinkedIn [#linkedin] | Endpoint | Credits | Paginates | | ---------------------------------------------------------------------------------------------------------- | ------- | --------- | | [`/v1/linkedin/profile`](/docs/api-reference/linkedin/profile) | 50 | — | | [`/v1/linkedin/company`](/docs/api-reference/linkedin/company) | 50 | — | | [`/v1/linkedin/company/by-domain`](/docs/api-reference/linkedin/company-by-domain) | 50 | — | | [`/v1/linkedin/profile/similar`](/docs/api-reference/linkedin/profile-similar) | 50 | — | | [`/v1/linkedin/search/companies`](/docs/api-reference/linkedin/search-companies) | 100 | Yes | | [`/v1/linkedin/profile/posted-jobs`](/docs/api-reference/linkedin/profile-posted-jobs) | 50 | — | | [`/v1/linkedin/job/hiring-team`](/docs/api-reference/linkedin/job-hiring-team) | 50 | — | | [`/v1/linkedin/profile/articles`](/docs/api-reference/linkedin/profile-articles) | 50 | Yes | | [`/v1/linkedin/article`](/docs/api-reference/linkedin/article) | 50 | — | | [`/v1/linkedin/article/comments`](/docs/api-reference/linkedin/article-comments) | 50 | Yes | | [`/v1/linkedin/article/reactions`](/docs/api-reference/linkedin/article-reactions) | 50 | Yes | | [`/v1/linkedin/profile/activity`](/docs/api-reference/linkedin/profile-activity) | 50 | — | | [`/v1/linkedin/company/also-viewed`](/docs/api-reference/linkedin/company-also-viewed) | 50 | — | | [`/v1/linkedin/company/employees-count`](/docs/api-reference/linkedin/company-employees-count) | 50 | — | | [`/v1/linkedin/profile/interests/schools`](/docs/api-reference/linkedin/profile-interests-schools) | 50 | Yes | | [`/v1/linkedin/profile/interests/newsletters`](/docs/api-reference/linkedin/profile-interests-newsletters) | 50 | Yes | | [`/v1/linkedin/profile/interests/top-voices`](/docs/api-reference/linkedin/profile-interests-top-voices) | 50 | — | | [`/v1/linkedin/profile/position-skills`](/docs/api-reference/linkedin/profile-position-skills) | 50 | — | | [`/v1/linkedin/profile/top-position`](/docs/api-reference/linkedin/profile-top-position) | 50 | — | | [`/v1/linkedin/search/people/by-url`](/docs/api-reference/linkedin/search-people-by-url) | 100 | — | | [`/v1/linkedin/profile/all`](/docs/api-reference/linkedin/profile-all) | 50 | — | | [`/v1/linkedin/profile/complete`](/docs/api-reference/linkedin/profile-complete) | 100 | — | | [`/v1/linkedin/profile/with-posts`](/docs/api-reference/linkedin/profile-with-posts) | 100 | — | | [`/v1/linkedin/post/with-comments`](/docs/api-reference/linkedin/post-with-comments) | 50 | — | | [`/v1/linkedin/post`](/docs/api-reference/linkedin/post) | 50 | — | | [`/v1/linkedin/search/people`](/docs/api-reference/linkedin/search-people) | 100–500 | Yes | | [`/v1/linkedin/company/people`](/docs/api-reference/linkedin/company-people) | 100–500 | Yes | | [`/v1/linkedin/post/comments`](/docs/api-reference/linkedin/post-comments) | 50 | Yes | | [`/v1/linkedin/profile/posts`](/docs/api-reference/linkedin/profile-posts) | 50–2000 | — | | [`/v1/linkedin/profile/reactions`](/docs/api-reference/linkedin/profile-reactions) | 50 | — | | [`/v1/linkedin/post/reposts`](/docs/api-reference/linkedin/post-reposts) | 50 | Yes | | [`/v1/linkedin/group/posts`](/docs/api-reference/linkedin/group-posts) | 50 | Yes | | [`/v1/linkedin/company/affiliated-pages`](/docs/api-reference/linkedin/company-affiliated-pages) | 50 | — | | [`/v1/linkedin/post/comments/replies`](/docs/api-reference/linkedin/post-comments-replies) | 50 | Yes | | [`/v1/linkedin/profile/experiences`](/docs/api-reference/linkedin/profile-experiences) | 50 | Yes | | [`/v1/linkedin/profile/educations`](/docs/api-reference/linkedin/profile-educations) | 50 | Yes | | [`/v1/linkedin/profile/skills`](/docs/api-reference/linkedin/profile-skills) | 50 | Yes | | [`/v1/linkedin/profile/honors`](/docs/api-reference/linkedin/profile-honors) | 50 | Yes | | [`/v1/linkedin/profile/certifications`](/docs/api-reference/linkedin/profile-certifications) | 50 | Yes | | [`/v1/linkedin/profile/publications`](/docs/api-reference/linkedin/profile-publications) | 50 | Yes | | [`/v1/linkedin/profile/volunteers`](/docs/api-reference/linkedin/profile-volunteers) | 50 | Yes | | [`/v1/linkedin/profile/recommendations`](/docs/api-reference/linkedin/profile-recommendations) | 50 | Yes | | [`/v1/linkedin/profile/interests/companies`](/docs/api-reference/linkedin/profile-interests-companies) | 50 | Yes | | [`/v1/linkedin/profile/interests/groups`](/docs/api-reference/linkedin/profile-interests-groups) | 50 | Yes | | [`/v1/linkedin/profile/images`](/docs/api-reference/linkedin/profile-images) | 50 | — | | [`/v1/linkedin/profile/videos`](/docs/api-reference/linkedin/profile-videos) | 50 | — | | [`/v1/linkedin/profile/comments`](/docs/api-reference/linkedin/profile-comments) | 50 | — | | [`/v1/linkedin/post/reactions`](/docs/api-reference/linkedin/post-reactions) | 100–500 | Yes | | [`/v1/linkedin/company/jobs`](/docs/api-reference/linkedin/company-jobs) | 100 | Yes | | [`/v1/linkedin/search/jobs`](/docs/api-reference/linkedin/search-jobs) | 100 | Yes | | [`/v1/linkedin/search/location`](/docs/api-reference/linkedin/search-location) | 10 | — | | [`/v1/linkedin/search/schools`](/docs/api-reference/linkedin/search-schools) | 10 | Yes | | [`/v1/linkedin/search/industry`](/docs/api-reference/linkedin/search-industry) | 10 | — | | [`/v1/linkedin/profile/about`](/docs/api-reference/linkedin/profile-about) | 50 | — | | [`/v1/linkedin/profile/contact`](/docs/api-reference/linkedin/profile-contact) | 50 | — | | [`/v1/linkedin/profile/stats`](/docs/api-reference/linkedin/profile-stats) | 50 | — | | [`/v1/linkedin/company/job-count`](/docs/api-reference/linkedin/company-job-count) | 50 | — | | [`/v1/linkedin/company/insights`](/docs/api-reference/linkedin/company-insights) | 50 | — | | [`/v1/linkedin/group`](/docs/api-reference/linkedin/group) | 50 | — | | [`/v1/linkedin/job`](/docs/api-reference/linkedin/job) | 50 | — | | [`/v1/linkedin/company/posts`](/docs/api-reference/linkedin/company-posts) | 50 | Yes | | [`/v1/linkedin/ad`](/docs/api-reference/linkedin/ad) | 50 | — | | [`/v1/linkedin/ads/search`](/docs/api-reference/linkedin/ads-search) | 50 | Yes | | [`/v1/linkedin/profile/posts/archive`](/docs/api-reference/linkedin/profile-posts-archive) | 50–5000 | Yes | | [`/v1/linkedin/search/posts`](/docs/api-reference/linkedin/search-posts) | 10–480 | Yes | | [`/v1/linkedin/post/transcript`](/docs/api-reference/linkedin/post-transcript) | 100 | — | | [`/v1/linkedin/profile/full`](/docs/api-reference/linkedin/profile-full) | 50 | Yes | ## Nextdoor [#nextdoor] | Endpoint | Credits | Paginates | | ---------------------------------------------------------------- | ------- | --------- | | [`/v1/nextdoor/business`](/docs/api-reference/nextdoor/business) | 30 | — | | [`/v1/nextdoor/search`](/docs/api-reference/nextdoor/search) | 30–170 | — | ## Pinterest [#pinterest] | Endpoint | Credits | Paginates | | ------------------------------------------------------------------------ | ------- | --------- | | [`/v1/pinterest/search`](/docs/api-reference/pinterest/search) | 10–260 | Yes | | [`/v1/pinterest/pin`](/docs/api-reference/pinterest/pin) | 10 | — | | [`/v1/pinterest/url-stats`](/docs/api-reference/pinterest/url-stats) | 10 | — | | [`/v1/pinterest/board`](/docs/api-reference/pinterest/board) | 10–160 | Yes | | [`/v1/pinterest/user/boards`](/docs/api-reference/pinterest/user-boards) | 10 | — | | [`/v1/pinterest/trends`](/docs/api-reference/pinterest/trends) | 100 | — | ## Quora [#quora] | Endpoint | Credits | Paginates | | ---------------------------------------------------------- | ------- | --------- | | [`/v1/quora/search`](/docs/api-reference/quora/search) | 50 | — | | [`/v1/quora/post`](/docs/api-reference/quora/post) | 50 | — | | [`/v1/quora/answers`](/docs/api-reference/quora/answers) | 50 | — | | [`/v1/quora/posts`](/docs/api-reference/quora/posts) | 50 | — | | [`/v1/quora/profiles`](/docs/api-reference/quora/profiles) | 50 | — | | [`/v1/quora/spaces`](/docs/api-reference/quora/spaces) | 50 | — | | [`/v1/quora/topics`](/docs/api-reference/quora/topics) | 50 | — | ## Reddit [#reddit] | Endpoint | Credits | Paginates | | ------------------------------------------------------------------------------ | ------- | --------- | | [`/v1/reddit/subreddit`](/docs/api-reference/reddit/subreddit) | 10 | Yes | | [`/v1/reddit/subreddit/details`](/docs/api-reference/reddit/subreddit-details) | 10 | — | | [`/v1/reddit/search`](/docs/api-reference/reddit/search) | 10–300 | Yes | | [`/v1/reddit/post`](/docs/api-reference/reddit/post) | 10 | — | | [`/v1/reddit/post/comments`](/docs/api-reference/reddit/post-comments) | 50 | Yes | | [`/v1/reddit/subreddit/search`](/docs/api-reference/reddit/subreddit-search) | 10–260 | Yes | | [`/v1/reddit/profile`](/docs/api-reference/reddit/profile) | 10 | — | | [`/v1/reddit/profile/posts`](/docs/api-reference/reddit/profile-posts) | 10 | Yes | | [`/v1/reddit/profile/comments`](/docs/api-reference/reddit/profile-comments) | 20–2000 | — | | [`/v1/reddit/search/comments`](/docs/api-reference/reddit/search-comments) | 10 | Yes | | [`/v1/reddit/subreddits/search`](/docs/api-reference/reddit/subreddits-search) | 10–260 | Yes | | [`/v1/reddit/search/media`](/docs/api-reference/reddit/search-media) | 10 | Yes | | [`/v1/reddit/post/transcript`](/docs/api-reference/reddit/post-transcript) | 100 | — | | [`/v1/reddit/omni-search`](/docs/api-reference/reddit/omni-search) | 50–90 | Yes | ## Rumble [#rumble] | Endpoint | Credits | Paginates | | ---------------------------------------------------------------------------- | ------- | --------- | | [`/v1/rumble/search`](/docs/api-reference/rumble/search) | 10 | Yes | | [`/v1/rumble/channel/videos`](/docs/api-reference/rumble/channel-videos) | 10 | Yes | | [`/v1/rumble/video`](/docs/api-reference/rumble/video) | 10 | — | | [`/v1/rumble/video/transcript`](/docs/api-reference/rumble/video-transcript) | 100 | — | | [`/v1/rumble/video/comments`](/docs/api-reference/rumble/video-comments) | 10 | — | ## Snapchat [#snapchat] | Endpoint | Credits | Paginates | | ------------------------------------------------------------------------------------ | ------- | --------- | | [`/v1/snapchat/profile`](/docs/api-reference/snapchat/profile) | 10 | — | | [`/v1/snapchat/spotlight/comments`](/docs/api-reference/snapchat/spotlight-comments) | 10 | Yes | ## Substack [#substack] | Endpoint | Credits | Paginates | | ---------------------------------------------------------- | ------- | --------- | | [`/v1/substack/posts`](/docs/api-reference/substack/posts) | 10–120 | — | ## Telegram [#telegram] | Endpoint | Credits | Paginates | | -------------------------------------------------------------------------- | ------- | --------- | | [`/v1/telegram/profile`](/docs/api-reference/telegram/profile) | 10 | — | | [`/v1/telegram/profile/posts`](/docs/api-reference/telegram/profile-posts) | 10 | Yes | | [`/v1/telegram/post`](/docs/api-reference/telegram/post) | 10 | — | ## TikTok [#tiktok] | Endpoint | Credits | Paginates | | -------------------------------------------------------------------------------------- | -------- | --------- | | [`/v1/tiktok/profile`](/docs/api-reference/tiktok/profile) | 10 | — | | [`/v1/tiktok/profile/videos`](/docs/api-reference/tiktok/profile-videos) | 10 | Yes | | [`/v1/tiktok/post`](/docs/api-reference/tiktok/post) | 10 | — | | [`/v1/tiktok/post/comments`](/docs/api-reference/tiktok/post-comments) | 10–30 | Yes | | [`/v1/tiktok/video/comment/replies`](/docs/api-reference/tiktok/video-comment-replies) | 10 | Yes | | [`/v1/tiktok/comment`](/docs/api-reference/tiktok/comment) | 20–60 | — | | [`/v1/tiktok/search`](/docs/api-reference/tiktok/search) | 10–370 | Yes | | [`/v1/tiktok/trending`](/docs/api-reference/tiktok/trending) | 50 | — | | [`/v1/tiktok/search/hashtag`](/docs/api-reference/tiktok/search-hashtag) | 10 | Yes | | [`/v1/tiktok/search/top`](/docs/api-reference/tiktok/search-top) | 10 | Yes | | [`/v1/tiktok/search/users`](/docs/api-reference/tiktok/search-users) | 10–1310 | Yes | | [`/v1/tiktok/similar`](/docs/api-reference/tiktok/similar) | 50 | — | | [`/v1/tiktok/user/audience`](/docs/api-reference/tiktok/user-audience) | 50 | — | | [`/v1/tiktok/user/followers`](/docs/api-reference/tiktok/user-followers) | 10 | Yes | | [`/v1/tiktok/user/following`](/docs/api-reference/tiktok/user-following) | 10 | Yes | | [`/v1/tiktok/user/live`](/docs/api-reference/tiktok/user-live) | 10 | — | | [`/v1/tiktok/post/transcript`](/docs/api-reference/tiktok/post-transcript) | 100 | — | | [`/v1/tiktok/video/screen-text`](/docs/api-reference/tiktok/video-screen-text) | 50 | — | | [`/v1/tiktok/song`](/docs/api-reference/tiktok/song) | 10 | — | | [`/v1/tiktok/song/videos`](/docs/api-reference/tiktok/song-videos) | 10 | Yes | | [`/v1/tiktok/hashtags/popular`](/docs/api-reference/tiktok/hashtags-popular) | 60–960 | — | | [`/v1/tiktok/videos/popular`](/docs/api-reference/tiktok/videos-popular) | 260–450 | — | | [`/v1/tiktok/profile/region`](/docs/api-reference/tiktok/profile-region) | 10 | — | | [`/v1/tiktok/adlibrary/search`](/docs/api-reference/tiktok/adlibrary-search) | 50–170 | Yes | | [`/v1/tiktok/adlibrary/ad`](/docs/api-reference/tiktok/adlibrary-ad) | 50 | — | | [`/v1/tiktok/search/suggestions`](/docs/api-reference/tiktok/search-suggestions) | 10 | — | | [`/v1/tiktok/collection/videos`](/docs/api-reference/tiktok/collection-videos) | 10 | Yes | | [`/v1/tiktok/profile/playlists`](/docs/api-reference/tiktok/profile-playlists) | 10 | — | | [`/v1/tiktok/playlist/videos`](/docs/api-reference/tiktok/playlist-videos) | 10 | Yes | | [`/v1/tiktok/user/liked`](/docs/api-reference/tiktok/user-liked) | 10 | Yes | | [`/v1/tiktok/location/posts`](/docs/api-reference/tiktok/location-posts) | 10 | Yes | | [`/v1/tiktok/effects`](/docs/api-reference/tiktok/effects) | 10 | — | | [`/v1/tiktok/effect/videos`](/docs/api-reference/tiktok/effect-videos) | 10 | Yes | | [`/v1/tiktok/search/music`](/docs/api-reference/tiktok/search-music) | 10 | Yes | | [`/v1/tiktok/hashtag`](/docs/api-reference/tiktok/hashtag) | 10 | — | | [`/v1/tiktok/ads/top`](/docs/api-reference/tiktok/ads-top) | 100–1000 | — | | [`/v1/tiktok/profile/full`](/docs/api-reference/tiktok/profile-full) | 50 | Yes | ## TikTok Shop [#tiktok-shop] | Endpoint | Credits | Paginates | | ---------------------------------------------------------------------------------- | ------- | --------- | | [`/v1/tiktokshop/product`](/docs/api-reference/tiktokshop/product) | 10 | — | | [`/v1/tiktokshop/product/reviews`](/docs/api-reference/tiktokshop/product-reviews) | 10 | Yes | | [`/v1/tiktokshop/products`](/docs/api-reference/tiktokshop/products) | 10 | Yes | | [`/v1/tiktokshop/search`](/docs/api-reference/tiktokshop/search) | 10 | Yes | | [`/v1/tiktokshop/user/showcase`](/docs/api-reference/tiktokshop/user-showcase) | 10 | Yes | | [`/v1/tiktokshop/sales`](/docs/api-reference/tiktokshop/sales) | 0–80 | — | ## Truth Social [#truth-social] | Endpoint | Credits | Paginates | | -------------------------------------------------------------------------- | ------- | --------- | | [`/v1/truthsocial/profile`](/docs/api-reference/truthsocial/profile) | 10 | — | | [`/v1/truthsocial/user/posts`](/docs/api-reference/truthsocial/user-posts) | 10 | Yes | | [`/v1/truthsocial/post`](/docs/api-reference/truthsocial/post) | 10 | — | ## Twitch [#twitch] | Endpoint | Credits | Paginates | | ---------------------------------------------------------------------- | ------- | --------- | | [`/v1/twitch/profile`](/docs/api-reference/twitch/profile) | 10 | — | | [`/v1/twitch/clip`](/docs/api-reference/twitch/clip) | 10 | — | | [`/v1/twitch/user/videos`](/docs/api-reference/twitch/user-videos) | 10 | — | | [`/v1/twitch/user/schedule`](/docs/api-reference/twitch/user-schedule) | 10 | — | ## Twitter/X [#twitterx] | Endpoint | Credits | Paginates | | ------------------------------------------------------------------------------ | ------- | --------- | | [`/v1/twitter/profile`](/docs/api-reference/twitter/profile) | 10 | — | | [`/v1/twitter/user/tweets`](/docs/api-reference/twitter/user-tweets) | 10 | Yes | | [`/v1/twitter/tweet`](/docs/api-reference/twitter/tweet) | 10 | — | | [`/v1/twitter/community`](/docs/api-reference/twitter/community) | 10 | — | | [`/v1/twitter/community/tweets`](/docs/api-reference/twitter/community-tweets) | 10 | — | | [`/v1/twitter/tweet/transcript`](/docs/api-reference/twitter/tweet-transcript) | 100 | — | | [`/v1/twitter/ai-search`](/docs/api-reference/twitter/ai-search) | 50 | — | | [`/v1/twitter/search/tweets`](/docs/api-reference/twitter/search-tweets) | 10–50 | Yes | | [`/v1/twitter/tweet/replies`](/docs/api-reference/twitter/tweet-replies) | 10 | Yes | | [`/v1/twitter/user/media`](/docs/api-reference/twitter/user-media) | 10 | Yes | | [`/v1/twitter/user/followers`](/docs/api-reference/twitter/user-followers) | 10 | Yes | | [`/v1/twitter/user/following`](/docs/api-reference/twitter/user-following) | 10 | Yes | | [`/v1/twitter/tweet/retweeters`](/docs/api-reference/twitter/tweet-retweeters) | 10 | Yes | | [`/v1/twitter/search/users`](/docs/api-reference/twitter/search-users) | 10 | Yes | | [`/v1/twitter/profile/full`](/docs/api-reference/twitter/profile-full) | 50 | Yes | ## Weibo [#weibo] | Endpoint | Credits | Paginates | | -------------------------------------------------------------------- | ------- | --------- | | [`/v1/weibo/post`](/docs/api-reference/weibo/post) | 10 | — | | [`/v1/weibo/profile`](/docs/api-reference/weibo/profile) | 10 | — | | [`/v1/weibo/user/posts`](/docs/api-reference/weibo/user-posts) | 10 | Yes | | [`/v1/weibo/post/comments`](/docs/api-reference/weibo/post-comments) | 10 | Yes | | [`/v1/weibo/search`](/docs/api-reference/weibo/search) | 10 | Yes | | [`/v1/weibo/trending`](/docs/api-reference/weibo/trending) | 10 | — | ## Xiaohongshu (RedNote) [#xiaohongshu-rednote] | Endpoint | Credits | Paginates | | -------------------------------------------------------------------------------- | ------- | --------- | | [`/v1/xiaohongshu/search`](/docs/api-reference/xiaohongshu/search) | 50–1000 | Yes | | [`/v1/xiaohongshu/trending`](/docs/api-reference/xiaohongshu/trending) | 50–1000 | — | | [`/v1/xiaohongshu/profile`](/docs/api-reference/xiaohongshu/profile) | 50 | — | | [`/v1/xiaohongshu/profile/posts`](/docs/api-reference/xiaohongshu/profile-posts) | 50–1000 | Yes | | [`/v1/xiaohongshu/post`](/docs/api-reference/xiaohongshu/post) | 50 | — | | [`/v1/xiaohongshu/post/comments`](/docs/api-reference/xiaohongshu/post-comments) | 50–1000 | Yes | ## YouTube [#youtube] | Endpoint | Credits | Paginates | | -------------------------------------------------------------------------------------------- | ------- | --------- | | [`/v1/youtube/channel`](/docs/api-reference/youtube/channel) | 10 | — | | [`/v1/youtube/channel/about`](/docs/api-reference/youtube/channel-about) | 250 | — | | [`/v1/youtube/channel/videos`](/docs/api-reference/youtube/channel-videos) | 10–20 | Yes | | [`/v1/youtube/video`](/docs/api-reference/youtube/video) | 10 | — | | [`/v1/youtube/video/sponsors`](/docs/api-reference/youtube/video-sponsors) | 100 | — | | [`/v1/youtube/video/comments`](/docs/api-reference/youtube/video-comments) | 10 | Yes | | [`/v1/youtube/video/comment/replies`](/docs/api-reference/youtube/video-comment-replies) | 10 | Yes | | [`/v1/youtube/search`](/docs/api-reference/youtube/search) | 10–150 | Yes | | [`/v1/youtube/channel/shorts`](/docs/api-reference/youtube/channel-shorts) | 10–20 | Yes | | [`/v1/youtube/community-post`](/docs/api-reference/youtube/community-post) | 10 | — | | [`/v1/youtube/playlist`](/docs/api-reference/youtube/playlist) | 10–110 | Yes | | [`/v1/youtube/search/hashtag`](/docs/api-reference/youtube/search-hashtag) | 10–110 | Yes | | [`/v1/youtube/shorts/trending`](/docs/api-reference/youtube/shorts-trending) | 50–150 | — | | [`/v1/youtube/video/transcript`](/docs/api-reference/youtube/video-transcript) | 30 | — | | [`/v1/youtube/channel/playlists`](/docs/api-reference/youtube/channel-playlists) | 10 | Yes | | [`/v1/youtube/channel/lives`](/docs/api-reference/youtube/channel-lives) | 10–70 | Yes | | [`/v1/youtube/channel/community-posts`](/docs/api-reference/youtube/channel-community-posts) | 10 | Yes | | [`/v1/youtube/videos/trending`](/docs/api-reference/youtube/videos-trending) | 10–60 | Yes | | [`/v1/youtube/playlist/items`](/docs/api-reference/youtube/playlist-items) | 10–110 | Yes | | [`/v1/youtube/search/advanced`](/docs/api-reference/youtube/search-advanced) | 10–110 | Yes | | [`/v1/youtube/search/suggestions`](/docs/api-reference/youtube/search-suggestions) | 10 | — | | [`/v1/youtube/video/audio`](/docs/api-reference/youtube/video-audio) | 50 | — | | [`/v1/youtube/video/files`](/docs/api-reference/youtube/video-files) | 50 | — | | [`/v1/youtube/video/subtitles`](/docs/api-reference/youtube/video-subtitles) | 10 | — | | [`/v1/youtube/video/thumbnails`](/docs/api-reference/youtube/video-thumbnails) | 10 | — | | [`/v1/youtube/profile/full`](/docs/api-reference/youtube/profile-full) | 50 | Yes | ## Zhihu [#zhihu] | Endpoint | Credits | Paginates | | -------------------------------------------------------------------------- | ------- | --------- | | [`/v1/zhihu/answer`](/docs/api-reference/zhihu/answer) | 10 | — | | [`/v1/zhihu/question`](/docs/api-reference/zhihu/question) | 10 | — | | [`/v1/zhihu/question/answers`](/docs/api-reference/zhihu/question-answers) | 10 | — | | [`/v1/zhihu/profile`](/docs/api-reference/zhihu/profile) | 10 | — | | [`/v1/zhihu/search/articles`](/docs/api-reference/zhihu/search-articles) | 10 | Yes | --- # Errors (/docs/errors) Every InsightSocial API error type with its status, what to do about it, and copy-paste retry loops. Every failure returns the same error body, not the success envelope: `success: false`, an `error` object with a `type` to branch on, a readable `message`, `param` when one parameter is at fault and `top_up_url` when you are out of credits, plus the usual `request_id` and credit fields. A failed call is never charged. ```json title="Response" { "success": false, "error": { "type": "INSUFFICIENT_CREDITS", "message": "This call needs up to 170 credits and 120 remain. Add credits: https://www.insightsocial.app/api/top-up?need=50&u=6f1c2b7e-0d4a-4c8e-9b21-3a5f7d9e1c40&via=api_402", "top_up_url": "https://www.insightsocial.app/api/top-up?need=50&u=6f1c2b7e-0d4a-4c8e-9b21-3a5f7d9e1c40&via=api_402" }, "request_id": "req_1a2b3c4d5e6f", "credits_used": 0, "credits_remaining": 120 } ``` * **`error.type`** is what your code should branch on. * **`error.param`** names the query parameter at fault, when there is one (for example `cursor` on a cursor error). It is absent otherwise. * **`error.top_up_url`**, on `INSUFFICIENT_CREDITS` only, opens the checkout for the credits you are short, already tied to your account. The same link is at the end of `message`. * **`error.message`** explains the failure in a sentence and often names what to change. Show it or log it, but do not parse it. * **`credits_used`** is `0` on every error. * **`credits_remaining`** is your balance when we know it, and `null` when we do not (authentication failures, for example). * **`request_id`** matches the `X-Request-Id` header. Include it when you contact support. That is the whole error body. It carries no `schema_version`, `data` or `unavailable`, so check `success` before reading anything else. Refusals made before a call reaches a platform (`UNSUPPORTED_PARAMETER`, `CURSOR_INVALID`, `CURSOR_EXPIRED`, authentication, rate-limit and idempotency errors, `INSUFFICIENT_CREDITS`) do not appear in the dashboard's Activity Log. Other errors, including the `400` parameter errors a platform returns, do. ## Error types [#error-types] | `error.type` | Status | Retry? | What it means | | ------------------------------------------------------------ | -------------------- | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | `MISSING_API_KEY` | 401 | No | No `x-api-key` header on the request | | `INVALID_API_KEY` | 401 | No | The value is not an InsightSocial key, or no key matches it | | `API_KEY_REVOKED` | 401 | No | The key has been revoked | | `INSUFFICIENT_CREDITS` | 402 | No | Your balance is below what this call needs to hold | | `UNKNOWN_PLATFORM` | 404 | No | The first path segment is not one of the platforms we serve | | `UNKNOWN_ENDPOINT` | 404 | No | The platform exists but that path does not | | `RESOURCE_NOT_FOUND` | 404 | No | Nothing exists at the identifier you sent | | `METHOD_NOT_SUPPORTED` | 405 | No | Every endpoint is a GET: any other method, and the three POST endpoints in the catalogue, answer 405 | | `UNSUPPORTED_PARAMETER` | 400 | No | A parameter this endpoint does not have, or one that asks for analysis schema 2 does not carry. `error.param` names it | | `CURSOR_INVALID` | 400 | No | The cursor was not issued by this API, was edited, or belongs to a different request | | `CURSOR_EXPIRED` | 400 | No | The cursor is more than 24 hours old | | `IDEMPOTENCY_IN_PROGRESS` | 409 | Yes, after `Retry-After` | A call with the same `Idempotency-Key` is still running | | `IDEMPOTENCY_KEY_REUSED` | 409 | No | The `Idempotency-Key` was already used for a different request | | `IDEMPOTENCY_REPLAY_UNAVAILABLE` | 409 | No | The original call succeeded, but its response is too large to replay | | `RATE_LIMITED` | 429 | Yes, after `Retry-After` | More than 60 requests in 60 seconds on this key | | `CONCURRENCY_LIMIT` | 429 | Yes, after `Retry-After` | More than 10 requests in flight on this key | | `CLIENT_CLOSED_REQUEST` | 499 | Your call | Your client disconnected before the response | | `INTERNAL_ERROR` | 500 | Yes, with backoff | Something went wrong on our side | | `SERVICE_UNAVAILABLE` | 503 | Yes, after `Retry-After` or backoff | We could not complete the call right now | | `UPSTREAM_ERROR` (or the platform's own type) | 503 | Yes, after `Retry-After` | The platform did not answer in time | | `UPSTREAM_INVALID` | 503 | Yes, after `Retry-After` | The platform answered with something we could not read | | `ENDPOINT_UNAVAILABLE` | 503 | Not soon: `Retry-After` is an hour | This endpoint is switched off while it cannot get data | | Parameter errors, such as `INVALID_REQUEST` or `BAD_REQUEST` | 400 (or another 4xx) | No | A parameter is missing, invalid, or not accepted by this endpoint | When a request is rejected because of its parameters, the `error.type` is not drawn from a fixed list: you will usually see `INVALID_REQUEST` or `BAD_REQUEST`, but other values occur. Treat any 4xx you do not recognise as "fix the request", and read `error.message`, which says what was wrong. ## Which errors to retry [#which-errors-to-retry] Retry only `RATE_LIMITED`, `CONCURRENCY_LIMIT`, `IDEMPOTENCY_IN_PROGRESS`, `SERVICE_UNAVAILABLE`, `UPSTREAM_ERROR`, `UPSTREAM_INVALID` and `INTERNAL_ERROR`, plus any `429`, `500` or `503` whatever its `error.type`: when a platform fails, the 503 can carry that platform's own error type. A `409` is retryable only when its type is `IDEMPOTENCY_IN_PROGRESS`. Everything else is deterministic: the same request fails the same way until you change the request, the key or your balance. When a response carries `Retry-After`, wait at least that many seconds. Otherwise back off exponentially with jitter, and give up after a few attempts. ## Error reference [#error-reference] ### MISSING\_API\_KEY [#missing_api_key] **401.** No `x-api-key` header reached the API. Send the header, and if you already do, make sure nothing between you and the API, such as a proxy or gateway, removes it. A key sent in `Authorization` is not read and also produces this error. See [Authentication](/docs/authentication). ### INVALID\_API\_KEY [#invalid_api_key] **401.** Either the value does not look like an InsightSocial key (keys start `isk_live_` or `isk_test_`), or it looks right but matches no key. Copy it again from [API keys](https://www.insightsocial.app/portal/api/keys). ### API\_KEY\_REVOKED [#api_key_revoked] **401.** The key was revoked in the dashboard. Create a new one in the dashboard. ### INSUFFICIENT\_CREDITS [#insufficient_credits] **402.** Before a call runs, we hold the most it can cost. If your balance is below that amount, the call is refused and nothing is charged. `credits_remaining` shows your balance, and the message states both numbers. For a metered endpoint, the amount held is the most the call can cost with the parameters you sent, and on endpoints that accept `max_pages` it is multiplied by the number of pages. You can therefore get a 402 on a call that would have cost less in the end. A smaller `limit`, fewer `include` joins or fewer pages hold less; `dry_run=1` shows the hold for free. Top up on the [pricing page](https://www.insightsocial.app/pricing); retrying without a top-up fails the same way. ### UNKNOWN\_PLATFORM [#unknown_platform] **404.** The platform segment of the path is not one we serve. The 22 platforms are `tiktok`, `linkedin`, `twitter`, `youtube`, `reddit`, `pinterest`, `bluesky`, `truthsocial`, `snapchat`, `telegram`, `twitch`, `kick`, `rumble`, `kwai`, `douyin`, `xiaohongshu`, `quora`, `tiktokshop`, `weibo`, `zhihu`, `substack` and `nextdoor`. ### UNKNOWN\_ENDPOINT [#unknown_endpoint] **404.** The path is not in the catalogue. Check it against `GET /v1/endpoints` or the [API reference](/docs/api-reference). ### RESOURCE\_NOT\_FOUND [#resource_not_found] **404.** The endpoint exists, but nothing is there for the identifier you sent: a handle that does not exist, a deleted post, and so on. You are not charged. Retrying the same identifier returns the same answer, so record it and move on. ### INVALID\_REQUEST for a missing parameter [#invalid_request-for-a-missing-parameter] A required parameter left out is refused before anything is fetched: `400 INVALID_REQUEST`, with `error.param` naming it and a message such as "`url` is required on this endpoint". Nothing is charged. ### METHOD\_NOT\_SUPPORTED [#method_not_supported] **405.** This path is in the catalogue but cannot be called through the API. Pick another endpoint. ### UNSUPPORTED\_PARAMETER [#unsupported_parameter] **400.** You sent a parameter this endpoint does not have (a typo, or one that belongs to another endpoint), or one that asks for analysis: labels, relevance scoring, fit or brand judgments. Both are refused instead of being ignored, which would return unfiltered rows and still charge for them. `error.param` names the parameter; the endpoint's parameters are in `GET /v1/endpoints`. Nothing is charged. ```json title="Response" { "success": false, "error": { "type": "UNSUPPORTED_PARAMETER", "message": "`relevance` is not supported: it asks for analysis, which is not part of schema 2. Remove it and retry. Nothing was charged.", "param": "relevance" }, "request_id": "req_80d197121a1e", "credits_used": 0, "credits_remaining": null } ``` The refused parameters are `label`, `label_evidence`, `relevance`, `relevance_threshold`, `relevant_to`, `judgments`, `fit`, `goal`, `fit_tokens`, `seen`, `brand`, `brand_description`, `offer`, `exclude` (except on `/v1/pinterest/trends`, where it filters terms), `brief`, `use`, `moments`, and the value `format=stationery`. Two more are refused on specific endpoints only, where they ask for analysis; elsewhere they are ordinary parameters: | Parameter | Refused on | What it asked for | | ------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | | `q` | `/v1/tiktok/post/transcript`, `/v1/youtube/video/transcript` | A question answered about the video's transcript. On search endpoints `q` is the search query and works as before. | | `switch_from` | `/v1/twitter/search/tweets`, `/v1/reddit/search/comments` | Posts about switching away from a named brand. | Only the first refused parameter in your query is reported, so remove it and check the next. To filter rows by topic or language, do it on your side after the call; see [Schema 2](/docs/schema-2). ### CURSOR\_INVALID [#cursor_invalid] **400.** The cursor cannot be used for this request. Either it was not issued by this API (a cursor from the previous schema starts `is.` or `is2.`), it was edited or truncated, it was sent under a name other than `cursor`, or it belongs to a different request: another endpoint, or the same endpoint with different parameters. `error.param` names the parameter that carried it. Nothing is charged. Send `pagination.next_cursor` back unchanged, as `cursor`, with the same parameters as the first page. Only `limit`, `max_pages`, `dry_run` and `fresh` may change between pages. Otherwise start again without a cursor. See [Pagination](/docs/pagination#bad-or-stale-cursors). ### CURSOR\_EXPIRED [#cursor_expired] **400.** The cursor is more than 24 hours old. Start the walk again without a cursor. Nothing is charged. ### IDEMPOTENCY\_IN\_PROGRESS [#idempotency_in_progress] **409.** An earlier call with the same `Idempotency-Key` has not finished. Wait for `Retry-After`, then send the same request with the same key. Once the original has finished, you get its result as a free replay, unless the original never completed (see below). ### IDEMPOTENCY\_KEY\_REUSED [#idempotency_key_reused] **409.** The `Idempotency-Key` was already used for a different request: another endpoint or other parameters. Use a new key. Nothing is charged. ### IDEMPOTENCY\_REPLAY\_UNAVAILABLE [#idempotency_replay_unavailable] **409.** The original call with this `Idempotency-Key` succeeded, but its response is too large for us to replay. Send the request again with a new key to fetch it. Nothing is charged. ### RATE\_LIMITED [#rate_limited] **429.** This key sent more than 60 requests in a sliding 60-second window. `Retry-After` is the number of seconds until the oldest request leaves the window. Nothing is charged. See [Rate limits](/docs/rate-limits). ### CONCURRENCY\_LIMIT [#concurrency_limit] **429.** This key already had 10 requests in flight. `Retry-After` is `1`, since a slot frees as soon as any open request returns. Shrink your worker pool. ### CLIENT\_CLOSED\_REQUEST [#client_closed_request] **499.** Your client closed the connection before we answered. You only see this in logs, since nobody was listening for the response. Give slow endpoints a generous client timeout. ### INTERNAL\_ERROR [#internal_error] **500.** An unexpected error on our side. Nothing was charged. Retry with backoff, and if it keeps happening, contact support with the `request_id`. ### SERVICE\_UNAVAILABLE [#service_unavailable] **503.** We could not complete the call right now. Causes include being unable to verify your key or read your balance for a moment, or temporarily running out of capacity. Nothing was charged. When `Retry-After` is present (often `30`), wait that long; otherwise retry with backoff. ### UPSTREAM\_ERROR [#upstream_error] **503.** The platform did not answer, even after our own retries. Nothing was charged. `Retry-After` is at least `30`, longer when the platform asked for more. ### UPSTREAM\_INVALID [#upstream_invalid] **503.** The platform answered, but with something that does not fit the response schema, so we did not serve it. A page whose rows all lack an id is also refused this way, rather than charged as an empty page. Nothing was charged. `Retry-After` is `30`. If it repeats on the same input, contact support with the `request_id`. ### ENDPOINT\_UNAVAILABLE [#endpoint_unavailable] **503.** The endpoint exists but is switched off, because it stopped returning data for every input. It is left out of `GET /v1/endpoints` and the API reference until it works again. Nothing was charged. `Retry-After` is `3600`: retrying sooner gets the same answer, so a generic retry loop should honour it or stop. We test these endpoints daily and switch each one back on once it answers again. ### Parameter errors [#parameter-errors] **400**, or another 4xx. A required parameter is missing, a value is in the wrong format, or the endpoint does not accept a parameter you sent. The `message` says what was rejected and usually names the parameter to fix. Check the endpoint's parameters on its [API reference](/docs/api-reference) page or in `GET /v1/endpoints`. Nothing is charged. ## Idempotency [#idempotency] Send an `Idempotency-Key` header, a fresh UUID per logical operation, to make any call safe to retry after a timeout or a dropped connection. * A retry with the same key returns the original result with `idempotent_replay: true`, `charge_reason: "replay"` and `credits_used: 0`. * A retry that arrives while the original is still running gets `409 IDEMPOTENCY_IN_PROGRESS`. Wait for `Retry-After` and try again with the same key. * A key reused for a different request, or across schemas, gets `409 IDEMPOTENCY_KEY_REUSED`. Use a new key. * Keys are scoped to your account. * A key longer than 255 characters, or with characters other than letters, digits, `.`, `_`, `:` and `-`, is ignored. The call then runs normally, with no replay protection. * If we never answered the original successfully (for example your client disconnected before it finished), the retry that delivers the data is charged as a normal call (`charge_reason: "miss"`) at exactly the ceiling the call reserved: the listed price, or the top of the range for a metered endpoint, multiplied by `max_pages` if you sent it. Like any charged call, it can be covered by one of your free calls. It costs 0 if the replay returns nothing. ## What is never charged [#what-is-never-charged] Every error on this page costs 0 credits, including a request refused for an unsupported parameter or a bad cursor. So do empty results, `dry_run=1` calls and replays of a call we already answered. API credits are non-refundable, and a call that fails is simply never charged. See [Credits](/docs/credits). ## Retry loops [#retry-loops] Each loop retries only the transient statuses (429, 500, 503, and 409 when the type is `IDEMPOTENCY_IN_PROGRESS`), honors `Retry-After` when it is sent, otherwise backs off exponentially with jitter, and stops after five retries. ```bash title="cURL" #!/usr/bin/env bash url="https://api.insightsocial.app/v1/tiktok/profile?handle=khaby.lame" max_retries=5 attempt=0 while :; do body=$(mktemp); headers=$(mktemp) status=$(curl -s -o "$body" -D "$headers" -w '%{http_code}' \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" "$url") if [ "$status" -lt 400 ]; then cat "$body"; rm -f "$body" "$headers"; break fi retry_409=false if [ "$status" = "409" ] && grep -q '"IDEMPOTENCY_IN_PROGRESS"' "$body"; then retry_409=true; fi case "$status" in 429|500|503) ;; 409) $retry_409 || { echo "Not retryable: 409"; cat "$body"; rm -f "$body" "$headers"; exit 1; } ;; *) echo "Not retryable: $status"; cat "$body"; rm -f "$body" "$headers"; exit 1 ;; esac attempt=$((attempt + 1)) if [ "$attempt" -gt "$max_retries" ]; then echo "Giving up after $max_retries retries (last status $status)" rm -f "$body" "$headers"; exit 1 fi wait_s=$(grep -i '^retry-after:' "$headers" | tr -d '\r' | awk '{print $2}') if [ -z "$wait_s" ]; then wait_s=$(awk "BEGIN{srand(); print (2 ^ $attempt) * (0.5 + rand() / 2)}") fi rm -f "$body" "$headers" sleep "$wait_s" done ``` ```python title="Python" import os import random import time import uuid import requests BASE = "https://api.insightsocial.app/v1" RETRYABLE = {429, 500, 503} def retryable(res): if res.status_code == 409: return res.json()["error"]["type"] == "IDEMPOTENCY_IN_PROGRESS" return res.status_code in RETRYABLE def get_with_retry(path, params=None, max_retries=5): headers = { "x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"], # One key for every attempt, so a retry never pays twice. "Idempotency-Key": str(uuid.uuid4()), } for attempt in range(max_retries + 1): res = requests.get(f"{BASE}{path}", params=params, headers=headers, timeout=120) if not retryable(res) or attempt == max_retries: return res.json() retry_after = res.headers.get("Retry-After") delay = float(retry_after) if retry_after else (2 ** attempt) * (0.5 + random.random() / 2) time.sleep(delay) body = get_with_retry("/tiktok/profile", {"handle": "khaby.lame"}) print(body["success"], body.get("error")) ``` ```ts title="Node.js" const BASE = "https://api.insightsocial.app/v1"; const RETRYABLE = new Set([429, 500, 503]); const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); async function getWithRetry(path: string, params: Record = {}, maxRetries = 5) { const url = new URL(BASE + path); for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v); const headers = { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY!, // One key for every attempt, so a retry never pays twice. "Idempotency-Key": crypto.randomUUID(), }; for (let attempt = 0; ; attempt++) { const res = await fetch(url, { headers }); const body = await res.json(); const retryable = RETRYABLE.has(res.status) || (res.status === 409 && body.error?.type === "IDEMPOTENCY_IN_PROGRESS"); if (!retryable || attempt >= maxRetries) return body; const retryAfter = Number(res.headers.get("Retry-After")); const delayMs = retryAfter > 0 ? retryAfter * 1000 : 2 ** attempt * 1000 * (0.5 + Math.random() / 2); await sleep(delayMs); } } const body = await getWithRetry("/tiktok/profile", { handle: "khaby.lame" }); console.log(body.success, body.error); ``` ## Debugging tips [#debugging-tips] * Log `request_id` (also sent as `X-Request-Id`) with every failure, so support can trace the exact call. * A `503` on an input that worked before is usually temporary. Retry after `Retry-After`. * A `400` that names `error.param` tells you exactly which parameter to remove or fix. * Some calls take a while to answer. Set a client timeout of a minute or more on heavy endpoints rather than aborting early. ## Next steps [#next-steps] The two 429s and how to size a job. What calls cost and what is never charged. The envelope and every response header. --- # Introduction (/docs) Public data from 22 social platforms through one API key, one JSON envelope and one credit balance. InsightSocial API gives you public data from 22 social platforms through more than 300 GET endpoints. You authenticate every call with the same `x-api-key` header, every answer arrives in the same JSON envelope, and every call draws on one credit balance, the same one you already use for InsightSocial exports. ## Your first call [#your-first-call] ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/profile?handle=khaby.lame" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` That is the whole protocol: one GET request with one header. The profile call costs 10 credits, and the response tells you what you were charged and what is left, so you never need a separate balance check to keep track. Sign up and your key is ready on the next screen. Your first 10 calls priced at 100 credits or less are free. Run any endpoint from your browser before you write code. ## One request shape, 22 platforms [#one-request-shape-22-platforms] Switch platforms by changing one path segment. The header stays the same and the envelope stays the same. ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/profile?handle=nasa" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" curl "https://api.insightsocial.app/v1/tiktok/profile?handle=nasa" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" curl "https://api.insightsocial.app/v1/youtube/channel?handle=nasa" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" curl "https://api.insightsocial.app/v1/twitter/profile?handle=nasa" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` The platforms differ in what they expose, so field coverage differs too, but the answer has one shape everywhere: a profile is a profile, a post is a post, whichever platform it came from. A field a platform does not show is `null`. See [Schema 2](/docs/schema-2). | Platform | Base path | Overview | | --------------------- | --------------------- | ---------------------------------------------------- | | TikTok | `/v1/tiktok/...` | [TikTok](/docs/platforms/tiktok) | | LinkedIn | `/v1/linkedin/...` | [LinkedIn](/docs/platforms/linkedin) | | Twitter/X | `/v1/twitter/...` | [Twitter/X](/docs/platforms/twitter) | | YouTube | `/v1/youtube/...` | [YouTube](/docs/platforms/youtube) | | Reddit | `/v1/reddit/...` | [Reddit](/docs/platforms/reddit) | | Pinterest | `/v1/pinterest/...` | [Pinterest](/docs/platforms/pinterest) | | Bluesky | `/v1/bluesky/...` | [Bluesky](/docs/platforms/bluesky) | | Truth Social | `/v1/truthsocial/...` | [Truth Social](/docs/platforms/truthsocial) | | Snapchat | `/v1/snapchat/...` | [Snapchat](/docs/platforms/snapchat) | | Telegram | `/v1/telegram/...` | [Telegram](/docs/platforms/telegram) | | Twitch | `/v1/twitch/...` | [Twitch](/docs/platforms/twitch) | | Kick | `/v1/kick/...` | [Kick](/docs/platforms/kick) | | Rumble | `/v1/rumble/...` | [Rumble](/docs/platforms/rumble) | | Kwai | `/v1/kwai/...` | [Kwai](/docs/platforms/kwai) | | Douyin | `/v1/douyin/...` | [Douyin](/docs/platforms/douyin) | | Xiaohongshu (RedNote) | `/v1/xiaohongshu/...` | [Xiaohongshu (RedNote)](/docs/platforms/xiaohongshu) | | Quora | `/v1/quora/...` | [Quora](/docs/platforms/quora) | | TikTok Shop | `/v1/tiktokshop/...` | [TikTok Shop](/docs/platforms/tiktokshop) | | Weibo | `/v1/weibo/...` | [Weibo](/docs/platforms/weibo) | | Zhihu | `/v1/zhihu/...` | [Zhihu](/docs/platforms/zhihu) | | Substack | `/v1/substack/...` | [Substack](/docs/platforms/substack) | | Nextdoor | `/v1/nextdoor/...` | [Nextdoor](/docs/platforms/nextdoor) | ## The response envelope [#the-response-envelope] Every successful call to a data endpoint returns a body with this top level, and the platform payload sits under `data`. A failed call returns a smaller error body instead: `success: false`, an `error` object with `type`, `message` and sometimes `param`, plus `request_id`, `credits_used` and `credits_remaining`, and no `schema_version`, `data` or `unavailable`; see [Errors](/docs/errors). `GET /v1/credits` and `GET /v1/endpoints` return bodies of their own; see [Response schema](/docs/response-schema). ```json title="Response" { "success": true, "platform": "tiktok", "endpoint": "/v1/tiktok/profile", "schema_version": "2", "data": { "author": { "id": "6772003040451462149", "username": "nasa", "display_name": "NASA", "followers": 9800000, "url": "https://www.tiktok.com/@nasa", "external_url": "https://www.nasa.gov" } }, "unavailable": [], "credits_used": 10, "credits_remaining": 490, "request_id": "req_1a2b3c4d5e6f", "cached": false, "idempotent_replay": false, "charge_reason": "miss", "free_call": false } ``` | Field | Use it to | | ------------------- | --------------------------------------------------------------------------------------------------------------- | | `success` | Branch first. When it is `false`, the body is an error body: read `error.type`. | | `schema_version` | Check you are reading the shape these docs describe: `"2"`. | | `data` | Read the platform payload. | | `unavailable` | See which fields this platform normally fills but this response could not, as paths into `data`. Usually empty. | | `pagination` | Page through list endpoints. Present only on lists. | | `credits_used` | See what this call cost. | | `credits_remaining` | See your balance after this call. | | `charge_reason` | See why you were charged what you were. | | `request_id` | Quote it when you contact support. | List endpoints add a top-level `pagination` object. Send `pagination.next_cursor` back unchanged as `cursor` until `has_more` is `false`. See [Pagination](/docs/pagination) and [Response schema](/docs/response-schema). ## Browse the catalogue for free [#browse-the-catalogue-for-free] `GET /v1/endpoints` lists every endpoint with its price, parameters and whether it paginates. It needs no key and costs nothing. `GET /v1/credits` returns your balance, also free. ```bash title="cURL" # Every TikTok endpoint, with prices and parameters curl "https://api.insightsocial.app/v1/endpoints?platform=tiktok" # Your balance curl "https://api.insightsocial.app/v1/credits" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## What calls cost [#what-calls-cost] Each endpoint has its own price in credits, listed in [Endpoint pricing](/docs/endpoint-pricing) and on every [API reference](/docs/api-reference) page. Some endpoints are metered: you see a range, we hold the top of the range while the call runs, and you pay what the call actually used. * The free plan includes 500 credits a month and Pro includes 10,000. Credit packs are on the [pricing page](https://www.insightsocial.app/pricing). * Your first 10 calls priced at 100 credits or less are free. * Failed calls, empty results and `dry_run` calls are never charged. * Repeating a call is charged again. Only an `Idempotency-Key` replay is free. * API credits are non-refundable. See [Credits](/docs/credits) for the full rules. Every key is limited to 60 requests a minute and 10 in flight; see [Rate limits](/docs/rate-limits). ## When a call fails [#when-a-call-fails] Failures use the same envelope with `success: false`. Branch on `error.type`, not on the message text. | `error.type` | HTTP | What to do | | ----------------------- | ---- | ----------------------------------------------------------------- | | `MISSING_API_KEY` | 401 | Send your key in the `x-api-key` header. | | `INVALID_API_KEY` | 401 | Copy the key again from the dashboard. | | `INSUFFICIENT_CREDITS` | 402 | Top up, or pick a cheaper endpoint. | | `UNSUPPORTED_PARAMETER` | 400 | Remove the parameter named in `error.param`. Nothing was charged. | | `UNKNOWN_ENDPOINT` | 404 | Check the path against the catalogue. | | `RATE_LIMITED` | 429 | Wait for `Retry-After`, then slow down. | | `SERVICE_UNAVAILABLE` | 503 | Retry after `Retry-After` or a short backoff. | The complete list, with retry advice, is in [Errors](/docs/errors). ## Next steps [#next-steps] Key, first call, a multi-platform loop and your first paginated list. Creating, sending, rotating and revoking keys. Prices, metered endpoints, free calls and the shared balance. What each of the 22 platforms offers. Every endpoint with parameters and prices. --- # Labels (/docs/labels) Labels, relevance scores and their parameters were removed in schema 2. What those parameters return now, and how to filter results yourself. Comment and post lists used to carry model judgments: `labels`, `relevance`, `label_share` and `labels_evidence`, with parameters to tune them. Schema 2, which every key gets from October 4, 2026, removed them on every endpoint. Responses now carry the platform's data only. What changed is on [Schema 2](/docs/schema-2). ## The parameters now return 400 [#the-parameters-now-return-400] These parameters asked for analysis. Under schema 2 they answer `400 UNSUPPORTED_PARAMETER`, with `error.param` naming the parameter, and nothing is charged: `label`, `label_evidence`, `relevance`, `relevance_threshold`, `relevant_to`, `judgments`, `fit`, `goal`, `fit_tokens`, `seen`, `brand`, `brand_description`, `offer`, `exclude` (except on `/v1/pinterest/trends`, where it filters terms), `brief`, `use`, `moments`, and `format=stationery`. Two more are refused on specific endpoints only, where they ask for analysis; elsewhere they are ordinary parameters: | Parameter | Refused on | What it asked for | | ------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | | `q` | `/v1/tiktok/post/transcript`, `/v1/youtube/video/transcript` | A question answered about the video's transcript. On search endpoints `q` is the search query and works as before. | | `switch_from` | `/v1/twitter/search/tweets`, `/v1/reddit/search/comments` | Posts about switching away from a named brand. | ```json title="Response" { "success": false, "error": { "type": "UNSUPPORTED_PARAMETER", "message": "`relevance` is not supported: it asks for analysis, which is not part of schema 2. Remove it and retry. Nothing was charged.", "param": "relevance" }, "request_id": "req_80d197121a1e", "credits_used": 0, "credits_remaining": null } ``` Remove the parameter and send the call again. ## Filtering results yourself [#filtering-results-yourself] A search returns what the platform returns for your query. To keep only the rows about your topic, filter on the text in your own code. A keyword filter covers most cases: ```python title="filter.py" KEYWORDS = ["insightsocial", "insight social"] def mentions(text): t = (text or "").lower() return any(k in t for k in KEYWORDS) posts = [item["post"] for item in body["data"]["items"]] on_topic = [p for p in posts if mentions(p["content"]["text"])] ``` For tone, topic or paid-promotion checks, run your own classifier or model on `post.content.text` or `comment.text`. To keep one language, filter on `post.language` or `comment.language`, the platform's own tag. A full monitoring example is in [Brand mention monitoring](/docs/recipes/brand-mention-monitoring). --- # MCP server, CLI and agent skills (/docs/mcp) Connect Claude Code, Cursor, Codex, Gemini CLI or any MCP client to the InsightSocial API. A hosted MCP server at one URL, plus the open-source local MCP server, CLI and agent skill. There are two MCP servers with the same tools: a hosted one at `https://api.insightsocial.app/mcp`, which needs nothing installed, and a local one in the official `insightsocial` npm package, which is also a CLI. The agent skill teaches your agent how to use either. The package and the skill are open source under the [InsightSocial GitHub organization](https://github.com/insightsocial). You do not need any of them to use the API, which is plain HTTPS (see [Using an AI agent](/docs/ai-agents)), but they save your agent from writing its own HTTP client and keep large responses out of its context. ## Hosted MCP server [#hosted-mcp-server] In Claude (desktop, claude.ai, Cowork), ChatGPT or any client that supports sign-in, add a connector with the URL `https://api.insightsocial.app/mcp`, click Connect, sign in to InsightSocial and click Allow. The app gets its own key, listed under Connected apps on [API keys](https://www.insightsocial.app/portal/api/keys), where you can disconnect it. Step-by-step for each app: [Claude](/mcp/claude), [ChatGPT](/mcp/chatgpt), [Claude Code](/mcp/claude-code), [Cursor](/mcp/cursor) and [Codex](/mcp/codex). A client that cannot sign in can send your API key as a Bearer token instead: ```json title="mcpServers config" { "mcpServers": { "insightsocial": { "url": "https://api.insightsocial.app/mcp", "headers": { "Authorization": "Bearer $INSIGHTSOCIAL_API_KEY" } } } } ``` A JSON config does not read shell variables: put your key in place of `$INSIGHTSOCIAL_API_KEY`. Cursor is the exception: write `Bearer ${env:INSIGHTSOCIAL_API_KEY}` and it reads the key from your environment. ```bash title="Claude Code" claude mcp add --transport http insightsocial https://api.insightsocial.app/mcp --header "Authorization: Bearer $INSIGHTSOCIAL_API_KEY" ``` It has the tools listed under [MCP server](#mcp-server) below, with three differences: results are kept on our side for 3 days instead of on your disk, `read_result` reshapes them with fields, max items or an outline but not jq, and there are two more tools, `quote_endpoint` (the exact price of a call before you make it, free) and `send_feedback` (tell us about a missing endpoint or field). `call_endpoint` is marked as a tool that spends, so clients ask before running it. Get a key on the [API dashboard](https://www.insightsocial.app/portal/api). ## One command [#one-command] ```bash title="Terminal" npx -y insightsocial init ``` `init` signs you in through your browser and saves a key for this machine to `~/.insightsocial/config.json`, installs the agent skill into the agents it finds, and writes or prints the MCP config. Signing in opens a sign-in page and prints a short code: type the code on the page and click Allow. The CLI then prints which account it signed into. Nothing to copy or paste. To use a key you already have, run `npx -y insightsocial login --api-key isk_live_…`. New accounts get 10 free calls on endpoints priced at 100 credits or less. ## MCP server [#mcp-server] The local server runs over stdio and reads the key that `insightsocial login` (or `init`) saved, so your MCP config holds no secret. ```bash title="Claude Code" claude mcp add insightsocial --scope user -- npx -y insightsocial mcp ``` ```json title="Cursor, Windsurf, Claude Desktop and other clients" { "mcpServers": { "insightsocial": { "command": "npx", "args": ["-y", "insightsocial", "mcp"] } } } ``` You can pass `INSIGHTSOCIAL_API_KEY` in the server's `env` instead of saving it. Without a key, searching and describing endpoints still work. The server is listed in the official MCP Registry as `app.insightsocial/insightsocial`. | Tool | What it does | Cost | | ------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------- | | `search_endpoints` | Find endpoints by keywords and platform | Free | | `describe_endpoint` | Inputs, allowed values, an example and the price for one endpoint | Free | | `call_endpoint` | Fetch data. Saves the full response and returns a `result_id` with a trimmed view and a ready call for the next page | The endpoint's price | | `read_result` | Re-slice a saved result with jq, fields, max items or an outline with sizes | Free | | `get_credits` | Balance, plan and usage | Free | Because every result is saved in full and re-read with `read_result`, a 50 KB page of comments never has to sit in the model's context, and reading it again costs nothing. ## Agent skill [#agent-skill] The skill teaches an agent the workflow: search, price, call, page. It also covers when a call is free and when to stop and ask before spending. It uses the MCP server when it is connected and falls back to the CLI or plain REST when it is not. ```bash title="Any agent that supports Agent Skills" npx skills add insightsocial/skills ``` ```bash title="Claude Code plugin (skill and MCP server together)" claude plugin marketplace add insightsocial/skills claude plugin install insightsocial@insightsocial ``` ```bash title="Gemini CLI" gemini extensions install https://github.com/insightsocial/skills ``` ## CLI [#cli] The same package works from a terminal or a script. Results are saved under `./.insightsocial/`, so you can reshape them later without paying again. ```bash title="Terminal" npx -y insightsocial search tiktok followers npx -y insightsocial describe /v1/tiktok/profile npx -y insightsocial run /v1/tiktok/profile -p handle=natgeo npx -y insightsocial view --last --jq '.data.author | {username, followers}' npx -y insightsocial credits ``` `search`, `list`, `describe`, `view` and `credits` are free. `run` costs the endpoint's price and prints the exact command for the next page when there is one. Each page is a separate charged call. ## OpenAPI spec [#openapi-spec] To generate a client or your own agent tools, use the OpenAPI 3.1 spec. It is live and keyless at `https://api.insightsocial.app/v1/openapi.json`, and a copy synced daily from the live API is at [github.com/insightsocial/openapi](https://github.com/insightsocial/openapi). ## Next steps [#next-steps] The community node and two ready-made workflows. One paste-in prompt, no install. What each call costs and what is free. How cursors work across every list endpoint. --- # Metric substitutions (/docs/metric-substitutions) Which unified fields stay null on which platform, and how to fill the ones a join can recover. Every platform maps onto one unified schema, but no platform publishes every field in it. When a platform does not provide a value, the response carries `null`. A unified field never holds a made-up number, and never holds a different metric under its name. When a platform has a related metric worth keeping, it goes under `ext.*`, so the unified field keeps its exact meaning. This page lists those cases. If a field is listed here as always `null` on a platform, that is how the platform works, not a bug. Fields a platform never shows are also never listed in a response's `unavailable` array; that array is for fields the platform does show but this response could not fill. See [Data availability](/docs/data-availability). ## Ratios you compute yourself [#ratios-you-compute-yourself] Schema 2 returns counts, not derived metrics. There is no engagement rate, reach estimate, language guess or category in the response: compute what you need from the fields that are there. * **Engagement rate by followers:** `(likes + comments + shares) / followers`, using `post.engagement.*` and the author's `followers` from a profile call. On X and TikTok, post rows also carry the author's follower count in `post.ext.author_followers`, so no second call is needed there. * **Engagement rate by views:** `(likes + comments + shares) / views`, where the platform shows views (video on most platforms). * Leave out any count that is `null` rather than treating it as `0`, and skip the ratio when the denominator is `null` or `0`. A `null` count means the platform does not show it; it is not zero. * **Language:** `post.language` and `comment.language` carry the platform's own tag when it states one, and are `null` otherwise. Nothing is detected for you. ## Pinterest [#pinterest] Pinterest spreads its counts between the list endpoints and the pin itself. * Search rows have no counts: `post.engagement.saves`, `likes` (reactions), `comments` and `shares` are `null` on a plain `/v1/pinterest/search` call. Add `include=engagement` and each row is filled from the pin's own record in the same call, at 10 extra credits per row filled. `/v1/pinterest/pin` returns the same counts for a single pin for 10 credits. * `post.engagement.views` is `null` on search rows. Pinterest publishes no view count there. * Board rows have saves, comments and shares but no date: `post.published_at` is `null` on a plain `/v1/pinterest/board` call because the board data has no date. `include=engagement` fills the date from the pin, along with any missing reaction count. * `post.content.text` is the pin's title, or its description when there is no title. Many pins have neither, so `null` means the pin really has no text. Pinterest's auto-generated image caption is never used here. ## LinkedIn [#linkedin] Two author fields are weaker on people-list rows than on the member's own profile, and a join recovers both in the same call. * `author.followers` on `/v1/linkedin/search/people`, `/v1/linkedin/company/people` and `/v1/linkedin/post/reactions` rows is LinkedIn's **rounded display figure**, not an exact count: 39,000 for a member with 39,278, or 2,000 for one with 2,344. Those rows set `author.followers_approximate` to `true`. Many rows show no figure at all, and there `author.followers` is `null`, not a guess. * `author.following` is `null` on every plain people-list row. * Send `include=profile` to join each row to that member's profile in the same call. `author.followers` becomes the exact count, `author.following` gets the member's connection count (on LinkedIn, following means connections), and `author.location`, `author.joined_at`, plus country, website, cover image and profile flags under `author.ext`, are filled where the row lacked them. Every row the join fills sets `author.followers_approximate` to `false`, including rows that had no count before, so the flag always tells you whether the figure is exact. Rows the join could not fill keep their original flag. * The list costs 100 credits, and the join adds 40 credits per row it fills, up to 500 credits in total. Rows served from a recent fetch and rows the join cannot fill add nothing. `limit` (1 to 10) caps both the rows and the extra credits. See [LinkedIn](/docs/platforms/linkedin). ## Always-null fields by platform [#always-null-fields-by-platform] These fields are `null` on every surface of a platform because the platform never shows them. No parameter will fill them. | Platform | Always `null` | Why | | -------- | ------------------------------------------------- | --------------------------------------------------------------------------------- | | YouTube | `post.engagement.shares`, `post.engagement.saves` | Both are private to the channel owner | | Reddit | `post.engagement.views`, `.shares`, `.saves` | Reddit shows no view or share counts, and "saved" is a per-user flag, not a count | | Reddit | `author.verified` | Not shown | On every platform, a top-level comment has `parent_id: null`, and a reply carries its parent comment's id where the platform says which one it is. One field has a default instead of a `null`: a single tweet from Twitter/X has no pinned flag, so `post.flags.pinned` is `false`. --- # n8n integration (/docs/n8n) Use the InsightSocial API in n8n with the official community node, or start from two free workflows for viral content research and creator outreach lists. The `n8n-nodes-insightsocial` community node calls InsightSocial endpoints from an n8n workflow. It covers TikTok, LinkedIn, Twitter/X, YouTube, Reddit and Pinterest, and reads their endpoints, parameters and prices from the live catalogue, so a new endpoint on those platforms shows up in n8n with no node update. For every other platform the API serves, use an HTTP Request node ([Without the node](#without-the-node)). ## Install the node [#install-the-node] In n8n, open **Settings → Community nodes → Install** and enter: ```text title="Package name" n8n-nodes-insightsocial ``` On a self-hosted n8n you can also run `npm install n8n-nodes-insightsocial` in your custom folder (usually `~/.n8n/custom`) and restart n8n. ## Add your key [#add-your-key] Open the [API dashboard](https://www.insightsocial.app/portal/api): your first key is created the first time you open it. Copy it from [API keys](https://www.insightsocial.app/portal/api/keys). Keys start with `isk_live_`. In n8n, create an **InsightSocial API** credential and paste the key. Leave the base URL as it is. Click **Test**. It calls `GET /v1/credits`, which is free. ## Operations [#operations] | Operation | What it does | Cost | | -------------- | --------------------------------------------------------------------- | -------------------- | | Call Endpoint | Pick a platform and an endpoint, fill in its parameters, get the data | The endpoint's price | | Get Credits | Your balance and this month's usage | Free | | List Endpoints | Every endpoint on a platform, with its parameters and price | Free | The endpoint dropdown shows each price, for example `Profile (10 credits)` or, on TikTok, `Post/Comments (10-30 credits, metered)`, so you can see what a workflow costs before you run it. Failed calls and empty results are free. ## Ready-made workflows [#ready-made-workflows] It is free to import and needs only an InsightSocial key. | Workflow | What it builds | | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | | [Viral Content Radar](https://github.com/insightsocial/n8n-viral-content-radar) | Every weekday, this week's top TikToks in your niche, the top video's transcript, and an AI brief on why they spread | ## Without the node [#without-the-node] Any n8n **HTTP Request** node works too: send a GET to `https://api.insightsocial.app/v1/...` with your key in an `x-api-key` header. The [endpoint reference](/docs/api-reference) lists every path and parameter. ## Next steps [#next-steps] Connect Claude, Cursor or any MCP client. End-to-end builds you can adapt. What each call costs and what is free. --- # Pagination (/docs/pagination) Read pagination.next_cursor, send it back as cursor, stop when has_more is false. The same loop works on every list endpoint. List endpoints return one page at a time. Walking a list is the same on every platform: take the cursor from the response, send it back, and stop when the response says there is nothing left. ## The rule [#the-rule] **Send `pagination.next_cursor` back as the `cursor` query parameter. Stop when `pagination.has_more` is `false`.** You never build a cursor or decode one. It is an opaque string that starts `v2c.`. Pass it back exactly as you received it, under the name `cursor`, with the same parameters as the first page, within 24 hours. ## The pagination block [#the-pagination-block] A list response carries a `pagination` object next to `data`: ```json title="Response" { "success": true, "platform": "tiktok", "endpoint": "/v1/tiktok/profile/videos", "schema_version": "2", "data": { "items": [ /* this page's videos, each { "post": { ... } } */ ], "total": null, "truncated": null }, "pagination": { "next_cursor": "v2c.pvp_XLAfnPv6WqqWVPeenDzzgzIG5pSI…", "has_more": true, "page_size": 10 }, "unavailable": [], "credits_used": 10, "credits_remaining": 9490, "request_id": "req_1a2b3c4d5e6f", "cached": false, "idempotent_replay": false, "charge_reason": "miss", "free_call": false } ``` | Field | Meaning | | ------------- | -------------------------------------------------------------------------------------- | | `next_cursor` | Token for the next page. Send it back as `cursor`. `null` on the last page. | | `has_more` | `true` while there are more pages. **This is your stop signal.** | | `page_size` | How many items this page returned. It reports; it does not control. | | `stopped_at` | Only when you sent `since` or `stop_at_id`. See [Incremental sync](#incremental-sync). | Do not use an empty page or a total count to decide you are done. `has_more` is the only reliable signal. `data.total`, when present, is the platform's own total (all comments on a post, for example), not the number of pages left. The cursor is only in `pagination.next_cursor`. There is no copy inside `data`. ## A round trip [#a-round-trip] Page 1, no cursor: ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/profile/videos?handle=khaby.lame" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` The response carries `"pagination": { "next_cursor": "v2c.pvp_XLAf…", "has_more": true, "page_size": 10 }`. Page 2 sends that value back, with the same `handle`: ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/profile/videos?handle=khaby.lame&cursor=v2c.pvp_XLAf…" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` Repeat until `has_more` is `false`. URL-encode the cursor if your HTTP client does not do it for you. A cursor is bound to the request that produced it: the same endpoint and the same parameters. Only `limit`, `max_pages`, `dry_run` and `fresh` may change between pages. Change anything else, such as the `handle` or a filter, and the cursor is refused with `CURSOR_INVALID`; start a new walk instead. ## The loop [#the-loop] ```bash title="cURL" #!/usr/bin/env bash # Walk every page of a list and print each item as one JSON line. Needs jq. url="https://api.insightsocial.app/v1/tiktok/profile/videos" cursor="" while :; do if [ -n "$cursor" ]; then page=$(curl -sG "$url" --data-urlencode "handle=khaby.lame" \ --data-urlencode "cursor=$cursor" -H "x-api-key: $INSIGHTSOCIAL_API_KEY") else page=$(curl -sG "$url" --data-urlencode "handle=khaby.lame" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY") fi echo "$page" | jq -c '.data.items[]' [ "$(echo "$page" | jq -r '.pagination.has_more')" = "true" ] || break cursor=$(echo "$page" | jq -r '.pagination.next_cursor') done ``` ```python title="Python" import os import requests BASE = "https://api.insightsocial.app/v1" HEADERS = {"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]} def paginate(path, params): cursor = None while True: query = dict(params) if cursor: query["cursor"] = cursor # always the parameter named "cursor" body = requests.get(f"{BASE}/{path}", params=query, headers=HEADERS).json() if not body["success"]: raise RuntimeError(f'{body["error"]["type"]}: {body["request_id"]}') yield from body["data"]["items"] page = body["pagination"] if not page["has_more"]: break cursor = page["next_cursor"] # send it back unchanged for video in paginate("tiktok/profile/videos", {"handle": "khaby.lame"}): print(video["post"]["url"]) ``` ```ts title="Node.js" const BASE = "https://api.insightsocial.app/v1"; async function* paginate(path: string, params: Record) { let cursor: string | null = null; while (true) { const url = new URL(`${BASE}/${path}`); for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v); if (cursor) url.searchParams.set("cursor", cursor); // always "cursor" const res = await fetch(url, { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY! }, }); const body = await res.json(); if (!body.success) throw new Error(`${body.error.type}: ${body.request_id}`); yield* body.data.items; if (!body.pagination.has_more) return; cursor = body.pagination.next_cursor; // send it back unchanged } } for await (const video of paginate("tiktok/profile/videos", { handle: "khaby.lame" })) { console.log(video.post.url); } ``` Three things matter: 1. **Send the cursor back byte for byte, under the name `cursor`, with the same parameters.** Do not trim, decode or re-encode it. 2. **Stop on `has_more: false`**, which is also when `next_cursor` is `null`. 3. **Finish a walk within 24 hours.** An older cursor is refused with `CURSOR_EXPIRED`; start again from page 1. ## Draining a whole list [#draining-a-whole-list] A full walk is a series of normal calls, so plan for three things. * **Cost.** Every page is billed as one call to that endpoint. Fifty pages of a 10-credit endpoint cost about 500 credits. Multiply the page count by the price in [Endpoint pricing](/docs/endpoint-pricing) before you start, and cap the number of pages if you only need the most recent items. Re-walking the same pages is charged again, so keep the pages you already have. * **Limits.** Pages of one list are sequential, since each needs the previous cursor. You can walk several lists in parallel, but one key allows 10 calls in flight and 60 calls per minute. Past that you get `429` (`CONCURRENCY_LIMIT` or `RATE_LIMITED`) with a `Retry-After` header, and nothing is charged. * **Retries.** On a `429` or a `503`, wait and retry **the same cursor**. Never move past a page you did not read successfully. ```python title="Python" import time def get_page(path, query): for attempt in range(5): res = requests.get(f"{BASE}/{path}", params=query, headers=HEADERS) if res.status_code in (429, 503): time.sleep(float(res.headers.get("Retry-After", 2 ** attempt))) continue # same query, same cursor return res.json() raise RuntimeError("gave up after 5 attempts") ``` ## Several pages in one call: `max_pages` [#several-pages-in-one-call-max_pages] Some endpoints take `max_pages` (1 to 5, default 1). The call walks up to that many pages itself and returns the rows from all of them in `data.items`. `pagination.next_cursor` continues from where it stopped, and `has_more` says whether there is more. The walk can stop before `max_pages` when the list runs out. Each page walked is billed as one call. The walk itself is still one request, so it takes a single slot of your rate limit however many pages it covers. What we hold before the call is the most one page can cost with your parameters, times `max_pages`, and the call never costs more than that. See [Credits](/docs/credits#reserve-the-ceiling-settle-the-actual). ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/search/top?query=basketball&max_pages=3" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` This holds up to 30 credits (10 × 3) and charges for the pages actually walked. To see the hold before you run it, add `dry_run=1`: the response carries `data.dry_run` with `credits_min` and `credits_max`, and costs nothing. ## Incremental sync [#incremental-sync] A daily poll only needs what was posted since the last run. Four creator feeds take two parameters that end the walk where your previous poll stopped, so you pay only for the pages that have new posts. | Platform | Endpoint | | --------- | ------------------------------------------------------------------ | | TikTok | `GET /v1/tiktok/profile/videos` | | Twitter/X | `GET /v1/twitter/user/tweets` | | YouTube | `GET /v1/youtube/channel/videos`, `GET /v1/youtube/channel/shorts` | | Parameter | Value | Effect | | ------------ | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `stop_at_id` | `post.id` or `post.url` of the newest post you already have | The page ends just before that post. It and everything older are left off, no `next_cursor` is returned, and `stopped_at` is `known_id`. If the post is not on this page, the full page comes back with its cursor, so keep walking. | | `since` | `YYYY-MM-DD` (midnight UTC) or an ISO 8601 timestamp | Older posts are left off. The page that reaches one ends the walk, with `stopped_at` set to `since`. | ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/profile/videos?handle=nasa&since=2026-09-01" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```json title="Response" "pagination": { "next_cursor": null, "has_more": false, "page_size": 6, "stopped_at": "since" } ``` | `stopped_at` | Meaning | | ------------ | --------------------------------------------------------------------- | | `known_id` | The walk reached the post named in `stop_at_id`. | | `since` | The walk reached a post older than `since`. | | `end` | The list ran out before either boundary. | | `null` | No boundary on this page yet. Send `next_cursor` back and keep going. | Send the same `stop_at_id` or `since` on every page of the walk, and store the newest post you received for the next run. ### Date filters on other lists [#date-filters-on-other-lists] About eighty more lists of posts and comments take `since` and `until` as filters, in the same formats (`until` includes its whole UTC day), and the feeds above take `until` too. Each endpoint's reference shows whether it has them. On nine of them `since` also ends the walk as above and sorts the list newest first: comments on LinkedIn, TikTok and YouTube posts, LinkedIn company posts, X search, and Reddit search, subreddits and user posts. Elsewhere the list is not in date order, so rows outside the window are left off each page but the walk does not stop: keep following `next_cursor`. A page is charged even when every row on it was filtered out. A row with no date is kept. Pinned posts sit out of date order. They never end the walk and are never taken as the stop point, so do not store a pinned post as your newest. These parameters do not change what a page costs. What they save is the pages you never fetch: if the post you already have shows up on the first page, the walk ends there and that first page is the whole bill. ## Native paging parameters [#native-paging-parameters] Every endpoint pages with `cursor` and nothing else, with one exception. `/v1/youtube/video/comment/replies` requires `continuationToken`, and its value is not a page token: it is the `id` of a top-level comment from `/v1/youtube/video/comments`, which names the thread to open. Page through that thread's replies with `cursor` like any other list. A response never hands you a platform page token: the only cursor it carries is `pagination.next_cursor`. Sending `next_cursor` under any other name, such as `continuationToken`, or a cursor from the previous schema (`is.` or `is2.`), is refused with `CURSOR_INVALID` instead of quietly returning page 1 again. A few search endpoints also take `page`, a page number. It picks the page a walk starts on; it is not a token. Walk on from there with `cursor`. ## Bad or stale cursors [#bad-or-stale-cursors] A bad cursor is refused before anything is fetched, with `error.param` naming the parameter that carried it. Errors are never charged. | `error.type` | Cause | What to do | | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | | `CURSOR_INVALID` | The cursor was edited or truncated, was not issued by this API, was sent under a name other than `cursor`, or belongs to a different endpoint or different parameters. | Send `pagination.next_cursor` back unchanged with the original parameters, or start again without a cursor. | | `CURSOR_EXPIRED` | The cursor is more than 24 hours old. | Start again without a cursor. | ```json title="Response" { "success": false, "error": { "type": "CURSOR_INVALID", "message": "This cursor was not issued by this API. Send `pagination.next_cursor` back unchanged. Nothing was charged.", "param": "cursor" }, "request_id": "req_a7f5ccf4ce56", "credits_used": 0, "credits_remaining": null } ``` ## `limit` is not always a page size [#limit-is-not-always-a-page-size] What `limit` does depends on the endpoint. Read its description on the endpoint page before you rely on it. * **Page size or row cap.** It trims one page. On `GET /v1/linkedin/search/people`, `limit` takes the top rows of a page and the cursor still moves past the whole page, so the skipped rows do not reappear on the next one. `pagination.page_size` in the response is a report of what arrived, never a control. ## Every paginated endpoint [#every-paginated-endpoint] These 102 endpoints return the `pagination` block and take `cursor`. Each page is one call at the price shown; a range means the endpoint is metered. Every price is also on [Endpoint pricing](/docs/endpoint-pricing). ### TikTok [#tiktok] | Endpoint | Credits per call | Also takes | | ----------------------------------------------------------------------------------- | ---------------- | --------------------- | | [`/tiktok/profile/videos`](/docs/api-reference/tiktok/profile-videos) | 10 | `since`, `stop_at_id` | | [`/tiktok/post/comments`](/docs/api-reference/tiktok/post-comments) | 10–30 | — | | [`/tiktok/video/comment/replies`](/docs/api-reference/tiktok/video-comment-replies) | 10 | — | | [`/tiktok/search`](/docs/api-reference/tiktok/search) | 10–370 | `max_pages` | | [`/tiktok/search/hashtag`](/docs/api-reference/tiktok/search-hashtag) | 10 | `max_pages` | | [`/tiktok/search/top`](/docs/api-reference/tiktok/search-top) | 10 | `max_pages` | | [`/tiktok/search/users`](/docs/api-reference/tiktok/search-users) | 10–1,310 | — | | [`/tiktok/user/followers`](/docs/api-reference/tiktok/user-followers) | 10 | — | | [`/tiktok/user/following`](/docs/api-reference/tiktok/user-following) | 10 | — | | [`/tiktok/song/videos`](/docs/api-reference/tiktok/song-videos) | 10 | — | | [`/tiktok/adlibrary/search`](/docs/api-reference/tiktok/adlibrary-search) | 50–170 | — | | [`/tiktok/collection/videos`](/docs/api-reference/tiktok/collection-videos) | 10 | — | | [`/tiktok/playlist/videos`](/docs/api-reference/tiktok/playlist-videos) | 10 | — | | [`/tiktok/user/liked`](/docs/api-reference/tiktok/user-liked) | 10 | — | | [`/tiktok/location/posts`](/docs/api-reference/tiktok/location-posts) | 10 | — | | [`/tiktok/effect/videos`](/docs/api-reference/tiktok/effect-videos) | 10 | — | | [`/tiktok/search/music`](/docs/api-reference/tiktok/search-music) | 10 | — | | [`/tiktok/profile/full`](/docs/api-reference/tiktok/profile-full) | 50 | — | ### LinkedIn [#linkedin] | Endpoint | Credits per call | Also takes | | ------------------------------------------------------------------------------------------------------- | ---------------- | ---------- | | [`/linkedin/search/companies`](/docs/api-reference/linkedin/search-companies) | 100 | — | | [`/linkedin/profile/articles`](/docs/api-reference/linkedin/profile-articles) | 50 | — | | [`/linkedin/article/comments`](/docs/api-reference/linkedin/article-comments) | 50 | — | | [`/linkedin/article/reactions`](/docs/api-reference/linkedin/article-reactions) | 50 | — | | [`/linkedin/profile/interests/schools`](/docs/api-reference/linkedin/profile-interests-schools) | 50 | — | | [`/linkedin/profile/interests/newsletters`](/docs/api-reference/linkedin/profile-interests-newsletters) | 50 | — | | [`/linkedin/search/people`](/docs/api-reference/linkedin/search-people) | 100–500 | — | | [`/linkedin/company/people`](/docs/api-reference/linkedin/company-people) | 100–500 | — | | [`/linkedin/post/comments`](/docs/api-reference/linkedin/post-comments) | 50 | — | | [`/linkedin/post/reposts`](/docs/api-reference/linkedin/post-reposts) | 50 | — | | [`/linkedin/group/posts`](/docs/api-reference/linkedin/group-posts) | 50 | — | | [`/linkedin/post/comments/replies`](/docs/api-reference/linkedin/post-comments-replies) | 50 | — | | [`/linkedin/profile/experiences`](/docs/api-reference/linkedin/profile-experiences) | 50 | — | | [`/linkedin/profile/educations`](/docs/api-reference/linkedin/profile-educations) | 50 | — | | [`/linkedin/profile/skills`](/docs/api-reference/linkedin/profile-skills) | 50 | — | | [`/linkedin/profile/honors`](/docs/api-reference/linkedin/profile-honors) | 50 | — | | [`/linkedin/profile/certifications`](/docs/api-reference/linkedin/profile-certifications) | 50 | — | | [`/linkedin/profile/publications`](/docs/api-reference/linkedin/profile-publications) | 50 | — | | [`/linkedin/profile/volunteers`](/docs/api-reference/linkedin/profile-volunteers) | 50 | — | | [`/linkedin/profile/recommendations`](/docs/api-reference/linkedin/profile-recommendations) | 50 | — | | [`/linkedin/profile/interests/companies`](/docs/api-reference/linkedin/profile-interests-companies) | 50 | — | | [`/linkedin/profile/interests/groups`](/docs/api-reference/linkedin/profile-interests-groups) | 50 | — | | [`/linkedin/post/reactions`](/docs/api-reference/linkedin/post-reactions) | 100–500 | — | | [`/linkedin/company/jobs`](/docs/api-reference/linkedin/company-jobs) | 100 | — | | [`/linkedin/search/jobs`](/docs/api-reference/linkedin/search-jobs) | 100 | — | | [`/linkedin/search/schools`](/docs/api-reference/linkedin/search-schools) | 10 | — | | [`/linkedin/company/posts`](/docs/api-reference/linkedin/company-posts) | 50 | — | | [`/linkedin/ads/search`](/docs/api-reference/linkedin/ads-search) | 50 | — | | [`/linkedin/profile/posts/archive`](/docs/api-reference/linkedin/profile-posts-archive) | 50–5,000 | — | | [`/linkedin/search/posts`](/docs/api-reference/linkedin/search-posts) | 10–480 | — | | [`/linkedin/profile/full`](/docs/api-reference/linkedin/profile-full) | 50 | — | ### Twitter/X [#twitterx] | Endpoint | Credits per call | Also takes | | --------------------------------------------------------------------------- | ---------------- | --------------------- | | [`/twitter/user/tweets`](/docs/api-reference/twitter/user-tweets) | 10 | `since`, `stop_at_id` | | [`/twitter/search/tweets`](/docs/api-reference/twitter/search-tweets) | 10–50 | `max_pages` | | [`/twitter/tweet/replies`](/docs/api-reference/twitter/tweet-replies) | 10 | — | | [`/twitter/user/media`](/docs/api-reference/twitter/user-media) | 10 | — | | [`/twitter/user/followers`](/docs/api-reference/twitter/user-followers) | 10 | — | | [`/twitter/user/following`](/docs/api-reference/twitter/user-following) | 10 | — | | [`/twitter/tweet/retweeters`](/docs/api-reference/twitter/tweet-retweeters) | 10 | — | | [`/twitter/search/users`](/docs/api-reference/twitter/search-users) | 10 | — | | [`/twitter/profile/full`](/docs/api-reference/twitter/profile-full) | 50 | — | ### YouTube [#youtube] | Endpoint | Credits per call | Also takes | | ----------------------------------------------------------------------------------------- | ---------------- | --------------------- | | [`/youtube/channel/videos`](/docs/api-reference/youtube/channel-videos) | 10–20 | `since`, `stop_at_id` | | [`/youtube/video/comments`](/docs/api-reference/youtube/video-comments) | 10 | — | | [`/youtube/video/comment/replies`](/docs/api-reference/youtube/video-comment-replies) | 10 | — | | [`/youtube/search`](/docs/api-reference/youtube/search) | 10–150 | `max_pages` | | [`/youtube/channel/shorts`](/docs/api-reference/youtube/channel-shorts) | 10–20 | `since`, `stop_at_id` | | [`/youtube/playlist`](/docs/api-reference/youtube/playlist) | 10–110 | — | | [`/youtube/search/hashtag`](/docs/api-reference/youtube/search-hashtag) | 10–110 | `max_pages` | | [`/youtube/channel/playlists`](/docs/api-reference/youtube/channel-playlists) | 10 | — | | [`/youtube/channel/lives`](/docs/api-reference/youtube/channel-lives) | 10–70 | — | | [`/youtube/channel/community-posts`](/docs/api-reference/youtube/channel-community-posts) | 10 | — | | [`/youtube/videos/trending`](/docs/api-reference/youtube/videos-trending) | 10–60 | — | | [`/youtube/playlist/items`](/docs/api-reference/youtube/playlist-items) | 10–110 | — | | [`/youtube/search/advanced`](/docs/api-reference/youtube/search-advanced) | 10–110 | `max_pages` | | [`/youtube/profile/full`](/docs/api-reference/youtube/profile-full) | 50 | — | ### Reddit [#reddit] | Endpoint | Credits per call | Also takes | | --------------------------------------------------------------------------- | ---------------- | ----------- | | [`/reddit/subreddit`](/docs/api-reference/reddit/subreddit) | 10 | — | | [`/reddit/search`](/docs/api-reference/reddit/search) | 10–300 | `max_pages` | | [`/reddit/post/comments`](/docs/api-reference/reddit/post-comments) | 50 | — | | [`/reddit/subreddit/search`](/docs/api-reference/reddit/subreddit-search) | 10–260 | — | | [`/reddit/profile/posts`](/docs/api-reference/reddit/profile-posts) | 10 | — | | [`/reddit/search/comments`](/docs/api-reference/reddit/search-comments) | 10 | — | | [`/reddit/subreddits/search`](/docs/api-reference/reddit/subreddits-search) | 10–260 | — | | [`/reddit/search/media`](/docs/api-reference/reddit/search-media) | 10 | — | | [`/reddit/omni-search`](/docs/api-reference/reddit/omni-search) | 50–90 | — | ### Pinterest [#pinterest] | Endpoint | Credits per call | Also takes | | ----------------------------------------------------------- | ---------------- | ---------- | | [`/pinterest/search`](/docs/api-reference/pinterest/search) | 10–260 | — | | [`/pinterest/board`](/docs/api-reference/pinterest/board) | 10–160 | — | ### Truth Social [#truth-social] | Endpoint | Credits per call | Also takes | | ----------------------------------------------------------------------- | ---------------- | ---------- | | [`/truthsocial/user/posts`](/docs/api-reference/truthsocial/user-posts) | 10 | — | ### Snapchat [#snapchat] | Endpoint | Credits per call | Also takes | | --------------------------------------------------------------------------------- | ---------------- | ---------- | | [`/snapchat/spotlight/comments`](/docs/api-reference/snapchat/spotlight-comments) | 10 | — | ### Telegram [#telegram] | Endpoint | Credits per call | Also takes | | ----------------------------------------------------------------------- | ---------------- | ---------- | | [`/telegram/profile/posts`](/docs/api-reference/telegram/profile-posts) | 10 | — | ### Rumble [#rumble] | Endpoint | Credits per call | Also takes | | --------------------------------------------------------------------- | ---------------- | ---------- | | [`/rumble/search`](/docs/api-reference/rumble/search) | 10 | — | | [`/rumble/channel/videos`](/docs/api-reference/rumble/channel-videos) | 10 | — | ### Kwai [#kwai] | Endpoint | Credits per call | Also takes | | --------------------------------------------------------- | ---------------- | ---------- | | [`/kwai/user/posts`](/docs/api-reference/kwai/user-posts) | 10 | — | ### Douyin [#douyin] | Endpoint | Credits per call | Also takes | | ----------------------------------------------------------------------- | ---------------- | ---------- | | [`/douyin/comment/replies`](/docs/api-reference/douyin/comment-replies) | 50–2,500 | — | | [`/douyin/search/users`](/docs/api-reference/douyin/search-users) | 50–1,250 | — | ### Xiaohongshu (RedNote) [#xiaohongshu-rednote] | Endpoint | Credits per call | Also takes | | ----------------------------------------------------------------------------- | ---------------- | ---------- | | [`/xiaohongshu/search`](/docs/api-reference/xiaohongshu/search) | 50–1,000 | — | | [`/xiaohongshu/profile/posts`](/docs/api-reference/xiaohongshu/profile-posts) | 50–1,000 | — | | [`/xiaohongshu/post/comments`](/docs/api-reference/xiaohongshu/post-comments) | 50–1,000 | — | ### TikTok Shop [#tiktok-shop] | Endpoint | Credits per call | Also takes | | ------------------------------------------------------------------------------- | ---------------- | ---------- | | [`/tiktokshop/product/reviews`](/docs/api-reference/tiktokshop/product-reviews) | 10 | — | | [`/tiktokshop/products`](/docs/api-reference/tiktokshop/products) | 10 | — | | [`/tiktokshop/search`](/docs/api-reference/tiktokshop/search) | 10 | — | | [`/tiktokshop/user/showcase`](/docs/api-reference/tiktokshop/user-showcase) | 10 | — | ### Weibo [#weibo] | Endpoint | Credits per call | Also takes | | ----------------------------------------------------------------- | ---------------- | ---------- | | [`/weibo/user/posts`](/docs/api-reference/weibo/user-posts) | 10 | — | | [`/weibo/post/comments`](/docs/api-reference/weibo/post-comments) | 10 | — | | [`/weibo/search`](/docs/api-reference/weibo/search) | 10 | — | ### Zhihu [#zhihu] | Endpoint | Credits per call | Also takes | | --------------------------------------------------------------------- | ---------------- | ---------- | | [`/zhihu/search/articles`](/docs/api-reference/zhihu/search-articles) | 10 | — | ## See also [#see-also] How each page is held and charged. Shared-cache hits and forcing a fresh fetch. The price of every endpoint. Retries, idempotency and rate limits for long walks. --- # Production checklist (/docs/production-checklist) Timeouts, retries, idempotency, pagination, rate limits, caching, keys, budgets and logging before you ship. Route every call through one server-side wrapper that handles the key, timeouts, retries and logging. Keep per-endpoint choices, like the timeout, as arguments so each call site can set its own. ## Start with one request wrapper [#start-with-one-request-wrapper] ```ts title="Node.js" const BASE_URL = "https://api.insightsocial.app"; const BASE_BACKOFF_MS = 500; const MAX_BACKOFF_MS = 8_000; // error.type values worth retrying. Everything else is a permanent answer. const RETRYABLE = new Set([ "RATE_LIMITED", "CONCURRENCY_LIMIT", "IDEMPOTENCY_IN_PROGRESS", "SERVICE_UNAVAILABLE", "UPSTREAM_ERROR", "UPSTREAM_INVALID", "INTERNAL_ERROR", ]); const RETRYABLE_STATUS = new Set([429, 500, 503]); interface Envelope { success: boolean; schema_version?: "2"; data?: T; pagination?: { next_cursor: string | null; has_more: boolean; page_size: number; stopped_at?: "since" | "known_id" | "end" | null; }; unavailable?: string[]; error?: { type: string; message: string; param?: string }; request_id: string; credits_used: number; credits_remaining: number | null; cached?: boolean; idempotent_replay?: boolean; charge_reason?: "miss" | "shared_cache" | "replay" | "no_result" | "dry_run"; free_call?: boolean; } interface Attempt { endpoint: string; attempt: number; status: number | null; errorType: string | null; requestId: string | null; creditsUsed: number | null; chargeReason: string | null; latencyMs: number; } export class InsightSocialError extends Error { constructor(message: string, readonly attempt: Attempt) { super(message); this.name = "InsightSocialError"; } } const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); function backoff(attempt: number, retryAfterMs = 0) { const cap = Math.min(MAX_BACKOFF_MS, BASE_BACKOFF_MS * 2 ** attempt); return Math.max(retryAfterMs, Math.random() * cap); // full jitter, never below Retry-After } export async function callApi(opts: { endpoint: `/v1/${string}`; query?: Record; attemptTimeoutMs: number; maxRetries?: number; onAttempt?: (a: Attempt) => void; }): Promise> { const key = process.env.INSIGHTSOCIAL_API_KEY; if (!key) throw new Error("INSIGHTSOCIAL_API_KEY is not set"); const url = new URL(opts.endpoint, BASE_URL); for (const [k, v] of Object.entries(opts.query ?? {})) url.searchParams.set(k, v); const maxRetries = opts.maxRetries ?? 3; const idempotencyKey = crypto.randomUUID(); // one per logical call, reused on every retry for (let attempt = 0; attempt <= maxRetries; attempt++) { const started = performance.now(); const log = (a: Omit): Attempt => { const entry = { endpoint: opts.endpoint, attempt: attempt + 1, latencyMs: Math.round(performance.now() - started), ...a, }; try { opts.onAttempt?.(entry); } catch { /* logging must not change the outcome */ } return entry; }; let res: Response; try { res = await fetch(url, { headers: { "x-api-key": key, "Idempotency-Key": idempotencyKey }, signal: AbortSignal.timeout(opts.attemptTimeoutMs), }); } catch (cause) { const entry = log({ status: null, errorType: "NETWORK_OR_TIMEOUT", requestId: null, creditsUsed: null, chargeReason: null }); if (attempt < maxRetries) { await sleep(backoff(attempt)); continue; } throw new InsightSocialError(String(cause), entry); } const retryAfter = Number(res.headers.get("retry-after")); const retryAfterMs = Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter * 1_000 : undefined; let body: Envelope | undefined; try { body = (await res.json()) as Envelope; } catch { body = undefined; } const entry = log({ status: res.status, errorType: body?.error?.type ?? (body ? null : "INVALID_RESPONSE"), requestId: body?.request_id ?? res.headers.get("x-request-id"), creditsUsed: body?.credits_used ?? null, chargeReason: body?.charge_reason ?? null, }); if (res.ok && body?.success) { // These docs describe schema 2. Fail loudly if a body arrives in another shape. if (body.schema_version !== "2") { throw new InsightSocialError(`Unexpected schema_version: ${String(body.schema_version)}`, entry); } return body; } // By status as well as type: a 503 can carry the platform's own error type. const retryable = RETRYABLE_STATUS.has(res.status) || RETRYABLE.has(body?.error?.type); if (!retryable || attempt === maxRetries) { throw new InsightSocialError(body?.error?.message ?? `HTTP ${res.status}`, entry); } await sleep(backoff(attempt, retryAfterMs)); } throw new Error("unreachable"); } const profile = await callApi({ endpoint: "/v1/tiktok/profile", query: { handle: "natgeo" }, attemptTimeoutMs: 90_000, onAttempt: (a) => console.info("insightsocial_attempt", a), }); console.log(profile.request_id, profile.credits_used, profile.charge_reason); ``` The key is read from the server environment only. The wrapper checks `schema_version` on every success, so a change of response shape fails at the edge of your code, not deep inside a parser. Each attempt reports `request_id`, the charge and the charge reason to your logs. See [Authentication](/docs/authentication) and [Response schema](/docs/response-schema). ## Set timeouts per endpoint [#set-timeouts-per-endpoint] Pass a per-attempt timeout on every call. When a source is slow we retry it ourselves before answering, so one call can take a minute or more in the worst case. A timeout much shorter than that turns slow successes into failures and retries. Start from your own measurements of uncached calls, per endpoint. A single profile, a feed page, a metered search with `max_pages` and a transcript all behave differently. Total wall time for a logical call is the attempts plus backoff plus any `Retry-After` waits. If you abandon an attempt, the call is not charged. See the idempotency caveat below before you retry it. ## Retry only transient failures [#retry-only-transient-failures] Retry these `error.type` values: `RATE_LIMITED`, `CONCURRENCY_LIMIT`, `IDEMPOTENCY_IN_PROGRESS`, `SERVICE_UNAVAILABLE`, `UPSTREAM_ERROR`, `UPSTREAM_INVALID`, `INTERNAL_ERROR`, and any `429`, `500` or `503` whatever its type. Honor `Retry-After` when it is present, otherwise back off exponentially with full jitter, and cap the number of attempts. Do not retry answers that will not change: `MISSING_API_KEY`, `INVALID_API_KEY`, `API_KEY_REVOKED`, `INSUFFICIENT_CREDITS`, `UNKNOWN_PLATFORM`, `UNKNOWN_ENDPOINT`, `METHOD_NOT_SUPPORTED`, parameter errors such as `INVALID_REQUEST` and `UNSUPPORTED_PARAMETER` (remove the parameter named in `error.param`), `IDEMPOTENCY_KEY_REUSED` (use a new key), and `RESOURCE_NOT_FOUND`, which means nothing exists at the identifier you sent (not charged). `CURSOR_INVALID` and `CURSOR_EXPIRED` are not retried with the same cursor: restart the list without one. Branch on `error.type`, never on the message text. See [Error handling](/docs/errors). Errors are never charged, so a retry costs only time and rate-limit room. ## Make retries safe [#make-retries-safe] Generate one `Idempotency-Key` per logical call and send the same value on every retry of that call. * The key may be up to 255 characters of letters, digits, `.`, `_`, `:` and `-`. A key outside that format is ignored, not rejected, so the retry is treated as a new call. * Keys are scoped to your account. * A replay of a call we already answered comes back with `idempotent_replay: true`, `charge_reason: "replay"` and `credits_used: 0`. * A retry that arrives while the first attempt is still running gets `409 IDEMPOTENCY_IN_PROGRESS` with `Retry-After`. Wait and send it again. * Do not reuse a key for a new page, a changed parameter or a different endpoint. A key reused with a different request is rejected with `409 IDEMPOTENCY_KEY_REUSED`. If we never answered the first attempt successfully, for example because your client timed it out, the retry with the same key that delivers the data is charged as a normal call (`charge_reason: "miss"`) at exactly the ceiling the call reserved: the listed price, or the top of the range for a metered endpoint, multiplied by `max_pages` if you sent it. Like any charged call, it can be covered by one of your free calls. It costs 0 if the replay returns nothing. ## Drain every page [#drain-every-page] For a list, send `pagination.next_cursor` back unchanged as `cursor`, with the same parameters as the first page, and stop when `pagination.has_more` is `false`. Do not treat an empty page or a count as the end. Cursors start with `v2c.`, are opaque, and last 24 hours. A cursor sent with different parameters answers `400 CURSOR_INVALID`; an old one answers `400 CURSOR_EXPIRED`. Neither is charged. Long walks should save their place in your own store and be able to restart from page 1. Pages are sequential. Give each page its own idempotency key, and keep that key for the page's retries. On a retry, resend the same cursor. See [Pagination](/docs/pagination). ## Control rate and concurrency [#control-rate-and-concurrency] Each key allows **60 calls per rolling minute** and **10 calls in flight**. They fail differently: `RATE_LIMITED` means you started too many calls in the window, `CONCURRENCY_LIMIT` means too many are still running. Both are `429` with `Retry-After`, and neither is charged. Keep your worker pool and your call rate below both limits, and apply backpressure before adding retries, since retries use the same budget. There are no rate-limit headers to read, so track your own counts. See [Rate limits](/docs/rate-limits). ## Decide when cached data is acceptable [#decide-when-cached-data-is-acceptable] A response with `cached: true` came from our shared cache and costs 2 credits. It is not a guarantee: the entry may not exist when you call. Every repeat of a call is charged, so cache responses you need again on your side. Send `Cache-Control: no-cache` (or `fresh=1`) only where your application needs data as of now. It is always charged at the endpoint's full price. See [Caching](/docs/caching). ## Separate keys by environment [#separate-keys-by-environment] Create separate keys for production, staging, CI and local development, and store each in a server-side secret store. You can hold up to 25 keys. Revoking one does not touch the others, and each key has its own rate and concurrency limits. Keys have no scopes: every key reaches every endpoint. And every key draws on the same account balance, so a separate key isolates revocation and rate limits, not spend. ## Budget your spend [#budget-your-spend] List every endpoint you will call in production and its expected volume, and price it with [Endpoint pricing](/docs/endpoint-pricing). For metered endpoints, budget the ceiling. `dry_run=1` returns the range in `data.dry_run` (`credits_min`, `credits_max`) with `charge_reason: "dry_run"`, and charges nothing. A call whose ceiling your balance cannot cover fails with `402 INSUFFICIENT_CREDITS` before it runs, and nothing is charged. Read `credits_remaining` from each response, or poll `GET /v1/credits` (free), and alert on your own threshold. Remember that exports on the same account draw on the same balance. See [Credits](/docs/credits). ## Pin the response shape [#pin-the-response-shape] From October 4, 2026 every key gets [schema 2](/docs/schema-2). Before you ship: * Check `schema_version` is `"2"` on every success (the wrapper above does). * Read `unavailable` on every response. It lists fields, as paths into `data`, that this platform normally fills but this response could not. Log it, and decide per field whether a gap is acceptable. * Treat every id as a string and every time as ISO 8601 UTC. * Keep a default branch wherever you switch on `post.kind`. New values may be added. * Send no parameter that schema 2 refuses. They answer `400 UNSUPPORTED_PARAMETER`. * Treat beta endpoints (metrics, untyped lists) as loosely typed. They keep the source's own structure under our naming rules (snake\_case keys, string ids, ISO times where the source gives a timestamp), can carry the source's own figures, and their fields may change. On `profile/full`, parse `data.profile` as a profile and `data.posts[].post` as posts, and treat only its other keys as loosely typed. ## Log what support needs [#log-what-support-needs] For every attempt, record: * `request_id` (also the `X-Request-Id` header) * the endpoint and HTTP status * `error.type` on failures * `credits_used` and `charge_reason` * `cached` * `unavailable`, when it is not empty * your measured latency and the attempt number Never log the API key or full sensitive request data. When you report a problem, include the `request_id` values involved. ## Deployment checklist [#deployment-checklist] * [ ] The production endpoint set and required parameters are fixed. * [ ] Each endpoint has a tested per-attempt timeout. * [ ] Only the transient `error.type` values are retried, with a cap, `Retry-After`, and jittered backoff. * [ ] Each logical call has its own `Idempotency-Key`, reused only for its retries. * [ ] Every success is checked for `"schema_version": "2"`, and no request sends a refused parameter. * [ ] `unavailable` is logged, and each field your product needs has a plan for when it is listed. * [ ] Pagination stops on `has_more: false`, sends the cursor back unchanged with the same parameters, and restarts on `CURSOR_EXPIRED`. * [ ] Call rate and in-flight calls are both bounded below the per-key limits. * [ ] Each endpoint is marked as accepting cached data or requiring a fresh fetch. * [ ] The production key is loaded from a server-side secret store and used nowhere else. * [ ] Expected spend is budgeted from current prices, with an alert on `credits_remaining`. * [ ] `request_id`, status, error type, credits, charge reason, latency and attempt number are logged. * [ ] A clean pre-production run passed, following [Testing your integration](/docs/testing-your-integration). ## Next steps [#next-steps] Check success, failure, pagination, retry and cache paths before launch. Every error type and whether to retry it. Call rate and concurrency per key. Holds, settlement and charge reasons. --- # Quickstart (/docs/quickstart) Get a key, make a call, read the envelope, page through a list and check your balance. Five steps. The first call takes a minute; by the end you will have read four platforms from one script and walked a paginated list. If Claude, Cursor or another agent is writing your integration, see [AI agents](/docs/ai-agents) for what to hand it. ### Get your API key [#get-your-api-key] Sign in and open the [API dashboard](https://www.insightsocial.app/portal/api). Your first key is created for you the first time you open it. Copy it from [API keys](https://www.insightsocial.app/portal/api/keys), where you can also make more at any time. A key starts with `isk_live_`. You can show or copy the full value from the dashboard at any time. Keep it in a secret store rather than in your code, and export it for the examples below: ```bash title="cURL" export INSIGHTSOCIAL_API_KEY="isk_live_..." ``` Keep the key on your server. See [Authentication](/docs/authentication) for rotation and revocation. ### Make your first call [#make-your-first-call] ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/profile?handle=nasa" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python title="Python" import os import requests res = requests.get( "https://api.insightsocial.app/v1/tiktok/profile", params={"handle": "nasa"}, headers={"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]}, ) print(res.json()) ``` ```ts title="Node.js" const res = await fetch( "https://api.insightsocial.app/v1/tiktok/profile?handle=nasa", { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY! } }, ); console.log(await res.json()); ``` No token exchange and no per-platform setup: the header is the whole credential. ### Read the response [#read-the-response] ```json title="Response" { "success": true, "platform": "tiktok", "endpoint": "/v1/tiktok/profile", "schema_version": "2", "data": { "author": { "id": "6772003040451462149", "username": "nasa", "display_name": "NASA", "avatar_url": "https://p16-sign-va.tiktokcdn.com/…", "bio": "Making the seemingly impossible, possible. ✨", "verified": true, "followers": 9800000, "followers_approximate": null, "following": 12, "posts_count": 1210, "likes_count": 98400000, "url": "https://www.tiktok.com/@nasa", "location": null, "external_url": "https://www.nasa.gov", "private": false, "joined_at": null, "last_post_at": "2026-10-03T14:10:18.000Z", "ext": { "region": "US" } } }, "unavailable": [], "credits_used": 0, "credits_remaining": 500, "request_id": "req_d6ad52ab1f9f", "cached": false, "idempotent_replay": false, "charge_reason": "miss", "free_call": true } ``` The payload is under `data`. A profile has the same fields on every platform; a field the platform does not show is `null` (TikTok shows no `joined_at`). Ids are always strings and times are ISO 8601 in UTC. `schema_version` says which response shape you got, and `unavailable` lists any field this platform normally fills that this response could not; it is empty here. See [Schema 2](/docs/schema-2). `credits_used` is what this call cost and `credits_remaining` is your balance after it. Here `free_call` is `true`: your first 10 calls priced at 100 credits or less cost nothing, so this 10-credit call came out of that allowance. The same numbers are also sent as headers, which is handy for logging: | Header | Carries | | --------------------- | --------------------------------------------------------------- | | `X-Request-Id` | The same value as `request_id`. Quote it to support. | | `X-Credits-Used` | Credits charged for this call. | | `X-Credits-Remaining` | Your balance after the call. Omitted when it could not be read. | Every field is described in [Response schema](/docs/response-schema). ### Read four platforms in one script [#read-four-platforms-in-one-script] Changing platform means changing the path, nothing else. This loop reads the same handle on four platforms, prints the follower count and the running cost, and spends up to 40 credits (less while you still have free calls). ```python title="Python" import os import requests KEY = os.environ["INSIGHTSOCIAL_API_KEY"] BASE = "https://api.insightsocial.app/v1" for path in ["tiktok/profile", "youtube/channel", "twitter/profile"]: body = requests.get( f"{BASE}/{path}", params={"handle": "nasa"}, headers={"x-api-key": KEY}, ).json() if not body["success"]: print(path, body["error"]["type"], body["error"]["message"]) continue followers = body["data"]["author"]["followers"] print(f"{path:<20} {followers:>14,} cost {body['credits_used']} left {body['credits_remaining']}") ``` ```ts title="Node.js" const KEY = process.env.INSIGHTSOCIAL_API_KEY!; const BASE = "https://api.insightsocial.app/v1"; for (const path of ["tiktok/profile", "youtube/channel", "twitter/profile"]) { const res = await fetch(`${BASE}/${path}?handle=nasa`, { headers: { "x-api-key": KEY }, }); const body = await res.json(); if (!body.success) { console.log(path, body.error.type, body.error.message); continue; } console.log( `${path.padEnd(20)} ${body.data.author.followers.toLocaleString().padStart(14)}` + ` cost ${body.credits_used} left ${body.credits_remaining}`, ); } ``` ```bash title="cURL" for path in tiktok/profile youtube/channel twitter/profile; do curl -s "https://api.insightsocial.app/v1/$path?handle=nasa" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" \ | python3 -c "import sys, json; r = json.load(sys.stdin); print('$path', r['data']['author']['followers'], 'cost', r['credits_used'])" done ``` ### Page through a list [#page-through-a-list] List endpoints return a `pagination` object next to `data`. Send `pagination.next_cursor` back as the `cursor` parameter, exactly as you received it, and stop when `has_more` is `false`. This walks the first three pages of NASA's followers on X, at 10 credits a page. ```python title="Python" import os import requests KEY = os.environ["INSIGHTSOCIAL_API_KEY"] URL = "https://api.insightsocial.app/v1/twitter/user/followers" params = {"handle": "nasa"} for page in range(3): body = requests.get(URL, params=params, headers={"x-api-key": KEY}).json() if not body["success"]: print(body["error"]["type"], body["error"]["message"]) break print("page", page + 1, "rows", len(body["data"].get("items", []))) pagination = body.get("pagination") or {} if not pagination.get("has_more"): break params["cursor"] = pagination["next_cursor"] ``` ```ts title="Node.js" const KEY = process.env.INSIGHTSOCIAL_API_KEY!; const url = new URL("https://api.insightsocial.app/v1/twitter/user/followers"); url.searchParams.set("handle", "nasa"); for (let page = 1; page <= 3; page++) { const body = await (await fetch(url, { headers: { "x-api-key": KEY } })).json(); if (!body.success) { console.log(body.error.type, body.error.message); break; } console.log("page", page, "rows", body.data.items?.length ?? 0); if (!body.pagination?.has_more) break; url.searchParams.set("cursor", body.pagination.next_cursor); } ``` Cursors start with `v2c.` and are opaque: do not parse or edit them. Send them back only as `cursor`, with the same other parameters as the first page, within 24 hours. Details in [Pagination](/docs/pagination). ## Check your balance [#check-your-balance] `GET /v1/credits` is free and returns your balance, this month's usage and how many free calls you have left. ```bash title="cURL" curl "https://api.insightsocial.app/v1/credits" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```json title="Response" { "success": true, "credits_used": 0, "credits_remaining": 380, "plan": { "tier": "free", "credits_per_month": 500, "resets_at": "2026-10-01T00:00:00Z" }, "usage": { "window_start": "2026-09-01T00:00:00Z", "used": 120, "used_export": 40, "used_api": 80 }, "pack_credits": 0, "free_calls": { "remaining": 4, "total": 10 }, "key": { "id": "5b0c1e2a-7d4f-4a8e-9c3b-2f6d1a0e8b7c", "name": "production" }, "request_id": "req_1a2b3c4d5e6f" } ``` The balance is shared with InsightSocial export credits, which is why `usage` splits `used_export` from `used_api`. To find endpoints without spending anything, query the catalogue at `GET /v1/endpoints`, which needs no key. ## Make a retry safe [#make-a-retry-safe] Add an `Idempotency-Key` header with a fresh UUID per logical operation. If a timeout makes you send the same request again, the replay comes back with `idempotent_replay: true` and costs 0 credits. ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/profile?handle=nasa" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" ``` ## When a call fails [#when-a-call-fails] Failures share the envelope, with `success: false` and an `error` object. Branch on `error.type`. ```json title="Response" { "success": false, "error": { "type": "INSUFFICIENT_CREDITS", "message": "This call needs up to 170 credits and 120 remain. Add credits: https://www.insightsocial.app/api/top-up?need=50&u=6f1c2b7e-0d4a-4c8e-9b21-3a5f7d9e1c40&via=api_402", "top_up_url": "https://www.insightsocial.app/api/top-up?need=50&u=6f1c2b7e-0d4a-4c8e-9b21-3a5f7d9e1c40&via=api_402" }, "request_id": "req_1a2b3c4d5e6f", "credits_used": 0, "credits_remaining": 120 } ``` A failed call is never charged. Retry only `RATE_LIMITED`, `CONCURRENCY_LIMIT`, `IDEMPOTENCY_IN_PROGRESS`, `SERVICE_UNAVAILABLE`, `UPSTREAM_ERROR`, `UPSTREAM_INVALID` and `INTERNAL_ERROR`; the rest fail the same way until you change the request. A `400 UNSUPPORTED_PARAMETER` names the parameter to remove in `error.param`. See [Errors](/docs/errors). ## Next steps [#next-steps] The cursor loop and the endpoints that page differently. Prices, metered endpoints, free calls and the shared cache. Every error type and which ones to retry. What each of the 22 platforms offers. --- # Rate limits (/docs/rate-limits) 60 requests per minute and 10 concurrent requests per API key, what a 429 looks like, and how to size a job. Each API key may send **60 requests per minute** and have **10 requests in flight** at once. Going over either limit returns a `429`, and a rejected request costs nothing. Beyond those two ceilings, what bounds your volume is your credit balance. ## The limits at a glance [#the-limits-at-a-glance] | Limit | Applies to | Value | When exceeded | | ------------ | ----------- | ------------------------------------ | ------------------------------------------------------------------- | | Request rate | Per API key | **60 requests / sliding 60 seconds** | `429 RATE_LIMITED` with `Retry-After` | | Concurrency | Per API key | **10 requests in flight** | `429 CONCURRENCY_LIMIT` with `Retry-After: 1` | | Credits | Per account | Your balance | `402 INSUFFICIENT_CREDITS` | | API keys | Per account | **25 keys** | Key creation is refused. See [Authentication](/docs/authentication) | The dashboard [Playground](https://www.insightsocial.app/portal/api/explorer) has its own allowance with the same numbers, so trying endpoints there does not eat into your keys' limits. ## Request rate: 60 per minute per key [#request-rate-60-per-minute-per-key] Every data request on a key counts toward a sliding 60-second window. That includes requests that end in a `402`, `404` or `405`. A `max_pages` walk is one request and takes one slot. None of these count: `GET /v1/credits`, `GET /v1/endpoints`, the bare `GET /v1`, and any request rejected for a missing or bad key, since authentication runs first. ```json title="Response" { "success": false, "error": { "type": "RATE_LIMITED", "message": "Too many requests on this key. Honour Retry-After, then back off with jitter." }, "request_id": "req_1a2b3c4d5e6f", "credits_used": 0, "credits_remaining": null } ``` `Retry-After` is the number of seconds until the oldest request in the window drops out, at least `1`. ## Concurrency: 10 in flight per key [#concurrency-10-in-flight-per-key] Separately, a key may have at most 10 open requests. This is not a time window: a slot frees the moment one of your requests returns, so an 11th request sent while 10 are open is rejected. ```json title="Response" { "success": false, "error": { "type": "CONCURRENCY_LIMIT", "message": "Too many calls in flight on this key. Retry shortly." }, "request_id": "req_1a2b3c4d5e6f", "credits_used": 0, "credits_remaining": null } ``` `Retry-After` is `1` on this one. The API sends no headers describing your remaining headroom. The only timing header is `Retry-After`. It comes with every `429`, and also with `409 IDEMPOTENCY_IN_PROGRESS` and some `503` responses. Pace yourself from your own counts, as described below. ## Credits are the volume limit [#credits-are-the-volume-limit] There is no daily or monthly request quota. What limits sustained work is your balance: the free plan includes 500 credits a month, Pro 10,000, and packs add more. Prices differ per endpoint and some are metered, so price every endpoint your job uses on [Endpoint pricing](/docs/endpoint-pricing) before you size it. See [Credits](/docs/credits) for how charging works. ## Handling a 429 [#handling-a-429] ### Read `error.type` [#read-errortype] `RATE_LIMITED` means you are sending too fast: slow the request rate. `CONCURRENCY_LIMIT` means too many requests are open at once: shrink the worker pool. They need different fixes. ### Wait for `Retry-After` [#wait-for-retry-after] Wait at least that many seconds before retrying. ### Back off with jitter [#back-off-with-jitter] If the retry also gets a `429`, double the wait and add random jitter so your workers do not all retry in the same instant. ### Cap the attempts [#cap-the-attempts] After a handful of attempts, give up and surface the error. ```ts title="Node.js" async function callWithBackoff(url: string, init: RequestInit, maxRetries = 5): Promise { for (let attempt = 0; ; attempt++) { const res = await fetch(url, init); // Only 429s are handled here. A 402 or another 4xx will not // change on retry, so return it straight away. if (res.status !== 429 || attempt >= maxRetries) return res; const retryAfter = Number(res.headers.get("Retry-After")) || 1; const backoff = retryAfter * 2 ** attempt; const jittered = backoff * (0.5 + Math.random() * 0.5); await new Promise((r) => setTimeout(r, jittered * 1000)); } } ``` The [Errors](/docs/errors) page has complete retry loops in cURL, Python and Node.js that also cover `503` and `500`. ## Sizing a job [#sizing-a-job] * Run at most **10 workers per key**. * Keep the total under **60 requests a minute**, which is one request a second on average. * Budget credits per page, not per job, and remember that metered calls hold the top of their price range while they run. * Walk paginated endpoints until `pagination.has_more` is `false`. See [Pagination](/docs/pagination). * Send an `Idempotency-Key` on each call so retries never pay twice. ## Next steps [#next-steps] Which failures to retry, with backoff loops. What each call costs and what is never charged. Key management. Cursor loops that stay inside the limits. --- # Response schema (/docs/response-schema) The InsightSocial API envelope under schema 2, what sits inside data, pagination, response headers, idempotent replays and fresh fetches. Every data endpoint answers in one success envelope, and every failure in one error envelope, so a single parser handles every platform. The two share only a few fields: **check `success` first**, then read the body as one or the other. The two account endpoints are the exception: `GET /v1/credits` returns a balance body of its own (it still carries `success`, `credits_used` and `credits_remaining`), and `GET /v1/endpoints` returns the catalogue in its own shape. This page describes **schema 2**, the shape every key gets from October 4, 2026. What changed from the previous shape is on [Schema 2](/docs/schema-2). ## Successful response [#successful-response] ```json title="Response" { "success": true, "platform": "tiktok", "endpoint": "/v1/tiktok/profile", "schema_version": "2", "data": { "author": { "id": "6772003040451462149", "username": "nasa", "display_name": "NASA", "followers": 9800000, "followers_approximate": null, "url": "https://www.tiktok.com/@nasa", "external_url": "https://www.nasa.gov", "last_post_at": "2026-10-03T14:10:18.000Z" } }, "unavailable": [], "credits_used": 10, "credits_remaining": 9990, "request_id": "req_d6ad52ab1f9f", "cached": false, "idempotent_replay": false, "charge_reason": "miss", "free_call": false } ``` The profile is trimmed here. Every field of each entity is on its [unified schema](/docs/schema/author) page. ### Envelope fields [#envelope-fields] These are the fields of a **successful** response. An error carries far fewer; see [Error response](#error-response). | Field | Type | On every success | Description | | ------------------- | ---------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `success` | `boolean` | yes | `true`. Also on every error, as `false`: branch on it first. | | `platform` | `string` | yes | The platform you called, such as `tiktok`. | | `endpoint` | `string` | yes | The path you called, such as `/v1/tiktok/profile`. | | `schema_version` | `string` | yes | `"2"`. The contract `data` follows. An error never carries it. | | `data` | `object` | yes | The result. Its shape depends on the endpoint; see [Inside `data`](#inside-data). | | `pagination` | `object` | no | List endpoints only. See [List endpoints](#list-endpoints). | | `unavailable` | `string[]` | yes | Fields this platform normally fills that this response could not, as paths into `data`. Empty when nothing is missing. See [Data availability](/docs/data-availability#unavailable). | | `credits_used` | `integer` | yes | Credits charged for this call. `0` for replays, free calls, empty results, `dry_run=1` and failures. | | `credits_remaining` | `integer` | yes | Your balance after this call. | | `request_id` | `string` | yes | Our identifier for this call, in the form `req_` plus 12 hex characters. | | `cached` | `boolean` | yes | `true` when the result came from the shared cache rather than a live fetch. | | `idempotent_replay` | `boolean` | yes | `true` when this is a replay of an earlier call with the same `Idempotency-Key`. | | `charge_reason` | `string` | yes | Why `credits_used` has the value it has. See below. | | `free_call` | `boolean` | yes | `true` when the call used one of your free calls, so `credits_used` is `0`. | ### `charge_reason` [#charge_reason] | Value | Meaning | Credits | | -------------- | ----------------------------------------------- | ------------------------------------------------------------------ | | `miss` | A live fetch | The endpoint's price, or for a metered endpoint what the call used | | `shared_cache` | Served from the shared cache | 2 | | `replay` | An idempotent replay of a call you already made | 0 | | `no_result` | Nothing to charge for, such as an empty result | 0 | | `dry_run` | A `dry_run=1` price quote. No data was fetched | 0 | The pricing rules are on [Credits](/docs/credits). ## Inside `data` [#inside-data] `data` holds one entity, or a page of them, under a key named after the entity: | Endpoint returns | `data` holds | Schema | | ------------------ | ---------------------- | ----------------------------------------- | | One post | `data.post` | [Post](/docs/schema/post) | | A list of posts | `data.items[].post` | [Post](/docs/schema/post) | | One profile | `data.author` | [Author and profile](/docs/schema/author) | | A list of profiles | `data.items[].author` | [Author and profile](/docs/schema/author) | | One comment | `data.comment` | [Comment](/docs/schema/comment) | | A list of comments | `data.items[].comment` | [Comment](/docs/schema/comment) | | A transcript | `data.transcript` | [Transcript](/docs/schema/transcript) | A list also carries these fields next to `items`: * **`data.total`**: the platform's own total, when it states one (a comment count, for example). It is not the size of this page, and it is `null` when the platform does not say. * **`data.truncated`**: `true` when the list is known to be cut short by the platform, `false` when the platform says it is complete, `null` when we cannot tell. On a Reddit comment tree it is `true` once the tree reaches Reddit's ten-level depth limit and otherwise `null`: Reddit leaves some branches behind "load more" links that the source does not count. To judge how complete a Reddit thread is, compare with the post's `engagement.comments` from `/v1/reddit/post`, which also counts deleted and removed comments. * **`data.ext`**: what the page says about itself beyond its rows, under the same conventions as an entity's `ext` (snake\_case keys, string ids, ISO times). Present only when the platform sends something; absent otherwise, so treat it as optional. The same rules hold everywhere inside `data`: * **Ids are strings.** Several platforms use ids above 2^53, which a JSON number would corrupt. Never parse an id as a number. * **Times are ISO 8601 in UTC**, ending in `Z`. * **`null` means not known.** A count the platform hides is `null`, never `0`. `0` means zero. * **`content.media_urls` is always an array** (or `null`), never a bare string. * **`ext` keys are snake\_case.** `ext` holds what one platform carries that the others cannot mean the same way. Treat every `ext` key as optional. Some long-tail endpoints (metrics, and lists with no matching entity) are marked **beta** on their reference page. They return the source's own structure under our naming rules: snake\_case keys, string ids, and ISO times where the source gives a timestamp. Some pass on figures the source itself computes, such as a `confidence` on `/v1/youtube/video/sponsors`, and a source's own date text (a local `datetime`, a `time_ago`) stays as the source wrote it. Their fields may change. `profile/full` is beta too, but its profile and posts are typed: `data.profile` is a [profile](/docs/schema/author) and each `data.posts[].post` is a [post](/docs/schema/post). It pages its posts with `cursor` like a list. Any other key under its `data` follows the beta rules above. The typed entities above carry no analysis of ours: no engagement rate, labels or relevance scores. Compute what you need from the raw counts; see [Schema 2](/docs/schema-2) for what was removed and the [creator engagement recipe](/docs/recipes/creator-engagement-scoring) for an engagement rate built from `engagement` and the author's `followers`. ### One schema [#one-schema] Every key gets schema 2, and it is the only shape served. An error has no `schema_version` field. See [Schema 2](/docs/schema-2) for what changed from the previous shape. ## Error response [#error-response] An error is a different, smaller body. It has no `platform`, `endpoint`, `schema_version`, `data`, `unavailable`, `cached` or `charge_reason`, so read `success` before anything else: ```json title="Response" { "success": false, "error": { "type": "UNSUPPORTED_PARAMETER", "message": "`relevance` is not supported: it asks for analysis, which is not part of schema 2. Remove it and retry. Nothing was charged.", "param": "relevance" }, "request_id": "req_80d197121a1e", "credits_used": 0, "credits_remaining": null } ``` | Field | Description | | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | `error.type` | A stable string to branch on. | | `error.message` | A readable explanation, often naming what to fix. Do not parse it. | | `error.param` | The query parameter at fault, when there is one. | | `request_id` | Quote it to support. | | `credits_used` | Always `0`: failed calls are never charged. | | `credits_remaining` | Your balance when we know it, otherwise `null` (for example on authentication failures, or on a request refused before we read your balance). | That is the whole body: `success`, `error` (`type`, `message`, and `param` when one parameter is at fault), `request_id`, `credits_used` and `credits_remaining`. ```ts title="Node.js" const body = await res.json(); if (!body.success) { // { error: { type, message, param? }, request_id, credits_used, credits_remaining } throw new Error(`${body.error.type}: ${body.error.message} (${body.request_id})`); } // Only now: body.schema_version, body.data, body.unavailable, body.pagination ``` **Not every error is in your Activity Log.** A request refused before it reaches a platform writes no log row: `400 UNSUPPORTED_PARAMETER`, `400 CURSOR_INVALID` and `CURSOR_EXPIRED`, authentication and rate-limit errors, idempotency conflicts and `402 INSUFFICIENT_CREDITS`. `dry_run=1` quotes are not logged either. Other errors, including the `400` parameter errors a platform returns, are logged with their status. The full list of types is on [Errors](/docs/errors). ## Response headers [#response-headers] | Header | Value | | --------------------- | --------------------------------------------------------------------------------------------- | | `X-Request-Id` | Same as `request_id` in the body. | | `X-Credits-Used` | Credits charged for this call. | | `X-Credits-Remaining` | Your balance after the call. Omitted when it is unknown, never sent as a placeholder `0`. | | `Retry-After` | Seconds to wait. Sent on `429`, on `409 IDEMPOTENCY_IN_PROGRESS` and on some `503` responses. | | `Cache-Control` | `no-store`. Do not cache API responses in a shared proxy. | CORS headers are also set, and `X-Request-Id`, `X-Credits-Used`, `X-Credits-Remaining` and `Retry-After` are exposed to browser code. Keys still belong on your server; see [Authentication](/docs/authentication). ## List endpoints [#list-endpoints] List responses put their rows in `data.items` and carry a `pagination` object at the root of the envelope: ```json title="Response" { "success": true, "platform": "twitter", "endpoint": "/v1/twitter/user/tweets", "schema_version": "2", "data": { "items": [ { "post": { "id": "2106502020849127865", "kind": null, "author": { "id": null, "username": "NASA" } } } ], "total": null, "truncated": null }, "pagination": { "next_cursor": "v2c.M-GEP84JXNZPqhQ0NlEOubhbuFGGiCK9…", "has_more": true, "page_size": 19 }, "unavailable": ["items[].post.author.id"], "credits_used": 10, "credits_remaining": 9980, "request_id": "req_161a29ec13ca", "cached": false, "idempotent_replay": false, "charge_reason": "miss", "free_call": false } ``` Here `unavailable` says that no row on this page carries an author id, though the platform has one. The rows are still valid; plan for `author.id` being `null` on this endpoint. | Field | Description | | ------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | `next_cursor` | Send it back as the `cursor` query parameter to get the next page. Starts with `v2c.`; pass it unchanged. `null` on the last page. | | `has_more` | `false` on the last page. Stop there. | | `page_size` | Rows on this page. | | `stopped_at` | Only on creator post lists called with `since` or `stop_at_id`. Says which boundary ended the walk: `since`, `known_id` or `end`. | The cursor is only valid as `cursor`, with the same endpoint and parameters, for 24 hours. The full loop is on [Pagination](/docs/pagination). ## Idempotent requests [#idempotent-requests] Send an `Idempotency-Key` header to make a call safe to retry. Use a fresh UUID for each logical operation. ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/profile?handle=khaby.lame" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" \ -H "Idempotency-Key: c3f9d27e-81b4-4e06-a5d2-94be0f6c1a78" ``` ```python title="Python" import os import uuid import requests res = requests.get( "https://api.insightsocial.app/v1/tiktok/profile", params={"handle": "khaby.lame"}, headers={ "x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"], "Idempotency-Key": str(uuid.uuid4()), }, ) body = res.json() print(body["idempotent_replay"], body["credits_used"]) ``` ```ts title="Node.js" const res = await fetch( "https://api.insightsocial.app/v1/tiktok/profile?handle=khaby.lame", { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY!, "Idempotency-Key": crypto.randomUUID(), }, }, ); const body = await res.json(); console.log(body.idempotent_replay, body.credits_used); ``` * A replay returns `idempotent_replay: true`, `charge_reason: "replay"` and `credits_used: 0`. * If the original call with the same key is still running, you get `409 IDEMPOTENCY_IN_PROGRESS` with `Retry-After`. Wait, then send the same key again. * Keys are scoped to your account. Reusing a key for a different request, or with a different schema, answers `409 IDEMPOTENCY_KEY_REUSED`. * A key must be at most 255 characters of letters, digits, `.`, `_`, `:` or `-`. A key that does not fit is ignored, and the call runs as an ordinary request. ## Force a fresh fetch [#force-a-fresh-fetch] Repeat calls can be served from the shared cache (`cached: true`) at 2 credits. To skip it and fetch live, send `Cache-Control: no-cache`, or add `fresh=1` to the query: ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/profile?handle=khaby.lame" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" \ -H "Cache-Control: no-cache" ``` A fresh fetch is always charged at the normal price. See [Credits](/docs/credits) for the shared cache. ## Next steps [#next-steps] The cursor loop, identical on every list endpoint. Every error type and whether to retry it. Prices, charge reasons and the shared cache. --- # Schema 2 (/docs/schema-2) The only response shape since October 4, 2026, and what changed from the previous one. Since **October 4, 2026** every API key gets **schema 2**, and it is the only shape served: one shape per entity (post, profile, comment, transcript) on every platform. The envelope is the same; what changed is inside `data`. Every response says which schema it follows: ```json { "success": true, "schema_version": "2", "data": { ... }, "unavailable": [] } ``` The previous shape is no longer served. An `InsightSocial-Version` header is ignored, and `/v1/openapi-legacy.json` is gone. ## What changed [#what-changed] | Before | Schema 2 | | ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | `computed` (engagement rate, language, category, estimated reach, `vs_creator`) on every item | Removed. | | `labels`, `relevance`, `label_share`, `labels_evidence`, `creator_baseline`, `comment_recency`, `dropped`, `_warnings` | Removed. What a response could not fill is listed in `unavailable` instead. | | `data.next_cursor` | Removed. Read `pagination.next_cursor`. | | Cursors `is.…` / `is2.…` | Cursors `v2c.…`. Send them back as `cursor`, with the same parameters, within 24 hours. | | Ids sometimes numbers | Always strings. | | Times as ISO strings or epoch numbers | Always ISO 8601 UTC, ending in `Z`. | | `content.media_urls` a string or an array | Always an array. | | Author id in `ext.author_id` (some platforms) | `author.id` on every post and comment, `null` where the source has none. | | Language in `ext.content_language` / `ext.default_language` | `language` on posts and comments. | | `ext.followers_approximate` | `followers_approximate` on profiles. | | Bio link in `ext.bio_link` | `external_url`. `url` is always the profile itself. | | `ext` keys in mixed case (YouTube) | snake\_case: `madeForKids` → `made_for_kids`. | | A top-level comment's `parent_id` set to the post id (X, Reddit) | `null`. Replies carry their parent comment's id. | | Reddit `author.display_name` holding the `t2_…` account id | `author.id`; `display_name` is `null`. | | YouTube comment `ext.replies_token` | Removed. Fetch replies with the comment's `id` as `continuationToken`. | New on posts: `kind`, the format, one of eight values: `text`, `image`, `carousel`, `video`, `short`, `live`, `article` or `link`. It is `null` when the source does not say and the format cannot be read without guessing. New values may be added; keep a default branch. Transcripts have one shape everywhere: `data.transcript` is `{ "language", "text", "segments": [{ "text", "start_seconds", "duration_seconds" }] }`, where it used to be a string on some platforms and a list on others. ## Parameters that now return 400 [#parameters-that-now-return-400] A parameter the endpoint does not have also answers `400 UNSUPPORTED_PARAMETER` (it used to be ignored and the call still charged). The ones below asked for analysis that schema 2 does not carry. They answer `400 UNSUPPORTED_PARAMETER`, with `error.param` naming the parameter, and nothing is charged: `label`, `label_evidence`, `relevance`, `relevance_threshold`, `relevant_to`, `judgments`, `fit`, `goal`, `fit_tokens`, `seen`, `brand`, `brand_description`, `offer`, `exclude` (except on `/v1/pinterest/trends`, where it filters terms), `brief`, `use`, `moments`, `format=stationery`, `q` on `/v1/tiktok/post/transcript` and `/v1/youtube/video/transcript` (it asked a question about the video), and `switch_from` on `/v1/twitter/search/tweets` and `/v1/reddit/search/comments`. Elsewhere `q` and `switch_from` are not refused. `dry_run=1` returns our price quote, charges nothing, and reports `charge_reason: "dry_run"`: ```json { "data": { "dry_run": { "credits_min": 50, "credits_max": 150 } } } ``` `credits_min` is the least one page can cost. `credits_max` is what the call would hold with those parameters (`limit`, `include` and the like), multiplied by `max_pages` when you send it. ## `unavailable` [#unavailable] A list of the fields this platform normally exposes that this response could not fill, as paths into `data`, for example `"items[].post.author.id"`. Empty when nothing is missing. Fields a platform never shows (YouTube share counts, Reddit view counts) are not listed: they are `null` everywhere and described on each platform's page. ## Prices [#prices] Unchanged: a call is still charged what it used. While a metered call runs, the hold on your balance is lower on 24 endpoints, because the analysis they no longer do cannot be charged, and higher on one, `/v1/tiktok/search/users` (up to 1,310 credits), whose real maximum is above what it used to hold. ## The full schema [#the-full-schema] The OpenAPI document at [`/v1/openapi.json`](https://api.insightsocial.app/v1/openapi.json) types every response. --- # Testing your integration (/docs/testing-your-integration) Test against the live API without surprises. What is free, what is billed, and which paths to check before launch. Begin with a call that costs nothing. It proves your key works and records your starting balance before any billed test. ```bash title="cURL" curl --include "https://api.insightsocial.app/v1/credits" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```json title="Response" { "success": true, "credits_used": 0, "credits_remaining": 500, "plan": { "tier": "free", "credits_per_month": 500, "resets_at": "2026-10-01T00:00:00.000Z" }, "usage": { "window_start": "2026-09-01T00:00:00.000Z", "used": 0, "used_export": 0, "used_api": 0 }, "pack_credits": 0, "free_calls": { "remaining": 10, "total": 10 }, "key": { "id": "3f6c2a8e-7b41-4d0f-9a52-1c8e5d7b9f20", "name": "staging" }, "request_id": "req_1a2b3c4d5e6f" } ``` Check for status `200`, `success: true` and `credits_used: 0`. Keep the `request_id` in your test log. ## There is no sandbox [#there-is-no-sandbox] Every test runs against the real API, with the same prices, caching and rate limits as production. Keys come in two forms, `isk_live_…` and `isk_test_…`. They behave identically: an `isk_test_` key reaches the same data and **spends real credits** from the same balance. The prefix is a label for your own bookkeeping, not a test mode. Use fixtures for parser tests that must be deterministic, and a small number of budgeted live calls to prove the end-to-end path works today. Neither proves that a source will be available tomorrow. ## Use a separate test key [#use-a-separate-test-key] Create a key just for development or staging at [Dashboard → API keys](https://www.insightsocial.app/portal/api/keys) and keep it apart from production. Store it as `INSIGHTSOCIAL_API_KEY` in a server-side secret. Keep it out of source control, browser code, snapshots and logs. A separate key lets you revoke it without touching production, and it has its own rate limits. It does not have its own budget: keys cannot be capped, and every key spends from the account balance. Record the balance before and after each test run, and revoke the key if it ever shows up in test output. See [Authentication](/docs/authentication). ## Free checks first [#free-checks-first] These cost nothing: | Check | What it proves | | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `GET /v1/endpoints` | The catalogue, prices and parameters. Needs no key, so it does not test yours. | | `GET /v1/credits` | Your key is valid. Returns balance, plan and free calls left. | | `dry_run=1` on any data endpoint | Returns the price range in `data.dry_run` (`credits_min`, `credits_max`) without running the call. `credits_max` includes any `max_pages` you send. `charge_reason` is `dry_run`. | | Any call that returns an error | Errors are never charged. That includes `400 UNSUPPORTED_PARAMETER`, so sending a parameter schema 2 refuses is a free way to find it. | A `dry_run=1` call looks like this: ```json title="Response" { "success": true, "platform": "youtube", "endpoint": "/v1/youtube/channel/videos", "schema_version": "2", "data": { "dry_run": { "credits_min": 10, "credits_max": 20 } }, "unavailable": [], "credits_used": 0, "credits_remaining": 480, "request_id": "req_2ac2c2b769ef", "cached": false, "idempotent_replay": false, "charge_reason": "dry_run", "free_call": false } ``` Then make one real call to check auth, transport and your parser against the live service: ```bash title="cURL" curl --include "https://api.insightsocial.app/v1/tiktok/profile?handle=natgeo" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` This endpoint costs 10 credits. On a new account it may use one of your 10 lifetime free calls instead (`free_call: true`, `credits_used: 0`). Read `credits_used` and `charge_reason` rather than assuming what was billed, and keep live calls out of unit tests and pull-request loops. Check that the body says `"schema_version": "2"`: that is the contract these docs describe. See [Schema 2](/docs/schema-2). ## Try calls in the Playground [#try-calls-in-the-playground] The [Playground](https://www.insightsocial.app/portal/api/explorer) in your dashboard runs any endpoint from the browser, signed in as you, with no key to paste. Use it to see real responses and prices before you write code. Its calls are real and are charged exactly like API calls. ## Test fixtures, nulls and unavailable fields [#test-fixtures-nulls-and-unavailable-fields] Keep small response fixtures in your own test suite, with keys and unneeded personal data removed. This one is trimmed from a real X response and covers the states a parser must tell apart: ```json title="Success fixture" { "success": true, "platform": "twitter", "endpoint": "/v1/twitter/user/tweets", "schema_version": "2", "data": { "items": [ { "post": { "id": "2106502020849127865", "url": "https://x.com/NASA/status/2106502020849127865", "kind": null, "content": { "text": "RT @Astro_Jessica: Room with a view. …", "media_urls": null, "thumbnail_url": null, "duration_seconds": null }, "author": { "id": null, "username": "NASA", "display_name": "NASA", "avatar_url": "https://pbs.twimg.com/…", "verified": true }, "engagement": { "views": 40169, "likes": 0, "comments": 0, "shares": 572, "saves": 0 }, "flags": { "nsfw": null, "spoiler": null, "pinned": false, "deleted": false, "likes_hidden": null, "comments_hidden": null, "shares_hidden": null, "views_hidden": null, "saves_hidden": null }, "published_at": "2026-10-03T21:49:53.000Z", "language": "en", "ext": { "author_followers": 92378243, "quote_count": 0 } } } ], "total": null, "truncated": null }, "pagination": { "next_cursor": "v2c.M-GEP84JXNZPqhQ0…", "has_more": true, "page_size": 19 }, "unavailable": ["items[].post.author.id"], "credits_used": 10, "credits_remaining": 490, "request_id": "req_161a29ec13ca", "cached": false, "idempotent_replay": false, "charge_reason": "miss", "free_call": false } ``` Assert each case on its own: 1. `schema_version` is `"2"`. Fail the test on anything else, so a key that is still on the old shape is caught early. 2. A present value, such as `post.author.username`. 3. A `null`, such as `post.kind` here: the field exists but this source did not say. `null` means "not known"; `0` means zero. 4. A field listed in `unavailable`. Here `items[].post.author.id` is `null` on every row of the page, and the response says so. Record `unavailable` per call instead of judging completeness from nulls. 5. `ext`: platform-specific keys in snake\_case. Check that a key exists before reading it. 6. Ids are strings, even when they look like numbers. Keep them as strings: several platforms use ids above 2^53. 7. Times are ISO 8601 in UTC, ending in `Z`. 8. `post.kind` is one of `text`, `image`, `carousel`, `video`, `short`, `live`, `article`, `link`, or `null`. New values may be added, so your code needs a default branch. See [Response schema](/docs/response-schema) for the full envelope. For lists, test a one-page and a multi-page walk: send `pagination.next_cursor` back unchanged as `cursor` and stop on `has_more: false`. See [Pagination](/docs/pagination). Keep error fixtures too, and branch on `error.type`: ```json title="Error fixture" { "success": false, "error": { "type": "RATE_LIMITED", "message": "Too many requests on this key. Honour Retry-After, then back off with jitter." }, "request_id": "req_9a8b7c6d5e4f", "credits_used": 0, "credits_remaining": null } ``` Add one for every error type you handle: at least `INVALID_API_KEY`, `INSUFFICIENT_CREDITS`, `RATE_LIMITED`, `CONCURRENCY_LIMIT` and `SERVICE_UNAVAILABLE`. Schema 2 adds five more worth a fixture each: | `error.type` | Status | When | | ------------------------ | ------ | --------------------------------------------------------------------------------------- | | `UNSUPPORTED_PARAMETER` | 400 | A parameter that asked for analysis. `error.param` names it. Nothing is charged. | | `CURSOR_INVALID` | 400 | The cursor was not issued by this API, is malformed, or belongs to a different request. | | `CURSOR_EXPIRED` | 400 | The cursor is more than 24 hours old. Start again without one. | | `UPSTREAM_INVALID` | 503 | The source returned a body we could not serve. Nothing is charged. Retry. | | `IDEMPOTENCY_KEY_REUSED` | 409 | An `Idempotency-Key` reused with different parameters, or across schemas. | ```json title="UNSUPPORTED_PARAMETER fixture" { "success": false, "error": { "type": "UNSUPPORTED_PARAMETER", "message": "`relevance` is not supported: it asks for analysis, which is not part of schema 2. Remove it and retry. Nothing was charged.", "param": "relevance" }, "request_id": "req_80d197121a1e", "credits_used": 0, "credits_remaining": null } ``` See [Error handling](/docs/errors) and the retry wrapper in the [Production checklist](/docs/production-checklist). ## Test repeat calls and forced fetches [#test-repeat-calls-and-forced-fetches] Send the same call twice: ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/profile?handle=natgeo" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" curl "https://api.insightsocial.app/v1/tiktok/profile?handle=natgeo" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` Each call may come back as a `miss` at the full price, or as `shared_cache` (`cached: true`) at 2 credits. Both calls are charged: a repeat is a new call. Assert on the `charge_reason` and `credits_used` you actually receive. See [Caching](/docs/caching). Test a forced fetch only when you need one, and budget it at the endpoint's full price: ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/profile?handle=natgeo" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" \ -H "Cache-Control: no-cache" ``` A successful forced fetch skips the shared cache: assert `charge_reason: "miss"` and the normal charge. ## Test retries with an Idempotency-Key [#test-retries-with-an-idempotency-key] Send the same call twice with one key: ```bash title="cURL" IDEMPOTENCY_KEY="$(uuidgen)" curl "https://api.insightsocial.app/v1/tiktok/profile?handle=nasa" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" \ -H "Idempotency-Key: $IDEMPOTENCY_KEY" curl "https://api.insightsocial.app/v1/tiktok/profile?handle=nasa" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" \ -H "Idempotency-Key: $IDEMPOTENCY_KEY" ``` The second response should have `idempotent_replay: true`, `charge_reason: "replay"` and `credits_used: 0`. If the second request arrives while the first is still running, expect `409 IDEMPOTENCY_IN_PROGRESS`; wait for `Retry-After` and send it again. Use a new key for every distinct call. A key first used with one schema answers `409 IDEMPOTENCY_KEY_REUSED` when reused with the other. See [Production checklist](/docs/production-checklist#make-retries-safe). ## Pre-production checklist [#pre-production-checklist] * [ ] The test key is separate from production, and the balance is recorded before and after each run. * [ ] The suite lists each endpoint, its current price, and the most calls it will make. * [ ] Free checks (`/v1/credits`, `/v1/endpoints`, `dry_run=1`) run before any billed call. * [ ] Every response is checked for `"schema_version": "2"`. * [ ] Success and error fixtures cover values, `null`, absent `ext` keys, `unavailable` entries, string ids, ISO times and an unknown `kind`. * [ ] No request sends a parameter that schema 2 refuses. See [Schema 2](/docs/schema-2#parameters-that-now-return-400). * [ ] Pagination tests stop on `has_more: false`, return the cursor unchanged with the same parameters, and restart on `CURSOR_EXPIRED`. * [ ] Retry tests branch on `error.type`, use bounded delays, and resend the same cursor. * [ ] Repeat-call tests check `charge_reason`, `cached` and `credits_used`. * [ ] Forced fetches are budgeted as billed calls. * [ ] Idempotency tests replay one identical call and use a new key for anything else. * [ ] Logs tie together status, `request_id`, `error.type`, charge reason, credits and attempt count. * [ ] Production keys never enter the test environment or its output. ## Next steps [#next-steps] Turn these tests into release gates. The cost of every call in your test plan. The success and error envelopes your fixtures should match. --- # API reference (/docs/api-reference) Every endpoint, with its parameters, its price and a request you can send from the page. Every data endpoint is a `GET` on `https://api.insightsocial.app/v1/{platform}/{resource}` with your key in the `x-api-key` header. Each page lists the parameters, the price in credits and the response, and its request panel sends a real call with your key. There is no sandbox. A request sent from these pages is charged like any other call. Free ways to check a call first are on [Testing your integration](/docs/testing-your-integration). Your balance, and the public endpoint catalogue. 37 endpoints. 67 endpoints. 15 endpoints. 26 endpoints. 14 endpoints. 6 endpoints. 4 endpoints. 3 endpoints. 2 endpoints. 3 endpoints. 4 endpoints. 1 endpoint. 5 endpoints. 3 endpoints. 8 endpoints. 6 endpoints. 7 endpoints. 6 endpoints. 6 endpoints. 5 endpoints. 1 endpoint. 2 endpoints. Using an AI agent? Give it `https://www.insightsocial.app/docs/api-reference.md`: every endpoint on one Markdown page, with its path and required parameters. See [Using an AI agent](/docs/ai-agents). The whole table of prices is on [Endpoint pricing](/docs/endpoint-pricing). The same catalogue as JSON, free and without a key: `GET https://api.insightsocial.app/v1/endpoints`. --- # Search Douyin videos by keyword (/docs/how-to/douyin-search) Find Douyin videos by keyword, with caption, creator, likes, comments, shares, saves, music and duration. 50 credits per video returned. To search Douyin videos by keyword, call `GET /v1/douyin/search` with a `query` in Chinese or English. One call returns up to 25 videos, 10 by default, each with its caption and hashtags, creator, like, comment, share and save counts, music ID, cover image, video URL and duration. It is metered at 50 to 1,250 credits per call: the range scales with `limit`, which works out to 50 credits per video, so the default 10 videos cost 500. 50 to 1,250 credits per call: 50 at `limit=1`, 1,250 at `limit=25`. The sample below used the default `limit` of 10 and was charged 500. When the call starts, the most it can cost with your `limit` is held; you are charged what it used and the rest is released. Add `dry_run=1` to get a free quote first. Asking the same search again within 1 hour is answered from the shared cache for 2 credits. Failed calls and empty results are free. ## Which parameters can I set? [#which-parameters-can-i-set] | Parameter | Values | | ----------- | ------------------------------------------------------------------------ | | `query` | Required. The search keywords, for example `美食` (food) or `coffee`. | | `limit` | Videos to return, 1 to 25. Default 10. | | `sort` | `relevance` (default), `most_liked` or `latest`. | | `published` | Recency window: `all` (default), `day`, `week` or `half_year`. | | `duration` | Video length: `all` (default), `under_1m`, `one_to_five_m` or `over_5m`. | ## Make the request [#make-the-request] ```bash title="cURL" curl -G "https://api.insightsocial.app/v1/douyin/search" \ --data-urlencode "query=美食" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python title="Python" import os import requests res = requests.get( "https://api.insightsocial.app/v1/douyin/search", params={"query": "美食", "limit": 10, "sort": "most_liked"}, headers={"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]}, timeout=120, ) for item in res.json()["data"]["items"]: post = item["post"] print(post["engagement"]["likes"], post["engagement"]["shares"], post["url"]) ``` ```ts title="Node.js" const url = new URL("https://api.insightsocial.app/v1/douyin/search"); url.searchParams.set("query", "美食"); url.searchParams.set("limit", "10"); url.searchParams.set("sort", "most_liked"); const body = await (await fetch(url, { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY! } })).json(); for (const { post } of body.data.items) console.log(post.engagement.likes, post.engagement.shares, post.url); ``` ## What comes back [#what-comes-back] A real response from 2026-10-14, shortened: one video instead of 10, the caption and long URLs cut, and the creator replaced with a placeholder. ```json title="Response (shortened)" { "success": true, "endpoint": "/v1/douyin/search", "schema_version": "2", "data": { "items": [ { "post": { "id": "7644834211292280293", "url": "https://www.douyin.com/video/7644834211292280293", "kind": "video", "content": { "text": "简单几步教你做出五⭐️级酒店的酸辣柠檬虾 #酸辣柠檬虾 #柠檬虾做法 …", "media_urls": ["https://api-play.amemv.com/aweme/v1/play/?video_id=…"], "thumbnail_url": "https://p3-sign.douyinpic.com/tos-cn-p-0015c000-ce/…", "duration_seconds": 17.3 }, "author": { "id": "example_user_id", "username": "example_user", "display_name": "Example User", "verified": false }, "engagement": { "views": null, "likes": 3111106, "comments": 43865, "shares": 1765351, "saves": 2519903 }, "published_at": "2026-05-28T07:01:10.000Z", "ext": { "music_id": "7587240130655537202", "author_followers": 711275, "download_count": 34926 } } } ], "total": null }, "pagination": { "next_cursor": null, "has_more": false, "page_size": 10 }, "unavailable": [], "credits_used": 500 } ``` | Field | What it holds | | --------------------------- | -------------------------------------------------------------------- | | `data.items[].post` | One video in the shared [post shape](/docs/schema/post). | | `post.content.text` | The caption, hashtags included. | | `post.content.media_urls` | A playback URL for the video file. | | `post.engagement` | Likes, comments, shares and saves. | | `post.author` | The creator: numeric ID, Douyin ID, nickname, avatar, verified flag. | | `post.ext.author_followers` | The creator's follower count. | | `post.ext.music_id` | The sound the video uses. | | `post.ext.download_count` | How many times the video was downloaded. | ## What are the limits? [#what-are-the-limits] * **25 videos per search.** The endpoint does not paginate: `has_more` was `false` in the sample. Use different keywords, `sort` orders or `published` windows to reach more videos. * **No view counts.** `engagement.views` is `null` on every video in the sample, which means unknown, not zero. * **No total.** `data.total` is `null`: the search does not say how many videos match. * **Douyin ID can be missing.** `author.username` was `null` for 4 of the 10 creators in the sample. `author.id`, the numeric user ID, was always set. * **Short-lived media links.** The cover image URLs carry an expiry time, about two weeks after the call in the sample. Download what you need instead of storing the links. * **Price per video.** The cost grows with `limit`, so ask for the number of videos you need, not the maximum. ## What can I build with it? [#what-can-i-build-with-it] * **Market research in China.** Search a product or category with `sort=most_liked` to see which videos and hashtags lead it. * **Creator discovery.** Rank the authors in your results by `ext.author_followers`, then pass `author.id` as `id` to `GET /v1/douyin/profile` (60 credits) for the full profile. * **Trend checks.** Run the same keyword with `published=week` and `sort=latest` each week to see what is new. The other Douyin endpoints pick up where search stops: `search/users` (50 to 1,250 credits) finds creators instead of videos, `post` (100) reads one video, `post/comments` (20 to 1,000) and `comment/replies` (50 to 2,500) read its comments, `profile` (60) and `profile/posts` (50 to 1,250) cover a creator, and `trending` (250) returns the live hot-search board. ## Related [#related] * [`GET /v1/douyin/search` reference](/docs/api-reference/douyin/search): every parameter and field. * [`GET /v1/douyin/search/users`](/docs/api-reference/douyin/search-users): search creators instead of videos. * [`GET /v1/douyin/trending`](/docs/api-reference/douyin/trending): the live hot-search board. * [Douyin endpoints](/docs/platforms/douyin): everything the API covers on Douyin. --- # How-to guides (/docs/how-to) Short answers to "how do I get this data by API?" for 14 jobs other APIs don't cover, from TikTok likes to Douyin search, each with code and its price. Each guide answers one question: how to get one kind of public social data through the InsightSocial API. It names the endpoint, shows a working request in cURL, Python and Node.js, shows a real response (shortened, with private accounts replaced by placeholders), and states the price in credits and the limits before you spend anything. These are jobs most social data APIs, and the platforms' own APIs, don't offer. For full builds that combine several endpoints, see [Recipes](/docs/recipes). ## TikTok [#tiktok] | Guide | Endpoint | Credits | | -------------------------------------------------------------------------------------- | ---------------------------------- | ----------- | | [Get the videos a TikTok user has liked](/docs/how-to/tiktok-videos-a-user-liked) | `GET /v1/tiktok/user/liked` | 10 per page | | [Find TikTok creators similar to one you know](/docs/how-to/tiktok-similar-creators) | `GET /v1/tiktok/similar` | 50 | | [Get TikTok videos tagged at a location](/docs/how-to/tiktok-videos-by-location) | `GET /v1/tiktok/location/posts` | 10 per page | | [Read on-screen text from TikTok videos](/docs/how-to/read-on-screen-text-from-videos) | `GET /v1/tiktok/video/screen-text` | 50 | ## LinkedIn [#linkedin] | Guide | Endpoint | Credits | | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | ----------------- | | [Get the employees of a LinkedIn company](/docs/how-to/linkedin-company-employees) | `GET /v1/linkedin/company/people` | 100 per page | | [Get the people who reacted to or reposted a LinkedIn post](/docs/how-to/linkedin-post-reactions-and-reposts) | `GET /v1/linkedin/post/reactions`, `GET /v1/linkedin/post/reposts` | 100 / 50 per page | | [Check when a LinkedIn member was last active](/docs/how-to/linkedin-last-active) | `GET /v1/linkedin/profile/activity` | 50 | | [Get the posts in a LinkedIn group](/docs/how-to/linkedin-group-posts) | `GET /v1/linkedin/group/posts` | 50 per page | ## YouTube, Reddit and Pinterest [#youtube-reddit-and-pinterest] | Guide | Endpoint | Credits | | ------------------------------------------------------------------------------------ | -------------------------------- | ----------- | | [Get a YouTube channel's business email](/docs/how-to/youtube-channel-email) | `GET /v1/youtube/channel/about` | 250 | | [Search Reddit comments by keyword](/docs/how-to/reddit-comment-search) | `GET /v1/reddit/search/comments` | 10 per page | | [Get Pinterest Trends for a country](/docs/how-to/pinterest-trends) | `GET /v1/pinterest/trends` | 100 | | [Get Pinterest save counts for any URL](/docs/how-to/pinterest-save-counts-for-urls) | `GET /v1/pinterest/url-stats` | 10 | ## Chinese platforms [#chinese-platforms] | Guide | Endpoint | Credits | | ---------------------------------------------------------------------------------------- | ---------------------------- | ------------ | | [Search Xiaohongshu (RedNote) notes by keyword](/docs/how-to/xiaohongshu-rednote-search) | `GET /v1/xiaohongshu/search` | 50 per note | | [Search Douyin videos by keyword](/docs/how-to/douyin-search) | `GET /v1/douyin/search` | 50 per video | ## How is a call priced? [#how-is-a-call-priced] Every guide states its price. Failed calls, empty results and `dry_run=1` quotes are free. Asking the same thing again soon after is answered from the shared cache for 2 credits. Where a price is a range, the endpoint is metered: the most the call can cost is held when it starts and you pay what it used. A new account's first 10 calls are free on any endpoint priced at 100 credits or less. See [Credits](/docs/credits). --- # Get the employees of a LinkedIn company (/docs/how-to/linkedin-company-employees) List the LinkedIn members who work at a company, with headline, location and profile URL, by company ID. 100 credits per page of 10. To list a company's employees on LinkedIn, call `GET /v1/linkedin/company/people` with the company's numeric `company_id`. It returns the members who list the company as their employer, 10 a page, each with name, headline, location, profile picture, profile URL and premium and Top Voice flags, plus the total number of such members. A plain page costs 100 credits. Metered at 100–500 credits a page. A plain page of 10 costs 100 credits, so 10 pages (100 people) cost 1,000 credits. Adding `include=profile` joins each row to the member's profile, so the call holds up to 500 credits when it starts and you're charged what it used. Send `dry_run=1` for a free quote. Asking for the same page again within 6 hours is answered from the shared cache for 2 credits. Failed calls and empty results are free. ## How do I find the company ID? [#how-do-i-find-the-company-id] Call `GET /v1/linkedin/company` (50 credits) with the company page URL, for example `https://www.linkedin.com/company/microsoft/`. It returns the numeric company ID that this endpoint needs. Microsoft's is `1035`. If you only know the company's website, `GET /v1/linkedin/company/by-domain` looks the page up from the domain. ## Make the request [#make-the-request] ```bash title="cURL" curl "https://api.insightsocial.app/v1/linkedin/company/people?company_id=1035" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python title="Python" import os import requests res = requests.get( "https://api.insightsocial.app/v1/linkedin/company/people", params={"company_id": "1035"}, headers={"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]}, timeout=120, ) body = res.json() print(body["data"]["total"], "members list this company") for item in body["data"]["items"]: person = item["author"] print(person["display_name"], "|", person["bio"], "|", person["location"], person["url"]) ``` ```ts title="Node.js" const url = new URL("https://api.insightsocial.app/v1/linkedin/company/people"); url.searchParams.set("company_id", "1035"); const body = await (await fetch(url, { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY! } })).json(); console.log(`${body.data.total} members list this company`); for (const { author } of body.data.items) console.log(author.display_name, "|", author.bio, "|", author.location, author.url); ``` ## What comes back [#what-comes-back] A real response from 2026-10-14 for Microsoft (`company_id=1035`), shortened: one person instead of 10, long URLs and the cursor cut, and the member replaced with a placeholder. ```json title="Response (shortened)" { "success": true, "endpoint": "/v1/linkedin/company/people", "schema_version": "2", "data": { "items": [ { "author": { "id": "ACoAAAF7Yz…", "username": "example_user", "display_name": "Example User", "avatar_url": "https://media.licdn.com/dms/image/v2/…", "bio": "Software Engineer @ Microsoft", "verified": false, "followers": null, "followers_approximate": null, "following": null, "url": "https://www.linkedin.com/in/example_user", "location": "United States", "joined_at": null, "ext": { "urn": "ACoAAAF7Yz…", "is_top_voice": false, "is_premium": true } } } ], "total": 89216, "truncated": null }, "pagination": { "next_cursor": "v2c.s9XmZtLY…", "has_more": true, "page_size": 10 }, "unavailable": ["items[].author.following", "items[].author.joined_at"], "credits_used": 100 } ``` | Field | What it holds | | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | | `data.items[].author` | One member in the shared [author shape](/docs/schema/author): name, handle, avatar, profile URL. | | `author.bio` | The member's LinkedIn headline, usually their role and employer. | | `author.location` | Where the member says they are, such as `United States` or `Seattle, WA`. | | `author.followers` | Follower count. Filled on only a few rows, and then approximate (`followers_approximate: true`, for example `9000`). | | `author.ext.is_premium`, `is_top_voice` | Whether the member has LinkedIn Premium and the Top Voice badge. | | `data.total` | How many members list the company. 89,216 for Microsoft here. | ## How do I get more than 10 people? [#how-do-i-get-more-than-10-people] Send `pagination.next_cursor` back as `cursor`, with the same `company_id`, and stop when `pagination.has_more` is `false`. Each plain page is 100 credits. ```python title="Python: read up to 10 pages" import os import requests BASE = "https://api.insightsocial.app/v1" HEADERS = {"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]} params = {"company_id": "1035"} people = [] for _ in range(10): body = requests.get(f"{BASE}/linkedin/company/people", params=params, headers=HEADERS, timeout=120).json() people += [item["author"] for item in body["data"]["items"]] if not body["pagination"]["has_more"]: break params["cursor"] = body["pagination"]["next_cursor"] ``` A large company has tens of thousands of members, so set a page limit before you start. See [Pagination](/docs/pagination) for the full rules. ## What are the limits? [#what-are-the-limits] * **Self-reported employer.** The list is members who list the company on their profile. Headlines are the member's own text and can name a different employer: one row in our Microsoft test had a headline naming another company. Check `GET /v1/linkedin/profile/experiences` when current employment matters. * **Follower counts are sparse.** `followers` was `null` on 8 of 10 rows in our test, and approximate on the other 2. `null` means unknown, not zero. Add `include=profile` to get the exact follower count and the connection count (`following`) for every row, at a higher price. * **No join date.** `following` and `joined_at` are `null` on a plain call. * **`limit` skips rows.** `limit` (1 to 10) keeps the top N rows of a page, but the cursor still moves past all 10, so the skipped rows are not on the next page. * **No filters.** You can't filter by title or location here. Use `GET /v1/linkedin/search/people` with `current_company` and `title` to narrow the list. ## What can I build with it? [#what-can-i-build-with-it] * **Account-based prospecting.** List the people at a target account, then filter headlines for the roles you sell to. * **Hiring and talent research.** See which roles a company's members list and where they are based. * **Org snapshots.** Store `data.total` per company each month to track how many members list it, alongside `GET /v1/linkedin/company/employees-count`. ## Related [#related] * [`GET /v1/linkedin/company/people` reference](/docs/api-reference/linkedin/company-people): every parameter and field. * [`GET /v1/linkedin/company`](/docs/api-reference/linkedin/company): look up a company and get its `company_id`. * [`GET /v1/linkedin/search/people`](/docs/api-reference/linkedin/search-people): search members across LinkedIn with filters. * [LinkedIn endpoints](/docs/platforms/linkedin): everything the API covers on LinkedIn. --- # Get the posts in a LinkedIn group (/docs/how-to/linkedin-group-posts) Read a LinkedIn group's discussion feed: post text, author, headline, likes, comments, shares and publish time, by group ID. 50 credits per page. To read the posts in a LinkedIn group, call `GET /v1/linkedin/group/posts` with the group's numeric `group_id`. Each post comes back with its text, the author's name and headline, like, comment and share counts with a breakdown by reaction type, attached media, and when it was published. It costs 50 credits a page of up to 10 posts. LinkedIn's own Groups API is open only to approved partners, so for most developers this is the way to read a group feed. 50 credits per page of up to 10 posts. Reading 5 pages (50 posts) costs 250 credits. Asking for the same page again within 6 hours is answered from the shared cache for 2 credits. Failed calls and empty results are free. ## How do I find the group ID? [#how-do-i-find-the-group-id] The `group_id` is the number in the group's URL: `https://www.linkedin.com/groups/62438/` has the ID `62438`. Open the group on LinkedIn and copy the number after `/groups/`. To check a group before reading its feed, `GET /v1/linkedin/group` (50 credits) returns its name, description, member count, posting rules, owners, and whether it is public. ## Make the request [#make-the-request] ```bash title="cURL" curl "https://api.insightsocial.app/v1/linkedin/group/posts?group_id=62438" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python title="Python" import os import requests res = requests.get( "https://api.insightsocial.app/v1/linkedin/group/posts", params={"group_id": "62438"}, headers={"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]}, timeout=120, ) for item in res.json()["data"]["items"]: post = item["post"] print(post["published_at"], post["author"]["display_name"], post["engagement"]["likes"], post["url"]) ``` ```ts title="Node.js" const url = new URL("https://api.insightsocial.app/v1/linkedin/group/posts"); url.searchParams.set("group_id", "62438"); const body = await (await fetch(url, { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY! } })).json(); for (const { post } of body.data.items) { console.log(post.published_at, post.author.display_name, post.engagement.likes, post.url); } ``` ## What comes back [#what-comes-back] A real response from 2026-10-14, shortened: one post instead of 10, long URLs cut, and the author replaced with a placeholder. ```json title="Response (shortened)" { "success": true, "endpoint": "/v1/linkedin/group/posts", "schema_version": "2", "data": { "items": [ { "post": { "id": "urn:li:groupPost:62438-7515763090810978304", "url": "https://www.linkedin.com/feed/update/urn:li:activity:7515763091653943296", "content": { "text": "This article examines the risks of autonomous AI agents…", "media_urls": null }, "author": { "id": "ACoAAACQPQ…", "username": "example_user", "display_name": "Example User", "avatar_url": "https://media.licdn.com/dms/image/v2/…" }, "engagement": { "views": null, "likes": 2, "comments": 0, "shares": 0, "saves": null }, "published_at": "2026-10-13T00:00:00.000Z", "ext": { "reaction_counts": [{ "count": 2, "type": "LIKE" }], "post_type": "ugc", "published_at_precision": "day", "author_headline": "Founder at an analytics consultancy", "author_type": "user" } } } ], "total": 10, "truncated": null }, "pagination": { "next_cursor": null, "has_more": false, "page_size": 10 }, "unavailable": [], "credits_used": 50 } ``` | Field | What it holds | | --------------------------------- | -------------------------------------------------------------------------------------------------------- | | `data.items[].post` | One group post in the shared [post shape](/docs/schema/post): text, media, author, counts, publish time. | | `post.id` | The group post's ID (`urn:li:groupPost:…`). | | `post.url` | The post's activity URL. Pass it to `post/comments` or `post/reactions` to read the discussion under it. | | `post.ext.reaction_counts` | Reactions split by type: `LIKE`, `PRAISE` and so on. | | `post.ext.author_headline` | The author's LinkedIn headline, so you see role and company without a profile call. | | `post.ext.published_at_precision` | How exact `published_at` is: `hour` or `day`. LinkedIn shows relative times, so the time is rounded. | ## How do I get older posts? [#how-do-i-get-older-posts] Send `pagination.next_cursor` back as `cursor`, with the same `group_id`, and stop when `pagination.has_more` is `false`. Each page is 50 credits. ```python title="Python: read up to 5 pages" import os import requests BASE = "https://api.insightsocial.app/v1" HEADERS = {"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]} params = {"group_id": "62438"} posts = [] for _ in range(5): body = requests.get(f"{BASE}/linkedin/group/posts", params=params, headers=HEADERS, timeout=120).json() posts += body["data"]["items"] if not body["pagination"]["has_more"]: break params["cursor"] = body["pagination"]["next_cursor"] ``` In our test on 2026-10-14 the group returned one page of 10 posts with `has_more: false`, so don't count on a deep history for every group. See [Pagination](/docs/pagination) for the full rules. ## What are the limits? [#what-are-the-limits] * **Rounded times.** `published_at` is rounded to the hour or the day; check `ext.published_at_precision` before comparing times. * **Order.** Posts came back mostly newest first, but not strictly: in our test the first post was a day older than the nine after it. Sort by `published_at` yourself if order matters. * **Feed depth.** The test group gave one page of 10 posts and no cursor. How far back a group's feed goes is not guaranteed. * **No view or save counts.** `engagement.views` and `engagement.saves` are `null`, which means unknown, not zero. * **Comments are a separate call.** Comment counts are included; the comments themselves come from `GET /v1/linkedin/post/comments` with the post's `url`. ## What can I build with it? [#what-can-i-build-with-it] * **Community monitoring.** Poll the groups in your industry daily and alert on posts that mention your brand, a competitor, or a problem you solve. * **Topic research.** Collect a group's posts and the reaction counts to see which topics its members respond to. * **Finding active members.** The authors and their headlines show who posts in a group, a starting list for partnerships or outreach. ## Related [#related] * [`GET /v1/linkedin/group/posts` reference](/docs/api-reference/linkedin/group-posts): every parameter and field. * [`GET /v1/linkedin/group`](/docs/api-reference/linkedin/group): the group's name, rules, member count and owners. * [`GET /v1/linkedin/post/comments`](/docs/api-reference/linkedin/post-comments): the comments under one group post. * [LinkedIn endpoints](/docs/platforms/linkedin): everything the API covers on LinkedIn. --- # Check when a LinkedIn member was last active (/docs/how-to/linkedin-last-active) Find when a LinkedIn member last showed public activity, such as a post, with an exact timestamp, by profile URL. 50 credits per call. To check when a LinkedIn member was last active, call `GET /v1/linkedin/profile/activity` with their profile `url`. It returns the time of their most recent public activity, what kind of activity it was (for example `post`), and LinkedIn's short "how long ago" label such as `2w`. It costs 50 credits a call. It answers "is this person still active on LinkedIn?" without pulling their whole feed. 50 credits per call. Checking 100 profiles costs 5,000 credits. Asking for the same profile again within 24 hours is answered from the shared cache for 2 credits. Failed calls and empty results are free. ## How do I find the profile URL? [#how-do-i-find-the-profile-url] Use the member's public profile address, the one in the browser bar on their profile: `https://www.linkedin.com/in/adamselipsky/`. If you have a name but no URL, `GET /v1/linkedin/search/people` finds members by keyword, and every person row other endpoints return carries the profile link in `author.url`. ## Make the request [#make-the-request] ```bash title="cURL" curl -G "https://api.insightsocial.app/v1/linkedin/profile/activity" \ --data-urlencode "url=https://www.linkedin.com/in/adamselipsky/" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python title="Python" import os from datetime import datetime, timezone import requests res = requests.get( "https://api.insightsocial.app/v1/linkedin/profile/activity", params={"url": "https://www.linkedin.com/in/adamselipsky/"}, headers={"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]}, timeout=120, ) data = res.json()["data"] last = datetime.fromisoformat(data["timestamp"].replace("Z", "+00:00")) days = (datetime.now(timezone.utc) - last).days print(f"Last {data['type']} {days} days ago ({data['recent_activity']})") ``` ```ts title="Node.js" const url = new URL("https://api.insightsocial.app/v1/linkedin/profile/activity"); url.searchParams.set("url", "https://www.linkedin.com/in/adamselipsky/"); const { data } = await (await fetch(url, { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY! } })).json(); const days = Math.floor((Date.now() - Date.parse(data.timestamp)) / 86_400_000); console.log(`Last ${data.type} ${days} days ago (${data.recent_activity})`); ``` ## What comes back [#what-comes-back] A real response from 2026-10-14, complete apart from the billing fields at the end. ```json title="Response" { "success": true, "endpoint": "/v1/linkedin/profile/activity", "schema_version": "2", "data": { "date": "2026-09-29 00:28:48.785 +0000 UTC", "recent_activity": "2w", "timestamp": "2026-09-29T00:28:48.785Z", "type": "post" }, "unavailable": [], "credits_used": 50 } ``` | Field | What it holds | | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------- | | `data.timestamp` | When the most recent public activity happened, as an ISO 8601 UTC time. Use this one for date math. | | `data.date` | The same moment as a plain text string. | | `data.type` | What the activity was. Here `post`: the member's latest public activity was a post. | | `data.recent_activity` | LinkedIn's relative label for how long ago it was. `2w` here: two weeks before the call, which matches the timestamp (15 days). | ## What are the limits? [#what-are-the-limits] * **Public activity, not logins.** The endpoint reports the latest activity LinkedIn shows publicly, such as a post. It does not tell you when someone last logged in, read their feed or viewed a profile. A member who reads LinkedIn daily but never posts can look inactive. * **One event, not a feed.** You get the time and type of the latest activity only, not its content. Use `GET /v1/linkedin/profile/posts` for the posts themselves. * **Coarse label.** `recent_activity` is a rounded label like `2w`. Compute recency from `timestamp` if you need days. * **Cached for up to 24 hours.** A call inside that window can be answered from the shared cache, so very recent activity may not show yet. Add `fresh=1` to skip the cache and pay the full 50 credits. See [Caching](/docs/caching). ## What can I build with it? [#what-can-i-build-with-it] * **Lead list hygiene.** Before outreach, check each prospect and drop or deprioritize the ones with no public activity in months. A post this month means a message is more likely to be seen. * **Engagement timing.** Contact people shortly after they post, while they are checking their notifications. * **Account monitoring.** Track the last-active date of a competitor's executives or key customers' champions across weeks to notice who has gone quiet. ## Related [#related] * [`GET /v1/linkedin/profile/activity` reference](/docs/api-reference/linkedin/profile-activity): every parameter and field. * [`GET /v1/linkedin/profile/posts`](/docs/api-reference/linkedin/profile-posts): the member's posts, once you know they are active. * [`GET /v1/linkedin/profile`](/docs/api-reference/linkedin/profile): their name, headline, location and follower count. * [LinkedIn endpoints](/docs/platforms/linkedin): everything the API covers on LinkedIn. --- # Get the people who reacted to or reposted a LinkedIn post (/docs/how-to/linkedin-post-reactions-and-reposts) List who reacted to a LinkedIn post, with each reaction type, and who reposted it, by post URL. 100 credits a page of reactors, 50 a page of reposts. To see who engaged with a LinkedIn post, call `GET /v1/linkedin/post/reactions` with the post's `url` for the people who reacted, and `GET /v1/linkedin/post/reposts` with the same `url` for the people who reposted it. Reactions return each person's name, headline, profile URL and the reaction they left (like, praise, empathy and so on). Reposts return each reshare with the resharer and any text they added. A page of reactors costs 100 credits; a page of reposts costs 50. For the people who commented, use `GET /v1/linkedin/post/comments` (50 credits a page). `post/reactions` is metered at 100–500 credits a page. A plain page costs 100 credits. Adding `include=profile` joins each row to the member's profile, so the call holds up to 500 credits when it starts and you're charged what it used. Send `dry_run=1` for a free quote. `post/reposts` is 50 credits per page of 10. Asking for the same page again within 6 hours is answered from the shared cache for 2 credits. Failed calls and empty results are free. ## How do I find the post URL? [#how-do-i-find-the-post-url] The `url` has to carry the post's activity ID, in one of two forms: * `https://www.linkedin.com/feed/update/urn:li:activity:7501466755261820928` * `https://www.linkedin.com/posts/-activity--` On LinkedIn, open the post's menu and choose "Copy link to post". If you got the post from another endpoint (`profile/posts`, `company/posts`, `search/posts`), copy its `post.url` field. Don't rebuild the URL from `post.id`, which is not always the activity ID. ## Make the request [#make-the-request] ```bash title="cURL" POST_URL="https://www.linkedin.com/feed/update/urn:li:activity:7501466755261820928" curl -G "https://api.insightsocial.app/v1/linkedin/post/reactions" \ --data-urlencode "url=$POST_URL" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" curl -G "https://api.insightsocial.app/v1/linkedin/post/reposts" \ --data-urlencode "url=$POST_URL" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python title="Python" import os import requests BASE = "https://api.insightsocial.app/v1" HEADERS = {"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]} POST_URL = "https://www.linkedin.com/feed/update/urn:li:activity:7501466755261820928" reactions = requests.get(f"{BASE}/linkedin/post/reactions", params={"url": POST_URL}, headers=HEADERS, timeout=120).json() for item in reactions["data"]["items"]: person = item["author"] print(person["ext"]["reaction_type"], person["display_name"], person["url"]) reposts = requests.get(f"{BASE}/linkedin/post/reposts", params={"url": POST_URL}, headers=HEADERS, timeout=120).json() print(reposts["data"]["total"], "reposts") for item in reposts["data"]["items"]: post = item["post"] print(post["author"]["display_name"], "added text" if post["ext"]["is_repost_quote"] else "plain repost") ``` ```ts title="Node.js" const BASE = "https://api.insightsocial.app/v1"; const headers = { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY! }; const postUrl = "https://www.linkedin.com/feed/update/urn:li:activity:7501466755261820928"; const get = async (path: string) => { const url = new URL(`${BASE}${path}`); url.searchParams.set("url", postUrl); return (await fetch(url, { headers })).json(); }; const reactions = await get("/linkedin/post/reactions"); for (const { author } of reactions.data.items) console.log(author.ext.reaction_type, author.display_name, author.url); const reposts = await get("/linkedin/post/reposts"); console.log(`${reposts.data.total} reposts`); for (const { post } of reposts.data.items) console.log(post.author.display_name, post.ext.is_repost_quote); ``` ## What comes back [#what-comes-back] Real responses from 2026-10-14, shortened: one or two rows instead of a full page, long URLs and cursors cut, and private members replaced with placeholders. ```json title="post/reactions response (shortened)" { "success": true, "endpoint": "/v1/linkedin/post/reactions", "schema_version": "2", "data": { "items": [ { "author": { "id": "ACoAAD7nmw…", "username": null, "display_name": "Example User", "avatar_url": "https://media.licdn.com/dms/image/v2/…", "bio": "Data analyst | Business intelligence", "verified": null, "followers": null, "url": "https://www.linkedin.com/in/ACoAAD7nmw…", "ext": { "urn": "ACoAAD7nmw…", "reaction_type": "LIKE", "member_id": "1055365895" } } } ], "total": null, "truncated": null }, "pagination": { "next_cursor": "v2c.BLUP7GMD…", "has_more": true, "page_size": 44 }, "unavailable": [ "items[].author.verified", "items[].author.followers", "items[].author.following", "items[].author.joined_at" ], "credits_used": 100 } ``` ```json title="post/reposts response (shortened)" { "success": true, "endpoint": "/v1/linkedin/post/reposts", "schema_version": "2", "data": { "items": [ { "post": { "id": "7511864524241833985", "url": "https://www.linkedin.com/feed/update/urn:li:activity:7511864524241833985", "content": { "text": null }, "author": { "id": "ACoAACZmjG…", "username": "example_user", "display_name": "Example User" }, "engagement": { "likes": 3758, "comments": 349, "shares": 318 }, "published_at": null, "ext": { "author_type": "user", "is_repost_quote": false } } }, { "post": { "id": "7509225672431562753", "url": "https://www.linkedin.com/feed/update/urn:li:activity:7509225672431562753", "content": { "text": "This long and invasive pathways belongs to the past. Today, a simple blood test…" }, "author": { "id": "28438218", "username": "roche-belux", "display_name": "Roche Belgium & Luxembourg" }, "engagement": { "likes": 5, "comments": 0, "shares": 0 }, "published_at": null, "ext": { "author_followers": 15816, "author_type": "company", "is_repost_quote": true, "published_at_precision": "week" } } } ], "total": 318, "truncated": null }, "pagination": { "next_cursor": "v2c.6dxQa3CY…", "has_more": true, "page_size": 10 }, "unavailable": ["items[].post.published_at"], "credits_used": 50 } ``` | Field | What it holds | | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | `reactions: data.items[].author` | One person or page that reacted, in the shared [author shape](/docs/schema/author): name, headline (`bio`), avatar, profile URL. | | `reactions: author.ext.reaction_type` | The reaction they left: `LIKE`, `PRAISE`, `EMPATHY`, `APPRECIATION`, `INTEREST` and others. | | `reactions: author.ext.member_id` | LinkedIn's numeric member ID. Company pages that react have no `member_id`; their `url` is the company page. | | `reposts: data.items[].post` | One reshare in the shared [post shape](/docs/schema/post), with the resharer in `post.author`. | | `reposts: post.ext.is_repost_quote` | `true` when the resharer added their own text. Then `content.text` is that text and `engagement` counts their reshare. | | `reposts: data.total` | How many reposts the post has. 318 here, the same as the original post's share count. | | `reposts: post.ext.author_type` | `user` for a member, `company` for a company page. | ## How do I get every reactor and reposter? [#how-do-i-get-every-reactor-and-reposter] Both endpoints paginate. Send `pagination.next_cursor` back as `cursor`, with the same `url`, and stop when `pagination.has_more` is `false`. Each reactions page costs 100 credits (more with `include=profile`); each reposts page costs 50. ```python title="Python: walk every reactor, up to 20 pages" import os import requests BASE = "https://api.insightsocial.app/v1" HEADERS = {"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]} params = {"url": "https://www.linkedin.com/feed/update/urn:li:activity:7501466755261820928"} people = [] for _ in range(20): body = requests.get(f"{BASE}/linkedin/post/reactions", params=params, headers=HEADERS, timeout=120).json() people += [item["author"] for item in body["data"]["items"]] if not body["pagination"]["has_more"]: break params["cursor"] = body["pagination"]["next_cursor"] ``` To list only one kind of reaction, add `type` (`like`, `praise`, `empathy`, `appreciation`, `interest`, or `all`). See [Pagination](/docs/pagination) for the full rules. ## What are the limits? [#what-are-the-limits] * **Reactor handles.** Most reactor rows have `username: null`, and `url` points to the member's ID-based profile link (`/in/ACoAA…`) rather than their vanity handle. The link still opens the profile. * **Follower counts.** `followers`, `following`, `verified` and `joined_at` are `null` on reactor rows, which means unknown, not zero. Add `include=profile` to fill the exact follower count and connection count from each member's profile, at a higher price. * **No reactions total.** `data.total` is `null` on `post/reactions`. The post's like, comment and share counts are on `GET /v1/linkedin/post`. * **Plain reposts carry the original's numbers.** On a repost without added text, `content.text` is `null` and `engagement` repeats the original post's likes, comments and shares. Only quote reposts (`is_repost_quote: true`) have their own text and counts. * **No repost dates.** `published_at` is `null` on every repost row. * **Repeat reposters.** The same member can appear more than once if they reshared the post several times. Deduplicate on `post.author.id` if you want people, not reshares. ## What can I build with it? [#what-can-i-build-with-it] * **Lead lists from engagement.** The people who react to a competitor's or a thought leader's post are an audience already interested in the topic. Their headlines tell you role and company. * **Campaign reach reports.** For your own post, count reactions by `reaction_type` and list the company pages and members who reshared it with their own commentary. * **Advocate tracking.** Run the reposts endpoint across a company's recent posts to see which employees and partners reshare most often. ## Related [#related] * [`GET /v1/linkedin/post/reactions` reference](/docs/api-reference/linkedin/post-reactions): every parameter and field. * [`GET /v1/linkedin/post/reposts` reference](/docs/api-reference/linkedin/post-reposts): every parameter and field. * [`GET /v1/linkedin/post/comments`](/docs/api-reference/linkedin/post-comments): the people who commented on the post. * [LinkedIn endpoints](/docs/platforms/linkedin): everything the API covers on LinkedIn. --- # Get Pinterest save counts for any URL (/docs/how-to/pinterest-save-counts-for-urls) See how many times up to 10 web pages have been saved to Pinterest through the Save button, in one call. 10 credits per call. To see how many times a web page has been saved to Pinterest, call `GET /v1/pinterest/url-stats` with `urls`, a comma-separated list of 1 to 10 page URLs. It returns each URL with its save count, the number of times it was saved to Pinterest through the Save button. It costs 10 credits per call, whether you send one URL or 10. 10 credits per call of up to 10 URLs. Checking 100 pages takes 10 calls and costs 100 credits. Asking for the same URLs again within 6 hours is answered from the shared cache for 2 credits. Failed calls and empty results are free. ## Which URL do I pass? [#which-url-do-i-pass] Pass the full address, starting with `http://` or `https://`, exactly as people share it. The URLs go to Pinterest verbatim, and Pinterest counts each variant separately: `http` and `https`, with and without a trailing slash, and with and without a query string are different URLs with different counts. If you are not sure which form gets pinned, send the variants together in one call; they all fit in the same 10 credits. ## Make the request [#make-the-request] ```bash title="cURL" curl -G "https://api.insightsocial.app/v1/pinterest/url-stats" \ --data-urlencode "urls=https://www.allrecipes.com/recipe/10813/best-chocolate-chip-cookies/" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python title="Python" import os import requests urls = [ "https://www.allrecipes.com/recipe/10813/best-chocolate-chip-cookies/", "https://www.allrecipes.com/recipe/10813/best-chocolate-chip-cookies", ] res = requests.get( "https://api.insightsocial.app/v1/pinterest/url-stats", params={"urls": ",".join(urls)}, headers={"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]}, timeout=120, ) for item in res.json()["data"]["items"]: print(item["saves"], item["url"]) ``` ```ts title="Node.js" const urls = [ "https://www.allrecipes.com/recipe/10813/best-chocolate-chip-cookies/", "https://www.allrecipes.com/recipe/10813/best-chocolate-chip-cookies", ]; const url = new URL("https://api.insightsocial.app/v1/pinterest/url-stats"); url.searchParams.set("urls", urls.join(",")); const body = await (await fetch(url, { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY! } })).json(); for (const item of body.data.items) console.log(item.saves, item.url); ``` ## What comes back [#what-comes-back] A real response from 2026-10-14 for one URL. ```json title="Response" { "success": true, "endpoint": "/v1/pinterest/url-stats", "schema_version": "2", "data": { "items": [ { "url": "https://www.allrecipes.com/recipe/10813/best-chocolate-chip-cookies/", "saves": 35108, "pinterest": { "url": "https://www.allrecipes.com/recipe/10813/best-chocolate-chip-cookies/", "count": 35108 } } ], "total": 1 }, "pagination": { "next_cursor": null, "has_more": false, "page_size": 1 }, "unavailable": [], "credits_used": 10 } ``` | Field | What it holds | | ------------------------ | ----------------------------------------------------------------------------------------------- | | `data.items[].url` | The URL you sent. | | `data.items[].saves` | How many times that exact URL has been saved to Pinterest through the Save button. 35,108 here. | | `data.items[].pinterest` | The raw pair Pinterest returned: the URL it counted and its `count`. | | `data.total` | How many URLs the response covers. | ## What are the limits? [#what-are-the-limits] * **10 URLs per call.** Split longer lists into batches of 10. The endpoint does not paginate. * **Exact URLs only.** Each variant of a page has its own count. Add up the variants yourself if you want one number per page. * **Save button saves.** The count is what Pinterest reports for saves of the URL through its Save button. It says nothing about who saved it or when. * **Absolute URLs.** Each entry must start with `http://` or `https://`. ## What can I build with it? [#what-can-i-build-with-it] * **Content audits.** Rank a site's recipes, articles or product pages by Pinterest saves to see which ones travel on Pinterest. * **Competitor benchmarking.** Compare save counts for your pages and a competitor's pages on the same topic. * **Tracking over time.** Store the counts weekly for your key pages and watch which ones keep gaining saves. ## Related [#related] * [`GET /v1/pinterest/url-stats` reference](/docs/api-reference/pinterest/url-stats): every parameter and field. * [`GET /v1/pinterest/search`](/docs/api-reference/pinterest/search): find the pins about a topic; `include=engagement` adds each pin's save count. * [Pinterest endpoints](/docs/platforms/pinterest): everything the API covers on Pinterest. --- # Get Pinterest Trends for a country (/docs/how-to/pinterest-trends) List the top Pinterest search terms for one of 23 countries, with rank, search index and change, growing or seasonal. 100 credits per call. To see what a market is searching for on Pinterest, call `GET /v1/pinterest/trends` with a `country` code and a `type`. It returns up to 50 ranked search terms from Pinterest Trends, each with a relative search index, its weekly, monthly and yearly change, a seasonality score and the date of the list. It costs 100 credits per call, whether you ask for 5 terms or 50. You need no keyword to start from. 100 credits per call, at any `limit` from 1 to 50. Pulling all four tables for one country costs 400 credits. Asking for the same list again within 6 hours is answered from the shared cache for 2 credits. Failed calls and empty results are free, and so is a request for an unsupported country (a 400). ## Which parameters can I set? [#which-parameters-can-i-set] | Parameter | Values | | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `country` | `AR`, `AU`, `BR`, `CA`, `CO`, `DE`, `EG`, `ES`, `FR`, `GB`, `ID`, `IE`, `IN`, `IT`, `KR`, `MX`, `MY`, `NZ`, `PH`, `SA`, `TH`, `TR`, `US`, in any case. Defaults to `US`. | | `type` | Which Trends table: `growing` (the default), `seasonal`, `top_monthly` or `top_yearly`. | | `limit` | How many terms to return from the top, 1 to 50. Defaults to 25. | | `include` | Keep only terms that contain one of these keywords, comma-separated, up to 10 (for example `nails,wedding`). | | `exclude` | Drop terms that contain any of these keywords, comma-separated, up to 10 (for example `fall`). | Use `growing` for terms picking up now, `seasonal` for terms that return at this time of year, and `top_monthly` or `top_yearly` for the most searched terms over a month or a year. ## Make the request [#make-the-request] ```bash title="cURL" curl "https://api.insightsocial.app/v1/pinterest/trends?country=US&type=growing&limit=10" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python title="Python" import os import requests res = requests.get( "https://api.insightsocial.app/v1/pinterest/trends", params={"country": "US", "type": "growing", "limit": 10}, headers={"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]}, timeout=120, ) for item in res.json()["data"]["items"]: print(item["rank"], item["term"], item["search_index"], item["as_of"]) ``` ```ts title="Node.js" const url = new URL("https://api.insightsocial.app/v1/pinterest/trends"); url.searchParams.set("country", "US"); url.searchParams.set("type", "growing"); url.searchParams.set("limit", "10"); const body = await (await fetch(url, { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY! } })).json(); for (const t of body.data.items) console.log(t.rank, t.term, t.search_index, t.as_of); ``` ## What comes back [#what-comes-back] A real response from 2026-10-14 (`country=US`, `type=growing`, `limit=10`), shortened to two of the 10 terms. ```json title="Response (shortened)" { "success": true, "endpoint": "/v1/pinterest/trends", "schema_version": "2", "data": { "items": [ { "rank": 3, "term": "october nails ideas 2026", "country": "US", "market": "US", "type": "growing", "search_index": 37, "weekly_change": 0.06, "monthly_change": 100.01, "yearly_change": 100.01, "seasonality": 0.32323614, "url": "https://trends.pinterest.com/detail/?terms=october+nails+ideas+2026&country=US", "as_of": "2026-10-05" }, { "rank": 6, "term": "happy october", "country": "US", "market": "US", "type": "growing", "search_index": 39, "weekly_change": 55, "monthly_change": 100.01, "yearly_change": -0.08, "seasonality": 0.8605102, "url": "https://trends.pinterest.com/detail/?terms=happy+october&country=US", "as_of": "2026-10-05" } ], "total": 10 }, "pagination": { "next_cursor": null, "has_more": false, "page_size": 10 }, "unavailable": [], "credits_used": 100 } ``` | Field | What it holds | | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | | `rank` | The term's position in the table. | | `term` | The search term. | | `market` | Which Pinterest list the term came from. It can differ from `country`: `IE` reads the GB+IE list, `AU` and `NZ` read the AU+NZ list. | | `search_index` | Pinterest's relative search index for the term. In this response the highest value is 100. | | `weekly_change`, `monthly_change`, `yearly_change` | The change Pinterest reports for the term over each period. | | `seasonality` | Pinterest's seasonality score. Here the October greetings score about 0.86 to 0.88; most other terms score about 0.32. | | `url` | The term's page on Pinterest Trends. | | `as_of` | The date of the Trends list. | ## What are the limits? [#what-are-the-limits] * **23 countries.** Pinterest publishes no list for other countries; asking for one returns a free 400. * **Shared lists.** `IE` returns Pinterest's GB+IE list and `AU` and `NZ` return the AU+NZ list. `GB` alone has its own list. * **50 terms at most.** `limit` goes from 1 to 50. The endpoint does not paginate. * **Not real time.** The list is dated: the response captured on 2026-10-14 carried `as_of: "2026-10-05"`. * **Read the change fields with care.** No unit is documented, and in the sample most growing terms show the same `monthly_change` of 100.01. Compare terms by `rank` and `search_index` first. ## What can I build with it? [#what-can-i-build-with-it] * **Content calendars.** Pull the `seasonal` table each week and plan pins and blog posts around the terms that are coming back. * **Product and niche research.** Filter with `include` (for example `nails,wedding`) to watch only the terms in your category, across several countries. * **Trend alerts.** Store the `growing` table daily and flag terms that enter it or climb in `rank`. ## Related [#related] * [`GET /v1/pinterest/trends` reference](/docs/api-reference/pinterest/trends): every parameter and field. * [`GET /v1/pinterest/search`](/docs/api-reference/pinterest/search): the pins behind a trending term. * [Pinterest endpoints](/docs/platforms/pinterest): everything the API covers on Pinterest. --- # Read on-screen text from TikTok videos (/docs/how-to/read-on-screen-text-from-videos) Get the text burned into a TikTok video, read by OCR, from the video URL. 50 credits per video. To read the text shown on a TikTok video, call `GET /v1/tiktok/video/screen-text` with the video's `url`: it returns TikTok's native text stickers plus AI OCR of the cover frame, so captions burned in with an editor are caught too. It costs 50 credits per video. 50 credits per video. Reading 100 videos costs 5,000 credits. Asking for the same URL again within 6 hours is answered from the shared cache for 2 credits. Failed calls and empty results are free. ## Which text does each endpoint read? [#which-text-does-each-endpoint-read] A post carries text in three places, and each has its own endpoint. | Text | Endpoint | | -------------- | ----------------------------------------------- | | Caption | `GET /v1/tiktok/post` (10 credits) | | Spoken words | `GET /v1/tiktok/post/transcript` (100 credits) | | Text on screen | `GET /v1/tiktok/video/screen-text` (50 credits) | On TikTok, text typed with TikTok's own text tool is also on `GET /v1/tiktok/post` as `post.ext.on_screen_texts`. Use screen-text when you also need text burned into the video by an outside editor, which only OCR can see. ## How do I find the URL? [#how-do-i-find-the-url] Copy the video's link from the app or browser: a `/video/` or `/photo/` link, such as `https://www.tiktok.com/@stoolpresidente/video/7499229683859426602`. ## Make the request [#make-the-request] ```bash title="cURL" # TikTok video curl "https://api.insightsocial.app/v1/tiktok/video/screen-text?url=https://www.tiktok.com/@stoolpresidente/video/7499229683859426602" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python title="Python" import os import requests BASE = "https://api.insightsocial.app/v1" HEADERS = {"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]} tiktok = requests.get( f"{BASE}/tiktok/video/screen-text", params={"url": "https://www.tiktok.com/@stoolpresidente/video/7499229683859426602"}, headers=HEADERS, timeout=120, ).json() print("TikTok:", tiktok["data"]["texts"]) ``` ```ts title="Node.js" const BASE = "https://api.insightsocial.app/v1"; const headers = { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY! }; const tt = new URL(`${BASE}/tiktok/video/screen-text`); tt.searchParams.set("url", "https://www.tiktok.com/@stoolpresidente/video/7499229683859426602"); const tiktok = await (await fetch(tt, { headers })).json(); console.log("TikTok:", tiktok.data.texts); ``` ## What comes back [#what-comes-back] A real response from 2026-10-14, complete: ```json title="TikTok response" { "success": true, "endpoint": "/v1/tiktok/video/screen-text", "schema_version": "2", "data": { "video_id": "7499229683859426602", "url": "https://www.tiktok.com/@stoolpresidente/video/7499229683859426602", "texts": ["Delicious Pizza"], "native_texts": null, "ocr_texts": ["Delicious Pizza"], "source": "ocr", "media_type": "video", "frame": "cover" }, "unavailable": [], "credits_used": 50 } ``` | Field | What it holds | | ------------------- | ----------------------------------------------------------------------------- | | `data.texts` | All the text found on the video, native and OCR combined. | | `data.native_texts` | Text added with TikTok's text tool. `null` here, so everything came from OCR. | | `data.ocr_texts` | Text read by AI from the image. | | `data.source` | Where the text came from: `ocr` in this response. | | `data.frame` | Which frame OCR read: `cover`. | ## What are the limits? [#what-are-the-limits] * **The cover frame only.** OCR reads only the cover frame of a video, so burned-in text that appears later in the video is not read. * **Lines, not sentences.** OCR returns text in the lines it sees, so one sentence can arrive as two entries, and an entry can contain a line break (`"Happy\nBirth Day"`). Join them yourself if you need full sentences. * **Not the caption, not the audio.** Use the post and transcript endpoints in the table above for those. ## What can I build with it? [#what-can-i-build-with-it] * **Hook analysis.** Collect the text on the cover frame of top-performing videos in a niche and compare which hooks get the most views. * **Searchable archive.** Store caption, transcript and on-screen text together so a search finds a post by any words it shows. ## Related [#related] * [`GET /v1/tiktok/video/screen-text` reference](/docs/api-reference/tiktok/video-screen-text): every parameter and field. * [`GET /v1/tiktok/post/transcript`](/docs/api-reference/tiktok/post-transcript): the spoken words instead. * [Video transcription recipe](/docs/recipes/video-transcription-api): transcripts across platforms. * [TikTok endpoints](/docs/platforms/tiktok). --- # Search Reddit comments by keyword (/docs/how-to/reddit-comment-search) Search comments across all of Reddit by keyword, author or subreddit, each with its post title, subreddit and score. 10 credits per page. To search Reddit comments by keyword, call `GET /v1/reddit/search/comments` with a `query`. Each match comes back with the comment's text, author, score and time, plus the post it sits under: the post's title, URL, score, comment count and subreddit. It costs 10 credits a page. Reddit's search operators work in the query, so `author:username` lists one account's comments and `subreddit:name terms` keeps the search inside one community. 10 credits per page (24 comments in our test). Reading 10 pages costs 100 credits. Asking for the same page again within 1 hour is answered from the shared cache for 2 credits. Failed calls and empty results are free. ## How do I write the query? [#how-do-i-write-the-query] The `query` is the same text you would type in Reddit's search box, with three operators: | Query | Finds | | ---------------------------------- | ----------------------------------------------- | | `best project management software` | Comments that match these words | | `"project management software"` | Comments with the exact phrase | | `subreddit:projectmanagement jira` | Comments about Jira in r/projectmanagement only | | `author:example_user` | Comments by one account | Add `sort` to choose the order: `relevance`, `top` or `new`. ## Make the request [#make-the-request] ```bash title="cURL" curl -G "https://api.insightsocial.app/v1/reddit/search/comments" \ --data-urlencode "query=best project management software" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python title="Python" import os import requests res = requests.get( "https://api.insightsocial.app/v1/reddit/search/comments", params={"query": "best project management software"}, headers={"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]}, timeout=120, ) for item in res.json()["data"]["items"]: comment = item["comment"] print(f"r/{comment['ext']['subreddit']}", comment["engagement"]["likes"], comment["text"][:80], comment["url"]) ``` ```ts title="Node.js" const url = new URL("https://api.insightsocial.app/v1/reddit/search/comments"); url.searchParams.set("query", "best project management software"); const body = await (await fetch(url, { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY! } })).json(); for (const { comment } of body.data.items) { console.log(`r/${comment.ext.subreddit}`, comment.engagement.likes, comment.text.slice(0, 80), comment.url); } ``` ## What comes back [#what-comes-back] A real response from 2026-10-14, shortened: one comment instead of 24, the text and post title shortened, long URLs and the cursor cut, and Reddit usernames replaced with placeholders. ```json title="Response (shortened)" { "success": true, "endpoint": "/v1/reddit/search/comments", "schema_version": "2", "data": { "items": [ { "comment": { "id": "pfc2aq6", "url": "https://www.reddit.com/r/BetterOffline/comments/1x3l1fn/comment/pfc2aq6/", "parent_id": null, "post_id": "1x3l1fn", "text": "I look forward to people rediscovering software engineering methods from 20 years ago…", "author": { "id": "t2_…", "username": "example_user", "display_name": null, "avatar_url": "https://styles.redditmedia.com/…" }, "engagement": { "likes": 174, "replies": null }, "flags": { "pinned": null, "deleted": false }, "published_at": "2026-10-11T22:18:34.073Z", "language": "en", "ext": { "post_title": "The people who doubted me now ask me to clean up their LLM mess…", "post_url": "https://www.reddit.com/r/BetterOffline/comments/t3_1x3l1fn/", "subreddit": "BetterOffline", "subreddit_subscribers": 58872, "post_score": 523, "post_comment_count": 156, "post_author": "example_poster", "post_published_at": "2026-10-11T22:11:46.852Z" } } } ], "total": null, "truncated": null }, "pagination": { "next_cursor": "v2c.yQV705tt…", "has_more": true, "page_size": 24 }, "unavailable": ["items[].comment.engagement.replies"], "credits_used": 10 } ``` | Field | What it holds | | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- | | `data.items[].comment` | One matching comment in the shared [comment shape](/docs/schema/comment): text, author, score, time, link. | | `comment.engagement.likes` | The comment's score as Reddit shows it. | | `comment.post_id` | The ID of the post the comment is under. | | `comment.ext.post_title`, `post_url`, `post_score`, `post_comment_count` | The parent post, inline, so you don't need a second call to see what thread the comment is in. | | `comment.ext.subreddit`, `subreddit_subscribers` | The community and its size. | | `comment.language` | The detected language, or `und` when it could not be determined. | ## How do I get more than one page? [#how-do-i-get-more-than-one-page] Send `pagination.next_cursor` back as `cursor`, with the same `query` and `sort`, and stop when `pagination.has_more` is `false`. Each page is 10 credits. ```python title="Python: read up to 10 pages" import os import requests BASE = "https://api.insightsocial.app/v1" HEADERS = {"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]} params = {"query": "best project management software", "sort": "new"} comments = [] for _ in range(10): body = requests.get(f"{BASE}/reddit/search/comments", params=params, headers=HEADERS, timeout=120).json() comments += [item["comment"] for item in body["data"]["items"]] if not body["pagination"]["has_more"]: break params["cursor"] = body["pagination"]["next_cursor"] ``` See [Pagination](/docs/pagination) for the full rules. ## What are the limits? [#what-are-the-limits] * **No thread position.** `parent_id` is `null` on every row: you know which post a comment is under, not which comment it replied to. Use `GET /v1/reddit/post/comments` with the post's URL to see the whole thread. * **No reply counts.** `engagement.replies` is `null`, which means unknown, not zero. * **Relevance is loose.** Without quotes, matches share some of the words rather than the whole phrase: our test for "best project management software" also returned comments about software careers and game sales. Quote the phrase or add `subreddit:` to tighten it. * **No total.** `data.total` is `null`, so you can't know the number of matches up front. ## What can I build with it? [#what-can-i-build-with-it] * **Brand and competitor mentions.** Many product recommendations live in replies, not post titles. Search your brand and competitors' names with `sort=new` every day to catch new mentions. The [brand mention monitoring](/docs/recipes/brand-mention-monitoring) recipe shows the full loop. * **Customer research.** Search a problem phrase ("switching from Jira", "too expensive for a small team") and read what people say, grouped by `ext.subreddit`. * **Account history.** `author:username` lists what one account has said across Reddit, useful for checking a prospect or a reviewer. ## Related [#related] * [`GET /v1/reddit/search/comments` reference](/docs/api-reference/reddit/search-comments): every parameter and field. * [`GET /v1/reddit/search`](/docs/api-reference/reddit/search): search Reddit posts instead of comments. * [`GET /v1/reddit/post/comments`](/docs/api-reference/reddit/post-comments): every comment in one thread. * [Reddit endpoints](/docs/platforms/reddit): everything the API covers on Reddit. --- # Find TikTok creators similar to one you know (/docs/how-to/tiktok-similar-creators) Get about 30 TikTok accounts similar to a seed creator, with bio, verified badge and follower, video and like counts. 50 credits per call. To find TikTok creators similar to one you already know, call `GET /v1/tiktok/similar` with the seed creator's `handle`. It returns about 30 accounts, each with username, display name, avatar, bio, verified badge, and follower, following, video and like counts. It costs 50 credits per call. The list is fixed: there are no further pages, so to go wider you call it again on one of the results. 50 credits per call for about 30 accounts. Going one level wider, by calling it on each of those 30 accounts, costs 30 × 50 = 1,500 credits more. Asking for the same handle again within 6 hours is answered from the shared cache for 2 credits. Failed calls and empty results are free. ## How do I find the handle? [#how-do-i-find-the-handle] The handle is the name after the `@` in the profile URL: `https://www.tiktok.com/@gordonramsayofficial` has the handle `gordonramsayofficial`. Send it without the `@`. ## Make the request [#make-the-request] ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/similar?handle=gordonramsayofficial" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python title="Python" import os import requests res = requests.get( "https://api.insightsocial.app/v1/tiktok/similar", params={"handle": "gordonramsayofficial"}, headers={"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]}, timeout=120, ) for item in res.json()["data"]["items"]: a = item["author"] print(a["username"], a["followers"], a["verified"], a["url"]) ``` ```ts title="Node.js" const url = new URL("https://api.insightsocial.app/v1/tiktok/similar"); url.searchParams.set("handle", "gordonramsayofficial"); const body = await (await fetch(url, { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY! } })).json(); for (const { author } of body.data.items) console.log(author.username, author.followers, author.verified, author.url); ``` ## What comes back [#what-comes-back] A real response from 2026-10-14 for `@gordonramsayofficial`, shortened: two accounts instead of 30 and long URLs cut. ```json title="Response (shortened)" { "success": true, "endpoint": "/v1/tiktok/similar", "schema_version": "2", "data": { "items": [ { "author": { "id": "14598641", "username": "tillyramsay", "display_name": "tillyramsay", "avatar_url": "https://p19-common-sign.tiktokcdn-us.com/…", "bio": "Official TikTok of Tilly Ramsay", "verified": true, "followers": 9816700, "followers_approximate": null, "following": 107, "posts_count": 84, "likes_count": 126856718, "url": "https://www.tiktok.com/@tillyramsay", "location": null, "external_url": null, "private": false, "joined_at": "2015-11-03T00:00:00.000Z", "last_post_at": null } }, { "author": { "id": "6614519312189947909", "username": "mrbeast", "display_name": "MrBeast", "bio": "Checkout My New Book!👇", "verified": true, "followers": 143936169, "following": 346, "posts_count": 471, "likes_count": 1532891512, "url": "https://www.tiktok.com/@mrbeast", "private": false, "joined_at": "2018-10-20T00:00:00.000Z" } } ], "total": 30, "truncated": null }, "pagination": { "next_cursor": null, "has_more": false, "page_size": 30 }, "unavailable": [], "credits_used": 50 } ``` | Field | What it holds | | --------------------------------------- | ---------------------------------------------------------------------- | | `data.items[].author` | One similar account in the shared [author shape](/docs/schema/author). | | `author.followers` / `author.following` | Follower and following counts. | | `author.posts_count` | How many videos the account has posted. | | `author.likes_count` | Total likes across the account's videos. | | `author.bio` / `author.verified` | Profile bio and verified badge. | | `author.joined_at` | The day the account was created. | | `data.total` | How many accounts this call returned: 30 here. | | `pagination.has_more` | Always `false`: the list is one fixed set. | ## How do I go wider than 30 accounts? [#how-do-i-go-wider-than-30-accounts] Call the endpoint again with a result's `username` as the new `handle`, and drop accounts you have already seen by `author.id`. Each call is 50 credits, so set a budget first. ```python title="Python: two levels, deduplicated" import os import requests BASE = "https://api.insightsocial.app/v1" HEADERS = {"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]} def similar(handle): body = requests.get(f"{BASE}/tiktok/similar", params={"handle": handle}, headers=HEADERS, timeout=120).json() return [item["author"] for item in body["data"]["items"]] seen = {} first = similar("gordonramsayofficial") for a in first: seen[a["id"]] = a for a in first[:5]: # 5 more calls = 250 credits for b in similar(a["username"]): seen.setdefault(b["id"], b) print(len(seen), "unique accounts") ``` ## What are the limits? [#what-are-the-limits] * **About 30 accounts, one fixed list.** There is no cursor; `has_more` is `false`. Repeat the call on a result to go wider. * **Similarity is TikTok's, not topical.** For `@gordonramsayofficial` the list held Tilly Ramsay and kitchen clip accounts, but also MrBeast, Megan Thee Stallion and the Denver Broncos. Filter by bio or follower count in your own code. * **Mixed sizes.** The same list ran from under 3,000 followers to over 143 million. * **Some fields come back empty.** `location`, `external_url` and `last_post_at` were `null` on every account in the sample. `null` means unknown, not empty. ## What can I build with it? [#what-can-i-build-with-it] * **Influencer lookalikes.** Start from a creator who performed well for you and get a shortlist of similar accounts with their reach. * **Competitor mapping.** Seed with a competitor's brand account to see which accounts TikTok groups with it. * **Creator database seeding.** Walk two levels out from a few seeds and store every account with its counts. ## Related [#related] * [`GET /v1/tiktok/similar` reference](/docs/api-reference/tiktok/similar): every parameter and field. * [`GET /v1/tiktok/search/users`](/docs/api-reference/tiktok/search-users): find TikTok accounts by keyword instead of by seed. * [TikTok endpoints](/docs/platforms/tiktok): everything the API covers on TikTok. --- # Get the videos a TikTok user has liked (/docs/how-to/tiktok-videos-a-user-liked) List the videos a TikTok account has liked, with each video's author, views, likes and caption, by handle. 10 credits per page of 30 videos. To list the videos a TikTok account has liked, call `GET /v1/tiktok/user/liked` with the account's `handle` (or its numeric `user_id`). Each page returns 30 videos, newest first, each with its own author, view, like, comment, share and save counts, caption and a playable video URL. It costs 10 credits a page. Most accounts hide this list; a hidden list comes back as a not-found and costs nothing. TikTok's official API only offers liked-videos data through its Research API, which is limited to approved academic researchers. 10 credits per page of 30 videos. Walking 10 pages (300 videos) costs 100 credits. Asking for the same page again within 6 hours is answered from the shared cache for 2 credits. Failed calls, empty results and hidden lists are free. ## Why do most accounts return not found? [#why-do-most-accounts-return-not-found] Most TikTok accounts hide the videos they have liked. When the list is hidden, the endpoint answers with a 404 [not found](/docs/errors) and the call is refunded, so it costs 0 credits. Retrying the same account returns the same answer, so record it and move on. A 404 does not tell you whether the list is hidden or the account does not exist. If you need to know which, look the account up with `GET /v1/tiktok/profile` (10 credits). ## How do I find the handle? [#how-do-i-find-the-handle] The handle is the name after the `@` in the profile URL: `https://www.tiktok.com/@chipotle` has the handle `chipotle`. Send it without the `@`. If you already have the account's numeric ID, send it as `user_id` instead, which gives faster responses. `GET /v1/tiktok/profile` returns the ID for a handle. ## Make the request [#make-the-request] ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/user/liked?handle=chipotle" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python title="Python" import os import requests res = requests.get( "https://api.insightsocial.app/v1/tiktok/user/liked", params={"handle": "chipotle"}, headers={"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]}, timeout=120, ) if res.status_code == 404: print("Liked list is hidden or the account does not exist (not charged)") else: for item in res.json()["data"]["items"]: post = item["post"] print(post["author"]["username"], post["engagement"]["views"], post["url"]) ``` ```ts title="Node.js" const url = new URL("https://api.insightsocial.app/v1/tiktok/user/liked"); url.searchParams.set("handle", "chipotle"); const res = await fetch(url, { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY! } }); if (res.status === 404) { console.log("Liked list is hidden or the account does not exist (not charged)"); } else { const body = await res.json(); for (const { post } of body.data.items) console.log(post.author.username, post.engagement.views, post.url); } ``` ## What comes back [#what-comes-back] A real response from 2026-10-14 for `@chipotle`, shortened: one video instead of 30, long URLs cut, and the video's creator replaced with a placeholder. ```json title="Response (shortened)" { "success": true, "endpoint": "/v1/tiktok/user/liked", "schema_version": "2", "data": { "items": [ { "post": { "id": "7694937734091263262", "url": "https://www.tiktok.com/@example_creator/video/7694937734091263262", "kind": "short", "content": { "text": "whew I truly love you… #chipotle #margarita #newyork", "media_urls": ["https://v45.tiktokcdn-eu.com/…"], "thumbnail_url": "https://p19-common-sign.tiktokcdn-eu.com/…", "duration_seconds": 13.281 }, "author": { "id": "…", "username": "example_creator", "display_name": "Example Creator", "verified": false }, "engagement": { "views": 7822, "likes": 260, "comments": 9, "shares": 58, "saves": 8 }, "published_at": "2026-10-10T07:29:21.000Z", "ext": { "music_id": "7602834704501508112", "download_count": 0, "region": "US", "on_screen_texts": ["trying the chipotle margarita 😍"] } } } ], "total": null, "truncated": null }, "pagination": { "next_cursor": "v2c.Frx-WnqEJaeYmKVE…", "has_more": true, "page_size": 30 }, "unavailable": [], "credits_used": 10 } ``` | Field | What it holds | | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | `data.items[].post` | One liked video in the shared [post shape](/docs/schema/post): caption, video and thumbnail URLs, duration, views, likes, comments, shares, saves. | | `data.items[].post.author` | The account that posted the video, not the account whose likes you asked for. | | `data.items[].post.published_at` | When the video was posted, not when it was liked. | | `data.items[].post.ext.on_screen_texts` | Text the creator typed onto the video with TikTok's text tool. Present on 16 of the 30 videos in this sample. | | `data.items[].post.ext.music_id` | The sound the video uses. | | `data.total` | `null`: TikTok does not say how many videos the account has liked. | ## How do I get more than 30 videos? [#how-do-i-get-more-than-30-videos] Send `pagination.next_cursor` back as `cursor`, with the same `handle`, and stop when `pagination.has_more` is `false`. Each page is 10 credits. ```python title="Python: walk the first 5 pages" import os import requests BASE = "https://api.insightsocial.app/v1" HEADERS = {"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]} params = {"handle": "chipotle"} liked = [] for _ in range(5): body = requests.get(f"{BASE}/tiktok/user/liked", params=params, headers=HEADERS, timeout=120).json() liked += body["data"]["items"] if not body["pagination"]["has_more"]: break params["cursor"] = body["pagination"]["next_cursor"] ``` See [Pagination](/docs/pagination) for the full rules. ## What are the limits? [#what-are-the-limits] * **Hidden lists.** Most accounts hide their liked videos. A hidden list is a 404 not-found and is refunded. * **One direction only.** This is what one account liked. TikTok has no list of who liked a given video, so the API cannot return one. * **Order.** The list comes newest first, but `published_at` is the video's post date, so publish dates on a page are not in order: one page mixed videos posted between October 4 and October 12. * **No total.** `data.total` is `null`; you find the end of the list when `has_more` is `false`. * **Other people's videos.** Every item is a video by another creator, with that creator's own counts. ## What can I build with it? [#what-can-i-build-with-it] * **Brand affinity.** A brand's liked list shows which creator videos it engages with. All 30 videos on the first page of Chipotle's list mention Chipotle in the caption or on-screen text. * **Creator research.** What a creator likes shows the niches and peers they follow, which helps when you pitch them. * **UGC sourcing.** Videos a brand already liked are a short list of user content to ask permission to reuse. ## Related [#related] * [`GET /v1/tiktok/user/liked` reference](/docs/api-reference/tiktok/user-liked): every parameter and field. * [`GET /v1/tiktok/user/following`](/docs/api-reference/tiktok/user-following): the accounts a TikTok user follows. * [`GET /v1/tiktok/profile`](/docs/api-reference/tiktok/profile): check an account and get its user ID. * [TikTok endpoints](/docs/platforms/tiktok): everything the API covers on TikTok. --- # Get TikTok videos tagged at a location (/docs/how-to/tiktok-videos-by-location) List public TikTok videos tagged at a place, with views, likes, captions and authors, by TikTok place ID. 10 credits per page of 20 videos. To list the TikTok videos tagged at a place, call `GET /v1/tiktok/location/posts` with TikTok's `location_id` for that place. Each page returns 20 public videos with their view, like, comment, share and save counts, caption, author and a playable video URL. It costs 10 credits a page. 10 credits per page of 20 videos. Walking 10 pages (200 videos) costs 100 credits. Asking for the same page again within 6 hours is answered from the shared cache for 2 credits. Failed calls and empty results are free, and so is an unknown place ID. ## How do I find the location ID? [#how-do-i-find-the-location-id] The `location_id` is TikTok's own place ID, the long number in the URL of that place's page on TikTok. Open a video that has a location tag, tap the place name, and copy the number from the URL: a place page whose URL ends in `22535865202815278` has that ID. The API has no TikTok place search, so you cannot look up an ID by name; take it from the place page. The optional `region` parameter takes a two-letter country code (`US`, `GB`, …) and fetches the videos as seen from that country. It defaults to `US`. ## Make the request [#make-the-request] ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/location/posts?location_id=22535865202815278" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python title="Python" import os import requests res = requests.get( "https://api.insightsocial.app/v1/tiktok/location/posts", params={"location_id": "22535865202815278"}, headers={"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]}, timeout=120, ) for item in res.json()["data"]["items"]: post = item["post"] print(post["published_at"], post["engagement"]["views"], post["url"]) ``` ```ts title="Node.js" const url = new URL("https://api.insightsocial.app/v1/tiktok/location/posts"); url.searchParams.set("location_id", "22535865202815278"); const body = await (await fetch(url, { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY! } })).json(); for (const { post } of body.data.items) console.log(post.published_at, post.engagement.views, post.url); ``` ## What comes back [#what-comes-back] A real response from 2026-10-14 for the place ID above; its videos are from Seoul. Shortened: one video instead of 20, long URLs cut, and the poster's account replaced with a placeholder. ```json title="Response (shortened)" { "success": true, "endpoint": "/v1/tiktok/location/posts", "schema_version": "2", "data": { "items": [ { "post": { "id": "7695743564919213364", "url": "https://www.tiktok.com/@example_creator/video/7695743564919213364", "kind": "short", "content": { "text": "✨ Myeongdong Street 명동 거리 — Seoul’s Vibrant Heart 🇰🇷 …", "media_urls": ["https://v16m.tiktokcdn-us.com/…"], "thumbnail_url": "https://p19-common-sign.tiktokcdn-us.com/…", "duration_seconds": 21.034 }, "author": { "id": "…", "username": "example_creator", "display_name": "Example Creator", "verified": false }, "engagement": { "views": 4951, "likes": 324, "comments": 6, "shares": 12, "saves": 50 }, "published_at": "2026-10-12T11:35:36.000Z", "ext": { "music_id": "7695743622973131528", "download_count": 7, "region": "KR" } } } ], "total": null, "truncated": null }, "pagination": { "next_cursor": "v2c.sscG5h7wUiZWtLX_…", "has_more": true, "page_size": 20 }, "unavailable": [], "credits_used": 10 } ``` | Field | What it holds | | --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | `data.items[].post` | One video in the shared [post shape](/docs/schema/post): caption, video and thumbnail URLs, duration, views, likes, comments, shares, saves, publish time. | | `data.items[].post.author` | The account that posted the video. | | `data.items[].post.ext.region` | The region TikTok assigns to the video, not the place. One Seoul page carried KR, US, IT, DE, KE, VN and TH. | | `data.items[].post.ext.on_screen_texts` | Text typed onto the video with TikTok's text tool, when there is any. | | `data.total` | `null`: TikTok does not say how many videos are tagged at the place. | ## How do I get more than 20 videos? [#how-do-i-get-more-than-20-videos] Send `pagination.next_cursor` back as `cursor`, with the same `location_id` and `region`, and stop when `pagination.has_more` is `false`. Each page is 10 credits. ```python title="Python: walk the first 5 pages" import os import requests BASE = "https://api.insightsocial.app/v1" HEADERS = {"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]} params = {"location_id": "22535865202815278"} videos = [] for _ in range(5): body = requests.get(f"{BASE}/tiktok/location/posts", params=params, headers=HEADERS, timeout=120).json() videos += body["data"]["items"] if not body["pagination"]["has_more"]: break params["cursor"] = body["pagination"]["next_cursor"] ``` See [Pagination](/docs/pagination) for the full rules. ## What are the limits? [#what-are-the-limits] * **Place ID only.** There is no TikTok place search in the API. Copy the ID from the place page URL. * **Unknown place versus quiet place.** An ID TikTok does not know is a 404 not-found and is refunded. A real place with nothing recent returns an empty list, which is also free. * **Order.** Videos are not sorted by date: one page mixed videos posted between January 30 and October 14, 2026. Sort in your own code if you need to. * **Public videos only.** Videos from private accounts never appear. * **No total.** `data.total` is `null`; you find the end when `has_more` is `false`. ## What can I build with it? [#what-can-i-build-with-it] * **Venue and destination monitoring.** Track views and new videos at a hotel, restaurant, venue or city over time. * **Local creator discovery.** The authors of the most-viewed videos at a place are creators already covering it. * **Event coverage.** Pull the videos tagged at a stadium or festival ground in the days after an event. ## Related [#related] * [`GET /v1/tiktok/location/posts` reference](/docs/api-reference/tiktok/location-posts): every parameter and field. * [TikTok endpoints](/docs/platforms/tiktok): everything the API covers on TikTok. --- # Search Xiaohongshu (RedNote) notes by keyword (/docs/how-to/xiaohongshu-rednote-search) Find Xiaohongshu (RedNote) notes by keyword, with title, summary, creator, likes, comments, saves and shares. 50 credits per note returned. To search Xiaohongshu (RedNote) notes by keyword, call `GET /v1/xiaohongshu/search` with a `query` in Chinese or English. Each call returns up to 20 notes, 10 by default, with the note's title, a short summary, its creator, its like, comment, save and share counts, a cover image and the publish time. It is metered at 50 to 1,000 credits per call: the range scales with `limit`, which works out to 50 credits per note, so the default 10 notes cost 500. 50 to 1,000 credits per call: 50 at `limit=1`, 1,000 at `limit=20`. The sample below used the default `limit` of 10 and was charged 500. When the call starts, the most it can cost with your `limit` is held; you are charged what it used and the rest is released. Add `dry_run=1` to get a free quote first. Each further page is charged the same way. Asking the same search again within 1 hour is answered from the shared cache for 2 credits. Failed calls and empty results are free. ## Which parameters can I set? [#which-parameters-can-i-set] | Parameter | Values | | ----------- | ------------------------------------------------------------------------------------ | | `query` | Required. The search keywords, for example `护肤` (skincare) or `camping`. | | `limit` | Notes per call, 1 to 20. Default 10. | | `sort` | `relevance` (default), `latest`, `most_liked`, `most_commented` or `most_collected`. | | `type` | `all` (default), `image` or `video`. | | `published` | Recency window: `all` (default), `day`, `week` or `half_year`. | | `cursor` | The `pagination.next_cursor` from the previous page. Omit it for the first page. | ## Make the request [#make-the-request] ```bash title="cURL" curl -G "https://api.insightsocial.app/v1/xiaohongshu/search" \ --data-urlencode "query=护肤" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python title="Python" import os import requests res = requests.get( "https://api.insightsocial.app/v1/xiaohongshu/search", params={"query": "护肤", "limit": 10}, headers={"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]}, timeout=120, ) for item in res.json()["data"]["items"]: post = item["post"] print(post["ext"]["title"], post["engagement"]["likes"], post["engagement"]["saves"], post["url"]) ``` ```ts title="Node.js" const url = new URL("https://api.insightsocial.app/v1/xiaohongshu/search"); url.searchParams.set("query", "护肤"); url.searchParams.set("limit", "10"); const body = await (await fetch(url, { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY! } })).json(); for (const { post } of body.data.items) console.log(post.ext.title, post.engagement.likes, post.engagement.saves, post.url); ``` ## What comes back [#what-comes-back] A real response from 2026-10-14 for `query=护肤`, shortened: two notes instead of 10, summaries and long URLs cut, and the creators replaced with placeholders. ```json title="Response (shortened)" { "success": true, "endpoint": "/v1/xiaohongshu/search", "schema_version": "2", "data": { "items": [ { "post": { "id": "6a5f4af70000000011007275", "url": "https://www.xiaohongshu.com/explore/6a5f4af70000000011007275", "kind": "image", "content": { "text": "P1就是随手拍的照片…", "media_urls": null, "thumbnail_url": "https://sns-img-qc.xhscdn.com/notes_pre_post/…", "duration_seconds": null }, "author": { "id": "example_user_id", "username": "example_user", "display_name": "Example User", "verified": null }, "engagement": { "views": null, "likes": 5217, "comments": 63, "shares": 198, "saves": 2657 }, "published_at": "2026-07-21T10:33:27.000Z", "ext": { "title": "戒糖+内调1年,素颜已达next level", "media_type": "image", "text_truncated": true } } }, { "post": { "id": "6ab9051e000000000202b634", "url": "https://www.xiaohongshu.com/explore/6ab9051e000000000202b634", "kind": "video", "content": { "text": "一期无广的晚间护肤分享…", "media_urls": ["https://sns-video-bd.xhscdn.com/stream/…mp4"], "thumbnail_url": "https://sns-img-qc.xhscdn.com/…", "duration_seconds": 242.666 }, "author": { "id": "example_user_id_2", "username": "example_user_2", "display_name": "Example User 2", "verified": null }, "engagement": { "views": null, "likes": 841, "comments": 27, "shares": 34, "saves": 145 }, "published_at": "2026-09-27T11:59:26.000Z", "ext": { "title": "我的晚间护肤流程", "media_type": "video", "text_truncated": true } } } ], "total": null }, "pagination": { "next_cursor": "v2c.aucAu1l_…", "has_more": true, "page_size": 10 }, "unavailable": [], "credits_used": 500 } ``` | Field | What it holds | | ------------------------- | ---------------------------------------------------------------------------- | | `data.items[].post` | One note in the shared [post shape](/docs/schema/post). | | `post.ext.title` | The note's title. | | `post.content.text` | A short summary of the note body. `ext.text_truncated: true` says it is cut. | | `post.kind` | `image` for picture notes, `video` for video notes. | | `post.content.media_urls` | The video file for video notes; `null` for image notes in search results. | | `post.engagement` | Likes, comments, shares and saves (Xiaohongshu calls saves "collects"). | | `post.author` | The creator: ID, username, display name, avatar. | | `pagination.next_cursor` | Pass it back as `cursor` for the next page. | ## How do I get more notes? [#how-do-i-get-more-notes] Send `pagination.next_cursor` back as `cursor`, with the same `query` and filters, and stop when `pagination.has_more` is `false`. Each page is charged like the first: 50 credits per note, so 500 for a page of 10. ```python title="Python: walk the first 3 pages" import os import requests BASE = "https://api.insightsocial.app/v1" HEADERS = {"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]} params = {"query": "护肤", "limit": 10, "sort": "most_liked"} notes = [] for _ in range(3): body = requests.get(f"{BASE}/xiaohongshu/search", params=params, headers=HEADERS, timeout=120).json() notes += body["data"]["items"] if not body["pagination"]["has_more"]: break params["cursor"] = body["pagination"]["next_cursor"] ``` Three pages of 10 notes cost 1,500 credits, so set a page limit before you start. See [Pagination](/docs/pagination) for the full rules. ## What are the limits? [#what-are-the-limits] * **Summaries, not full notes.** Search returns a short summary of each note. Pass the note's ID to `GET /v1/xiaohongshu/post` (50 credits) for the full body, images or video. * **No view counts.** `engagement.views` is `null` on every note in the sample, which means unknown, not zero. * **No total.** `data.total` is `null`: the search does not say how many notes match. * **No verified badge.** `author.verified` is `null` in search results. * **Price per note.** The cost grows with `limit`, so ask for the number of notes you need, not the maximum. ## What can I build with it? [#what-can-i-build-with-it] * **Market research in China.** Search a product category such as `护肤` with `sort=most_collected` to see which notes people save, and which brands and claims they mention. * **Creator discovery.** The authors of the most-liked notes on a keyword are creators already working in that niche. Pass `post.author.id` as `id` to `GET /v1/xiaohongshu/profile` for their follower counts. * **Brand monitoring.** Search your brand name with `sort=latest` and `published=week` on a schedule to catch new notes about it. The other Xiaohongshu endpoints work with what search returns: `post` (50 credits) for a note's full body, `post/comments` (50 to 1,000) for its comments, `profile` (50) and `profile/posts` (50 to 1,000) for a creator, and `trending` (50 to 1,000) for the live hot-search board. ## Related [#related] * [`GET /v1/xiaohongshu/search` reference](/docs/api-reference/xiaohongshu/search): every parameter and field. * [`GET /v1/xiaohongshu/post`](/docs/api-reference/xiaohongshu/post): one note in full. * [`GET /v1/xiaohongshu/trending`](/docs/api-reference/xiaohongshu/trending): what is trending on Xiaohongshu now. * [Xiaohongshu endpoints](/docs/platforms/xiaohongshu): everything the API covers on Xiaohongshu (RedNote). --- # Get a YouTube channel's business email (/docs/how-to/youtube-channel-email) Read the address behind a YouTube channel's "View email address" button, plus its country and profile, by handle. 250 credits per channel. To get the business email a YouTube channel publishes, call `GET /v1/youtube/channel/about` with the channel's `handle`, `channelId` or `url`. It returns the address behind the About tab's "View email address" control on `author.ext.public_email`, the channel's listed country, and its profile: name, handle, avatar, bio, subscribers, join date and total views. It costs 250 credits per channel. The cheaper `GET /v1/youtube/channel` (10 credits) only finds emails written in the public description, so try it first and use this one for the channels it misses. 250 credits per channel. Checking 20 shortlisted channels costs 5,000 credits. Asking for the same channel again within 24 hours is answered from the shared cache for 2 credits. Failed calls and empty results are free. ## How do I find the channel handle? [#how-do-i-find-the-channel-handle] The handle is the part after `@` in the channel URL: `https://www.youtube.com/@mkbhd` has the handle `mkbhd`. Pass it without the `@`. If you have a URL in the older `https://www.youtube.com/channel/UC…` form, pass the `UC…` part as `channelId`, or pass the whole link as `url`. ## Should I try the cheaper call first? [#should-i-try-the-cheaper-call-first] Yes. Many creators write their business address in the channel description. `GET /v1/youtube/channel` reads that description and puts any address it finds on the same field, `author.ext.public_email`, for 10 credits. Only when that field is `null` is the 250-credit call worth making: it reads the address behind the About tab control, which the description does not always repeat. ```python title="Python: description first, About tab second" import os import requests BASE = "https://api.insightsocial.app/v1" HEADERS = {"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]} def business_email(handle): for path in ("/youtube/channel", "/youtube/channel/about"): body = requests.get(BASE + path, params={"handle": handle}, headers=HEADERS, timeout=120).json() email = body["data"]["author"]["ext"].get("public_email") if email: return email return None ``` ## Make the request [#make-the-request] ```bash title="cURL" curl "https://api.insightsocial.app/v1/youtube/channel/about?handle=mkbhd" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ```python title="Python" import os import requests res = requests.get( "https://api.insightsocial.app/v1/youtube/channel/about", params={"handle": "mkbhd"}, headers={"x-api-key": os.environ["INSIGHTSOCIAL_API_KEY"]}, timeout=120, ) author = res.json()["data"]["author"] print(author["display_name"], author["ext"]["public_email"], author["ext"]["country"]) ``` ```ts title="Node.js" const url = new URL("https://api.insightsocial.app/v1/youtube/channel/about"); url.searchParams.set("handle", "mkbhd"); const body = await (await fetch(url, { headers: { "x-api-key": process.env.INSIGHTSOCIAL_API_KEY! } })).json(); const { author } = body.data; console.log(author.display_name, author.ext.public_email, author.ext.country); ``` ## What comes back [#what-comes-back] A real response from 2026-10-14, shortened: the avatar URL is cut and two of the five links are dropped. ```json title="Response (shortened)" { "success": true, "endpoint": "/v1/youtube/channel/about", "schema_version": "2", "data": { "author": { "id": "UCBJycsmduvYEL83R_U4JriQ", "username": "@mkbhd", "display_name": "Marques Brownlee", "avatar_url": "https://yt3.googleusercontent.com/qu4TmIaYUlS41…", "bio": "MKBHD: Quality Tech Videos | YouTuber | Geek | … business@MKBHD.com\n\nNYC", "verified": true, "followers": 21400000, "followers_approximate": true, "posts_count": 1858, "url": "https://www.youtube.com/channel/UCBJycsmduvYEL83R_U4JriQ", "joined_at": "2008-03-21T00:00:00.000Z", "ext": { "country": "United States", "public_email": "business@mkbhd.com", "links": ["https://twitter.com/MKBHD", "https://discord.gg/MKBHD"], "keywords": "MKBHD, MarquesBrownlee, Marques, Brownlee", "total_views": 5767983054 } } }, "unavailable": [], "credits_used": 250 } ``` | Field | What it holds | | ------------------------------ | --------------------------------------------------------------------------------------------------------- | | `data.author.ext.public_email` | The address behind the About tab's "View email address" control. `null` when the channel has not set one. | | `data.author.ext.country` | The country the channel lists on its About tab. | | `data.author.ext.links` | The links shown on the About tab. | | `data.author.followers` | Subscriber count. `followers_approximate: true` means YouTube rounds it. | | `data.author.posts_count` | Number of videos on the channel. | | `data.author.ext.total_views` | Lifetime views across the channel. | | `data.author.joined_at` | When the channel was created. | The profile follows the shared [author shape](/docs/schema/author). ## What are the limits? [#what-are-the-limits] * **Not every channel sets one.** The address exists only when the creator added it on YouTube. Without one, `public_email` is `null`. * **One channel per call.** The catalogue marks this endpoint premium and advises shortlisting channels before you call it. * **Rounded subscribers.** YouTube shows rounded counts above 1,000, so `followers` is approximate. * **Personal address.** Add `contact_email=1` (no extra credits) to also get `author.ext.contact_email`: when the bio lists two or more addresses, the one the creator gives for personal contact, copied from the bio. It is `null` when there is one address or none, when every address belongs to a manager, agency or brand, or when the choice was not confident. ## What can I build with it? [#what-can-i-build-with-it] * **Sponsorship outreach.** Pull a niche's channels, keep those within your subscriber range, and collect the business address each one publishes for brand inquiries. * **Agency prospecting.** Group a shortlist by `ext.country` before you reach out, so each contact gets the right market and language. * **CRM enrichment.** Add the published business contact, subscriber count and total views to channel records you already keep. ## Related [#related] * [`GET /v1/youtube/channel/about` reference](/docs/api-reference/youtube/channel-about): every parameter and field. * [`GET /v1/youtube/channel`](/docs/api-reference/youtube/channel): the 10-credit profile, which reads emails from the description. * [YouTube endpoints](/docs/platforms/youtube): everything the API covers on YouTube. --- # Bluesky (/docs/platforms/bluesky) Bluesky API reference: 4 endpoints for profiles, posts and post search. Per-endpoint credit prices and cURL examples. Profiles, posts, a user's posts and post search on Bluesky. Pass handles as they appear, e.g. `espn.com`. Base path: `/v1/bluesky/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/bluesky/profile?handle=espn.com" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] Every endpoint here has a fixed price. | Endpoint | Credits | What it returns | Key parameters | | ------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | | [`/profile`](/docs/api-reference/bluesky/profile) | 10 | Returns a Bluesky user's public profile: handle, display name, avatar, description, follower and follows counts, post count, created date, and verification status. | `handle` | | [`/user/posts`](/docs/api-reference/bluesky/user-posts) | 10 | Returns a feed of posts for a Bluesky user: text, author info, embeds, reply/repost/like/quote counts, and when each was indexed. | `handle`, `user_id` | | [`/post`](/docs/api-reference/bluesky/post) | 10 | Returns one Bluesky post: its record text, author info, embeds, reply count, repost count, like count, quote count, and a threaded replies array. | `url` | | [`/search`](/docs/api-reference/bluesky/search) | 10 | Returns Bluesky posts matching a keyword, up to 100 per page, each with its text, author, like/comment/share counts, and when it was written. | `query` | --- # Douyin (/docs/platforms/douyin) Douyin API reference: 8 endpoints for creators, videos, comments, search and trending. Per-endpoint credit prices and cURL examples. Creator profiles, videos, comments and replies, creator and video search, and the hot-search board. Base path: `/v1/douyin/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/douyin/profile?url=https%3A%2F%2Fwww.douyin.com%2Fuser%2FMS4wLjABAAAAtxsy7VmVkU3RN9oIX0vdkh_6-LlQAb0gwI-tDf-bYNg" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] 5 of these are **metered**: the price depends on how much the call reads. See [Credits](/docs/credits). 1 is **beta**: it returns the platform's own structure under our naming rules (snake\_case keys, string ids, ISO times where the platform gives a timestamp) rather than a schema-2 entity, and their fields may change. See [Schema 2](/docs/schema-2). | Endpoint | Credits | What it returns | Key parameters | | ---------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | | [`/search`](/docs/api-reference/douyin/search) | 50–1250 | Returns Douyin videos matching a keyword: caption, creator, likes, comments, shares, saves, hashtags, music, cover image, and duration. | `query` | | [`/profile`](/docs/api-reference/douyin/profile) | 60 | Returns a Douyin creator's profile: nickname, Douyin ID, bio, avatar, follower and following counts, total likes received, video count, region, and verification. | `handle`, `url`, `id` | | [`/profile/posts`](/docs/api-reference/douyin/profile-posts) | 50–1250 | Returns a Douyin creator's recent videos, newest first: caption, likes, comments, shares, saves, hashtags, music, and cover image. | `handle`, `url`, `id` | | [`/post`](/docs/api-reference/douyin/post) | 100 | Returns one Douyin video: caption, creator, likes, comments, shares, saves, hashtags, music, duration, dimensions, cover image, and tagged place when set. | `url` | | [`/post/comments`](/docs/api-reference/douyin/post-comments) | 20–1000 | Returns top-level comments on a Douyin video: text, commenter, like count, reply count, IP region, and whether the creator liked it. | `url` | | [`/comment/replies`](/docs/api-reference/douyin/comment-replies) | 50–2500 | Returns the reply thread under one Douyin comment: text, replier, like count, IP region, and verification, each tagged with the parent comment id. | `url`, `comment_id` | | [`/search/users`](/docs/api-reference/douyin/search-users) | 50–1250 | Returns Douyin creators matching a keyword: nickname, Douyin ID, bio, follower count, total likes received, avatar, profile URL, and verification label. | `query` | | [`/trending`](/docs/api-reference/douyin/trending) | 250 | Returns the live Douyin hot-search board: roughly 50 trending topics with rank, hot value, view count, video count, and the time each topic broke. *Beta.* | — | --- # Kick (/docs/platforms/kick) Kick API reference: 1 endpoints for clips. Per-endpoint credit prices and cURL examples. Clip details. Base path: `/v1/kick/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/kick/clip?url=https%3A%2F%2Fkick.com%2Fxqc%2Fclips%2Fclip_abc123" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] Every endpoint here has a fixed price. | Endpoint | Credits | What it returns | Key parameters | | ---------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- | -------------- | | [`/clip`](/docs/api-reference/kick/clip) | 10 | Returns one Kick clip's title, view count, duration, category, creator name, channel name, thumbnail URL, and creation timestamp. | `url` | --- # Kwai (/docs/platforms/kwai) Kwai API reference: 3 endpoints for profiles and posts. Per-endpoint credit prices and cURL examples. Profiles, posts and a user's posts. Base path: `/v1/kwai/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/kwai/profile?handle=KwaiBrasilOficial" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] Every endpoint here has a fixed price. | Endpoint | Credits | What it returns | Key parameters | | ---------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------- | | [`/profile`](/docs/api-reference/kwai/profile) | 10 | Returns a Kwai user's public profile: username, bio, avatar, verification status, and follower, following, like, and post counts. | `handle`, `url` | | [`/user/posts`](/docs/api-reference/kwai/user-posts) | 10 | Returns a paginated list of a Kwai user's posts: captions, media URLs, covers, engagement counts, and author info. | `handle`, `url` | | [`/post`](/docs/api-reference/kwai/post) | 10 | Returns one Kwai post: caption, video and cover URLs, view/like/comment/share counts, author info, and music metadata. | — | --- # LinkedIn (/docs/platforms/linkedin) LinkedIn API reference: 67 endpoints for profiles, companies, posts, comments, reactions, jobs and search. Per-endpoint credit prices and cURL examples. People and their full profile sections, companies, posts, comments, reactions, articles, groups, jobs, ads and search. New to the API? Read the [LinkedIn scraper API overview](/social-media-api/linkedin) for what it returns and how it compares with the official API. Base path: `/v1/linkedin/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/linkedin/profile?url=https%3A%2F%2Fwww.linkedin.com%2Fin%2Fwilliamhgates%2F" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] 6 of these are **metered**: the price depends on how much the call reads. See [Credits](/docs/credits). 37 are **beta**: they return the platform's own structure under our naming rules (snake\_case keys, string ids, ISO times where the platform gives a timestamp) rather than a schema-2 entity, and their fields may change. See [Schema 2](/docs/schema-2). | Endpoint | Credits | What it returns | Key parameters | | ---------------------------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | | [`/profile`](/docs/api-reference/linkedin/profile) | 50 | Returns a LinkedIn member's public profile: full name, headline, location, follower and connection counts, profile picture, and profile URL. | `url` | | [`/company`](/docs/api-reference/linkedin/company) | 50 | Returns a LinkedIn company page: company name, description, follower count, headquarters location, website, and logo. | `url` | | [`/company/by-domain`](/docs/api-reference/linkedin/company-by-domain) | 50 | Returns the LinkedIn company page that owns a website domain: name, description, follower count, headquarters, website, logo, and numeric company id. | `domain` | | [`/profile/similar`](/docs/api-reference/linkedin/profile-similar) | 50 | Returns members LinkedIn groups with a given profile, each with handle, headline, profile URL, and picture. | `url` | | [`/search/companies`](/docs/api-reference/linkedin/search-companies) | 100 | Returns LinkedIn company pages matching a keyword, each with name, tagline, page URL, and logo. | `query` | | [`/profile/posted-jobs`](/docs/api-reference/linkedin/profile-posted-jobs) | 50 | Returns the jobs a LinkedIn member has posted, each with job id, title, hiring company, location, and posting date. *Beta.* | `url` | | [`/job/hiring-team`](/docs/api-reference/linkedin/job-hiring-team) | 50 | Returns the members LinkedIn shows as the hiring team on a job, each with handle, headline, profile URL, and picture. | `id`, `url` | | [`/profile/articles`](/docs/api-reference/linkedin/profile-articles) | 50 | Returns Pulse articles a LinkedIn member published, each with text, author, engagement, and date. | `url` | | [`/article`](/docs/api-reference/linkedin/article) | 50 | Returns one LinkedIn Pulse article: its text, author, like and comment counts, and publish time. | `url` | | [`/article/comments`](/docs/api-reference/linkedin/article-comments) | 50 | Returns comments on a LinkedIn Pulse article, with commenter identity, text, and timestamp. | `url` | | [`/article/reactions`](/docs/api-reference/linkedin/article-reactions) | 50 | Returns members who reacted to a LinkedIn Pulse article, each with handle, name, picture, and reaction type. | `url` | | [`/profile/activity`](/docs/api-reference/linkedin/profile-activity) | 50 | Returns when a LinkedIn member last showed public activity. *Beta.* | `url` | | [`/company/also-viewed`](/docs/api-reference/linkedin/company-also-viewed) | 50 | Returns company pages LinkedIn shows as people also viewed, each with name, page URL, and logo. | `company_id`, `url` | | [`/company/employees-count`](/docs/api-reference/linkedin/company-employees-count) | 50 | Returns how many LinkedIn members list a company as employer, optionally broken down by location. *Beta.* | `company_id` | | [`/profile/interests/schools`](/docs/api-reference/linkedin/profile-interests-schools) | 50 | Returns the school pages a LinkedIn member follows, each with name and page URL. *Beta.* | `url` | | [`/profile/interests/newsletters`](/docs/api-reference/linkedin/profile-interests-newsletters) | 50 | Returns the newsletters a LinkedIn member follows, each with name and page URL. *Beta.* | `url` | | [`/profile/interests/top-voices`](/docs/api-reference/linkedin/profile-interests-top-voices) | 50 | Returns the Top Voice profiles a LinkedIn member follows, each with name and profile URL. *Beta.* | `url` | | [`/profile/position-skills`](/docs/api-reference/linkedin/profile-position-skills) | 50 | Returns a member's positions with the skills listed on each role. *Beta.* | `url` | | [`/profile/top-position`](/docs/api-reference/linkedin/profile-top-position) | 50 | Returns the company page of the member's current top position: company id, name, website, headcount, industries and locations, not the job title. *Beta.* | `url` | | [`/search/people/by-url`](/docs/api-reference/linkedin/search-people-by-url) | 100 | Returns LinkedIn members from a people-search results URL, each with handle, headline, and profile URL. | `url` | | [`/profile/all`](/docs/api-reference/linkedin/profile-all) | 50 | Returns a member's entire public profile in one call: `author` with both counts, and `background` with About, experience, education, skills, recommendations, Featured and interests. *Beta.* | `url`, `urls` | | [`/profile/complete`](/docs/api-reference/linkedin/profile-complete) | 100 | Returns a member's full background: `author` in the /profile shape, and `background` with About, experiences, educations, skills and recommendations in the profile/\* item shapes. *Beta.* | `url` | | [`/profile/with-posts`](/docs/api-reference/linkedin/profile-with-posts) | 100 | Returns a member's profile with follower and connection counts in `author`, recent `posts` in the profile/posts item shape, and experiences, educations and skills under `background`. *Beta.* | `url` | | [`/post/with-comments`](/docs/api-reference/linkedin/post-with-comments) | 50 | Returns one LinkedIn post packed with its comments in a single payload. *Beta.* | `url` | | [`/post`](/docs/api-reference/linkedin/post) | 50 | Returns one LinkedIn post: its text, author name and picture, like, comment and share counts, attached media, and the publish time. | `url` | | [`/search/people`](/docs/api-reference/linkedin/search-people) | 100–500 | Returns LinkedIn members matching a name or filters, each with handle, headline, location, follower count, profile URL, and member id. | `query` | | [`/company/people`](/docs/api-reference/linkedin/company-people) | 100–500 | Returns the members who list a company as their employer, each with handle, headline, location, profile picture, and follower count. | `company_id` | | [`/post/comments`](/docs/api-reference/linkedin/post-comments) | 50 | Returns the comments on a LinkedIn post: commenter name, comment text, reaction counts, reply count, pinned and edited flags, and timestamps. | `url` | | [`/profile/posts`](/docs/api-reference/linkedin/profile-posts) | 50–2000 | Returns the posts a LinkedIn member published, each with text, author name, like, comment and share counts, media, and publish time. | `url` | | [`/profile/reactions`](/docs/api-reference/linkedin/profile-reactions) | 50 | Returns the posts a LinkedIn member reacted to, each with the post text, its original author, like, comment and share counts, and date. | `url` | | [`/post/reposts`](/docs/api-reference/linkedin/post-reposts) | 50 | Returns the reposts of a LinkedIn post, each with the resharer's name, any added commentary, engagement counts, and publish time. | `url` | | [`/group/posts`](/docs/api-reference/linkedin/group-posts) | 50 | Returns the posts inside a LinkedIn group, each with text, author name, like, comment and share counts, media, and publish time. | `group_id` | | [`/company/affiliated-pages`](/docs/api-reference/linkedin/company-affiliated-pages) | 50 | Returns a company's affiliated and showcase pages, each with page name, LinkedIn URL, speciality, follower count, and logo. | `company_id` | | [`/post/comments/replies`](/docs/api-reference/linkedin/post-comments-replies) | 50 | Returns the replies under one LinkedIn comment, each with the replier's name, reply text, reaction and reply counts, and timestamps. | `url`, `comment_id` | | [`/profile/experiences`](/docs/api-reference/linkedin/profile-experiences) | 50 | Returns a LinkedIn member's work history, with each role's job title, company, employment dates, location, and description. *Beta.* | `url` | | [`/profile/educations`](/docs/api-reference/linkedin/profile-educations) | 50 | Returns a LinkedIn member's education history, with each entry's school, degree, field of study, and the years attended. *Beta.* | `url` | | [`/profile/skills`](/docs/api-reference/linkedin/profile-skills) | 50 | Returns the skills listed on a LinkedIn member's profile, with each skill's name and the endorsements shown against it. *Beta.* | `url` | | [`/profile/honors`](/docs/api-reference/linkedin/profile-honors) | 50 | Returns the honors and awards on a LinkedIn member's profile, with each award's title, issuer, date, and description. *Beta.* | `url` | | [`/profile/certifications`](/docs/api-reference/linkedin/profile-certifications) | 50 | Returns the licenses and certifications on a LinkedIn member's profile, with each one's name, issuer, and issue or expiry dates. *Beta.* | `url` | | [`/profile/publications`](/docs/api-reference/linkedin/profile-publications) | 50 | Returns the publications on a LinkedIn member's profile, with each one's title, publisher, publication date, description, and link. *Beta.* | `url` | | [`/profile/volunteers`](/docs/api-reference/linkedin/profile-volunteers) | 50 | Returns the volunteer experience on a LinkedIn member's profile, with each entry's role, organisation, cause, and dates. *Beta.* | `url` | | [`/profile/recommendations`](/docs/api-reference/linkedin/profile-recommendations) | 50 | Returns the recommendations on a LinkedIn member's profile, with the recommender's name and headline, the recommendation text, and date. *Beta.* | `url` | | [`/profile/interests/companies`](/docs/api-reference/linkedin/profile-interests-companies) | 50 | Returns the companies a LinkedIn member follows, with each company's name, LinkedIn URL, follower count, and logo. *Beta.* | `url` | | [`/profile/interests/groups`](/docs/api-reference/linkedin/profile-interests-groups) | 50 | Returns the LinkedIn groups a member follows, with each group's name, URL, and the size of its membership. *Beta.* | `url` | | [`/profile/images`](/docs/api-reference/linkedin/profile-images) | 50 | Returns the image posts on a LinkedIn member's profile, with each post's text, image links, engagement counts, and publish time. | `url` | | [`/profile/videos`](/docs/api-reference/linkedin/profile-videos) | 50 | Returns the video posts on a LinkedIn member's profile, with each post's text, video and thumbnail links, engagement counts, and date. | `url` | | [`/profile/comments`](/docs/api-reference/linkedin/profile-comments) | 50 | Returns the comments a LinkedIn member left on other people's posts, with the comment text, the post it sits under, and the timestamp. *Beta.* | `url` | | [`/post/reactions`](/docs/api-reference/linkedin/post-reactions) | 100–500 | Returns the people who reacted to a LinkedIn post, each with their name, headline, profile URL, and the reaction they left. | `url` | | [`/company/jobs`](/docs/api-reference/linkedin/company-jobs) | 100 | Returns the jobs a company has posted, each with job id, title, location, hiring company details, posting date, and Easy Apply flag. *Beta.* | `company_id` | | [`/search/jobs`](/docs/api-reference/linkedin/search-jobs) | 100 | Returns LinkedIn job postings matching a keyword, each with job id, title, hiring company, location, posting date, and Easy Apply flag. *Beta.* | `query` | | [`/search/location`](/docs/api-reference/linkedin/search-location) | 10 | Returns LinkedIn locations matching a place name, each with the location's display name and the geocode id LinkedIn filters on. *Beta.* | `query` | | [`/search/schools`](/docs/api-reference/linkedin/search-schools) | 10 | Returns LinkedIn school pages matching a name, each with the school's name, page URL, and the id used in search filters. *Beta.* | `query` | | [`/search/industry`](/docs/api-reference/linkedin/search-industry) | 10 | Returns LinkedIn industries matching a keyword, each with the industry name and the id LinkedIn uses to identify it. *Beta.* | `query` | | [`/profile/about`](/docs/api-reference/linkedin/profile-about) | 50 | Returns the month a LinkedIn member joined and how recently contact details and the profile photo were updated, plus identity verification when LinkedIn shows it for that member. *Beta.* | `url` | | [`/profile/contact`](/docs/api-reference/linkedin/profile-contact) | 50 | Returns the contact details a LinkedIn member exposes publicly: websites, phone numbers, address, WeChat, and Twitter, alongside their name and profile urn. *Beta.* | `url` | | [`/profile/stats`](/docs/api-reference/linkedin/profile-stats) | 50 | Returns a LinkedIn member's audience size: their follower count and their connection count. *Beta.* | `url` | | [`/company/job-count`](/docs/api-reference/linkedin/company-job-count) | 50 | Returns the number of jobs a LinkedIn company currently has open. *Beta.* | `company_id` | | [`/company/insights`](/docs/api-reference/linkedin/company-insights) | 50 | Returns headcount breakdowns of a LinkedIn company's members as name and count pairs, covering locations, schools, job functions, skills, service categories, and fields of study. *Beta.* | `company_id` | | [`/group`](/docs/api-reference/linkedin/group) | 50 | Returns a LinkedIn group's profile: name, description, member count, posting rules, industries, owners, logo and cover images, and its public and active flags. *Beta.* | `group_id` | | [`/job`](/docs/api-reference/linkedin/job) | 50 | Returns one LinkedIn job posting in full: title, hiring company, location, posting date, the job description text, and the Easy Apply flag. *Beta.* | `id` | | [`/company/posts`](/docs/api-reference/linkedin/company-posts) | 50 | Returns the recent posts from a LinkedIn company page, each with text, author name, like, comment and share counts, media, and date. | `company_id` | | [`/ad`](/docs/api-reference/linkedin/ad) | 50 | Returns one LinkedIn ad from the Ad Library: the ad copy, creative images, the advertiser's name and logo, total impressions, and start date. | `url` | | [`/ads/search`](/docs/api-reference/linkedin/ads-search) | 50 | Returns ads from the LinkedIn Ad Library matching a company, keyword, country, or date range, with each ad's copy and the advertiser behind it. *Beta.* | `company`, `keyword`, `companyId` | | [`/profile/posts/archive`](/docs/api-reference/linkedin/profile-posts-archive) | 50–5000 | Returns a LinkedIn member's deep post archive, read from their own feed rather than a search index, with the exact publish timestamp, media and the full engagement breakdown including share counts. | `url` | | [`/search/posts`](/docs/api-reference/linkedin/search-posts) | 10–480 | Returns public LinkedIn posts and Pulse articles matching a keyword, with each result's text, author, media, like and comment counts, and date. | `query`, `from_member`, `from_company` | | [`/post/transcript`](/docs/api-reference/linkedin/post-transcript) | 100 | Returns the spoken text of a video in a LinkedIn post. | `url` | | [`/profile/full`](/docs/api-reference/linkedin/profile-full) | 50 | Returns a LinkedIn company page and its latest 10 posts in one call. *Beta.* | `url` | --- # Nextdoor (/docs/platforms/nextdoor) Nextdoor API reference: 2 endpoints for local businesses and their contact details. Per-endpoint credit prices and cURL examples. Local business pages on Nextdoor, and businesses by city and trade, with contact details. Base path: `/v1/nextdoor/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/nextdoor/business?slug=radiant-plumbing-air-conditioning-austin-tx" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] 1 of these is **metered**: the price depends on how much the call reads. See [Credits](/docs/credits). | Endpoint | Credits | What it returns | Key parameters | | ---------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | | [`/business`](/docs/api-reference/nextdoor/business) | 30 | Returns one local business listed on Nextdoor: name, phone, email, website, street address, categories and how many neighbours recommend it. | `slug` | | [`/search`](/docs/api-reference/nextdoor/search) | 30–170 | Returns local businesses on Nextdoor for a city and trade, each with name, address, categories and, where listed, phone, email and website. | `city`, `query` | --- # Pinterest (/docs/platforms/pinterest) Pinterest API reference: 6 endpoints for pins, boards, user boards, trends and search. Per-endpoint credit prices and cURL examples. Pins, boards, user boards, trends and search. New to the API? Read the [Pinterest scraper API overview](/social-media-api/pinterest) for what it returns and how it compares with the official API. Base path: `/v1/pinterest/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/pinterest/pin?url=https%3A%2F%2Fwww.pinterest.com%2Fpin%2F211174978421744%2F" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] 2 of these are **metered**: the price depends on how much the call reads. See [Credits](/docs/credits). 2 are **beta**: they return the platform's own structure under our naming rules (snake\_case keys, string ids, ISO times where the platform gives a timestamp) rather than a schema-2 entity, and their fields may change. See [Schema 2](/docs/schema-2). | Endpoint | Credits | What it returns | Key parameters | | ----------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | | [`/search`](/docs/api-reference/pinterest/search) | 10–260 | Returns Pinterest pins matching a keyword, each with its text, original image, pinner and pin date; include=engagement adds save, reaction, comment and share counts. | `query` | | [`/pin`](/docs/api-reference/pinterest/pin) | 10 | Returns one Pinterest pin: its text, original image, pinner, pin date, and its save, reaction, comment and share counts. | `url` | | [`/url-stats`](/docs/api-reference/pinterest/url-stats) | 10 | Returns how many times each of up to 10 external URLs has been saved to Pinterest through the Save Button. *Beta.* | `urls` | | [`/board`](/docs/api-reference/pinterest/board) | 10–160 | Returns the pins on a Pinterest board with text, image URL, author, and save, comment and share counts; include=engagement adds each pin's date and reaction count. | `url` | | [`/user/boards`](/docs/api-reference/pinterest/user-boards) | 10 | Returns the boards a Pinterest user has created, each with its title, description, pin count, and cover image. | `handle` | | [`/trends`](/docs/api-reference/pinterest/trends) | 100 | Returns the Pinterest Trends list for one country: ranked search terms with a relative search index, for growing, seasonal, monthly or yearly tables. *Beta.* | — | --- # Quora (/docs/platforms/quora) Quora API reference: 7 endpoints for questions, answers, profiles and spaces. Per-endpoint credit prices and cURL examples. Questions, answers, space posts, profiles, spaces and topics search. New to the API? Read the [Quora scraper API overview](/social-media-api/quora) for what it returns and how it compares with the official API. Base path: `/v1/quora/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/quora/search?query=learn%20programming" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] Every endpoint here has a fixed price. 2 are **beta**: they return the platform's own structure under our naming rules (snake\_case keys, string ids, ISO times where the platform gives a timestamp) rather than a schema-2 entity, and their fields may change. See [Schema 2](/docs/schema-2). | Endpoint | Credits | What it returns | Key parameters | | ------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------- | -------------- | | [`/search`](/docs/api-reference/quora/search) | 50 | Returns Quora questions matching a keyword: title, URL, answer count, follower count, and publish time. | `query` | | [`/post`](/docs/api-reference/quora/post) | 50 | Returns one Quora question: title, body text, and published date. | `url` | | [`/answers`](/docs/api-reference/quora/answers) | 50 | Returns Quora answers matching a keyword: the answer text, author name and credential, upvotes, views, and the parent question title. | `query` | | [`/posts`](/docs/api-reference/quora/posts) | 50 | Returns posts from Quora Spaces matching a keyword: URL, author, upvotes, comments, and publish time. | `query` | | [`/profiles`](/docs/api-reference/quora/profiles) | 50 | Returns Quora profiles matching a keyword: display name, profile URL, credential, follower count, and avatar. | `query` | | [`/spaces`](/docs/api-reference/quora/spaces) | 50 | Returns Quora Spaces matching a keyword: name, URL, description, member count, and icon. *Beta.* | `query` | | [`/topics`](/docs/api-reference/quora/topics) | 50 | Returns Quora topics matching a keyword: name, URL, follower count, and topic photo. *Beta.* | `query` | --- # Reddit (/docs/platforms/reddit) Reddit API reference: 14 endpoints for subreddits, posts, comment threads, users and search. Per-endpoint credit prices and cURL examples. Subreddits, posts, comments, user profiles, transcripts and search. New to the API? Read the [Reddit scraper API overview](/social-media-api/reddit) for what it returns and how it compares with the official API. Base path: `/v1/reddit/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/reddit/subreddit?subreddit=technology" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] 5 of these are **metered**: the price depends on how much the call reads. See [Credits](/docs/credits). 1 is **beta**: it returns the platform's own structure under our naming rules (snake\_case keys, string ids, ISO times where the platform gives a timestamp) rather than a schema-2 entity, and their fields may change. See [Schema 2](/docs/schema-2). | Endpoint | Credits | What it returns | Key parameters | | -------------------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | | [`/subreddit`](/docs/api-reference/reddit/subreddit) | 10 | Returns posts from a subreddit, each with title, body, score, comment count, author, permalink, and creation timestamp. | `subreddit` | | [`/subreddit/details`](/docs/api-reference/reddit/subreddit-details) | 10 | Returns a subreddit's own details: subscriber count, active user count, description, creation date, rules, and icon URL. | `subreddit`, `url` | | [`/search`](/docs/api-reference/reddit/search) | 10–300 | Returns posts matching a keyword from across Reddit, each with title, score, comment count, subreddit, permalink, and the body at ext.selftext. | `query` | | [`/post`](/docs/api-reference/reddit/post) | 10 | Returns one post from its URL including the body text, plus score, comment count, share count, author, author avatar, thumbnail, and creation timestamp. | `url` | | [`/post/comments`](/docs/api-reference/reddit/post-comments) | 50 | Returns the full comment tree for a post, each comment with author, body, score, direct-reply count, nesting depth, timestamp, and its nested replies. | `url` | | [`/subreddit/search`](/docs/api-reference/reddit/subreddit-search) | 10–260 | Returns posts matching a query inside one subreddit, each with title, score, comment count, and permalink. | `subreddit` | | [`/profile`](/docs/api-reference/reddit/profile) | 10 | Returns one Reddit account: total karma, the post/comment/award karma split, cake day, bio, avatar, banner, trophy count and profile title. | `handle` | | [`/profile/posts`](/docs/api-reference/reddit/profile-posts) | 10 | Returns the posts one account has submitted, newest first, with the body at ext.selftext, score, comment count, upvote ratio, flair, media and ext.subreddit. | `handle` | | [`/profile/comments`](/docs/api-reference/reddit/profile-comments) | 20–2000 | Returns an account's own comment history, newest first, each with the text, score, permalink, parent\_id, the post it sits under and ext.subreddit. | `handle` | | [`/search/comments`](/docs/api-reference/reddit/search-comments) | 10 | Returns comments matching a phrase from Reddit's comment index, each with its parent post inline: ext.post\_title, ext.subreddit, ext.post\_score and ext.post\_url. | `query` | | [`/subreddits/search`](/docs/api-reference/reddit/subreddits-search) | 10–260 | Returns up to 25 communities matching a topic, each with the name at author.id, subscriber count, description and icon. | `query` | | [`/search/media`](/docs/api-reference/reddit/search-media) | 10 | Returns up to 25 Reddit posts that carry an image, video or gallery, with the media at content.media\_urls plus title, score, comment count and subreddit. | `query` | | [`/post/transcript`](/docs/api-reference/reddit/post-transcript) | 100 | Returns the transcript of a Reddit video post, both the raw caption file and a plain-text version, when Reddit publishes captions for it. | `url` | | [`/omni-search`](/docs/api-reference/reddit/omni-search) | 50–90 | Returns threads from across Reddit for one keyword with their top comments inline at top\_comments, plus a roll-up of which subreddits are talking, their weekly active users and tone. *Beta.* | `query` | --- # Rumble (/docs/platforms/rumble) Rumble API reference: 5 endpoints for videos, comments, transcripts and search. Per-endpoint credit prices and cURL examples. Videos, channel videos, comments, transcripts and search. Base path: `/v1/rumble/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/rumble/search?query=funny%20cats" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] Every endpoint here has a fixed price. | Endpoint | Credits | What it returns | Key parameters | | ------------------------------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | | [`/search`](/docs/api-reference/rumble/search) | 10 | Returns Rumble videos and shorts matching a keyword: title, URL, thumbnail, channel, published date, and view count. | `query` | | [`/channel/videos`](/docs/api-reference/rumble/channel-videos) | 10 | Returns a Rumble channel's metadata and a page of its videos and shorts. | `handle`, `url` | | [`/video`](/docs/api-reference/rumble/video) | 10 | Returns one Rumble video's title, description, thumbnail, channel, publish date, view count, likes, dislikes, captions, and media metadata. | `url` | | [`/video/transcript`](/docs/api-reference/rumble/video-transcript) | 100 | Returns the transcript of a Rumble video when captions are available. | `url` | | [`/video/comments`](/docs/api-reference/rumble/video-comments) | 10 | Returns the top-level comments on a Rumble video: comment text, author, created time, like and dislike counts, and reply count. | `url` | --- # Snapchat (/docs/platforms/snapchat) Snapchat API reference: 2 endpoints for profiles and Spotlight comments. Per-endpoint credit prices and cURL examples. Public profiles and Spotlight comments. Base path: `/v1/snapchat/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/snapchat/profile?handle=djkhaled305" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] Every endpoint here has a fixed price. | Endpoint | Credits | What it returns | Key parameters | | ------------------------------------------------------------------------ | ------- | --------------------------------------------------------------------------------------------------------------------- | -------------- | | [`/profile`](/docs/api-reference/snapchat/profile) | 10 | Returns a Snapchat user's public profile: display name, Bitmoji avatar URL, subscriber count, and bio description. | `handle` | | [`/spotlight/comments`](/docs/api-reference/snapchat/spotlight-comments) | 10 | Returns comments on a Snapchat Spotlight snap: text, display name, reaction count, nested reply count, and timestamp. | `url` | --- # Substack (/docs/platforms/substack) Substack API reference: 1 endpoints for publication posts with full text. Per-endpoint credit prices and cURL examples. A Substack publication's posts, or one post, with full text and engagement. Base path: `/v1/substack/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/substack/posts?url=https%3A%2F%2Fwww.astralcodexten.com" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] 1 of these is **metered**: the price depends on how much the call reads. See [Credits](/docs/credits). | Endpoint | Credits | What it returns | Key parameters | | ---------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | | [`/posts`](/docs/api-reference/substack/posts) | 10–120 | Returns a publication’s recent posts, or one post: title, full text and Markdown, author, reactions, comments, restacks, word count and whether it is paid. | `url` | --- # Telegram (/docs/platforms/telegram) Telegram API reference: 3 endpoints for channel profiles and posts. Per-endpoint credit prices and cURL examples. Public channel profiles and their posts. Base path: `/v1/telegram/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/telegram/profile?handle=telegram" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] Every endpoint here has a fixed price. | Endpoint | Credits | What it returns | Key parameters | | -------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | | [`/profile`](/docs/api-reference/telegram/profile) | 10 | Returns a public Telegram channel or group's profile: display name, description, avatar URL, verification status, and subscriber count. | `handle` | | [`/profile/posts`](/docs/api-reference/telegram/profile-posts) | 10 | Returns one page of recent public posts from a Telegram channel or group, each with its text, publish time, view count, reaction breakdown, and media URLs. | `handle` | | [`/post`](/docs/api-reference/telegram/post) | 10 | Returns one public Telegram post: text, publish time, view count, the per-emoji reaction breakdown, and direct media URLs. | `url` | --- # TikTok (/docs/platforms/tiktok) TikTok API reference: 37 endpoints for profiles, videos, comments, followers, hashtags, search and transcripts. Per-endpoint credit prices and cURL examples. Profiles, videos, comments, followers and following, hashtags, songs, playlists, trending and popular feeds, search, transcripts and the TikTok Ad Library. New to the API? Read the [TikTok scraper API overview](/social-media-api/tiktok) for what it returns and how it compares with the official API. Base path: `/v1/tiktok/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktok/profile?handle=charlidamelio" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] 9 of these are **metered**: the price depends on how much the call reads. See [Credits](/docs/credits). 6 are **beta**: they return the platform's own structure under our naming rules (snake\_case keys, string ids, ISO times where the platform gives a timestamp) rather than a schema-2 entity, and their fields may change. See [Schema 2](/docs/schema-2). | Endpoint | Credits | What it returns | Key parameters | | ---------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------- | | [`/profile`](/docs/api-reference/tiktok/profile) | 10 | Returns a TikTok account's public profile: display name, bio, follower count on author.followers (or the rounded figure with followers\_approximate), likes, verification, and user id. | `handle`, `user_id` | | [`/profile/videos`](/docs/api-reference/tiktok/profile-videos) | 10 | Returns a page of an account's recent public videos, each with caption, view, like, comment and share counts, and a thumbnail URL. | `handle`, `user_id` | | [`/post`](/docs/api-reference/tiktok/post) | 10 | Returns one TikTok video in full: caption, engagement counts, author, sound, video metadata, and any on-screen text the creator typed with TikTok's text tool (post.ext.on\_screen\_texts). | `url` | | [`/post/comments`](/docs/api-reference/tiktok/post-comments) | 10–30 | Returns a page of comments on one TikTok video, each with the commenter's username, comment text, like count, reply count, and timestamp. | `url` | | [`/video/comment/replies`](/docs/api-reference/tiktok/video-comment-replies) | 10 | Returns the replies under a single TikTok comment, with each reply's text, author, likes, and timestamps. | `comment_id`, `url` | | [`/comment`](/docs/api-reference/tiktok/comment) | 20–60 | Returns one TikTok comment with its current like count, reply count, pinned flag, author, and timestamp, found by link, by id, or by its text. | `comment_url`, `post_url` | | [`/search`](/docs/api-reference/tiktok/search) | 10–370 | Returns TikTok videos matching a keyword, each with caption, view and like counts, author details, a thumbnail, and post.ext.region (the country the video is registered to). | `query` | | [`/trending`](/docs/api-reference/tiktok/trending) | 50 | Returns a page of popular TikTok videos with caption, view and like counts, author and thumbnail. | `region` | | [`/search/hashtag`](/docs/api-reference/tiktok/search-hashtag) | 10 | Returns TikTok videos posted under a given hashtag, each with caption, view, like, comment and share counts, author details, and a thumbnail. | `hashtag` | | [`/search/top`](/docs/api-reference/tiktok/search-top) | 10 | Returns the videos TikTok ranks highest for a keyword on its Top tab, each with caption, author, engagement counts, a music id, and post.ext.region (the country the video is registered to). | `query` | | [`/search/users`](/docs/api-reference/tiktok/search-users) | 10–1310 | Returns TikTok accounts for a search term with username, name, avatar, followers, verification. | `query` | | [`/similar`](/docs/api-reference/tiktok/similar) | 50 | Returns about 30 TikTok accounts similar to a given creator, each with username, display name, avatar, bio, verification, and follower, following, video and like counts. | `handle` | | [`/user/audience`](/docs/api-reference/tiktok/user-audience) | 50 | Returns where a creator's followers are: the top countries in their audience, with sampled follower counts and each country's share. *Beta.* | `handle` | | [`/user/followers`](/docs/api-reference/tiktok/user-followers) | 10 | Returns a page of accounts that follow a TikTok user, each with username, display name, avatar, and its own follower count. | `handle`, `user_id` | | [`/user/following`](/docs/api-reference/tiktok/user-following) | 10 | Returns a page of accounts a TikTok user follows, each with username, display name, avatar, and its own follower count. | `handle`, `user_id` | | [`/user/live`](/docs/api-reference/tiktok/user-live) | 10 | Returns a TikTok account's live room in the platform's own shape: cover image, title, start time, status code, viewer and entry counts, stream ids, and the host's profile. *Beta.* | `handle` | | [`/post/transcript`](/docs/api-reference/tiktok/post-transcript) | 100 | Returns the spoken text of a TikTok video from its captions, with an option to fall back to AI transcription when no captions exist. | `url` | | [`/video/screen-text`](/docs/api-reference/tiktok/video-screen-text) | 50 | Returns the text shown on the video itself: native text stickers plus AI OCR of the cover frame, so burned-in editor captions are caught too. *Beta.* | `url` | | [`/song`](/docs/api-reference/tiktok/song) | 10 | Returns one TikTok sound's details: title, artist, duration, how many videos use it, and its cover image. | `clipId` | | [`/song/videos`](/docs/api-reference/tiktok/song-videos) | 10 | Returns videos that use a given TikTok sound, each with caption, author details, and engagement counts. | `clipId` | | [`/hashtags/popular`](/docs/api-reference/tiktok/hashtags-popular) | 60–960 | Returns TikTok's trending-hashtag board for one of 27 markets over 7, 30 or 90 days: each hashtag's rank, window post and view counts, daily popularity curve, industry board and top creators. | — | | [`/videos/popular`](/docs/api-reference/tiktok/videos-popular) | 260–450 | Returns TikTok's Top Videos board for the US, Japan, Vietnam, Thailand or Indonesia over 7 or 30 days: each video's rank, lifetime and window views, organic views, engagement rate and creator. | — | | [`/profile/region`](/docs/api-reference/tiktok/profile-region) | 10 | Returns the two letter country code for a public TikTok profile, for example US or MX. *Beta.* | `handle` | | [`/adlibrary/search`](/docs/api-reference/tiktok/adlibrary-search) | 50–170 | Returns TikTok Ad Library ads matching a keyword or advertiser name, each with creative, title, advertiser, impressions and date; include=ad adds the brand, landing page and advertiser link. | `query`, `advertiser_name` | | [`/adlibrary/ad`](/docs/api-reference/tiktok/adlibrary-ad) | 50 | Returns one TikTok Ad Library ad: creative video, title, advertiser account, landing page, brand name, and first-shown date. | `ad_id`, `url` | | [`/search/suggestions`](/docs/api-reference/tiktok/search-suggestions) | 10 | Returns the autocomplete suggestions TikTok's own search box shows for a partial query, as a list of suggestion rows. *Beta.* | `query` | | [`/collection/videos`](/docs/api-reference/tiktok/collection-videos) | 10 | Returns the public videos inside a TikTok collection, each with caption, play like comment share and save counts, author, and a playable URL. | `url` | | [`/profile/playlists`](/docs/api-reference/tiktok/profile-playlists) | 10 | Returns the playlists a TikTok creator has published on their profile, each with its playlist id, its name, and the number of videos it holds. | `handle`, `user_id` | | [`/playlist/videos`](/docs/api-reference/tiktok/playlist-videos) | 10 | Returns the videos inside one of a creator's profile playlists, in playlist order, each with engagement counts, caption, author, and a playable URL. | `playlist_id`, `handle`, `user_id` | | [`/user/liked`](/docs/api-reference/tiktok/user-liked) | 10 | Returns the videos a TikTok account has liked, newest first, each carrying its own third party author, engagement counts, caption, and a playable URL. | `handle`, `user_id` | | [`/location/posts`](/docs/api-reference/tiktok/location-posts) | 10 | Returns public TikTok videos tagged at a place, each with engagement counts, caption, author, and a playable URL. | `location_id` | | [`/effects`](/docs/api-reference/tiktok/effects) | 10 | Returns TikTok camera effects by id, each with its name, its designer, the views of videos made with it, and how many such videos exist. | `ids` | | [`/effect/videos`](/docs/api-reference/tiktok/effect-videos) | 10 | Returns public TikTok videos created with a camera effect, each with engagement counts, caption, author, and a playable URL. | `effect_id` | | [`/search/music`](/docs/api-reference/tiktok/search-music) | 10 | Returns TikTok sounds matching a keyword, each with title, artist, duration, cover art, a preview audio URL, and how many videos use it. | `query` | | [`/hashtag`](/docs/api-reference/tiktok/hashtag) | 10 | Returns TikTok's own record for a hashtag, with its display name, its description where one exists, the live total views under the tag, and how many videos carry it. | `hashtag`, `hashtag_id` | | [`/ads/top`](/docs/api-reference/tiktok/ads-top) | 100–1000 | Returns TikTok's Creative Center leaderboard of top-performing ads for a market and time window, each with click-through rate, board rank, like count, industry, objective, and the ad video. | — | | [`/profile/full`](/docs/api-reference/tiktok/profile-full) | 50 | Returns a TikTok profile plus its latest 10 videos in one call. *Beta.* | `handle`, `user_id` | --- # TikTok Shop (/docs/platforms/tiktokshop) TikTok Shop API reference: 6 endpoints for products, reviews, shops and sales. Per-endpoint credit prices and cURL examples. TikTok Shop products, reviews, shop catalogues, creator showcases, product search and sales by market. Base path: `/v1/tiktokshop/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/tiktokshop/product?url=https%3A%2F%2Fwww.tiktok.com%2Fshop%2Fpdp%2Fgoli-ashwagandha-gummies-with-vitamin-d-ksm-66-vegan-non-gmo%2F1729587769570529799" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] 1 of these is **metered**: the price depends on how much the call reads. See [Credits](/docs/credits). 6 are **beta**: they return the platform's own structure under our naming rules (snake\_case keys, string ids, ISO times where the platform gives a timestamp) rather than a schema-2 entity, and their fields may change. See [Schema 2](/docs/schema-2). | Endpoint | Credits | What it returns | Key parameters | | -------------------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | | [`/product`](/docs/api-reference/tiktokshop/product) | 10 | Returns one TikTok Shop product in full: description, price and discount, rating, review count, brand, specs, stock, seller details, shipping estimate, and images. *Beta.* | `url`, `product_id` | | [`/product/reviews`](/docs/api-reference/tiktokshop/product-reviews) | 10 | Returns reviews on a TikTok Shop product: rating, text, author, buyer country, verified-purchase and incentivized-review flags, the purchased SKU, and a timestamp. *Beta.* | `url`, `product_id` | | [`/products`](/docs/api-reference/tiktokshop/products) | 10 | Returns the products listed on a TikTok Shop storefront: title, images, canonical URL, price and discount, sold count, review count, rating, SKU ID, and the shop's own profile. *Beta.* | `url` | | [`/search`](/docs/api-reference/tiktokshop/search) | 10 | Returns TikTok Shop products matching a keyword across every storefront, each with price, rating, sold count, seller trust label, ship-from location, and promotion badges. *Beta.* | `query` | | [`/user/showcase`](/docs/api-reference/tiktokshop/user-showcase) | 10 | Returns the products featured in a TikTok user's public showcase: title, price and discount, rating, sold count, images, and SKU ID. *Beta.* | `handle` | | [`/sales`](/docs/api-reference/tiktokshop/sales) | 0–80 | Returns, per market, listings found, their units sold added up, an estimated sales figure in local currency, and the top listings by units for a keyword. *Beta.* | `query` | --- # Truth Social (/docs/platforms/truthsocial) Truth Social API reference: 3 endpoints for profiles and posts. Per-endpoint credit prices and cURL examples. Profiles, posts and a user's posts on Truth Social. Base path: `/v1/truthsocial/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/truthsocial/profile?handle=realDonaldTrump" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] Every endpoint here has a fixed price. | Endpoint | Credits | What it returns | Key parameters | | ----------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | | [`/profile`](/docs/api-reference/truthsocial/profile) | 10 | Returns a Truth Social user's public profile: display name, follower count, following count, truth count, bio, and profile image URL. | `handle` | | [`/user/posts`](/docs/api-reference/truthsocial/user-posts) | 10 | Returns a Truth Social user's recent truths: text content, like count, retruth count, reply count, media attachments, and creation timestamp. | `handle`, `user_id` | | [`/post`](/docs/api-reference/truthsocial/post) | 10 | Returns one Truth Social post: text content, like count, retruth count, reply count, media attachments, author info, and creation timestamp. | `url` | --- # Twitch (/docs/platforms/twitch) Twitch API reference: 4 endpoints for streamer profiles, videos, clips and schedules. Per-endpoint credit prices and cURL examples. Streamer profiles, videos, clips and stream schedules. Base path: `/v1/twitch/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/twitch/profile?handle=ninja" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] Every endpoint here has a fixed price. 1 is **beta**: it returns the platform's own structure under our naming rules (snake\_case keys, string ids, ISO times where the platform gives a timestamp) rather than a schema-2 entity, and their fields may change. See [Schema 2](/docs/schema-2). | Endpoint | Credits | What it returns | Key parameters | | ------------------------------------------------------------ | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | | [`/profile`](/docs/api-reference/twitch/profile) | 10 | Returns a Twitch streamer's public profile: display name, follower count, bio, profile image URL, broadcast language, and partner or affiliate status. | `handle` | | [`/clip`](/docs/api-reference/twitch/clip) | 10 | Returns one Twitch clip's title, view count, duration, creator name, broadcaster name, game name, thumbnail URL, and creation timestamp. | `url` | | [`/user/videos`](/docs/api-reference/twitch/user-videos) | 10 | Returns up to 100 of a Twitch user's videos: id, slug, URL, embed URL, title, view count, language, duration, game info, broadcaster details, thumbnail, and available qualities. | `handle` | | [`/user/schedule`](/docs/api-reference/twitch/user-schedule) | 10 | Returns a Twitch user's upcoming stream schedule, each entry with start time, end time, title, description, and thumbnail URL. *Beta.* | `handle` | --- # Twitter/X (/docs/platforms/twitter) Twitter/X API reference: 15 endpoints for profiles, tweets, replies, followers, communities and search. Per-endpoint credit prices and cURL examples. Profiles, tweets, replies, retweeters, media, followers and following, communities and search on Twitter/X. New to the API? Read the [Twitter/X scraper API overview](/social-media-api/twitter) for what it returns and how it compares with the official API. Base path: `/v1/twitter/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/twitter/profile?handle=elonmusk" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] 1 of these is **metered**: the price depends on how much the call reads. See [Credits](/docs/credits). 2 are **beta**: they return the platform's own structure under our naming rules (snake\_case keys, string ids, ISO times where the platform gives a timestamp) rather than a schema-2 entity, and their fields may change. See [Schema 2](/docs/schema-2). | Endpoint | Credits | What it returns | Key parameters | | ------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | | [`/profile`](/docs/api-reference/twitter/profile) | 10 | Returns an X (Twitter) account's public profile: follower count, following count, tweet count, bio, profile and banner image URLs, and verification status. | `handle` | | [`/user/tweets`](/docs/api-reference/twitter/user-tweets) | 10 | Returns an account's most recent tweets in descending order, with full text, like, retweet, reply, bookmark and view counts, media, and creation time. | `handle` | | [`/tweet`](/docs/api-reference/twitter/tweet) | 10 | Returns one tweet in full: its text, like, retweet, reply and quote counts, media attachments, author info, and creation timestamp. | `url` | | [`/community`](/docs/api-reference/twitter/community) | 10 | Returns an X (Twitter) community's details: name, description, member count, rules, and creation date. | `url` | | [`/community/tweets`](/docs/api-reference/twitter/community-tweets) | 10 | Returns recent tweets posted inside an X (Twitter) community, each with its text, engagement counts, and author info. | `url` | | [`/tweet/transcript`](/docs/api-reference/twitter/tweet-transcript) | 100 | Returns the transcript of a video attached to a tweet, including auto-generated captions. | `url` | | [`/ai-search`](/docs/api-reference/twitter/ai-search) | 50 | Returns a written answer to a plain-English question about X (Twitter), the X posts cited as sources, and how many searches the model ran. *Beta.* | `query` | | [`/search/tweets`](/docs/api-reference/twitter/search-tweets) | 10–50 | Returns tweets matching a keyword or phrase, each with the full text, like, retweet, reply, bookmark and view counts, media attachments, author info, and creation time. | `query` | | [`/tweet/replies`](/docs/api-reference/twitter/tweet-replies) | 10 | Returns the replies to a tweet, each with the reply text, author info, like and reply counts, and creation time. | `url` | | [`/user/media`](/docs/api-reference/twitter/user-media) | 10 | Returns the tweets on an account's Media tab, only those carrying a photo or video, with media URLs, engagement counts, and creation time. | `handle` | | [`/user/followers`](/docs/api-reference/twitter/user-followers) | 10 | Returns the accounts following an X (Twitter) user, each with the handle, display name, bio, follower and tweet counts, privacy flag, and join date. | `handle` | | [`/user/following`](/docs/api-reference/twitter/user-following) | 10 | Returns the accounts an X (Twitter) user follows, each with the handle, display name, bio, follower and tweet counts, privacy flag, and join date. | `handle` | | [`/tweet/retweeters`](/docs/api-reference/twitter/tweet-retweeters) | 10 | Returns the accounts that retweeted a tweet, each with the handle, display name, bio, follower and tweet counts, privacy flag, and join date. | `url` | | [`/search/users`](/docs/api-reference/twitter/search-users) | 10 | Returns X (Twitter) accounts matching a name, handle or keyword, with handle, display name, bio, avatar, follower, following and tweet counts, location, verification, join date, and a private flag. | `query` | | [`/profile/full`](/docs/api-reference/twitter/profile-full) | 50 | Returns an X account's profile and its recent tweets in one call. *Beta.* | `handle` | --- # Weibo (/docs/platforms/weibo) Weibo API reference: 6 endpoints for profiles, posts, comments, search and trending. Per-endpoint credit prices and cURL examples. Weibo profiles, posts, a user's posts, comments, post search and the hot-search board. Base path: `/v1/weibo/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/weibo/post?post_id=5092682368025584" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] Every endpoint here has a fixed price. 1 is **beta**: it returns the platform's own structure under our naming rules (snake\_case keys, string ids, ISO times where the platform gives a timestamp) rather than a schema-2 entity, and their fields may change. See [Schema 2](/docs/schema-2). | Endpoint | Credits | What it returns | Key parameters | | ----------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------- | -------------- | | [`/post`](/docs/api-reference/weibo/post) | 10 | Returns one public Weibo post: its text, author, like, comment and repost counts, image count and publish time. | `post_id` | | [`/profile`](/docs/api-reference/weibo/profile) | 10 | Returns a public Weibo account: name, bio, avatar, follower, following and post counts, verification, location and website. | `user_id` | | [`/user/posts`](/docs/api-reference/weibo/user-posts) | 10 | Returns a page of an account’s recent public posts, each with text, engagement counts and publish time. | `user_id` | | [`/post/comments`](/docs/api-reference/weibo/post-comments) | 10 | Returns a page of first-level comments on a post, each with text, author, likes, reply count and time. | `post_id` | | [`/search`](/docs/api-reference/weibo/search) | 10 | Returns public Weibo posts matching a keyword, each with text, author, engagement counts and URL. | `query` | | [`/trending`](/docs/api-reference/weibo/trending) | 10 | Returns the current Weibo hot-search ranking: each topic’s keyword, rank, heat and label, pinned topics marked. *Beta.* | — | --- # Xiaohongshu (RedNote) (/docs/platforms/xiaohongshu) Xiaohongshu (RedNote) API reference: 6 endpoints for creators, notes, comments, search and trending. Per-endpoint credit prices and cURL examples. Xiaohongshu (RedNote) creators, notes, comments, note search and the hot-search board. Base path: `/v1/xiaohongshu/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/xiaohongshu/profile?url=https%3A%2F%2Fwww.xiaohongshu.com%2Fuser%2Fprofile%2F6a59f257000000000f03b000" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] 4 of these are **metered**: the price depends on how much the call reads. See [Credits](/docs/credits). 1 is **beta**: it returns the platform's own structure under our naming rules (snake\_case keys, string ids, ISO times where the platform gives a timestamp) rather than a schema-2 entity, and their fields may change. See [Schema 2](/docs/schema-2). | Endpoint | Credits | What it returns | Key parameters | | ----------------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | | [`/search`](/docs/api-reference/xiaohongshu/search) | 50–1000 | Returns Xiaohongshu notes matching a keyword: title, short summary, creator, likes, comments, saves, shares, and cover image. | `query` | | [`/trending`](/docs/api-reference/xiaohongshu/trending) | 50–1000 | Returns the live Xiaohongshu hot search board: ranked topics with a hot value. *Beta.* | — | | [`/profile`](/docs/api-reference/xiaohongshu/profile) | 50 | Returns a Xiaohongshu (RedNote) creator's profile: display name, RedNote ID, bio, avatar, followers, following, notes posted, likes received, and IP province. | `url`, `id` | | [`/profile/posts`](/docs/api-reference/xiaohongshu/profile-posts) | 50–1000 | Returns a Xiaohongshu creator's notes, newest first: title, short summary, engagement counts, and pinned flag. | `url`, `id` | | [`/post`](/docs/api-reference/xiaohongshu/post) | 50 | Returns one Xiaohongshu note in full: body text, images or video, creator, likes, comments, saves, shares, and the IP province. | `url` | | [`/post/comments`](/docs/api-reference/xiaohongshu/post-comments) | 50–1000 | Returns top-level comments on a Xiaohongshu note: text, commenter, likes, reply count, pin flag, and the commenter's IP province. | `url` | --- # YouTube (/docs/platforms/youtube) YouTube API reference: 26 endpoints for channels, videos, shorts, comments, transcripts and search. Per-endpoint credit prices and cURL examples. Channels, videos, shorts, comments, playlists, community posts, transcripts and subtitles, trending and search. New to the API? Read the [YouTube scraper API overview](/social-media-api/youtube) for what it returns and how it compares with the official API. Base path: `/v1/youtube/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/youtube/channel?handle=MrBeast" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] 10 of these are **metered**: the price depends on how much the call reads. See [Credits](/docs/credits). 7 are **beta**: they return the platform's own structure under our naming rules (snake\_case keys, string ids, ISO times where the platform gives a timestamp) rather than a schema-2 entity, and their fields may change. See [Schema 2](/docs/schema-2). | Endpoint | Credits | What it returns | Key parameters | | --------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------- | | [`/channel`](/docs/api-reference/youtube/channel) | 10 | Returns a YouTube channel's public profile: subscriber count on author.followers (rounded above 1,000), video and view totals, description, banner and avatar URLs, and author.ext.public\_email. | `channelId`, `handle`, `url` | | [`/channel/about`](/docs/api-reference/youtube/channel-about) | 250 | Returns the address behind a channel's View email address control on author.ext.public\_email, its listed country, and the profile: id, handle, name, avatar, bio, URL, subscribers, join date, views. | `channelId`, `handle`, `url` | | [`/channel/videos`](/docs/api-reference/youtube/channel-videos) | 10–20 | Returns recent videos published by a channel, each with title, view count, duration, thumbnail, and publish date; pass includeExtras=true to add like and comment counts. | `channelId`, `handle` | | [`/video`](/docs/api-reference/youtube/video) | 10 | Returns full details for one video: title, view, like and comment counts, description, tags, duration, channel info, and publish date. | `url` | | [`/video/sponsors`](/docs/api-reference/youtube/video-sponsors) | 100 | Returns whether a video carries a paid-promotion disclosure plus the brands likely sponsoring it, each with supporting evidence and a confidence score. *Beta.* | `url` | | [`/video/comments`](/docs/api-reference/youtube/video-comments) | 10 | Returns comments on a video, each with the author name, comment text, like count, reply count, and publish timestamp. | `url` | | [`/video/comment/replies`](/docs/api-reference/youtube/video-comment-replies) | 10 | Returns the replies under one comment, each with the reply text, author details, like count, and publish date. | `continuationToken` | | [`/search`](/docs/api-reference/youtube/search) | 10–150 | Returns YouTube search results for a keyword: videos, channels, playlists, shorts, and live streams, each with title, thumbnail, views, and channel. | `query` | | [`/channel/shorts`](/docs/api-reference/youtube/channel-shorts) | 10–20 | Returns the Shorts published by a channel, each with title, view count, like count, and thumbnail. | `channelId`, `handle` | | [`/community-post`](/docs/api-reference/youtube/community-post) | 10 | Returns one YouTube community post: its text, like count, comment count, attached images, and author info. | `url` | | [`/playlist`](/docs/api-reference/youtube/playlist) | 10–110 | Returns the videos in a playlist in playlist order: video id, title, thumbnail, channel and publish date. | `playlist_id` | | [`/search/hashtag`](/docs/api-reference/youtube/search-hashtag) | 10–110 | Returns videos posted under a hashtag, each with view count, channel info, and publish date. | `hashtag` | | [`/shorts/trending`](/docs/api-reference/youtube/shorts-trending) | 50–150 | Returns the Shorts trending on YouTube right now, each with view count, like count, channel info, and thumbnail. | — | | [`/video/transcript`](/docs/api-reference/youtube/video-transcript) | 30 | Returns the spoken transcript of a video as timestamped segments, each with text, start time and duration, plus language, word count, and speech rate. | `url` | | [`/channel/playlists`](/docs/api-reference/youtube/channel-playlists) | 10 | Returns the playlists on a channel's Playlists tab, each with playlist id, title, thumbnail, video count, channel info, and playlist URL. | `channelId`, `handle` | | [`/channel/lives`](/docs/api-reference/youtube/channel-lives) | 10–70 | Returns the live and past streams on a channel's Live tab, each with title, URL, thumbnail, view count, publish time, and duration. | `channelId`, `handle` | | [`/channel/community-posts`](/docs/api-reference/youtube/channel-community-posts) | 10 | Returns the posts on a channel's Posts tab, each with post id, URL, text, images, attached video, like count, publish time, and channel info. | `channelId`, `handle` | | [`/videos/trending`](/docs/api-reference/youtube/videos-trending) | 10–60 | Returns the trending videos for a country and category, each with title, thumbnail, duration, view, like and comment counts, channel, and publish time. | — | | [`/playlist/items`](/docs/api-reference/youtube/playlist-items) | 10–110 | Returns the videos of a playlist in playlist order, each with video id, title, thumbnail, the video's own channel, its publish date, and its position and insertion time on post.ext. | `playlist_id` | | [`/search/advanced`](/docs/api-reference/youtube/search-advanced) | 10–110 | Returns video search results with the full filter set: sort order, length, live status, license, category, country, language, and publish date window. | `query` | | [`/search/suggestions`](/docs/api-reference/youtube/search-suggestions) | 10 | Returns the autocomplete suggestions YouTube's own search box shows for a partial query, as a plain list of strings. *Beta.* | `query` | | [`/video/audio`](/docs/api-reference/youtube/video-audio) | 50 | Returns the downloadable audio streams for a video, each with a direct media URL, mime type, bitrate, audio quality, sample rate, channels, and duration. *Beta.* | `url` | | [`/video/files`](/docs/api-reference/youtube/video-files) | 50 | Returns the downloadable video streams for a video, each with a direct media URL, mime type, resolution, quality label, frame rate, bitrate, and duration. *Beta.* | `url` | | [`/video/subtitles`](/docs/api-reference/youtube/video-subtitles) | 10 | Returns the caption track files for a video, each with a language code and name, file format, and a direct download URL, including auto-generated tracks. *Beta.* | `url` | | [`/video/thumbnails`](/docs/api-reference/youtube/video-thumbnails) | 10 | Returns a video's thumbnail images at every available size, each with a direct image URL, width, height, aspect ratio, and image format. *Beta.* | `url` | | [`/profile/full`](/docs/api-reference/youtube/profile-full) | 50 | Returns a channel's profile and up to 30 recent videos in one call. *Beta.* | `handle`, `channelId`, `url` | --- # Zhihu (/docs/platforms/zhihu) Zhihu API reference: 5 endpoints for profiles, questions, answers and articles. Per-endpoint credit prices and cURL examples. Zhihu profiles, questions, answers and article search. Base path: `/v1/zhihu/...` ## Quickstart [#quickstart] ```bash title="cURL" curl "https://api.insightsocial.app/v1/zhihu/answer?answer_id=2054145988235880002" \ -H "x-api-key: $INSIGHTSOCIAL_API_KEY" ``` ## Endpoints [#endpoints] Every endpoint here has a fixed price. | Endpoint | Credits | What it returns | Key parameters | | ----------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------- | -------------- | | [`/answer`](/docs/api-reference/zhihu/answer) | 10 | Returns one Zhihu answer: its text, author, the question it answers and its publish and update times. | `answer_id` | | [`/question`](/docs/api-reference/zhihu/question) | 10 | Returns a Zhihu question: its title, views, comments, answer and follower counts, and when it was asked. | `question_id` | | [`/question/answers`](/docs/api-reference/zhihu/question-answers) | 10 | Returns up to 20 answers to a question, each with its text, author, votes, comments, saves and times. | `question_id` | | [`/profile`](/docs/api-reference/zhihu/profile) | 10 | Returns a public Zhihu account: name, headline, avatar, follower count, and how many answers and articles it wrote. | `handle` | | [`/search/articles`](/docs/api-reference/zhihu/search-articles) | 10 | Returns Zhihu column articles matching a keyword, each with title, text, author, votes and comments. | `query` | --- # Brand mention monitoring (/docs/recipes/brand-mention-monitoring) Run a daily brand-mention sweep across the search endpoints of six platforms in parallel, drop off-topic rows with a keyword check, dedupe against earlier runs and alert on what is new. From 60 credits per sweep. This recipe is the daily job at the heart of social listening. Once a day it searches six platforms for your brand name, drops rows that turn out to be about something else, skips anything it has seen before, and sends what remains to Slack, email or a dashboard. At least 60 credits per sweep: six search calls whose price starts at 10 each. All six are metered, so each call holds its ceiling when it starts (480 on LinkedIn, 370 on TikTok, 300 on Reddit, 260 on Pinterest, 150 on YouTube, 50 on X) and is charged what it used. Keep at least 1,610 credits available while a sweep runs. A daily sweep costs at least 1,800 credits a month. ## How do you track brand mentions with an API? [#how-do-you-track-brand-mentions-with-an-api] Call each platform's keyword search with your brand name, in parallel, limited to the last day. Then check each row's text yourself: a brand name that is also an ordinary word ("notion", "apple") matches a lot of posts that are not about you. You also supply the dedupe layer, because "new since the last run" is your state. ## What you need [#what-you-need] | Endpoint | Platform | Date window | Credits | | ------------------------------- | --------- | ----------------------------------------------- | ------- | | `GET /v1/reddit/search` | Reddit | `max_age_days` | 10–300 | | `GET /v1/tiktok/search` | TikTok | `max_age_days` | 10–370 | | `GET /v1/youtube/search` | YouTube | `max_age_days` | 10–150 | | `GET /v1/twitter/search/tweets` | X | `since:` operator in `query`, or `max_age_days` | 10–50 | | `GET /v1/linkedin/search/posts` | LinkedIn | `since` / `until` | 10–480 | | `GET /v1/pinterest/search` | Pinterest | `since` / `until` | 10–260 | All six take `query` and return posts in the same shape: the text is `post.content.text` and the link is `post.url`, on every platform. `max_age_days` keeps only rows published inside the window. It filters after each page is fetched, so the page is billed as usual, and a day with nothing new returns an empty list. ## The code [#the-code] ```python title="Python" # brand_mentions.py # Daily brand-mention sweep with a keyword check and dedupe. # Keep the known URLs somewhere durable between runs. # Run with: INSIGHTSOCIAL_API_KEY=isk_live_... python brand_mentions.py import json import os import re from concurrent.futures import ThreadPoolExecutor from datetime import date, timedelta from pathlib import Path import requests KEY = os.environ["INSIGHTSOCIAL_API_KEY"] BASE = "https://api.insightsocial.app/v1" BRAND = "notion" # The name is an ordinary word, so a row must also mention one of these. CONTEXT = ["app", "workspace", "template", "notes", "wiki", "database", "page"] KNOWN_FILE = Path("known-mentions.json") YESTERDAY = (date.today() - timedelta(days=1)).isoformat() SEARCHES = { "reddit": ("reddit/search", {"max_age_days": 1}), "tiktok": ("tiktok/search", {"max_age_days": 1}), "youtube": ("youtube/search", {"max_age_days": 1}), "twitter": ("twitter/search/tweets", {"max_age_days": 1}), "linkedin": ("linkedin/search/posts", {"since": YESTERDAY}), "pinterest": ("pinterest/search", {"since": YESTERDAY}), } BRAND_RE = re.compile(rf"\b{re.escape(BRAND)}\b", re.IGNORECASE) CONTEXT_RE = re.compile(r"\b(" + "|".join(map(re.escape, CONTEXT)) + r")\b", re.IGNORECASE) def on_topic(text): # A row with no text (a video with no caption) cannot be checked: leave it out. if not text or not BRAND_RE.search(text): return False return not CONTEXT or bool(CONTEXT_RE.search(text)) def get(path, **params): res = requests.get(f"{BASE}/{path}", params=params, headers={"x-api-key": KEY}, timeout=120) return res.json() def search(platform): path, extra = SEARCHES[platform] return platform, get(path, query=BRAND, **extra) # Step 1: six searches in parallel. with ThreadPoolExecutor(max_workers=6) as pool: results = dict(pool.map(search, SEARCHES)) # Step 2: keep on-topic rows, dedupe against earlier runs by post URL. known = set(json.loads(KNOWN_FILE.read_text())) if KNOWN_FILE.exists() else set() fresh, spent, off_topic = [], 0, 0 for platform, body in results.items(): spent += body.get("credits_used", 0) if not body["success"]: print(f"{platform}: {body['error']['type']}") continue for item in body["data"]["items"]: post = item["post"] text = post["content"]["text"] if not on_topic(text): off_topic += 1 continue url = post["url"] if url and url not in known: known.add(url) fresh.append((platform, post)) KNOWN_FILE.write_text(json.dumps(sorted(known))) # Step 3: alert on what is new. print(f"{len(fresh)} new mentions of {BRAND!r}, {off_topic} off-topic rows skipped ({spent} credits)") for platform, post in fresh: print(f"[{platform}] {post['content']['text'][:120]}") print(f" {post['url']}") # Replace print with a Slack webhook, an email or a database insert. ``` ```ts title="Node.js" // brand-mentions.ts import { readFile, writeFile } from "node:fs/promises"; const KEY = process.env.INSIGHTSOCIAL_API_KEY; if (!KEY) throw new Error("Set INSIGHTSOCIAL_API_KEY"); const BASE = "https://api.insightsocial.app/v1"; const BRAND = "notion"; const CONTEXT = ["app", "workspace", "template", "notes", "wiki", "database", "page"]; const yesterday = new Date(Date.now() - 86_400_000).toISOString().slice(0, 10); const searches: Record]> = { reddit: ["reddit/search", { max_age_days: "1" }], tiktok: ["tiktok/search", { max_age_days: "1" }], youtube: ["youtube/search", { max_age_days: "1" }], twitter: ["twitter/search/tweets", { max_age_days: "1" }], linkedin: ["linkedin/search/posts", { since: yesterday }], pinterest: ["pinterest/search", { since: yesterday }], }; const escape = (s: string) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); const brandRe = new RegExp(`\\b${escape(BRAND)}\\b`, "i"); const contextRe = new RegExp(`\\b(${CONTEXT.map(escape).join("|")})\\b`, "i"); const onTopic = (text: string | null) => !!text && brandRe.test(text) && (CONTEXT.length === 0 || contextRe.test(text)); async function get(path: string, params: Record) { const url = new URL(`${BASE}/${path}`); for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v); return (await fetch(url, { headers: { "x-api-key": KEY! } })).json(); } const platforms = Object.keys(searches); const bodies = await Promise.all( platforms.map((p) => get(searches[p][0], { query: BRAND, ...searches[p][1] })), ); const known = new Set( await readFile("known-mentions.json", "utf8").then(JSON.parse).catch(() => []), ); const fresh: { platform: string; url: string; text: string }[] = []; bodies.forEach((body, i) => { if (!body.success) return console.warn(`${platforms[i]}: ${body.error.type}`); for (const { post } of body.data.items) { const text: string | null = post.content.text; if (!onTopic(text)) continue; if (post.url && !known.has(post.url)) { known.add(post.url); fresh.push({ platform: platforms[i], url: post.url, text: text! }); } } }); await writeFile("known-mentions.json", JSON.stringify([...known])); console.log(`${fresh.length} new mentions of "${BRAND}"`); for (const m of fresh) console.log(`[${m.platform}] ${m.text.slice(0, 120)}\n ${m.url}`); ``` Run it once a day. The one-day window plus the URL set means each mention surfaces once. `/v1/linkedin/search/posts` and `/v1/pinterest/search` bound the period with `since` and `until` (`YYYY-MM-DD`). The code sets `since` to yesterday's date. On X, you can also put the window in the query itself, for example `query=notion since:2026-09-22`. ## What you get back [#what-you-get-back] ```text title="Example output" 14 new mentions of 'notion', 9 off-topic rows skipped (80 credits) [reddit] Switched our team wiki from Confluence to Notion, here is what broke https://www.reddit.com/r/productivity/comments/... [youtube] My 2026 Notion setup for university, templates included https://www.youtube.com/watch?v=... [twitter] notion's new offline mode finally shipped, every page loads on the train https://x.com/.../status/... ... ``` The figures are illustrative. The keyword check runs on your side, so it costs nothing, and a post about "a notion of fairness" does not reach your alert channel. Rows skipped this way were still fetched and are part of the page you paid for. ## What to change [#what-to-change] * **`BRAND` and `CONTEXT`.** Swap in a competitor, a product or a person. `CONTEXT` matters most when the name is also an ordinary word. Set it to `[]` for a name nobody uses for anything else. * **A stricter check.** Keyword rules miss sarcasm and odd phrasing. For borderline rows, send the text to a classifier or a language model you run, with a prompt that names your brand. * **One language.** Every post carries `post.language`, the platform's own tag (for example `en`). Many platforms leave it `null`, so keep rows where it is `null` rather than dropping them. * **The window.** Match `max_age_days` and `since` to how often the job runs, so windows neither overlap nor leave gaps. * **Fewer platforms, lower price.** Drop the searches you do not need. Each one removed saves at least 10 credits and lowers the hold. Check a call's price first with `dry_run=1`, which is never charged. * **Persist the known URLs properly.** A JSON file is fine on one machine. Move it to a database table before you run on more than one worker. ## Related [#related] How people feel about the brand, scored from comments. Track the accounts themselves, not only what people say. The post shape every search returns. Every search endpoint side by side. --- # Competitor tracking (/docs/recipes/competitor-tracking) Snapshot a competitor's followers, engagement and latest posts on TikTok, YouTube and X in one parallel sweep, then diff it against the last run. 60 to 70 credits per competitor. You will build the data side of a competitive dashboard: on a schedule, snapshot each competitor's follower counts, engagement rate and latest posts on three platforms, store the snapshot, and compare it with the previous one. Your stored history then reveals sudden follower jumps and new campaigns. 60 to 70 credits per competitor: three profiles at 10 credits each (30), plus three post lists: TikTok (10), YouTube (metered, 10–20) and X (10). Tracking 10 competitors once a week costs at least 2,400 credits a month. ## How do you track a competitor's social accounts? [#how-do-you-track-a-competitors-social-accounts] Call each platform's profile endpoint and its latest-posts endpoint in parallel, store the result keyed by competitor and date, and diff it against the previous snapshot to spot follower growth and new posts. For most consumer brands, three platforms at two calls each, six in total, is enough. ## What you need [#what-you-need] | Platform | Profile (10 credits) | Latest posts | | -------- | ------------------------------------ | ------------------------------------------------------------------------ | | TikTok | `GET /v1/tiktok/profile` (`handle`) | `GET /v1/tiktok/profile/videos` (`handle`), 10 | | YouTube | `GET /v1/youtube/channel` (`handle`) | `GET /v1/youtube/channel/videos` (`handle`, `includeExtras=true`), 10–20 | | X | `GET /v1/twitter/profile` (`handle`) | `GET /v1/twitter/user/tweets` (`handle`), 10 | Every profile comes back as `data.author` with `followers`, and every post list as `data.items[].post` with `engagement.likes`, `engagement.comments` and the rest, in the same shape on all three platforms. That makes one engagement formula possible: the code computes the average of `(likes + comments) / followers` over the latest posts. It skips a post whose likes or comments are `null` (hidden, or not shown on that list), and a platform whose follower count is `null`, rather than counting them as zero. On YouTube, likes and comments are only filled with `includeExtras=true`. YouTube rounds subscriber counts above 1,000, and the profile says so with `followers_approximate: true`. Add `GET /v1/linkedin/company` (50 credits, a company page URL) for the follower count, and `GET /v1/linkedin/company/posts` (50 credits, `company_id`) for the latest posts. `GET /v1/linkedin/profile/full` (50 credits) returns a company and its latest 10 posts in one call, but it is a beta endpoint: its body follows LinkedIn's own structure rather than the post and profile shapes used here. ## The code [#the-code] ```python title="Python" # competitor_tracking.py # Snapshots one competitor on three platforms. Store the result and diff runs. # Run with: INSIGHTSOCIAL_API_KEY=isk_live_... python competitor_tracking.py import os from concurrent.futures import ThreadPoolExecutor from datetime import date import requests KEY = os.environ["INSIGHTSOCIAL_API_KEY"] BASE = "https://api.insightsocial.app/v1" COMPETITOR = "duolingo" # the same handle on all three platforms here def get(path, **params): res = requests.get(f"{BASE}/{path}", params=params, headers={"x-api-key": KEY}, timeout=120) return res.json() PAIRS = { "tiktok": ("tiktok/profile", "tiktok/profile/videos", {}), "youtube": ("youtube/channel", "youtube/channel/videos", {"includeExtras": "true"}), "twitter": ("twitter/profile", "twitter/user/tweets", {}), } def own_posts(items): # Leave out pinned posts (old, out of date order) and reposts of other accounts. posts = [i["post"] for i in items] return [p for p in posts if not p["flags"]["pinned"] and not (p["ext"] or {}).get("retweeted_post")] def engagement_rate(posts, followers): """Average (likes + comments) / followers over the posts that show both counts.""" if not followers: return None rates = [(p["engagement"]["likes"] + p["engagement"]["comments"]) / followers for p in posts if p["engagement"]["likes"] is not None and p["engagement"]["comments"] is not None] return round(sum(rates) / len(rates), 6) if rates else None # Step 1: six calls in parallel (the key allows 10 in flight). with ThreadPoolExecutor(max_workers=6) as pool: futures = {} for platform, (profile_path, posts_path, extra) in PAIRS.items(): futures[(platform, "profile")] = pool.submit(get, profile_path, handle=COMPETITOR) futures[(platform, "posts")] = pool.submit(get, posts_path, handle=COMPETITOR, **extra) results = {k: f.result() for k, f in futures.items()} # Step 2: build today's snapshot. snapshot = {"date": date.today().isoformat(), "handle": COMPETITOR, "platforms": []} spent = 0 for platform in PAIRS: profile = results[(platform, "profile")] posts = results[(platform, "posts")] spent += profile.get("credits_used", 0) + posts.get("credits_used", 0) if not profile["success"]: print(f"{platform}: {profile['error']['type']}") continue author = profile["data"]["author"] items = own_posts(posts["data"]["items"]) if posts["success"] else [] latest = items[0] if items else None snapshot["platforms"].append({ "platform": platform, "followers": author["followers"], "followers_approximate": author["followers_approximate"], "engagement_rate": engagement_rate(items, author["followers"]), "posts_fetched": len(items), "latest_post_id": latest["id"] if latest else None, "latest_post_at": latest["published_at"] if latest else None, "latest_post": ((latest["content"]["text"] if latest else None) or "")[:80], }) for row in snapshot["platforms"]: print(row) print(f"credits used this run: {spent}") # Step 3: persist `snapshot` keyed by (handle, date), then compare with the last one: # follower_delta = today.followers - previous.followers # new_posts = posts published after previous.latest_post_at # engagement_jump = today.engagement_rate / trailing average # Alert when a delta crosses your threshold. ``` ```ts title="Node.js" // competitor-tracking.ts // Run with: INSIGHTSOCIAL_API_KEY=isk_live_... npx tsx competitor-tracking.ts const KEY = process.env.INSIGHTSOCIAL_API_KEY; if (!KEY) throw new Error("Set INSIGHTSOCIAL_API_KEY"); const BASE = "https://api.insightsocial.app/v1"; const competitor = "duolingo"; async function get(path: string, params: Record) { const url = new URL(`${BASE}/${path}`); for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v); const res = await fetch(url, { headers: { "x-api-key": KEY! } }); return res.json(); } const pairs: Record]> = { tiktok: ["tiktok/profile", "tiktok/profile/videos", {}], youtube: ["youtube/channel", "youtube/channel/videos", { includeExtras: "true" }], twitter: ["twitter/profile", "twitter/user/tweets", {}], }; // Pinned posts sit out of date order; reposts are someone else's post. const ownPosts = (items: any[]) => items.map((i) => i.post).filter((p) => !p.flags.pinned && !p.ext?.retweeted_post); function engagementRate(posts: any[], followers: number | null): number | null { if (!followers) return null; const rates = posts .filter((p) => p.engagement.likes !== null && p.engagement.comments !== null) .map((p) => (p.engagement.likes + p.engagement.comments) / followers); return rates.length ? rates.reduce((a, b) => a + b, 0) / rates.length : null; } // Step 1: six calls in parallel. const platforms = Object.keys(pairs); const results = await Promise.all( platforms.flatMap((p) => { const [profilePath, postsPath, extra] = pairs[p]; return [get(profilePath, { handle: competitor }), get(postsPath, { handle: competitor, ...extra })]; }), ); // Step 2: build today's snapshot. const rows = platforms.map((platform, i) => { const profile = results[i * 2]; const posts = results[i * 2 + 1]; const author = profile.success ? profile.data.author : null; const items = posts.success ? ownPosts(posts.data.items) : []; return { platform, followers: author?.followers ?? null, engagement_rate: author ? engagementRate(items, author.followers) : null, posts_fetched: items.length, latest_post_at: items[0]?.published_at ?? null, latest_post: items[0]?.content.text?.slice(0, 80) ?? null, }; }); console.table(rows); // Step 3: store rows keyed by (handle, date) and diff against the previous run. ``` ## What you get back [#what-you-get-back] ```text title="Example output" {'platform': 'tiktok', 'followers': 19300000, 'followers_approximate': None, 'engagement_rate': 0.0091, 'posts_fetched': 9, 'latest_post_id': '7...', 'latest_post_at': '2026-10-02T17:04:11.000Z', 'latest_post': '...'} {'platform': 'youtube', 'followers': 7640000, 'followers_approximate': True, 'engagement_rate': 0.0012, 'posts_fetched': 30, ...} {'platform': 'twitter', 'followers': 14900000, 'followers_approximate': None, 'engagement_rate': 0.0003, 'posts_fetched': 16, ...} credits used this run: 60 ``` The figures are illustrative. The rate is one formula applied to three platforms, not three platforms' own definitions, so compare it across competitors on the same platform first. A `None` rate means no post on the page showed both counts, or the profile had no follower count: keep it `None`, never `0`. ## What to change [#what-to-change] * **Handles per platform.** Real brands rarely use one handle everywhere. Keep a `{tiktok, youtube, twitter}` map per competitor. * **Your own formula.** Add `shares` where the platform shows them (TikTok, X), or divide by `views` instead of followers for reach-based engagement. A count the platform does not show is `null` on every row; the [platform pages](/docs/platforms/tiktok) list which. * **Only fetch new posts.** Store the newest post id per platform and pass it back as `stop_at_id`, or pass the previous run's date as `since`. The list then stops at what you already hold. See [Choosing endpoints](/docs/choosing-endpoints#only-what-is-new). * **Which platforms.** Drop a pair to save at least 20 credits, or add LinkedIn for 100 more. * **Store results, refresh on a schedule.** Every run is charged, so a dashboard should read from your own store and refresh on a schedule, not on every page view. ## Related [#related] Rank accounts on comparable engagement rates. What people say about them, not only what they post. The engagement fields and when each one is null. --- # Creator engagement scoring (/docs/recipes/creator-engagement-scoring) Compare one creator's engagement on TikTok, YouTube and X in a single ranked table, calculated with one formula from each platform's recent posts. 60 to 70 credits per creator. You will build a vetting table for influencer marketing: a single row per platform for one creator across TikTok, YouTube and X, sorted by an engagement rate you compute the same way on each network. 60 to 70 credits per creator: three profile calls at 10 credits each, plus one page of recent posts per platform (TikTok 10, YouTube 10–20, X 10). Vetting a shortlist of 100 creators costs at least 6,000 credits. Checking the same creator again is charged again, so keep the scores you calculated. ## How do you compare engagement rates across platforms? [#how-do-you-compare-engagement-rates-across-platforms] Fetch each platform's profile for the follower count, and one page of the creator's recent posts for the likes and comments. Then apply one formula everywhere: for each post, `(likes + comments) / followers`, and take the median over the page. The median keeps one viral post from carrying the whole score. Raw numbers do not compare on their own. A TikTok like is not a YouTube like, follower counts inflate differently, and every analytics tool defines "engagement rate" its own way. A formula you own, applied to the same fields on every platform, is what makes the ranking fair. Recent posts also avoid a trap in lifetime totals: a TikTok profile's like count is every heart the account ever received, which says little about how its videos do now. ## What you need [#what-you-need] | Endpoint | Returns | Credits | | -------------------------------- | ------------------------------------------------------------ | ------- | | `GET /v1/tiktok/profile` | `data.author.followers` | 10 | | `GET /v1/tiktok/profile/videos` | Recent videos, `post.engagement` | 10 | | `GET /v1/youtube/channel` | `data.author.followers` (rounded above 1,000) | 10 | | `GET /v1/youtube/channel/videos` | Recent videos; `includeExtras=true` fills likes and comments | 10–20 | | `GET /v1/twitter/profile` | `data.author.followers` | 10 | | `GET /v1/twitter/user/tweets` | Recent posts, `post.engagement` | 10 | ## The code [#the-code] ```python title="Python" # creator_scoring.py # Run with: INSIGHTSOCIAL_API_KEY=isk_live_... python creator_scoring.py import os from concurrent.futures import ThreadPoolExecutor from statistics import median import requests KEY = os.environ["INSIGHTSOCIAL_API_KEY"] BASE = "https://api.insightsocial.app/v1" # Real creators rarely share one handle, so map them per platform. CREATOR = {"tiktok": "mrbeast", "youtube": "MrBeast", "twitter": "MrBeast"} PATHS = { "tiktok": ("tiktok/profile", "tiktok/profile/videos", {}), "youtube": ("youtube/channel", "youtube/channel/videos", {"includeExtras": "true"}), "twitter": ("twitter/profile", "twitter/user/tweets", {}), } def get(path, **params): res = requests.get(f"{BASE}/{path}", params=params, headers={"x-api-key": KEY}, timeout=120) return res.json() def score(platform): profile_path, posts_path, extra = PATHS[platform] handle = CREATOR[platform] profile = get(profile_path, handle=handle) posts = get(posts_path, handle=handle, **extra) row = {"platform": platform, "followers": None, "engagement_rate": None, "posts_scored": 0, "credits": profile.get("credits_used", 0) + posts.get("credits_used", 0), "why": None} if not profile["success"] or not posts["success"]: row["why"] = (profile.get("error") or posts.get("error"))["type"] return row followers = profile["data"]["author"]["followers"] row["followers"] = followers if not followers: row["why"] = "no follower count" return row rates = [] for item in posts["data"]["items"]: post = item["post"] likes, comments = post["engagement"]["likes"], post["engagement"]["comments"] # Skip pinned posts (old, out of order) and posts with a hidden count. if post["flags"]["pinned"] or likes is None or comments is None: continue rates.append((likes + comments) / followers) row["posts_scored"] = len(rates) if rates: row["engagement_rate"] = round(median(rates), 4) else: row["why"] = "no post with both counts" return row with ThreadPoolExecutor(max_workers=3) as pool: rows = list(pool.map(score, CREATOR)) # Rank the comparable rows; keep the others visible but unranked. ranked = sorted((r for r in rows if r["engagement_rate"] is not None), key=lambda r: r["engagement_rate"], reverse=True) for r in ranked: print(f'{r["platform"]:<10} {r["followers"]:>12,} {r["engagement_rate"]:.4f} ({r["posts_scored"]} posts)') for r in rows: if r["engagement_rate"] is None: print(f'{r["platform"]:<10} cannot compare: {r["why"]}') print("credits used:", sum(r["credits"] for r in rows)) ``` ```ts title="Node.js" // creator-scoring.ts const KEY = process.env.INSIGHTSOCIAL_API_KEY; if (!KEY) throw new Error("Set INSIGHTSOCIAL_API_KEY"); const BASE = "https://api.insightsocial.app/v1"; const creator = { tiktok: "mrbeast", youtube: "MrBeast", twitter: "MrBeast" }; const paths: Record]> = { tiktok: ["tiktok/profile", "tiktok/profile/videos", {}], youtube: ["youtube/channel", "youtube/channel/videos", { includeExtras: "true" }], twitter: ["twitter/profile", "twitter/user/tweets", {}], }; async function get(path: string, params: Record) { const url = new URL(`${BASE}/${path}`); for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v); return (await fetch(url, { headers: { "x-api-key": KEY! } })).json(); } const median = (xs: number[]) => { const s = [...xs].sort((a, b) => a - b); const m = Math.floor(s.length / 2); return s.length % 2 ? s[m] : (s[m - 1] + s[m]) / 2; }; async function score(platform: keyof typeof creator) { const [profilePath, postsPath, extra] = paths[platform]; const handle = creator[platform]; const [profile, posts] = await Promise.all([ get(profilePath, { handle }), get(postsPath, { handle, ...extra }), ]); const followers: number | null = profile.success ? profile.data.author.followers : null; const rates = posts.success && followers ? posts.data.items .map((i: any) => i.post) .filter((p: any) => !p.flags.pinned && p.engagement.likes !== null && p.engagement.comments !== null) .map((p: any) => (p.engagement.likes + p.engagement.comments) / followers) : []; return { platform, followers, engagement_rate: rates.length ? median(rates) : null, posts_scored: rates.length }; } const rows = await Promise.all((Object.keys(creator) as (keyof typeof creator)[]).map(score)); rows.sort((a, b) => (b.engagement_rate ?? -1) - (a.engagement_rate ?? -1)); console.table(rows); ``` ## What you get back [#what-you-get-back] ```text title="Example output" tiktok 112,000,000 0.0109 (9 posts) youtube 298,000,000 0.0071 (30 posts) twitter 33,400,000 0.0021 (17 posts) credits used: 60 ``` The figures are illustrative. A `None` rate is a signal, not a low score: the profile had no follower count, or no post on the page showed both likes and comments. Treat such rows as "cannot compare", never as "best" or "worst". YouTube subscriber counts are rounded above 1,000 (`followers_approximate: true` on the profile), which is close enough for a ranking but not for a precise rate. ## What to change [#what-to-change] * **The formula.** Add `shares` and `saves` where a platform shows them, or divide by `views` for a reach-based rate. A count the platform never shows is `null` on every row, and a count hidden on one post is `null` on that post only, so filter on `None` exactly as the code does. * **A bigger sample.** Send `pagination.next_cursor` back as `cursor` with the same `handle` to read older posts, at the page price each. See [Pagination](/docs/pagination). * **Score a shortlist.** Loop over a list of creator maps and sort the flattened rows. Budget at least 60 credits per creator. * **Weight the rank.** Engagement rate alone favours small accounts. Blend it with `followers` for the trade-off your team actually makes. ## Related [#related] The engagement fields and when each one is null. Go deeper on one platform, down to each video. The same fields across a competitive set, over time. Find the creators to score in the first place. --- # Recipes (/docs/recipes) Eight end-to-end builds on the InsightSocial API, from brand monitoring to music trends, each with its credit cost worked out before you run it. Each recipe solves one real task from start to finish and tells you what a run costs before you start. The snippets are Python (3.9+, `requests`), with Node.js (22+, native `fetch`) where a recipe benefits from both. They read your key from `INSIGHTSOCIAL_API_KEY`, use real public accounts, queries and URLs, and read the [schema 2](/docs/schema-2) response shape: posts, profiles, comments and transcripts look the same on every platform. Anything a recipe derives, such as an engagement rate or a sentiment score, it computes from those fields in your code. New to the API? The [Quickstart](/docs/quickstart) gets you a key and a first call in a few minutes. ## Pick a recipe [#pick-a-recipe] | Recipe | What you build | Credits per run | | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | ----------------------------- | | [Brand mention monitoring](/docs/recipes/brand-mention-monitoring) | A daily sweep of six platforms' search for your brand, deduped | from 60 per sweep | | [Sentiment analysis](/docs/recipes/sentiment-analysis) | How people feel about a topic, scored from the comments with your own model | 200–630 | | [Competitor tracking](/docs/recipes/competitor-tracking) | Follower counts, engagement and latest posts across three platforms, snapshotted | 60–70 per competitor | | [Creator engagement scoring](/docs/recipes/creator-engagement-scoring) | One creator's engagement on three platforms, worked out from recent posts and ranked | 60–70 per creator | | [TikTok analytics dashboard](/docs/recipes/tiktok-analytics-dashboard) | Account KPIs, a per-video table and a comment feed | 30–50 per refresh | | [Search then enrich](/docs/recipes/search-then-enrich) | Posts on a topic, then the full profile of everyone who posted them | 120–520 | | [Video transcription](/docs/recipes/video-transcription-api) | One `transcribe()` function for five platforms | 30 (YouTube) or 100 per video | | [Music trend detection](/docs/recipes/music-trend-detection) | A heat score for a sound on TikTok | 20 per song | Where a price is a range, at least one endpoint in the recipe is metered: the most the call can cost with your parameters is held when it starts, and you are charged what it actually used. Failed calls, empty results and `dry_run=1` calls are never charged. Repeating a call is charged again (2 credits when the shared cache answers it), so store what you fetch. API credits are non-refundable. See [Credits](/docs/credits). ## Which recipe should I start with? [#which-recipe-should-i-start-with] If you want to see the breadth of the API, start with [Brand mention monitoring](/docs/recipes/brand-mention-monitoring). It runs six platforms' search endpoints in parallel from one key, with one response envelope to handle. If you already know the platform, the [TikTok analytics dashboard](/docs/recipes/tiktok-analytics-dashboard) is the shortest complete example: three calls, one account. ## The helper every recipe uses [#the-helper-every-recipe-uses] Every recipe calls the API through the same small function. It sends the key in `x-api-key`, raises on a failed call, and returns the whole envelope so you can read `data`, `pagination`, `unavailable` and `credits_used`. ```python title="Python" import os import requests KEY = os.environ["INSIGHTSOCIAL_API_KEY"] BASE = "https://api.insightsocial.app/v1" def get(path, **params): res = requests.get( f"{BASE}/{path}", params=params, headers={"x-api-key": KEY}, timeout=120, ) body = res.json() if not body["success"]: raise RuntimeError(f'{body["error"]["type"]}: {body["error"]["message"]}') return body ``` ```ts title="Node.js" const KEY = process.env.INSIGHTSOCIAL_API_KEY; if (!KEY) throw new Error("Set INSIGHTSOCIAL_API_KEY"); const BASE = "https://api.insightsocial.app/v1"; async function get(path: string, params: Record = {}) { const url = new URL(`${BASE}/${path}`); for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v); const res = await fetch(url, { headers: { "x-api-key": KEY! } }); const body = await res.json(); if (!body.success) throw new Error(`${body.error.type}: ${body.error.message}`); return body; } ``` A count the platform hides is `null`, never `0`, so the recipes skip nulls rather than adding them. `unavailable` lists the fields a response could not fill on any row, for example `["items[].post.author.id"]`. Two limits shape how the recipes run calls in parallel: 60 requests per minute and 10 calls in flight per key. The recipes keep their thread pools at 10 or fewer. See [Rate limits](/docs/rate-limits). ## Related [#related] Decision tables for the endpoints that look alike. Every endpoint and its credit price. The response shape every recipe reads. Getting past the first page of any list. --- # Music trend detection (/docs/recipes/music-trend-detection) Score how fast a sound is spreading on TikTok with a log-weighted heat score you can track day over day. 20 credits per song. You will build an early-warning detector for sounds that are taking off. A song moves on the creation side first: creators pick it up on TikTok, and only later does it reach the charts. Measuring how many videos use a sound, and how far those videos travel, catches the move while it is still early. 20 credits per song: the sound itself with its usage count (10) and one page of TikTok videos using it (10). Finding each track's id is a one-off at 10 credits. Scanning 100 tracks daily costs at least 60,000 credits a month. Scan a shortlist daily and a wider list weekly to keep that down. ## How can you catch a rising sound before it charts? [#how-can-you-catch-a-rising-sound-before-it-charts] Combine two signals. `GET /v1/tiktok/song` returns the sound with how many videos use it. `GET /v1/tiktok/song/videos` returns videos that use it, with their view counts. A log-weighted mix of the two, stored per day, shows which songs are accelerating. ## What you need [#what-you-need] | Endpoint | Signal | Parameter | Credits | | ---------------------------- | ------------------------------------------------------- | --------- | ------- | | `GET /v1/tiktok/song` | The sound, with its usage count in `post.ext.use_count` | `clipId` | 10 | | `GET /v1/tiktok/song/videos` | Videos that use the sound | `clipId` | 10 | ### Resolving the id [#resolving-the-id] TikTok keys sounds by id, not by name, and the id is stable per track. Look it up once and store it. * **TikTok `clipId`:** `GET /v1/tiktok/search/music` (10 credits) searches sounds by keyword. Each sound comes back as a post: `post.id` is the `clipId`, `post.content.text` the title, and `post.ext.video_count` how many videos use it. `sort_by=most-used` puts the biggest first. ## The code [#the-code] ```python title="Python" # music_heat.py # A heat score for one track. Store it per day and watch the delta. # Run with: INSIGHTSOCIAL_API_KEY=isk_live_... python music_heat.py import math import os from concurrent.futures import ThreadPoolExecutor import requests KEY = os.environ["INSIGHTSOCIAL_API_KEY"] BASE = "https://api.insightsocial.app/v1" # Resolve the id once (see above), then keep it. TIKTOK_CLIP_ID = "7364498342501435408" # "Espresso", Sabrina Carpenter def get(path, **params): res = requests.get(f"{BASE}/{path}", params=params, headers={"x-api-key": KEY}, timeout=120) return res.json() def views_on_page(body): """Sum of views on the page, and how many rows showed a view count.""" if not body["success"]: return 0, 0 views = [i["post"]["engagement"]["views"] for i in body["data"]["items"]] known = [v for v in views if v is not None] # null means hidden, not zero return sum(known), len(known) with ThreadPoolExecutor(max_workers=2) as pool: sg = pool.submit(get, "tiktok/song", clipId=TIKTOK_CLIP_ID) vd = pool.submit(get, "tiktok/song/videos", clipId=TIKTOK_CLIP_ID) song, videos = sg.result(), vd.result() use_count = (song["data"]["post"]["ext"] or {}).get("use_count") or 0 if song["success"] else 0 sample_views, on_page = views_on_page(videos) # One page is a sample, not a census. Weight it with the usage count, then track the trend. heat = 0.5 * math.log10(use_count + 1) + 0.5 * math.log10(sample_views + 1) print({ "use_count": use_count, "sample_views": sample_views, "videos_on_page": on_page, "heat_score": round(heat, 2), "credits_used": song.get("credits_used", 0) + videos.get("credits_used", 0), }) ``` ```ts title="Node.js" // music-heat.ts const KEY = process.env.INSIGHTSOCIAL_API_KEY; if (!KEY) throw new Error("Set INSIGHTSOCIAL_API_KEY"); const BASE = "https://api.insightsocial.app/v1"; const tiktokClipId = "7364498342501435408"; // "Espresso", Sabrina Carpenter async function get(path: string, params: Record) { const url = new URL(`${BASE}/${path}`); for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v); return (await fetch(url, { headers: { "x-api-key": KEY! } })).json(); } // Views summed over the rows that show a count; null means hidden, not zero. const viewsOnPage = (body: any): number => body.success ? body.data.items.reduce((s: number, i: any) => s + (i.post.engagement.views ?? 0), 0) : 0; const [song, videos] = await Promise.all([ get("tiktok/song", { clipId: tiktokClipId }), get("tiktok/song/videos", { clipId: tiktokClipId }), ]); const useCount: number = song.success ? song.data.post.ext?.use_count ?? 0 : 0; const sampleViews = viewsOnPage(videos); const heat = 0.5 * Math.log10(useCount + 1) + 0.5 * Math.log10(sampleViews + 1); console.log({ use_count: useCount, sample_views: sampleViews, heat_score: heat.toFixed(2) }); ``` ## What you get back [#what-you-get-back] ```text title="Example output" {'use_count': 2140000, 'sample_views': 52700000, 'videos_on_page': 30, 'heat_score': 7.03, 'credits_used': 20} ``` The figures are illustrative. The video list returns one page, not every video that uses the sound, so the view sum is a reach sample. A row whose view count is hidden (`null`) adds nothing to the sum and is not counted in `videos_on_page`. Compare a track's score with its own history, not with an absolute bar. ## What to change [#what-to-change] * **The id.** Swap in the track you are watching. Budget 10 credits once per new track if you still need to look it up. * **Weight the usage count's change.** `post.ext.use_count` is the cleanest creation-velocity number TikTok publishes; its day-over-day change is worth a term of its own in the score. * **See how the sound is being used.** Read the captions yourself: `post.content.text` on each row of `tiktok/song/videos`. Counting rows by `post.published_at` day gives you a date histogram of the page. * **Find candidates to score.** `GET /v1/tiktok/search/music` with `sort_by=most-used` (10) surfaces the most-used sounds for a keyword. * **Deepen the sample.** Send `pagination.next_cursor` back as `cursor`, with the same id, to read more pages at 10 credits each, and adjust the weights to match. * **Track the delta, not the level.** Store `heat_score` per track per day. A rising score is the signal. A high, flat score is a song that already broke. ## Related [#related] The same parallel-fetch and score pattern, on creators. Sounds, songs, effects and the rest of TikTok. Reading more than one page of a list. --- # Search then enrich (/docs/recipes/search-then-enrich) Find the posts about a topic on TikTok and X, collect the accounts that made them, and fetch each account's full profile into one lead list. From 120 credits per run. You will build a creator-discovery pipeline: search two platforms for posts about a topic, collect the unique accounts behind the top posts, and fetch each account's full profile (followers, bio, bio link, public contact email where one is listed) into one table. 120 to 520 credits: two searches (TikTok 10–370, X 10–50) plus 10 profile lookups at 10 credits each. Looking up an account again is charged again, so keep the profiles you already fetched. `ACCOUNTS_PER_PLATFORM` is the price dial. ## How do you turn a topic into a list of creators? [#how-do-you-turn-a-topic-into-a-list-of-creators] Chain two kinds of endpoint. A post search tells you who is posting about the topic right now. A profile call tells you who they are. Search rows carry the author's handle, and the handle is exactly what the profile endpoint takes, so there is no string-massaging in between. A search result shows that someone posted about the topic. It does not give you their follower count, bio or contact details at a useful depth. The profile does. ## What you need [#what-you-need] | Endpoint | Role | Credits | | ------------------------------- | ------------------------------------------------------------- | ------- | | `GET /v1/tiktok/search` | TikTok videos about the topic | 10–370 | | `GET /v1/twitter/search/tweets` | X posts about the topic | 10–50 | | `GET /v1/tiktok/profile` | Full TikTok account, including the bio link in `external_url` | 10 | | `GET /v1/twitter/profile` | Full X account, including the bio link in `external_url` | 10 | ## The code [#the-code] ```python title="Python" # search_then_enrich.py # Topic -> top posts -> unique authors -> full profiles. # Run with: INSIGHTSOCIAL_API_KEY=isk_live_... python search_then_enrich.py import os from concurrent.futures import ThreadPoolExecutor import requests KEY = os.environ["INSIGHTSOCIAL_API_KEY"] BASE = "https://api.insightsocial.app/v1" TOPIC = "home espresso setup" KEYWORDS = ["espresso"] # a post must mention one of these to count as on-topic ACCOUNTS_PER_PLATFORM = 5 SEARCH = {"tiktok": "tiktok/search", "twitter": "twitter/search/tweets"} PROFILE = {"tiktok": "tiktok/profile", "twitter": "twitter/profile"} def get(path, **params): res = requests.get(f"{BASE}/{path}", params=params, headers={"x-api-key": KEY}, timeout=120) return res.json() def on_topic(post): text = (post["content"]["text"] or "").lower() return any(k in text for k in KEYWORDS) # Step 1: search both platforms. with ThreadPoolExecutor(max_workers=2) as pool: found = dict(zip(SEARCH, pool.map( lambda p: get(SEARCH[p], query=TOPIC), SEARCH))) # Step 2: unique authors of on-topic posts, in the order the search ranked them. targets = [] for platform, body in found.items(): if not body["success"]: print(f"{platform} search: {body['error']['type']}") continue handles = [] for item in body["data"]["items"]: post = item["post"] handle = post["author"]["username"] if handle and handle not in handles and on_topic(post): handles.append(handle) targets += [(platform, h) for h in handles[:ACCOUNTS_PER_PLATFORM]] # Step 3: enrich every author with a profile call. def enrich(target): platform, handle = target return platform, handle, get(PROFILE[platform], handle=handle) with ThreadPoolExecutor(max_workers=10) as pool: profiles = list(pool.map(enrich, targets)) rows = [] for platform, handle, body in profiles: if not body["success"]: continue author = body["data"]["author"] rows.append({ "platform": platform, "handle": handle, "followers": author["followers"], "bio": (author["bio"] or "")[:60], "link": author["external_url"], "email": (author["ext"] or {}).get("public_email"), }) rows.sort(key=lambda r: r["followers"] or 0, reverse=True) for r in rows: print(r) spent = sum(b.get("credits_used", 0) for b in found.values()) + \ sum(b.get("credits_used", 0) for _, _, b in profiles) print(f"credits used: {spent}") ``` ```ts title="Node.js" // search-then-enrich.ts const KEY = process.env.INSIGHTSOCIAL_API_KEY; if (!KEY) throw new Error("Set INSIGHTSOCIAL_API_KEY"); const BASE = "https://api.insightsocial.app/v1"; const topic = "home espresso setup"; const keywords = ["espresso"]; const PER_PLATFORM = 5; const search = { tiktok: "tiktok/search", twitter: "twitter/search/tweets" }; const profile = { tiktok: "tiktok/profile", twitter: "twitter/profile" }; type P = keyof typeof search; async function get(path: string, params: Record) { const url = new URL(`${BASE}/${path}`); for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v); return (await fetch(url, { headers: { "x-api-key": KEY! } })).json(); } const onTopic = (post: any) => keywords.some((k) => (post.content.text ?? "").toLowerCase().includes(k)); // Step 1: search both platforms. const platforms = Object.keys(search) as P[]; const found = await Promise.all(platforms.map((p) => get(search[p], { query: topic }))); // Step 2: unique authors of on-topic posts, per platform. const targets: [P, string][] = []; found.forEach((body, i) => { if (!body.success) return; const handles = [ ...new Set( body.data.items .map((it: any) => it.post) .filter((post: any) => post.author.username && onTopic(post)) .map((post: any) => post.author.username), ), ]; for (const h of handles.slice(0, PER_PLATFORM)) targets.push([platforms[i], h]); }); // Step 3: enrich each author. const profiles = await Promise.all(targets.map(([p, h]) => get(profile[p], { handle: h }))); const rows = profiles .map((b, i) => b.success && { platform: targets[i][0], handle: targets[i][1], followers: b.data.author.followers, link: b.data.author.external_url, email: b.data.author.ext?.public_email ?? null, }) .filter(Boolean); console.table(rows); ``` ## What you get back [#what-you-get-back] ```text title="Example output" {'platform': 'tiktok', 'handle': '...', 'followers': 1840000, 'bio': 'coffee nerd. latte art every day', 'link': 'https://linktr.ee/...', 'email': None} {'platform': 'twitter', 'handle': '...', 'followers': 412000, 'bio': 'Espresso gear reviews. hello@example.com', 'link': None, 'email': 'hello@example.com'} ... credits used: 120 ``` The figures are illustrative. `email` is only present when the account lists one publicly in its bio, and `link` (the profile's `external_url`) only when it has a bio link. The keyword check runs on your side, so it costs nothing; posts it drops were still part of the page you paid for. ## What to change [#what-to-change] * **`TOPIC` and `KEYWORDS`.** Any subject with public discussion. `KEYWORDS` keeps out posts that only share a word with the topic. Set it to the words that must appear in a caption. * **`ACCOUNTS_PER_PLATFORM`.** Each extra account costs 10 credits. * **Skip the second step on TikTok.** `GET /v1/tiktok/search/users?include=profile` (10–1,310) searches accounts directly and fills bio, region and `external_url` on every row in one call. Use it when you want accounts that match a topic, rather than the authors of posts that match it. * **More platforms.** Add `youtube/search` with `youtube/channel`. The profile call costs 10. * **Go deeper than the profile.** Fetch each account's recent posts (`tiktok/profile/videos`, `twitter/user/tweets`) and score them as in [Creator engagement scoring](/docs/recipes/creator-engagement-scoring), or feed the top posts to the [Video transcription recipe](/docs/recipes/video-transcription-api) to get what was said. ## Related [#related] Rank the accounts you found. Turn the top posts into text. Post searches and account searches side by side. The same searches run as a daily sweep. --- # Sentiment analysis (/docs/recipes/sentiment-analysis) Find the conversation about a topic on YouTube and Reddit, pull the comments, and score each comment's sentiment with a model you run. From 200 credits per run. This recipe measures public mood around a topic in three steps: locate the posts where it is discussed, collect the comments on the most active ones, and score the sentiment of those comments. The API returns the comments; the scoring runs on your side, so you choose the model and can change it without changing the data. 200 to 630 credits. Two searches (YouTube 10–150, Reddit 10–300), three YouTube comment pages (10 each) and three Reddit comment trees (50 each). Scoring the comments costs nothing on the API side. The Reddit leg costs the most because each call returns a whole discussion with nested replies expanded, not one page. ## How do you analyze social media sentiment with an API? [#how-do-you-analyze-social-media-sentiment-with-an-api] Two stages. Search finds the posts where the topic is being discussed. The comment endpoints then return what people said under them, one `comment` per item with its text in `comment.text`. Score each text with a sentiment model and count the results, and you have a sentiment split. Sentiment lives in comments, not in posts. The post says "we changed our pricing". The comments say what people think of it. ## What you need [#what-you-need] | Endpoint | Role | Credits | | -------------------------------- | ----------------------------------------------------------------- | ------- | | `GET /v1/youtube/search` | Find videos about the topic | 10–150 | | `GET /v1/reddit/search` | Find Reddit threads about the topic | 10–300 | | `GET /v1/youtube/video/comments` | Top-level comments on a video | 10 | | `GET /v1/reddit/post/comments` | A thread's full comment tree, replies nested in `comment.replies` | 50 | The code uses [VADER](https://github.com/cjhutto/vaderSentiment) in Python (`pip install vaderSentiment requests`) and the [`sentiment`](https://www.npmjs.com/package/sentiment) package in Node.js (`npm install sentiment`). Both are small English word lists that run offline. Swap in any model you prefer: a multilingual transformer, or a language model with a prompt that names your topic. ## The code [#the-code] ```python title="Python" # sentiment.py # Collects comments about a topic and counts the sentiment split. # Run with: INSIGHTSOCIAL_API_KEY=isk_live_... python sentiment.py import os from collections import Counter from concurrent.futures import ThreadPoolExecutor import requests from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer KEY = os.environ["INSIGHTSOCIAL_API_KEY"] BASE = "https://api.insightsocial.app/v1" TOPIC = "github copilot pricing" KEYWORDS = ["copilot"] # a result must mention one of these to count as on-topic THREADS_PER_PLATFORM = 3 analyzer = SentimentIntensityAnalyzer() def get(path, **params): res = requests.get(f"{BASE}/{path}", params=params, headers={"x-api-key": KEY}, timeout=120) return res.json() def on_topic(post): text = (post["content"]["text"] or "").lower() return any(k in text for k in KEYWORDS) def band(text): # VADER's usual cut-offs on the compound score, from -1 to 1. score = analyzer.polarity_scores(text)["compound"] return "negative" if score <= -0.05 else "positive" if score >= 0.05 else "neutral" def flatten_thread(comments): # Reddit nests replies inside each comment; other platforms leave `replies` null. for c in comments: yield c yield from flatten_thread(c["replies"] or []) # Step 1: find the conversation on both platforms, keeping on-topic results. yt = get("youtube/search", query=TOPIC) rd = get("reddit/search", query=TOPIC, timeframe="month") def top_urls(body, keep=lambda url: True): if not body["success"]: return [] posts = [i["post"] for i in body["data"]["items"]] return [p["url"] for p in posts if p["url"] and keep(p["url"]) and on_topic(p)][:THREADS_PER_PLATFORM] videos = top_urls(yt, keep=lambda u: "watch?v=" in u) threads = top_urls(rd) # Step 2: pull the comments under the top results. jobs = [("youtube/video/comments", u) for u in videos] + \ [("reddit/post/comments", u) for u in threads] with ThreadPoolExecutor(max_workers=6) as pool: pages = list(pool.map(lambda j: (j, get(j[0], url=j[1])), jobs)) # Step 3: score every comment and count the split per platform. split = {"youtube": Counter(), "reddit": Counter()} spent = yt.get("credits_used", 0) + rd.get("credits_used", 0) for (path, url), body in pages: spent += body.get("credits_used", 0) if not body["success"]: continue platform = path.split("/")[0] for c in flatten_thread(item["comment"] for item in body["data"]["items"]): # The scorer is English-only. `language` is often null; keep those. if not c["text"] or c["language"] not in (None, "en"): split[platform]["skipped"] += 1 continue split[platform][band(c["text"])] += 1 for platform, counts in split.items(): print(platform, dict(counts)) print(f"credits used: {spent}") ``` ```ts title="Node.js" // sentiment.ts import Sentiment from "sentiment"; const KEY = process.env.INSIGHTSOCIAL_API_KEY; if (!KEY) throw new Error("Set INSIGHTSOCIAL_API_KEY"); const BASE = "https://api.insightsocial.app/v1"; const topic = "github copilot pricing"; const keywords = ["copilot"]; const scorer = new Sentiment(); async function get(path: string, params: Record) { const url = new URL(`${BASE}/${path}`); for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v); return (await fetch(url, { headers: { "x-api-key": KEY! } })).json(); } const onTopic = (post: any) => keywords.some((k) => (post.content.text ?? "").toLowerCase().includes(k)); const band = (text: string) => { const score = scorer.analyze(text).comparative; return score < -0.05 ? "negative" : score > 0.05 ? "positive" : "neutral"; }; // Reddit nests replies inside each comment; other platforms leave `replies` null. const flattenThread = (comments: any[]): any[] => comments.flatMap((c) => [c, ...flattenThread(c.replies ?? [])]); // Step 1: find the conversation. const [yt, rd] = await Promise.all([ get("youtube/search", { query: topic }), get("reddit/search", { query: topic, timeframe: "month" }), ]); const topUrls = (body: any, keep = (u: string) => true): string[] => body.success ? body.data.items.map((i: any) => i.post).filter((p: any) => p.url && keep(p.url) && onTopic(p)) .map((p: any) => p.url).slice(0, 3) : []; const videos = topUrls(yt, (u) => u.includes("watch?v=")); const threads = topUrls(rd); // Step 2: comments under the top results. const jobs = [ ...videos.map((u) => ["youtube", "youtube/video/comments", u]), ...threads.map((u) => ["reddit", "reddit/post/comments", u]), ]; const pages = await Promise.all(jobs.map(([, path, url]) => get(path, { url }))); // Step 3: score and count. const split: Record> = { youtube: {}, reddit: {} }; pages.forEach((body, i) => { if (!body.success) return; const counts = split[jobs[i][0]]; for (const c of flattenThread(body.data.items.map((it: any) => it.comment))) { const b = !c.text || (c.language !== null && c.language !== "en") ? "skipped" : band(c.text); counts[b] = (counts[b] ?? 0) + 1; } }); console.log(split); ``` ## What you get back [#what-you-get-back] ```text title="Example output" youtube {'negative': 212, 'neutral': 96, 'positive': 71} reddit {'negative': 88, 'neutral': 54, 'positive': 40, 'skipped': 3} credits used: 260 ``` The figures are illustrative. `skipped` counts comments with no text, or tagged with a language other than English. ## Where a word list stops [#where-a-word-list-stops] A word-list scorer judges how a comment feels, not how it feels about your topic in particular. A comment that is angry about a bug in a competing product still reads as negative, and sarcasm reads as praise. When you need sentiment toward one named thing, hand the comment text to a model you run with a prompt that names the topic. The same comments are worth reading for more than polarity. Counting comments that ask a question (a `?`, or "how do I") or mention cancelling is often a sharper signal than "38% negative". ## What to change [#what-to-change] * **`TOPIC` and `KEYWORDS`.** Any brand, product, feature or announcement. `KEYWORDS` drops search results that only share a word with the topic. * **How deep to go.** `THREADS_PER_PLATFORM` sets most of the price. At 3 per platform the floor is 200 credits. At 1 per platform it is 80. * **Other platforms.** Swap in `tiktok/search` with `tiktok/post/comments` (10–30), or `twitter/search/tweets` with `twitter/tweet/replies` (10). Every comment list returns the same `comment` shape. * **Other languages.** Comments carry `comment.language` when the platform states it. Route each language to a model that reads it, instead of skipping it. * **A fixed window.** Use `timeframe` on Reddit and `max_age_days` on the searches to cover a launch week. ## Related [#related] Every field on a comment, including `language` and `replies` . The daily feed of posts this pipeline can score. All comment lists side by side, with prices. Walk deeper into a comment thread. --- # TikTok analytics dashboard (/docs/recipes/tiktok-analytics-dashboard) Build the data layer of a TikTok dashboard for accounts you do not own, with account KPIs, a per-video table with engagement rates and a scored comment feed. 30 to 50 credits per refresh. This recipe gathers everything a TikTok dashboard needs for any public account: headline account numbers, a table of how each recent video performed, and the comments on the strongest video, each scored for sentiment on your side. 30 to 50 credits per refresh: `profile` (10), one page of `profile/videos` (10) and one page of `post/comments` (metered, 10–30). Every refresh is charged, so a dashboard should store the last result and refresh on a schedule rather than on every page load. Refreshing 50 accounts once a day costs at least 45,000 credits a month. ## Which calls feed a TikTok dashboard? [#which-calls-feed-a-tiktok-dashboard] A full refresh takes three calls. Start with `GET /v1/tiktok/profile` for followers and lifetime likes. Then `GET /v1/tiktok/profile/videos` gives the latest videos with their view, like, comment, share and save counts, and `GET /v1/tiktok/post/comments` fetches the comments for whichever video URL you pass. The engagement rates are calculated from those counts in your code, with a formula you can show your users. TikTok's built-in analytics stop at the accounts you log in to. Working from public numbers with one fixed engagement formula lets you chart any account, whether for a creator tool, a client report or a brand team. ## What you need [#what-you-need] | Endpoint | Returns | Parameters | Credits | | ------------------------------- | ----------------------------------------------------------- | --------------------------------- | ------- | | `GET /v1/tiktok/profile` | Followers, lifetime likes, bio, verification | `handle` or `user_id` | 10 | | `GET /v1/tiktok/profile/videos` | Recent videos with views, likes, comments, shares and saves | `handle`; next page with `cursor` | 10 | | `GET /v1/tiktok/post/comments` | A page of comments on one video | `url`; next page with `cursor` | 10–30 | Need audience geography? `GET /v1/tiktok/user/audience` (50 credits, beta) returns the top follower countries and each one's share. Age and gender are not public on TikTok, so no endpoint returns them. The comment panel scores sentiment with [VADER](https://github.com/cjhutto/vaderSentiment) in Python (`pip install vaderSentiment`) and the [`sentiment`](https://www.npmjs.com/package/sentiment) package in Node.js. Both read English only; use a multilingual model if your accounts comment in other languages. ## The code [#the-code] ```python title="Python" # tiktok_dashboard.py # One full refresh for a TikTok account you do not own. # Run with: INSIGHTSOCIAL_API_KEY=isk_live_... python tiktok_dashboard.py import os import requests from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer KEY = os.environ["INSIGHTSOCIAL_API_KEY"] BASE = "https://api.insightsocial.app/v1" HANDLE = "khaby.lame" def get(path, **params): res = requests.get(f"{BASE}/{path}", params=params, headers={"x-api-key": KEY}, timeout=120) body = res.json() if not body["success"]: raise RuntimeError(f'{body["error"]["type"]}: {body["error"]["message"]}') return body def ratio(part, whole): # None when either side is unknown; a hidden count is null, not 0. return round(part / whole, 4) if part is not None and whole else None # Panel 1: account KPIs profile = get("tiktok/profile", handle=HANDLE) author = profile["data"]["author"] followers = author["followers"] print("followers:", followers, "(rounded)" if author["followers_approximate"] else "") print("lifetime likes:", author["likes_count"]) # Panel 2: per-video table videos = get("tiktok/profile/videos", handle=HANDLE) rows = [] for item in videos["data"]["items"]: post = item["post"] e = post["engagement"] counts = [e["likes"], e["comments"], e["shares"]] interactions = sum(counts) if None not in counts else None rows.append({ "caption": (post["content"]["text"] or "")[:40], "published_at": post["published_at"], "views": e["views"], "likes": e["likes"], "comments": e["comments"], "shares": e["shares"], "rate_by_views": ratio(interactions, e["views"]), "rate_by_followers": ratio(interactions, followers), "url": post["url"], }) for r in rows[:10]: print(r) # Panel 3: comment feed of the most-viewed video, scored for sentiment analyzer = SentimentIntensityAnalyzer() top = max(rows, key=lambda r: r["views"] or 0, default=None) comments = None if top: comments = get("tiktok/post/comments", url=top["url"]) for item in comments["data"]["items"][:5]: text = item["comment"]["text"] or "" compound = analyzer.polarity_scores(text)["compound"] # -1 to 1 print(f"[{compound:+.2f}] {text}") total = profile["credits_used"] + videos["credits_used"] + (comments["credits_used"] if comments else 0) print("credits used:", total) ``` ```ts title="Node.js" // tiktok-dashboard.ts import Sentiment from "sentiment"; const KEY = process.env.INSIGHTSOCIAL_API_KEY; if (!KEY) throw new Error("Set INSIGHTSOCIAL_API_KEY"); const BASE = "https://api.insightsocial.app/v1"; const handle = "khaby.lame"; async function get(path: string, params: Record) { const url = new URL(`${BASE}/${path}`); for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v); const body = await (await fetch(url, { headers: { "x-api-key": KEY! } })).json(); if (!body.success) throw new Error(`${body.error.type}: ${body.error.message}`); return body; } // null when either side is unknown; a hidden count is null, not 0. const ratio = (part: number | null, whole: number | null) => part !== null && whole ? part / whole : null; // Panel 1: account KPIs const profile = await get("tiktok/profile", { handle }); const { followers, likes_count } = profile.data.author; console.log({ followers, lifetime_likes: likes_count }); // Panel 2: per-video table const videos = await get("tiktok/profile/videos", { handle }); const rows = videos.data.items.map(({ post }: any) => { const { views, likes, comments, shares } = post.engagement; const interactions = [likes, comments, shares].includes(null) ? null : likes + comments + shares; return { caption: post.content.text?.slice(0, 40) ?? "", views, likes, shares, rate_by_views: ratio(interactions, views), rate_by_followers: ratio(interactions, followers), url: post.url, }; }); console.table(rows.slice(0, 10)); // Panel 3: comments on the most-viewed video, scored for sentiment const scorer = new Sentiment(); const top = [...rows].sort((a, b) => (b.views ?? 0) - (a.views ?? 0))[0]; if (top) { const comments = await get("tiktok/post/comments", { url: top.url }); for (const { comment } of comments.data.items.slice(0, 5)) { const score = scorer.analyze(comment.text ?? "").comparative; console.log(`[${score.toFixed(2)}] ${comment.text}`); } } ``` ## What you get back [#what-you-get-back] ```text title="Example output" followers: 161000000 lifetime likes: 2500000000 {'caption': '...', 'published_at': '2026-09-30T18:12:44.000Z', 'views': 12400000, 'likes': 2100000, 'comments': 18400, 'shares': 41000, 'rate_by_views': 0.1743, 'rate_by_followers': 0.0134, 'url': 'https://www.tiktok.com/@khaby.lame/video/...'} {'caption': '...', 'published_at': '2026-09-27T16:40:02.000Z', 'views': 8100000, 'likes': 1400000, 'comments': 12100, 'shares': 22000, 'rate_by_views': 0.1771, 'rate_by_followers': 0.0089, 'url': 'https://www.tiktok.com/@khaby.lame/video/...'} [+0.64] this man never needs to say a word [+0.00] which country is this ... credits used: 30 ``` The figures are illustrative. `rate_by_views` is (likes + comments + shares) / views for each video; `rate_by_followers` divides the same sum by the account's followers. Both are `None` when a count is hidden. The profile's like count is lifetime hearts, so it is a KPI on its own, not an input to a rate. ## What to change [#what-to-change] * **`HANDLE`.** Any public TikTok account. Run the script over a list of handles and store each refresh keyed by `(handle, date)`, and follower and engagement charts come straight out of the table. * **Go past the first page.** Send `pagination.next_cursor` back as `cursor`, with the same `handle` or `url`, to get older videos or more comments. Cursors expire after 24 hours. See [Pagination](/docs/pagination). * **Only new videos.** Pass the id of the newest video you already hold as `stop_at_id`, or a date as `since`. * **Comment order.** Add `sort=recent` for newest first or `sort=top` for most liked. * **Add audience geography.** One `GET /v1/tiktok/user/audience` call adds 50 credits per account. ## Related [#related] Compare this account with its YouTube and X. Snapshot several rivals on four networks and compare over time. The engagement fields and when each one is null. Every TikTok endpoint and its price. --- # Video transcription (/docs/recipes/video-transcription-api) One transcribe() function that returns the spoken words of a video on YouTube, TikTok, X, Reddit or LinkedIn. 30 credits on YouTube, 100 on the others. You will build one `transcribe(url)` function that returns what was said in a social video, whichever of five platforms it lives on. Every transcript endpoint answers in the same shape, so the only platform-specific part is choosing the endpoint. 30 credits for a YouTube video, 100 credits for a video on any of the other four platforms. You make exactly one call per video. A video with no captions or no speech is not charged. Transcribing the same URL again is charged again, so store the transcript. ## How do you turn a social video into text? [#how-do-you-turn-a-social-video-into-text] Pass the video URL to that platform's transcript endpoint. Each one returns the spoken content as text. Transcripts are the densest signal in social video: captions and thumbnails are written to get the click, while the spoken words are what the creator actually said. ## What you need [#what-you-need] | Endpoint | Covers | Credits | | ---------------------------------- | -------------------------- | ------- | | `GET /v1/youtube/video/transcript` | YouTube videos and Shorts | 30 | | `GET /v1/tiktok/post/transcript` | TikTok videos | 100 | | `GET /v1/twitter/tweet/transcript` | Videos attached to X posts | 100 | | `GET /v1/reddit/post/transcript` | Reddit video posts | 100 | | `GET /v1/linkedin/post/transcript` | Videos in LinkedIn posts | 100 | Every one takes a `url` parameter. ### When there is nothing to transcribe [#when-there-is-nothing-to-transcribe] * **YouTube and LinkedIn** answer `404` when a video has no captions or no speech, and name the reason (for example `no_captions` or `no_speech`). That is an expected outcome, not a failure, and it is not charged. * **Reddit** answers with a transcript whose `text` is `null` when Reddit publishes no captions for the video, and lists `transcript.text` in `unavailable`. * **TikTok** reads the video's captions. Add `use_ai_as_fallback=true` to fall back to AI transcription when there are none. ### One shape on every platform [#one-shape-on-every-platform] Every transcript endpoint returns `data.transcript` with three fields: * **`text`:** the whole transcript as one string, or `null` when there is none. * **`language`:** the language tag the platform gives, such as `en`, or `null`. * **`segments`:** timed cues, each `{ text, start_seconds, duration_seconds }`, or `null` when the platform has no timings. YouTube has them; most of the others return the text only. See [Transcript](/docs/schema/transcript) for the full schema. ## The code [#the-code] ```python title="Python" # transcribe.py # Returns the transcript of a social video URL on any of five platforms. # Run with: INSIGHTSOCIAL_API_KEY=isk_live_... python transcribe.py import os from urllib.parse import urlparse import requests KEY = os.environ["INSIGHTSOCIAL_API_KEY"] BASE = "https://api.insightsocial.app/v1" ENDPOINT = { "youtube": "youtube/video/transcript", "tiktok": "tiktok/post/transcript", "twitter": "twitter/tweet/transcript", "reddit": "reddit/post/transcript", "linkedin": "linkedin/post/transcript", } HOSTS = {"youtube.com": "youtube", "youtu.be": "youtube", "tiktok.com": "tiktok", "x.com": "twitter", "twitter.com": "twitter", "reddit.com": "reddit", "v.redd.it": "reddit", "linkedin.com": "linkedin"} def platform_of(url): host = urlparse(url).netloc.lower().removeprefix("www.").removeprefix("m.") for suffix, platform in HOSTS.items(): if host == suffix or host.endswith("." + suffix): return platform raise ValueError(f"unsupported host: {host}") def extract_text(data): # The same on all five platforms. `text` is null when there is no transcript. return data["transcript"]["text"] or "" def transcribe(url): platform = platform_of(url) res = requests.get(f"{BASE}/{ENDPOINT[platform]}", params={"url": url}, headers={"x-api-key": KEY}, timeout=120) body = res.json() if not body["success"]: # A 404 here usually means "no captions" or "no speech", and costs nothing. return {"platform": platform, "text": None, "error": body["error"]["type"], "credits_used": body["credits_used"]} return {"platform": platform, "text": extract_text(body["data"]), "language": body["data"]["transcript"]["language"], "segments": body["data"]["transcript"]["segments"], "credits_used": body["credits_used"]} # Any public video URL on the five platforms works; add your own to the list. for url in [ "https://www.youtube.com/watch?v=dQw4w9WgXcQ", ]: t = transcribe(url) if t["text"] is None: print(f"[{t['platform']}] no transcript ({t['error']}), {t['credits_used']} credits") else: print(f"[{t['platform']}] {len(t['text'])} chars, {t['credits_used']} credits") print(t["text"][:200], "...") ``` ```ts title="Node.js" // transcribe.ts const KEY = process.env.INSIGHTSOCIAL_API_KEY; if (!KEY) throw new Error("Set INSIGHTSOCIAL_API_KEY"); const BASE = "https://api.insightsocial.app/v1"; const ENDPOINT: Record = { youtube: "youtube/video/transcript", tiktok: "tiktok/post/transcript", twitter: "twitter/tweet/transcript", reddit: "reddit/post/transcript", linkedin: "linkedin/post/transcript", }; const HOSTS: [string, string][] = [ ["youtube.com", "youtube"], ["youtu.be", "youtube"], ["tiktok.com", "tiktok"], ["x.com", "twitter"], ["twitter.com", "twitter"], ["reddit.com", "reddit"], ["v.redd.it", "reddit"], ["linkedin.com", "linkedin"], ]; function platformOf(url: string) { const host = new URL(url).hostname.replace(/^(www|m)\./, ""); const hit = HOSTS.find(([h]) => host === h || host.endsWith(`.${h}`)); if (!hit) throw new Error(`unsupported host: ${host}`); return hit[1]; } // The same on all five platforms. `text` is null when there is no transcript. const extractText = (data: any): string => data.transcript.text ?? ""; export async function transcribe(videoUrl: string) { const platform = platformOf(videoUrl); const url = new URL(`${BASE}/${ENDPOINT[platform]}`); url.searchParams.set("url", videoUrl); const body = await (await fetch(url, { headers: { "x-api-key": KEY! } })).json(); if (!body.success) return { platform, text: null, error: body.error.type }; return { platform, text: extractText(body.data), language: body.data.transcript.language, segments: body.data.transcript.segments, credits_used: body.credits_used, }; } console.log(await transcribe("https://www.youtube.com/watch?v=dQw4w9WgXcQ")); ``` ## What you get back [#what-you-get-back] ```json title="Response (YouTube, trimmed)" { "success": true, "platform": "youtube", "endpoint": "/v1/youtube/video/transcript", "schema_version": "2", "data": { "transcript": { "language": "en", "text": "[♪♪♪] ♪ We're no strangers to love ♪ ♪ You know the rules and so do I ♪ ...", "segments": [ { "text": "[♪♪♪]", "start_seconds": 1.36, "duration_seconds": 1.68 }, { "text": "♪ We're no strangers to love ♪", "start_seconds": 18.64, "duration_seconds": 3.24 } ] } }, "unavailable": [], "credits_used": 30, "credits_remaining": 9940, "request_id": "req_1a2b3c4d5e6f", "cached": false, "idempotent_replay": false, "charge_reason": "miss", "free_call": false } ``` On another platform the same call returns the same keys. Where the platform has no timings, `segments` is `null` and `text` carries the whole transcript. ## What to change [#what-to-change] * **Cheaper YouTube.** If you can parse caption files yourself, `GET /v1/youtube/video/subtitles` (10 credits, beta) returns the caption tracks with download URLs instead. * **Find a moment instead of reading everything.** Where `segments` is filled, search it for a phrase and read `start_seconds` to jump to that point in the video, for example to find a discount code or a sponsor mention. * **Pick a language.** YouTube, TikTok and Reddit take `language`, a two-letter code. ## Related [#related] Find the videos worth transcribing. Why YouTube has two options and the others have one. What each error type means and whether to retry. Every YouTube endpoint and its price. --- # Author (/docs/schema/author) The schema-2 author and profile objects. Every field, its type, and which platforms fill it. Any endpoint that returns a profile, creator, page or channel returns it in the profile shape below, whichever platform it came from. Posts and comments carry a smaller author object, a subset of the profile. One parser reads both from every platform. This page describes schema 2, which every key gets from October 4, 2026; what changed is on [Schema 2](/docs/schema-2). ## Where profiles sit in `data` [#where-profiles-sit-in-data] | Endpoint returns | Path | | ------------------------------------------------------------ | ------------------------------------------------------ | | One profile (`/v1/tiktok/profile`, `/v1/youtube/channel`, …) | `data.author` | | A list of profiles (followers, search results, reactions, …) | `data.items[].author` | | The author of a post | `data.post.author` or `data.items[].post.author` | | The author of a comment | `data.comment.author` or `data.items[].comment.author` | A list of profiles also carries `data.total` (the platform's own total, not the size of this page) and `data.truncated`, both `null` when the platform does not say. ## Author on a post or comment [#author-on-a-post-or-comment] | Field | Type | Nullable | Description | | -------------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `id` | `string` | Yes | The account's platform ID. On Reddit it is the account's `t2_…` ID, prefix kept, the same value as the Reddit profile's `id`. `null` where the source gives none: usually on Twitter/X and Pinterest posts, and then the response lists the path in `unavailable`. | | `username` | `string` | Yes | Handle. | | `display_name` | `string` | Yes | Display name or full name. On Reddit usually `null`: Reddit shows a username, and the `t2_…` ID that arrives in this place goes to `author.id`. | | `avatar_url` | `string` | Yes | Profile picture. | | `verified` | `boolean` | Yes | Whether the account is verified. | For followers, bio and the rest, call the platform's profile endpoint with the `username` or `id`. ## Profile [#profile] ### Example [#example] `/v1/tiktok/profile?handle=nasa`, shortened: ```json title="Response" { "success": true, "platform": "tiktok", "endpoint": "/v1/tiktok/profile", "schema_version": "2", "data": { "author": { "id": "6772003040451462149", "username": "nasa", "display_name": "NASA", "avatar_url": "https://p16-sign-va.tiktokcdn.com/…", "bio": "Making the seemingly impossible, possible. ✨", "verified": true, "followers": 9800000, "followers_approximate": null, "following": 12, "posts_count": 1210, "likes_count": 98400000, "url": "https://www.tiktok.com/@nasa", "location": null, "external_url": "https://www.nasa.gov", "private": false, "joined_at": null, "last_post_at": "2026-10-03T14:10:18.000Z", "ext": { "region": "US" } } }, "unavailable": [], "credits_used": 10, "credits_remaining": 9990, "request_id": "req_d6ad52ab1f9f", "cached": false, "idempotent_replay": false, "charge_reason": "miss", "free_call": false } ``` ### Fields [#fields] Every field is always present; a value the platform does not give is `null`. | Field | Type | Nullable | Description | | ----------------------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `id` | `string` | No | The platform's ID for the account, always a string. Never parse it as a number. On a Reddit user it is the account's `t2_…` ID with the prefix kept, so it matches `author.id` on that user's posts and comments. On a LinkedIn person it is the member URN (`ACoAA…`), the same value as `author.id` on that member's posts; the vanity slug is `username`, and the numeric member id is `ext.member_id`. The one exception is `/v1/linkedin/search/people/by-url`, whose source gives no URN: there `id` is the slug. A LinkedIn company keeps its numeric company id. | | `username` | `string` | Yes | Handle. | | `display_name` | `string` | Yes | Display name or full name. | | `avatar_url` | `string` | Yes | Profile picture. | | `bio` | `string` | Yes | Bio or description. | | `verified` | `boolean` | Yes | Whether the account is verified. | | `followers` | `integer` | Yes | Followers or subscribers, as a whole number. Exact on TikTok when an unrounded figure is available. On YouTube above 1,000 subscribers it is the rounded figure YouTube publishes (three significant digits). | | `followers_approximate` | `boolean` | Yes | `true` when `followers` is a rounded or published figure rather than an exact count: LinkedIn people-list display figures, TikTok when no exact count is available, and YouTube at 1,000 subscribers or more. `null` when the platform gives an exact count or does not say. | | `following` | `integer` | Yes | Accounts this account follows. | | `posts_count` | `integer` | Yes | Total posts or videos. | | `likes_count` | `integer` | Yes | Total likes received across the account's content, where shown. | | `url` | `string` | Yes | Link to the profile itself, always on the platform's own site. Never the bio link. | | `location` | `string` | Yes | An ISO region code such as `US`, or free-text location, where shown. | | `external_url` | `string` | Yes | The website or bio link, where shown. | | `private` | `boolean` | Yes | Whether the account is private. | | `joined_at` | `string` | Yes | When the account was created, ISO 8601 UTC ending in `Z`. | | `last_post_at` | `string` | Yes | When the account last posted, ISO 8601 UTC ending in `Z`. | | `ext` | `object` | Yes | Platform-specific fields. See below. | A count is `null` when the platform does not show it and `0` only when it really is zero. ## Extension fields (`ext`) [#extension-fields-ext] Platform-specific extras on the full profile. Each one appears only on platforms that provide it, so treat every `ext` field as optional. `ext` is `null` when a profile has no extras. Keys are snake\_case on every platform, `_id` values are strings and `_at` values are ISO 8601 UTC times. | Field | Type | Nullable | Description | | -------------------------------- | ---------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `ext.social_context` | `string` | Yes | Social context text the platform shows on the profile. | | `ext.account_created` | `string` | Yes | Account creation date as the platform shows it. | | `ext.country` | `string` | Yes | Country of the account. | | `ext.former_usernames` | `string[]` | Yes | Earlier usernames, where shown. | | `ext.public_email` | `string` | Yes | The first email address found in the bio. | | `ext.contact_email` | `string` | Yes | Opt in with `contact_email=1` on `/v1/youtube/channel` and `/v1/youtube/channel/about`. When a bio lists two or more addresses, this is the one the creator gives for personal contact, copied exactly. It stays `null` if the bio has fewer than two addresses, if all of them point to a manager, agency or brand, or if no single personal address stands out. `ext.public_email` is not affected. | | `ext.public_phone` | `string` | Yes | Public phone number on the profile. | | `ext.business_category` | `string` | Yes | Business category shown on the profile. | | `ext.hd_avatar_url` | `string` | Yes | Higher-resolution profile picture. | | `ext.website` | `string` | Yes | Website listed on the profile. | | `ext.cover_url` | `string` | Yes | Cover or banner image. | | `ext.employee_count` | `integer` | Yes | LinkedIn company employee count. | | `ext.employee_count_range.start` | `integer` | Yes | Lower bound of the LinkedIn company size range. | | `ext.employee_count_range.end` | `integer` | Yes | Upper bound of the LinkedIn company size range. | | `ext.founded_year` | `integer` | Yes | Year the company was founded. | | `ext.specialities` | `string[]` | Yes | Company specialties listed on LinkedIn. | | `ext.industries` | `string[]` | Yes | Company industries. | | `ext.headquarters` | `string` | Yes | Company headquarters. | | `ext.locations` | `string[]` | Yes | Company office locations. | | `ext.hashtags` | `string[]` | Yes | Hashtags the company follows or lists. | | `ext.funding` | `string` | Yes | Company funding details. | | `ext.links` | `string[]` | Yes | Links listed on the profile. | | `ext.urn` | `string` | Yes | LinkedIn URN. | | `ext.is_top_voice` | `boolean` | Yes | LinkedIn Top Voice badge. | | `ext.is_premium` | `boolean` | Yes | LinkedIn Premium member. | | `ext.is_creator` | `boolean` | Yes | LinkedIn creator mode. | | `ext.is_influencer` | `boolean` | Yes | LinkedIn influencer flag. | | `ext.is_open_to_work` | `boolean` | Yes | LinkedIn Open to Work flag. | | `ext.is_hiring` | `boolean` | Yes | LinkedIn Hiring flag. | | `ext.member_id` | `string` | Yes | LinkedIn numeric member ID, where the source gives one. | | `ext.company_id` | `string` | Yes | LinkedIn company ID, for the `company/*` endpoints. | | `ext.reaction_type` | `string` | Yes | The reaction a member left, on reaction lists. | | `ext.keywords` | `string` | Yes | YouTube channel keywords. | | `ext.total_views` | `integer` | Yes | Total channel views. | | `ext.joined_at_timestamp` | `string` | Yes | Account creation time as a timestamp. | | `ext.topic_categories` | `string[]` | Yes | YouTube topic categories. | | `ext.banner_external_url` | `string` | Yes | YouTube channel banner. | | `ext.made_for_kids` | `boolean` | Yes | YouTube made-for-kids flag. | | `ext.hidden_subscriber_count` | `boolean` | Yes | `true` when the YouTube channel hides its subscriber count. | | `ext.related_playlists` | `object` | Yes | YouTube related playlists, such as uploads. | | `ext.topic_ids` | `string[]` | Yes | YouTube topic IDs. | | `ext.unsubscribed_trailer` | `string` | Yes | YouTube channel trailer shown to non-subscribers. | | `ext.join_policy` | `string` | Yes | Who can join a group or community. | | `ext.is_nsfw` | `boolean` | Yes | Subreddit or account marked adult. | | `ext.rules` | `string[]` | Yes | Subreddit rules. | | `ext.weekly_active_users` | `integer` | Yes | Subreddit weekly visitors. | | `ext.weekly_contributions` | `integer` | Yes | Subreddit weekly contributions. | | `ext.rules_text` | `string` | Yes | Subreddit rules as text. | | `ext.language` | `string` | Yes | Language set on the account or community. | | `ext.post_karma` | `integer` | Yes | Reddit post karma. | | `ext.comment_karma` | `integer` | Yes | Reddit comment karma. | | `ext.awardee_karma` | `integer` | Yes | Reddit awardee karma. | | `ext.trophy_count` | `integer` | Yes | Reddit trophies. | | `ext.banner_url` | `string` | Yes | Profile banner image. | | `ext.social_links` | `string[]` | Yes | Social links listed on the profile. | | `ext.group` | `string` | Yes | Group details, on group responses. | ## Which platforms fill which fields [#which-platforms-fill-which-fields] Every platform that returns profiles uses this shape, and `id` is never `null`. The table covers the platforms the API launched with that return profiles. The others return the same shape, and each response's [`unavailable`](/docs/schema/post#unavailable) list names the fields it could not fill. **yes** means the platform can fill the field (it may still be `null` on a given row); a blank means it never does.

On TikTok and Twitter/X, `url` is built from the handle when the platform sends none, and the link in the bio is always `external_url`. On a Reddit user, `id` is the `t2_…` account ID and `display_name` is `null`; a subreddit's `id` is its name. ### `unavailable` [#unavailable] When a field the platform normally fills is `null` on every profile in a response, the response lists its path in `unavailable`, for example `"author.followers"` or `"items[].author.joined_at"`. `bio`, `external_url` and `location` are never listed, because `null` there usually means the account has none. Fields a platform never shows publicly are never listed either: | Platform | Never listed in `unavailable` | | -------- | ----------------------------------------------------- | | TikTok | `joined_at` | | YouTube | `following`, `likes_count`, `private` | | Reddit | `following`, `posts_count`, `likes_count`, `verified` | | LinkedIn | `posts_count`, `likes_count`, `private` | The table covers the platforms the API launched with; every platform, the other 16 included, is in [Data availability](/docs/data-availability#fields-a-platform-never-shows). For fields that are always `null` on a platform, see [Metric substitutions](/docs/metric-substitutions). ## Returned by [#returned-by] Endpoints that return a profile or a list of profiles use this shape on: [LinkedIn](/docs/platforms/linkedin) · [Reddit](/docs/platforms/reddit) · [TikTok](/docs/platforms/tiktok) · [Twitter/X](/docs/platforms/twitter) · [YouTube](/docs/platforms/youtube) To see which native platform field feeds each unified field, read [Field equivalence](/docs/schema/field-equivalence). --- # Comment (/docs/schema/comment) The schema-2 comment object. Every field, its type, and which platforms fill it. Any endpoint that returns comments or replies returns them in this shape, whichever platform they came from. One parser reads comments from every platform that has them. This page describes schema 2, which every key gets from October 4, 2026; what changed is on [Schema 2](/docs/schema-2). ## Where comments sit in `data` [#where-comments-sit-in-data] | Endpoint returns | Path | | ----------------------------- | ---------------------- | | One comment | `data.comment` | | A list of comments or replies | `data.items[].comment` | A list also carries `data.total` (the platform's own total, not the size of this page) and `data.truncated`, `true` when the platform cut the thread short (Reddit's "more replies" threshold). Both are `null` when the platform does not say. The next page is in `pagination.next_cursor`. ## Example [#example] One row from `/v1/twitter/tweet/replies`, shortened: ```json title="Response" { "success": true, "platform": "twitter", "endpoint": "/v1/twitter/tweet/replies", "schema_version": "2", "data": { "items": [ { "comment": { "id": "2106150051978662105", "url": "https://x.com/bobcarter101/status/2106150051978662105", "parent_id": null, "post_id": "2106061652617568263", "text": "@NASA @Space_Station skills required; watching SpaceX’s live stream.", "author": { "id": null, "username": "bobcarter101", "display_name": "Bob Carter", "avatar_url": "https://pbs.twimg.com/profile_images/…", "verified": true }, "engagement": { "likes": 3, "replies": 2 }, "flags": { "pinned": null, "deleted": false }, "published_at": "2026-10-02T22:31:17.000Z", "language": "en", "replies": null, "ext": { "author_followers": 4909, "quote_count": 0, "views": 681 } } } ], "total": null, "truncated": null }, "pagination": { "next_cursor": "v2c.ouEEuPti…", "has_more": true, "page_size": 36 }, "unavailable": ["items[].comment.author.id"], "credits_used": 10, "credits_remaining": 9990, "request_id": "req_48e49dfbad28", "cached": false, "idempotent_replay": false, "charge_reason": "miss", "free_call": false } ``` X gives no author ID on replies, so every row has `author.id: null` and the response says so in `unavailable`. ## Fields [#fields] Every field is always present; a value the platform does not give is `null`. | Field | Type | Nullable | Description | | --------------------- | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `id` | `string` | No | The platform's ID for the comment, always a string. | | `url` | `string` | Yes | Link to the comment on the platform. | | `parent_id` | `string` | Yes | ID of the comment this one replies to. `null` on a top-level comment, on every platform. A reply carries its parent comment's ID, never the post's. | | `post_id` | `string` | Yes | ID of the post the comment belongs to. | | `text` | `string` | Yes | The comment text. Placeholders such as `[deleted]` or `[removed]` become `null`, so you never see them as text. | | `author.id` | `string` | Yes | The commenter's platform ID. On Reddit it is the account's `t2_…` ID, prefix kept. `null` where the source gives none: on LinkedIn the source gives no member URN for commenters, so it is `null` there (join on `username`), and the numeric member id is in `ext.author_member_id`. | | `author.username` | `string` | Yes | The commenter's handle. `null` when the comment was removed. | | `author.display_name` | `string` | Yes | The commenter's display name. On Reddit usually `null`: Reddit shows a username, and the `t2_…` ID that arrives in this place goes to `author.id`. | | `author.avatar_url` | `string` | Yes | The commenter's profile picture. | | `author.verified` | `boolean` | Yes | Whether the commenter is verified. | | `engagement.likes` | `integer` | Yes | Likes or upvotes. `null` when not shown, and on Reddit when the score is below zero (see `ext.score`). | | `engagement.replies` | `integer` | Yes | Number of replies. `0` when the platform reports the count and there are none; `null` only when the platform gives no reply count. | | `flags.pinned` | `boolean` | Yes | Pinned by the post's author. `null` when the platform does not say. | | `flags.deleted` | `boolean` | No | The comment was deleted or removed. Always `true` or `false`. | | `published_at` | `string` | Yes | When the comment was posted, as ISO 8601 in UTC, ending in `Z`. | | `language` | `string` | Yes | The comment's language as the platform states it, such as `en`. `null` when the platform gives no tag. We do not detect languages. | | `replies` | `object[]` | Yes | Replies the platform returned inline, each a full comment object with its own `replies`. Filled on Reddit. `null` where the platform returns none inline: fetch them from the platform's replies endpoint with this comment's `id`. | | `ext` | `object` | Yes | Platform-specific fields. See below. | ## Fetching replies [#fetching-replies] Replies endpoints take the platform's own identifiers, which every comment carries: | Platform | Call | | -------- | ----------------------------------------------------------------------------------------------------------- | | YouTube | `/v1/youtube/video/comment/replies?continuationToken=` with the top-level `comment.id` | | Reddit | Replies arrive inline in `replies`. When `data.truncated` is `true`, page on with `pagination.next_cursor`. | ## Extension fields (`ext`) [#extension-fields-ext] Platform-specific extras. Each one appears only where the platform provides it, so treat every `ext` field as optional. `ext` is `null` when a comment has no extras. Keys are snake\_case on every platform, `_id` values are strings and `_at` values are ISO 8601 UTC times. `ext` never carries our cursors or tokens. | Field | Type | Nullable | Description | | --------------------------- | ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `ext.depth` | `integer` | Yes | Reddit nesting level: 0 for a top-level comment, 1 for a direct reply, and so on. Present when a flat thread was rebuilt into `replies[]`, so you can check the nesting yourself. | | `ext.ip_location` | `string` | Yes | Location the platform displays for the commenter, where shown. | | `ext.urn` | `string` | Yes | LinkedIn comment URN. | | `ext.reaction_counts` | `string[]` | Yes | Counts broken down by reaction type. | | `ext.is_edited` | `boolean` | Yes | `true` when the comment was edited. | | `ext.author_headline` | `string` | Yes | LinkedIn headline of the commenter. | | `ext.updated_at` | `string` | Yes | When the comment was last updated. | | `ext.author_url` | `string` | Yes | Link to the commenter's profile. | | `ext.viewer_rating` | `string` | Yes | YouTube viewer rating value. | | `ext.text_original` | `string` | Yes | The comment text in its original, unformatted form. | | `ext.preview_replies` | `object[]` | Yes | A few replies shown with the comment. | | `ext.lookup` | `string` | Yes | Details of how a single comment was located, on single-comment endpoints. | | `ext.post_title` | `string` | Yes | Title of the parent post. | | `ext.post_url` | `string` | Yes | Link to the parent post. | | `ext.subreddit` | `string` | Yes | Subreddit of the parent post. | | `ext.subreddit_subscribers` | `integer` | Yes | Subscriber count of that subreddit. | | `ext.post_score` | `integer` | Yes | Score of the parent post. | | `ext.post_comment_count` | `integer` | Yes | Comment count of the parent post. | | `ext.post_author` | `string` | Yes | Author of the parent post. | | `ext.post_published_at` | `string` | Yes | When the parent post was published. | | `ext.post_flair` | `string` | Yes | Flair on the parent post. | | `ext.is_submitter` | `boolean` | Yes | `true` when the commenter also wrote the post. | | `ext.edited_at` | `string` | Yes | When the comment was edited. | | `ext.controversiality` | `integer` | Yes | Reddit controversiality flag. | | `ext.author_followers` | `integer` | Yes | The commenter's follower count as included in the row. A snapshot, not live. Present on every `/v1/twitter/tweet/replies` row. | | `ext.author_following` | `integer` | Yes | The commenter's following count as included in the row. Also a snapshot. | | `ext.author_posts_count` | `integer` | Yes | The commenter's post count as included in the row. Also a snapshot. | | `ext.quote_count` | `integer` | Yes | Number of quote posts of this comment, where reported. On X a reply is itself a post. | | `ext.views` | `integer` | Yes | Views of the comment, where reported. Public on X replies from about 2022 onward. | | `ext.saves` | `integer` | Yes | Bookmarks of the comment, where reported (X). | | `ext.score` | `integer` | Yes | Reddit only. A comment score below zero. `engagement.likes` is then `null`, because a negative score is not a like count. | ## Which platforms fill which fields [#which-platforms-fill-which-fields] Every platform that returns comments uses this shape. `id` and `flags.deleted` are never `null`. The table covers the platforms the API launched with that return comments. The others return the same shape, and each response's [`unavailable`](/docs/schema/post#unavailable) list names the fields it could not fill. **yes** means the platform can fill the field (it may still be `null` on a given row); a blank means it never does.
| Platform | `parent_id` | `author.verified` | `flags.pinned` | `url` | `post_id` | `author.avatar_url` | `author.display_name` | `engagement.replies` | `author.username` | `engagement.likes` | | --------- | ----------- | ----------------- | -------------- | ----- | --------- | ------------------- | --------------------- | -------------------- | ----------------- | ------------------ | | LinkedIn | | | yes | | | | yes | yes | | | | Reddit | yes | | yes | yes | yes | yes | | | yes | yes | | TikTok | yes | yes | yes | | yes | yes | yes | yes | yes | yes | | Twitter/X | yes | yes | | | yes | yes | yes | yes | yes | yes | | YouTube | | | | | yes | yes | | yes | yes | yes |
`parent_id` is filled on replies only; top-level comments carry `null` everywhere. On Reddit, replies are nested in `replies[]` rather than counted. On Reddit, the account's `t2_` ID goes to `author.id`. ### `unavailable` [#unavailable] When a field the platform normally fills is `null` on every comment in a response, the response lists its path in `unavailable`, for example `"items[].comment.author.id"`. Fields a platform never shows are never listed: the comment `url` on TikTok and `author.display_name` on Reddit. ## Returned by [#returned-by] Endpoints that return a comment or a list of comments use this shape on: [LinkedIn](/docs/platforms/linkedin) · [Reddit](/docs/platforms/reddit) · [TikTok](/docs/platforms/tiktok) · [Twitter/X](/docs/platforms/twitter) · [YouTube](/docs/platforms/youtube) To see which native platform field feeds each unified field, read [Field equivalence](/docs/schema/field-equivalence). --- # Field equivalence (/docs/schema/field-equivalence) Which native platform field feeds each unified field, for the metrics people compare most across platforms. Each platform names the same number its own way: TikTok says `play_count`, YouTube says `viewCount`, Twitter/X says `views.count`. In a response, all three arrive as `post.engagement.views`. The tables below show, per platform, which native fields a unified field is filled from. Build comparisons on the unified field once and they work across every platform listed. Several native names per platform means different endpoints on that platform expose the value under different names. The paths on this page are schema 2, which every key gets from October 4, 2026. ## Fields that moved in schema 2 [#fields-that-moved-in-schema-2] Some values used to sit in `ext` on a few platforms. Schema 2 gives them one place on every platform: | Value | Previous place | Schema 2 | | -------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | Author ID on a post | `ext.author_id` (LinkedIn, TikTok), `ext.channel_id` (YouTube) | `post.author.id` | | Author ID on a comment | `ext.author_id`, `ext.author_channel_id` (YouTube), Reddit's `t2_` ID in `author.display_name` | `comment.author.id`. Reddit's stays `t2_…`, prefix kept. | | Reddit account ID on a post or profile | `author.display_name` (posts), `display_name` (profiles) | `post.author.id` and the profile's `id`, as `t2_…` with the prefix kept, so posts, comments and profiles join on one value. `display_name` is then `null`. | | Language of a post or comment | `ext.content_language`, `ext.default_language` | `post.language`, `comment.language` | | Rounded follower count | `ext.followers_approximate` | `author.followers_approximate` (profiles) | | Bio link | `ext.bio_link` (TikTok, X) | `author.external_url`. `author.url` is always the profile. | | Original Unix timestamp | `ext.published_at_epoch` | Removed. `published_at` is always ISO 8601 UTC. | | Post format | `ext.media_type`, `ext.content_type`, `ext.post_type` | `post.kind`. The `ext` keys stay where the platform sends them. | | YouTube `ext` keys | camelCase | snake\_case, such as `made_for_kids`, `category_id`, `default_audio_language` | `author.id` is `null` where the source gives no ID (usually Twitter/X and Pinterest posts), and the response lists it in `unavailable`. ## Engagement [#engagement] ### `post.engagement.views` [#postengagementviews] | Platform | Native field | | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | TikTok | `aweme_info.statistics.play_count`, `ch_info.view_count`, `impression`, `lifetime_views`, `statistics.play_count`, `stats.playCount`, `userCount`, `vv_count` | | Twitter/X | `view_count`, `views.count` | | YouTube | `viewCount`, `viewCountInt` | ### `post.engagement.likes` [#postengagementlikes] | Platform | Native field | | --------- | ----------------------------------------------------------------------------------------------- | | LinkedIn | `activity.num_likes`, `data.activity.num_likes`, `stats.total_reactions` | | Pinterest | `pin_count`, `reaction_counts.1`, `totalReactionCount` | | Reddit | `score`, `ups` (a score below zero gives `null` here and `ext.score`) | | TikTok | `aweme_info.statistics.digg_count`, `like`, `likes`, `statistics.digg_count`, `stats.diggCount` | | Twitter/X | `favorite_count`, `legacy.favorite_count` | | YouTube | `likeCount`, `likeCountInt` | ### `post.engagement.comments` [#postengagementcomments] | Platform | Native field | | --------- | -------------------------------------------------------------------------------------------------- | | LinkedIn | `activity.num_comments`, `data.activity.num_comments`, `stats.comments` | | Pinterest | `aggregatedPinData.commentCount`, `aggregated_pin_data.did_it_data.responses_count` | | Reddit | `comments`, `num_comments` | | TikTok | `aweme_info.statistics.comment_count`, `comment`, `statistics.comment_count`, `stats.commentCount` | | Twitter/X | `legacy.reply_count`, `reply_count` | | YouTube | `commentCount`, `commentCountInt` | ### `post.engagement.shares` [#postengagementshares] | Platform | Native field | | --------- | ------------------------------------------------------------------------------------------ | | LinkedIn | `activity.num_shares`, `data.activity.num_shares`, `stats.reposts` | | Pinterest | `repin_count`, `shareCount` | | TikTok | `aweme_info.statistics.share_count`, `share`, `statistics.share_count`, `stats.shareCount` | | Twitter/X | `legacy.retweet_count`, `retweet_count` | ### `post.engagement.saves` [#postengagementsaves] | Platform | Native field | | --------- | --------------------------------------------------------------------------------------- | | Pinterest | `aggregatedPinData.aggregatedStats.saves`, `aggregated_pin_data.aggregated_stats.saves` | | TikTok | `aweme_info.statistics.collect_count`, `statistics.collect_count`, `stats.collectCount` | | Twitter/X | `bookmark_count`, `legacy.bookmark_count` | A platform listed here may still return `null` on most surfaces; [Metric substitutions](/docs/metric-substitutions) says where. A platform missing from a table never fills that field: see [Never shown publicly](#never-shown-publicly). ### Never shown publicly [#never-shown-publicly] These post counts are not shown publicly on most of the platform. They are `null` on most endpoints, and a response never lists them in `unavailable`: | Platform | Post fields | | --------- | ---------------------------------------------------------------------------------- | | YouTube | `engagement.shares`, `engagement.saves` | | Reddit | `engagement.views`, `engagement.shares`, `engagement.saves`, `author.display_name` | | LinkedIn | `engagement.views`, `engagement.saves` | | Pinterest | `engagement.views` | Every other platform is in [Data availability](/docs/data-availability#fields-a-platform-never-shows). ## Post content [#post-content] ### `post.content.text` [#postcontenttext] | Platform | Native field | | --------- | ------------------------------------------------------------------------------------------------ | | LinkedIn | `data.text`, `description`, `text`, `title` | | Pinterest | `description`, `name`, `title` | | Reddit | `title` | | TikTok | `adTitle`, `ad_title`, `aweme_info.desc`, `ch_info.cha_name`, `desc`, `hashtag`, `name`, `title` | | Twitter/X | `note_tweet.note_tweet_results.result.text` | | YouTube | `content`, `title` | ### `post.published_at` [#postpublished_at] | Platform | Native field | | --------- | ------------------------------------------------------------------------------------------------------- | | LinkedIn | `created_at`, `data.created_at`, `posted_at.timestamp`, `startDate` | | Pinterest | `createdAt`, `created_at` | | Reddit | `created_utc`, `creationDate` | | TikTok | `aweme_info.create_time`, `createTime`, `create_time`, `created_at`, `first_shown_date`, `publish_time` | | Twitter/X | `created_at`, `legacy.created_at` | | YouTube | `publishDate`, `publishedAt`, `publishedTime`, `videoPublishedAt` | Whatever the native format (ISO string, Unix seconds or milliseconds, X's own date text), `published_at` is ISO 8601 in UTC, ending in `Z`. ## Author [#author] ### `author.followers` [#authorfollowers] | Platform | Native field | | --------- | ---------------------------------------------------------------------------------------------------------------- | | LinkedIn | `data.follower_and_connection.follower_count`, `data.follower_count`, `follower_count`, `follower_count_display` | | Reddit | `subscribers` | | TikTok | `follower_count`, `user.follower_count`, `user_info.follower_count` | | Twitter/X | `legacy.followers_count`, `member_count` | | YouTube | `SubscriberCount`, `subscriberCount` | ### `author.following` [#authorfollowing] | Platform | Native field | | --------- | ---------------------------------------------------------------------- | | LinkedIn | `data.follower_and_connection.connection_count` | | TikTok | `following_count`, `user.following_count`, `user_info.following_count` | | Twitter/X | `legacy.friends_count` | ### `author.posts_count` [#authorposts_count] | Platform | Native field | | --------- | ---------------------------------------------------------- | | TikTok | `aweme_count`, `user.aweme_count`, `user_info.aweme_count` | | Twitter/X | `legacy.statuses_count` | | YouTube | `TotalVideosCount`, `videoCount` | ### `author.likes_count` [#authorlikes_count] | Platform | Native field | | -------- | ---------------------------------------------------------------------- | | TikTok | `total_favorited`, `user.total_favorited`, `user_info.total_favorited` | Reddit profiles never carry `following`, `posts_count` or `likes_count`; Reddit karma is in `ext.post_karma` and `ext.comment_karma`. For every field, its nullability and per-platform coverage, see the [Post](/docs/schema/post), [Author](/docs/schema/author) and [Comment](/docs/schema/comment) pages. --- # Job (/docs/schema/job) The job posting shape returned by the LinkedIn job endpoints. A beta, long-tail shape in schema 2. Endpoints that return job postings use this shape. On InsightSocial that means LinkedIn. Schema 2 types four entities: [post](/docs/schema/post), [profile](/docs/schema/author), [comment](/docs/schema/comment) and [transcript](/docs/schema/transcript). The job endpoints are long-tail: their `data` is the source's own structure under our naming rules (snake\_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities, and its fields may change. The next page is in `pagination.next_cursor`. The fields below are what these endpoints return today. They are marked beta in the [API reference](/docs/api-reference) and can change without a schema version, so read them defensively. ## Fields [#fields] | Field | Type | Nullable | Description | | ------------------ | --------- | -------- | ----------------------------------------- | | `id` | `string` | No | The platform's ID for the job. | | `title` | `string` | Yes | Job title. | | `url` | `string` | Yes | Link to the posting. | | `company.id` | `string` | Yes | ID of the hiring company. | | `company.name` | `string` | Yes | Company name. | | `company.url` | `string` | Yes | Link to the company page. | | `company.verified` | `boolean` | Yes | Whether the company page is verified. | | `location` | `string` | Yes | Where the job is based. | | `listed_at` | `string` | Yes | When the job was posted, as ISO 8601 UTC. | | `easy_apply` | `boolean` | Yes | Whether the job accepts Easy Apply. | | `remote` | `string` | Yes | Remote, hybrid or on-site status. | | `employment_type` | `string` | Yes | Full-time, part-time, contract and so on. | | `experience_level` | `string` | Yes | Seniority level. | | `description` | `string` | Yes | Job description. | | `apply_url` | `string` | Yes | Where to apply. | ## Extension fields (`ext`) [#extension-fields-ext] Optional extras. Treat each as possibly absent. | Field | Type | Nullable | Description | | ---------------------------- | ---------- | -------- | --------------------------------------------- | | `ext.is_promote` | `boolean` | Yes | Whether the posting is promoted. | | `ext.applicant_count` | `integer` | Yes | Number of applicants shown. | | `ext.skills` | `string[]` | Yes | Skills listed on the job. | | `ext.job_provider` | `string` | Yes | Where the posting originates. | | `ext.salary_min` | `integer` | Yes | Lower end of the salary range. | | `ext.salary_max` | `integer` | Yes | Upper end of the salary range. | | `ext.salary_currency` | `string` | Yes | Salary currency. | | `ext.country_code` | `string` | Yes | Country of the job. | | `ext.linkedin_company_name` | `string` | Yes | Company name as shown on LinkedIn. | | `ext.industries` | `string` | Yes | Industries of the job. | | `ext.job_function` | `string` | Yes | Job function. | | `ext.accepting_applications` | `boolean` | Yes | Whether the job is still taking applications. | | `ext.board` | `string` | Yes | Job board the posting came from. | ## Which fields LinkedIn fills [#which-fields-linkedin-fills] `id` is never `null`. **yes** means LinkedIn can fill the field (it may still be `null` on a given row); a blank means it never does.
| Platform | `company.id` | `company.url` | `company.verified` | `easy_apply` | `experience_level` | `remote` | | -------- | ------------ | ------------- | ------------------ | ------------ | ------------------ | -------- | | LinkedIn | yes | yes | yes | yes | | |
## Returned by [#returned-by] [`/v1/linkedin/job`](/docs/api-reference/linkedin/job), [`/v1/linkedin/company/jobs`](/docs/api-reference/linkedin/company-jobs) and [`/v1/linkedin/search/jobs`](/docs/api-reference/linkedin/search-jobs). See [LinkedIn](/docs/platforms/linkedin). --- # Media list (/docs/schema/media-list) The list shape returned by the YouTube media-file endpoints. A beta, long-tail shape in schema 2. Endpoints that return a video's files (audio and video streams, subtitle tracks or thumbnails) use this shape. These endpoints are long-tail: schema 2 does not type their `data` as an entity. It is the source's own structure under our naming rules (snake\_case keys, such as `mime_type` rather than `mimeType`, string ids, ISO times where the source gives a timestamp), and its fields may change. They are marked beta in the [API reference](/docs/api-reference) and can change without a schema version. ## Fields [#fields] | Field | Type | Nullable | Description | | ------- | ---------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `items` | `object[]` | No | The files for the video. Each item has the file's direct `url` plus its own technical details, such as `mime_type`, `bitrate`, `quality`, `width` and `height`, or `language`. Which details appear depends on the kind of file. Items keep the platform's structure, with snake\_case keys; they are not remapped into a unified object. | | `total` | `integer` | Yes | Total number of results, when the platform reports one. Left out otherwise. | ## Where it is used [#where-it-is-used] Only YouTube returns this shape, on four endpoints. The fields inside each item follow the platform's structure, so there is no per-field availability table. When an endpoint pages, the next page is in `pagination.next_cursor`; see [Pagination](/docs/pagination). | Platform | Endpoints | | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | YouTube | [`/v1/youtube/video/audio`](/docs/api-reference/youtube/video-audio), [`/v1/youtube/video/files`](/docs/api-reference/youtube/video-files), [`/v1/youtube/video/subtitles`](/docs/api-reference/youtube/video-subtitles), [`/v1/youtube/video/thumbnails`](/docs/api-reference/youtube/video-thumbnails) | See [YouTube](/docs/platforms/youtube) for the rest of the platform's endpoints. --- # Post (/docs/schema/post) The schema-2 post object. Every field, its type, and which platforms fill it. Any endpoint that returns a post returns it in this shape, whichever platform it came from. Write one parser and it reads posts from every platform the API serves. This page describes schema 2, which every key gets from October 4, 2026. What changed from the previous shape is on [Schema 2](/docs/schema-2). ## Where posts sit in `data` [#where-posts-sit-in-data] | Endpoint returns | Path | | ---------------------------------------------------------------------- | ------------------- | | One post (`/v1/tiktok/post`, `/v1/youtube/video`, …) | `data.post` | | A list of posts (`/v1/tiktok/profile/videos`, `/v1/youtube/search`, …) | `data.items[].post` | A list also carries `data.total`, the total the platform states (not the size of this page), and `data.truncated`, `true` when the platform cut the list short. Both are `null` when the platform does not say. The next page is in `pagination.next_cursor`; see [Pagination](/docs/pagination). ## Example [#example] One row from `/v1/tiktok/profile/videos?handle=nasa`, shortened: ```json title="Response" { "success": true, "platform": "tiktok", "endpoint": "/v1/tiktok/profile/videos", "schema_version": "2", "data": { "items": [ { "post": { "id": "7548812094716415278", "url": "https://www.tiktok.com/@nasa/video/7548812094716415278", "kind": "short", "content": { "text": "Cementing their names in history. …", "media_urls": ["https://v16-webapp-prime.tiktok.com/video/…"], "thumbnail_url": "https://p16-sign-va.tiktokcdn.com/…", "duration_seconds": 42 }, "author": { "id": "6772003040451462149", "username": "nasa", "display_name": "NASA", "avatar_url": "https://p16-sign-va.tiktokcdn.com/…", "verified": true }, "engagement": { "views": 1840200, "likes": 120041, "comments": 978, "shares": 2104, "saves": 3311 }, "flags": { "nsfw": null, "spoiler": null, "pinned": true, "deleted": false, "likes_hidden": null, "comments_hidden": null, "shares_hidden": null, "views_hidden": null, "saves_hidden": null }, "published_at": "2026-09-10T21:20:24.000Z", "language": null, "ext": { "region": "US" } } } ], "total": null, "truncated": null }, "pagination": { "next_cursor": "v2c.ZIyWbi3x…", "has_more": true, "page_size": 10 }, "unavailable": [], "credits_used": 10, "credits_remaining": 9990, "request_id": "req_bc4ed40ba570", "cached": false, "idempotent_replay": false, "charge_reason": "miss", "free_call": false } ``` ## Fields [#fields] Every field below is always present. A value the platform does not give is `null`, never left out and never a placeholder. | Field | Type | Nullable | Description | | -------------------------- | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `id` | `string` | No | The platform's ID for the post. Always a string. Never parse it as a number: TikTok and X IDs are larger than 2^53. | | `url` | `string` | Yes | Link to the post on the platform. | | `kind` | `string` | Yes | The post's format: `text`, `image`, `carousel`, `video`, `short`, `live`, `article` or `link`. `short` is short-form vertical video (a TikTok, a YouTube Short). `null` when the platform does not say and it cannot be read without guessing. More values may be added, so keep a default branch when you switch on it. | | `content.text` | `string` | Yes | Caption, description or body text. | | `content.media_urls` | `string[]` | Yes | Main media, always an array, one URL per item, even for a single photo. `null` when the platform gives none. | | `content.thumbnail_url` | `string` | Yes | Thumbnail image. | | `content.duration_seconds` | `number` | Yes | Length of a video or clip in seconds. `null` when the post is not a video. | | `author.id` | `string` | Yes | The author's platform ID. On Reddit it is the account's `t2_…` ID, prefix kept. On LinkedIn a person's member URN (`ACoAA…`), as on their profile, with the numeric member id in `ext.author_member_id`; a company's numeric id. `null` where the source gives none; see [Which platforms fill which fields](#which-platforms-fill-which-fields). | | `author.username` | `string` | Yes | The author's handle. | | `author.display_name` | `string` | Yes | The author's display name. On Reddit usually `null`: Reddit shows a username, and the `t2_…` ID that arrives in this place goes to `author.id`. | | `author.avatar_url` | `string` | Yes | The author's profile picture. | | `author.verified` | `boolean` | Yes | Whether the author is verified. | | `engagement.views` | `integer` | Yes | Views where the platform shows them. | | `engagement.likes` | `integer` | Yes | Likes or reactions. On Reddit a score below zero is not a like count: `likes` is `null` and the score is in `ext.score`. | | `engagement.comments` | `integer` | Yes | Comment count. | | `engagement.shares` | `integer` | Yes | Shares, reposts or retweets. | | `engagement.saves` | `integer` | Yes | Saves or bookmarks. | | `flags.nsfw` | `boolean` | Yes | Marked as adult content. `null` when the platform does not say. | | `flags.spoiler` | `boolean` | Yes | Marked as a spoiler. `null` when the platform does not say. | | `flags.pinned` | `boolean` | Yes | Pinned to the profile. `null` when the platform does not say. | | `flags.deleted` | `boolean` | No | The post has been deleted or removed. Always `true` or `false`. | | `flags.likes_hidden` | `boolean` | Yes | `true` when the creator hides the like count; `engagement.likes` is then `null`. `null` on ordinary posts. | | `flags.comments_hidden` | `boolean` | Yes | `true` when the comment count is hidden; `engagement.comments` is then `null`. | | `flags.shares_hidden` | `boolean` | Yes | `true` when the share count is hidden; `engagement.shares` is then `null`. | | `flags.views_hidden` | `boolean` | Yes | `true` when the view count is hidden; `engagement.views` is then `null`. | | `flags.saves_hidden` | `boolean` | Yes | `true` when the save count is hidden; `engagement.saves` is then `null`. | | `published_at` | `string` | Yes | When the post was published, as ISO 8601 in UTC, ending in `Z`. Platforms that send Unix timestamps are converted. | | `language` | `string` | Yes | The post's language as the platform itself states it, such as `en` or `pt-BR`. `null` when the platform gives no tag. We do not detect languages. | | `ext` | `object` | Yes | Platform-specific fields. See below. | ### Counts: `null` is not `0` [#counts-null-is-not-0] A count is a whole number of zero or more, or `null`. `null` means the platform does not show it, or hides it on this post. `0` means it really is zero. Do not add a `null` into a total as if it were zero. ## Extension fields (`ext`) [#extension-fields-ext] Platform-specific extras. Each one appears only on platforms that provide it and is left out elsewhere, so treat all of them as optional. They hold detail the unified fields cannot, and the IDs that let you pass a result from one endpoint into the next. `ext` is `null` when a post has no extras. Keys are always snake\_case, on every platform, YouTube included (`made_for_kids`, `category_id`). An `ext` value whose key ends in `_id` is a string, and one whose key ends in `_at` is an ISO 8601 UTC time. `ext` never carries our cursors or tokens; page with `pagination.next_cursor`. | Field | Type | Nullable | Description | | -------------------------------- | ---------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `ext.music_id` | `string` | Yes | TikTok sound ID. Pass it to `/v1/tiktok/song/videos?clipId=` to find other videos using the same sound. | | `ext.author_followers` | `integer` | Yes | The author's follower count as carried on the row: X and TikTok post rows, and searches that include it. A snapshot, not live; call the platform's `profile` endpoint for the exact current count. | | `ext.author_following` | `integer` | Yes | Following count included in the row, when present. | | `ext.author_posts_count` | `integer` | Yes | The author's post count included in the row, when present. | | `ext.download_count` | `integer` | Yes | TikTok only. How many times the video was downloaded to a device. Separate from `engagement.saves`, which counts saves to an in-app collection. | | `ext.region` | `string` | Yes | TikTok only. The ISO 3166-1 alpha-2 country the video is registered to, usually the creator's account country. It is not the viewer's country or a language. On `/v1/tiktok/trending`, `/v1/tiktok/search` and `/v1/tiktok/search/top`, filter on it to keep rows from one country. | | `ext.subreddit` | `string` | Yes | Reddit subreddit name on search and list rows. Pass it to `/v1/reddit/subreddit/details?subreddit=`. | | `ext.title` | `string` | Yes | Post title, where the platform separates title from body. | | `ext.selftext` | `string` | Yes | Reddit text-post body. | | `ext.upvote_ratio` | `integer` | Yes | Reddit only. Share of votes that are upvotes, from 0 to 1. The value is a fraction even though the type says integer. Filled on `/v1/reddit/search` rows where available, `null` elsewhere. | | `ext.flair` | `string` | Yes | Reddit post flair. | | `ext.type` | `string` | Yes | Platform's own post type. | | `ext.content_type` | `string` | Yes | Platform's own content type. `kind` is read from it where it is present. | | `ext.repost_count` | `integer` | Yes | Repost count, where it is separate from shares. | | `ext.media_type` | `string` | Yes | Platform's media type (photo, video, carousel and so on). `kind` is read from it where it is present. | | `ext.text_truncated` | `boolean` | Yes | `true` when the text was cut short on this surface. | | `ext.ip_location` | `string` | Yes | Location the platform displays for the poster, where shown. | | `ext.carousel_count` | `integer` | Yes | Number of items in a carousel. | | `ext.remix_count` | `integer` | Yes | Number of remixes. | | `ext.usertags` | `string[]` | Yes | Accounts tagged in the post. | | `ext.music` | `string` | Yes | Music or sound attached to the post. | | `ext.sponsor_tags` | `string[]` | Yes | Sponsor or paid-partnership tags. | | `ext.location` | `string` | Yes | Location tagged on the post. | | `ext.retweeted_post` | `string` | Yes | Twitter/X: the original post behind a retweet. | | `ext.quote_count` | `integer` | Yes | Number of quote posts. | | `ext.all_media_urls` | `string[]` | Yes | Every media URL on the post. | | `ext.reaction_counts` | `string[]` | Yes | Counts broken down by reaction type. | | `ext.share_urn` | `string` | Yes | LinkedIn share URN. | | `ext.post_type` | `string` | Yes | Platform's post type. | | `ext.activity_id` | `string` | Yes | LinkedIn activity ID. | | `ext.published_at_precision` | `string` | Yes | How precise `published_at` is when the platform shows only a relative or rounded time. | | `ext.author_urn` | `string` | Yes | LinkedIn URN of the author. | | `ext.author_headline` | `string` | Yes | LinkedIn headline of the author. | | `ext.author_type` | `string` | Yes | Whether the LinkedIn author is a person or a company. | | `ext.is_repost_quote` | `boolean` | Yes | `true` when a repost adds its own commentary. | | `ext.article` | `string` | Yes | LinkedIn article attached to the post. | | `ext.reaction_type` | `string` | Yes | The reaction a member left, on reaction lists. | | `ext.download_media_urls` | `string[]` | Yes | Downloadable media URLs, when requested. | | `ext.tags` | `string[]` | Yes | Tags attached to the post. | | `ext.category_id` | `string` | Yes | YouTube category ID. | | `ext.category_title` | `string` | Yes | YouTube category name. | | `ext.topic_categories` | `string[]` | Yes | YouTube topic categories. | | `ext.duration` | `string` | Yes | YouTube duration in its original format. | | `ext.license` | `string` | Yes | YouTube license. | | `ext.made_for_kids` | `boolean` | Yes | YouTube made-for-kids flag. | | `ext.default_audio_language` | `string` | Yes | YouTube default audio language. | | `ext.has_paid_product_placement` | `boolean` | Yes | YouTube paid product placement flag. | | `ext.caption` | `string` | Yes | YouTube caption status. | | `ext.position` | `integer` | Yes | Position in a YouTube playlist. | | `ext.playlist_id` | `string` | Yes | YouTube playlist ID. | | `ext.video_owner_channel_id` | `string` | Yes | Channel that owns a video in a playlist. | | `ext.video_published_at` | `string` | Yes | When a playlist video was published. | | `ext.description` | `string` | Yes | Full description, where separate from `content.text`. | | `ext.playlist_item_id` | `string` | Yes | YouTube playlist item ID. | | `ext.playlist_owner_channel_id` | `string` | Yes | Channel that owns the playlist. | | `ext.playlist_owner_title` | `string` | Yes | Name of the playlist owner. | | `ext.published_label` | `string` | Yes | The relative time label the platform shows, such as "3 days ago". | | `ext.published_precision` | `string` | Yes | How precise the published time is. | | `ext.video_count` | `integer` | Yes | Number of videos, on playlist or collection rows. | | `ext.commerce` | `string` | Yes | Shopping or commerce details attached to the post. | | `ext.on_screen_texts` | `string[]` | Yes | Text shown on screen in the video. | | `ext.reshare_count` | `integer` | Yes | Reshare count, where reported separately. | | `ext.trend` | `string` | Yes | TikTok trend-board data. On `/v1/tiktok/hashtags/popular`: `rank`, `country_code`, `period_days`, `posts` and `views` for the period (not lifetime), `industry`, `industry_id`, `industry_label` for the first board read (`null` for the overall board), `boards` listing every board the hashtag ranks on as `{ industry, industry_id, industry_label, rank }`, `popularity_curve` as `{ date, value }` with value 0 to 100 relative to the period's peak, and `top_creators`. On `/v1/tiktok/videos/popular`: `rank`, `country_code`, `period_days`, `order_by`, `period_views`, `organic_views`, `engagement_rate`, `six_second_view_through_rate`, `content_tags`. Absent elsewhere. | | `ext.updated_at` | `string` | Yes | When the post was last edited, where shown. | | `ext.score` | `integer` | Yes | Reddit only. A post score below zero. A negative score is not a like count, so `engagement.likes` is `null` and the score is kept here. Absent when the score is zero or above. | ## Which platforms fill which fields [#which-platforms-fill-which-fields] Every platform returns this shape. `id` and `flags.deleted` are never `null`. The table covers the platforms the API launched with. The others return the same shape, and each response's [`unavailable`](/docs/schema/post#unavailable) list names the fields it could not fill. How to read the table: **yes** marks a field the platform is able to supply, though any single row can still have it `null`. An empty cell marks a field that platform never supplies, so expect `null` every time.
| Platform | `author.verified` | `engagement.saves` | `engagement.shares` | `content.duration_seconds` | `engagement.views` | `author.avatar_url` | `engagement.comments` | `content.media_urls` | `url` | `engagement.likes` | `content.thumbnail_url` | `flags.pinned` | | --------- | ----------------- | ------------------ | ------------------- | -------------------------- | ------------------ | ------------------- | --------------------- | -------------------- | ----- | ------------------ | ----------------------- | -------------- | | LinkedIn | | | yes | yes | | yes | yes | yes | yes | yes | yes | | | Pinterest | yes | yes | yes | yes | | yes | yes | yes | yes | yes | yes | | | Reddit | | | | yes | | yes | yes | yes | yes | yes | yes | yes | | TikTok | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | | Twitter/X | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | | | YouTube | | | | yes | yes | yes | yes | yes | yes | yes | yes | |
See [Metric substitutions](/docs/metric-substitutions) for the full list of per-platform nulls. The three fields schema 2 added are filled where the platform gives them: * **`author.id`**: LinkedIn, TikTok, YouTube (the channel ID) and Reddit, where it is the account's `t2_…` ID with the prefix kept, the same value comments and profiles carry. On Twitter/X and Pinterest the source usually gives none, so it is `null` and the response lists it in `unavailable`. * **`kind`**: read from the platform's own media or content type where it sends one (YouTube), and otherwise only where the format is certain: a Shorts URL, a TikTok video, a LinkedIn article. `null` otherwise. * **`language`**: only where the platform tags it, such as YouTube, Reddit and Twitter/X. ### `unavailable` [#unavailable] When a field the platform normally fills is `null` on every post in a response, the response lists its path in `unavailable`, for example `"items[].post.author.id"`. One filled row is enough to keep a field off the list. Fields a platform never shows publicly are never listed, so you are not told on every call: | Platform | Never listed in `unavailable` | | --------- | ---------------------------------------------------------------------------------- | | YouTube | `engagement.shares`, `engagement.saves` | | Reddit | `engagement.views`, `engagement.shares`, `engagement.saves`, `author.display_name` | | LinkedIn | `engagement.views`, `engagement.saves` | | Pinterest | `engagement.views` | TikTok and Twitter/X have nothing on the list. The table covers the platforms the API launched with; every platform, the other 16 included, is in [Data availability](/docs/data-availability#fields-a-platform-never-shows). `kind`, `content.*` and `language` are never listed on any platform, because `null` there usually describes the post (a photo has no duration) rather than a missing field. More on this in [Data availability](/docs/data-availability). ## Returned by [#returned-by] Endpoints that return a post or a list of posts use this shape on: [LinkedIn](/docs/platforms/linkedin) · [Pinterest](/docs/platforms/pinterest) · [Reddit](/docs/platforms/reddit) · [TikTok](/docs/platforms/tiktok) · [Twitter/X](/docs/platforms/twitter) · [YouTube](/docs/platforms/youtube) To see which native platform field feeds each unified field, read [Field equivalence](/docs/schema/field-equivalence). --- # Transcript (/docs/schema/transcript) The schema-2 transcript object, one shape on every platform, and which endpoints return it. Endpoints that turn the speech in a video or audio post into text return one shape on every platform, at `data.transcript`. This page describes schema 2, which every key gets from October 4, 2026; before it, the transcript was a string on some platforms and a list on others. See [Schema 2](/docs/schema-2). ## Example [#example] `/v1/youtube/video/transcript`, shortened: ```json title="Response" { "success": true, "platform": "youtube", "endpoint": "/v1/youtube/video/transcript", "schema_version": "2", "data": { "transcript": { "language": "en", "text": "[♪♪♪] ♪ We're no strangers to love ♪ ♪ You know the rules and so do I ♪ …", "segments": [ { "text": "[♪♪♪]", "start_seconds": 1.36, "duration_seconds": 1.68 }, { "text": "♪ We're no strangers to love ♪", "start_seconds": 18.64, "duration_seconds": 3.24 } ] } }, "unavailable": [], "credits_used": 30, "credits_remaining": 9970, "request_id": "req_5cace944c435", "cached": false, "idempotent_replay": false, "charge_reason": "miss", "free_call": false } ``` ## Fields [#fields] | Field | Type | Nullable | Description | | ---------------------------------------- | ---------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `transcript.language` | `string` | Yes | The transcript's language as the platform states it, such as `en`. `null` when it gives none. | | `transcript.text` | `string` | Yes | The whole transcript as one string. Where the platform sends timed cues, this is their text joined with spaces. `null` when there is no transcript text; the response then lists `transcript.text` in `unavailable`. | | `transcript.segments` | `object[]` | Yes | Timed cues, when the platform has them (YouTube). `null` when the platform sends the transcript as plain text only. | | `transcript.segments[].text` | `string` | No | The text of one cue. | | `transcript.segments[].start_seconds` | `number` | Yes | When the cue starts, in seconds from the start of the video. | | `transcript.segments[].duration_seconds` | `number` | Yes | How long the cue lasts, in seconds. | Read `transcript.text` for the words. Read `segments` only when you need timing, and check it for `null` first. ## Where it is used [#where-it-is-used] Seven platforms return this shape, on eight endpoints. | Platform | Endpoints | | --------- | ------------------------------------------------------------------------------ | | LinkedIn | [`/v1/linkedin/post/transcript`](/docs/api-reference/linkedin/post-transcript) | | Reddit | [`/v1/reddit/post/transcript`](/docs/api-reference/reddit/post-transcript) | | TikTok | [`/v1/tiktok/post/transcript`](/docs/api-reference/tiktok/post-transcript) | | Twitter/X | [`/v1/twitter/tweet/transcript`](/docs/api-reference/twitter/tweet-transcript) | | YouTube | [`/v1/youtube/video/transcript`](/docs/api-reference/youtube/video-transcript) | Prices differ per endpoint; see [Endpoint pricing](/docs/endpoint-pricing). A worked example is in [Video transcription](/docs/recipes/video-transcription-api). --- # Profile (/docs/api-reference/bluesky/profile) `GET https://api.insightsocial.app/v1/bluesky/profile` Returns a Bluesky user's public profile: handle, display name, avatar, description, follower and follows counts, post count, created date, and verification status. Use it when you have a handle and want the profile only; use user/posts for that account's posts. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | Bluesky handle (e.g. `espn.com`). | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # User › Posts (/docs/api-reference/bluesky/user-posts) `GET https://api.insightsocial.app/v1/bluesky/user/posts` Returns a feed of posts for a Bluesky user: text, author info, embeds, reply/repost/like/quote counts, and when each was indexed. Use it when you already have a handle or did and want that account's own posts; use search to find posts by keyword instead. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | no | Bluesky handle. Provide at least one of: `handle`, `user_id`. | | `user_id` | string | no | Bluesky `did` (Bluesky's internal user ID format, e.g. `did:plc:x7d6j54pm22ufehkes6jo4jf`). Provide at least one of: `handle`, `user_id`. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post (/docs/api-reference/bluesky/post) `GET https://api.insightsocial.app/v1/bluesky/post` Returns one Bluesky post: its record text, author info, embeds, reply count, repost count, like count, quote count, and a threaded replies array. Use it when you have a post URL; use user/posts to list everything one account has posted. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Bluesky post URL. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search (/docs/api-reference/bluesky/search) `GET https://api.insightsocial.app/v1/bluesky/search` Returns Bluesky posts matching a keyword, up to 100 per page, each with its text, author, like/comment/share counts, and when it was written. Use it to find posts by keyword across all of Bluesky; use user/posts when you already know the account. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search terms matched against post text. | | `sort` | string | no | `latest` (newest first, the default) or `top` (Bluesky's own top ranking, which favours popular posts over recent ones). One of: latest, top. | | `since` | string | no | Only posts written at or after this time. ISO 8601 date (`2026-09-01`) or datetime with a timezone (`2026-09-01T00:00:00Z`); any other shape is rejected with a free 400. | | `until` | string | no | Only posts written before this time. Same format as `since`. Set it to the oldest `published_at` of your last call to fetch the next older batch; the boundary is compared to the second, so a post from that same second can repeat, and deduplicating on `post.id` removes it. | | `lang` | string | no | Only posts tagged with this language, as a code such as `en`, `ja` or `ko`. | | `author` | string | no | Only posts by this account: a handle such as `espn.com` or a `did` such as `did:plc:...`. An account that does not exist returns an empty list. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search (/docs/api-reference/douyin/search) `GET https://api.insightsocial.app/v1/douyin/search` Returns Douyin videos matching a keyword: caption, creator, likes, comments, shares, saves, hashtags, music, cover image, and duration. Use it to find videos by keyword; use search/users to find creators instead. **Metered: 50–1250 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keywords, for example 美食 or coffee. | | `limit` | integer | no | Rows to return, 1 to 25. Default 10. | | `sort` | string | no | Result ordering: relevance, most_liked, or latest. Default relevance. One of: relevance, most_liked, latest. | | `published` | string | no | Recency window: all, day, week, or half_year. Default all. One of: all, day, week, half_year. | | `duration` | string | no | Length filter: all, under_1m, one_to_five_m, or over_5m. Default all. One of: all, under_1m, one_to_five_m, over_5m. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile (/docs/api-reference/douyin/profile) `GET https://api.insightsocial.app/v1/douyin/profile` Returns a Douyin creator's profile: nickname, Douyin ID, bio, avatar, follower and following counts, total likes received, video count, region, and verification. Use it to check a creator's follower count cheaply; use profile/posts for their videos. **60 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | no | Douyin sec_uid, the MS4wLjAB... string in a profile URL, or the numeric user ID. Provide at least one of: `handle`, `url`, `id`. | | `url` | string | no | Full Douyin profile URL, for example https://www.douyin.com/user/MS4wLjABAAAA... Provide at least one of: `handle`, `url`, `id`. | | `id` | string | no | Numeric Douyin user ID. Provide at least one of: `handle`, `url`, `id`. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Posts (/docs/api-reference/douyin/profile-posts) `GET https://api.insightsocial.app/v1/douyin/profile/posts` Returns a Douyin creator's recent videos, newest first: caption, likes, comments, shares, saves, hashtags, music, and cover image. Use it to pull a creator's recent videos; use profile when you only need their follower count. **Metered: 50–1250 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | no | Douyin sec_uid, the MS4wLjAB... string in a profile URL, or the numeric user ID. Provide at least one of: `handle`, `url`, `id`. | | `url` | string | no | Full Douyin profile URL. Provide at least one of: `handle`, `url`, `id`. | | `id` | string | no | Numeric Douyin user ID. Provide at least one of: `handle`, `url`, `id`. | | `limit` | integer | no | Rows to return, 1 to 25. Default 10. | | `recent_days` | integer | no | Only return videos published in the last N days. Leave unset for the newest regardless of age. | | `exclude_pinned` | boolean | no | Set true to skip videos pinned to the top of the profile, which can be old. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post (/docs/api-reference/douyin/post) `GET https://api.insightsocial.app/v1/douyin/post` Returns one Douyin video: caption, creator, likes, comments, shares, saves, hashtags, music, duration, dimensions, cover image, and tagged place when set. Use it when you have a video URL or aweme ID and need the full record; search returns only a summary row. **100 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Douyin video URL, for example https://www.douyin.com/video/7681266289940544369, or the bare numeric aweme ID. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post › Comments (/docs/api-reference/douyin/post-comments) `GET https://api.insightsocial.app/v1/douyin/post/comments` Returns top-level comments on a Douyin video: text, commenter, like count, reply count, IP region, and whether the creator liked it. Use it to read a video's top-level comments; use comment/replies for the thread under one of them. **Metered: 20–1000 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Douyin video URL or the bare numeric aweme ID. | | `limit` | integer | no | Comments to return, 1 to 100. Default 20. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Comment › Replies (/docs/api-reference/douyin/comment-replies) `GET https://api.insightsocial.app/v1/douyin/comment/replies` Returns the reply thread under one Douyin comment: text, replier, like count, IP region, and verification, each tagged with the parent comment id. Use it after post/comments, passing a comment id whose reply count is above zero. **Metered: 50–2500 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Douyin video URL or the bare numeric aweme ID the comment sits under. | | `comment_id` | string | yes | The comment to expand, taken from the id field of a GET /v1/douyin/post/comments row. Only comments with a non-zero engagement.replies have a thread. | | `limit` | integer | no | Replies to return, 1 to 50. Default 10. | | `cursor` | string | no | Continuation token from a previous response's pagination block. Omit for the first page. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Users (/docs/api-reference/douyin/search-users) `GET https://api.insightsocial.app/v1/douyin/search/users` Returns Douyin creators matching a keyword: nickname, Douyin ID, bio, follower count, total likes received, avatar, profile URL, and verification label. Use it to shortlist creators by keyword, follower band, or account type; use search to find videos instead. **Metered: 50–1250 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keywords, for example 美食 or a brand name. | | `limit` | integer | no | Rows to return, 1 to 25. Default 10. | | `cursor` | string | no | Continuation token from a previous response's pagination block. Omit for the first page. | | `followers` | string | no | Follower band: all, under_1k, 1k_to_10k, 10k_to_100k, 100k_to_1m, or over_1m. Default all. One of: all, under_1k, 1k_to_10k, 10k_to_100k, 100k_to_1m, over_1m. | | `user_type` | string | no | Account type: all, regular_user, enterprise_verified, or individual_verified. Default all. One of: all, regular_user, enterprise_verified, individual_verified. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Trending (/docs/api-reference/douyin/trending) `GET https://api.insightsocial.app/v1/douyin/trending` Returns the live Douyin hot-search board: roughly 50 trending topics with rank, hot value, view count, video count, and the time each topic broke. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to see what is trending across Douyin right now; there is no keyword filter, the whole board comes back in one call. **250 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Clip (/docs/api-reference/kick/clip) `GET https://api.insightsocial.app/v1/kick/clip` Returns one Kick clip's title, view count, duration, category, creator name, channel name, thumbnail URL, and creation timestamp. Use it when you have a Kick clip URL and need its stats and metadata. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the Kick clip | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile (/docs/api-reference/kwai/profile) `GET https://api.insightsocial.app/v1/kwai/profile` Returns a Kwai user's public profile: username, bio, avatar, verification status, and follower, following, like, and post counts. Use it for a quick profile snapshot; use user/posts for that account's posts. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | no | Kwai profile handle (without the @). Provide at least one of: `handle`, `url`. | | `url` | string | no | Kwai profile URL. Provide at least one of: `handle`, `url`. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # User › Posts (/docs/api-reference/kwai/user-posts) `GET https://api.insightsocial.app/v1/kwai/user/posts` Returns a paginated list of a Kwai user's posts: captions, media URLs, covers, engagement counts, and author info. Use it to list an account's posts; use profile when you only need the account's own counts. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | no | Kwai profile handle (without the @). Provide at least one of: `handle`, `url`. | | `url` | string | no | Kwai profile URL. Provide at least one of: `handle`, `url`. | | `cursor` | string | no | Cursor from the previous response for the next page | | `count` | integer | no | Number of posts to return (max 50) | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post (/docs/api-reference/kwai/post) `GET https://api.insightsocial.app/v1/kwai/post` Returns one Kwai post: caption, video and cover URLs, view/like/comment/share counts, author info, and music metadata. Use it when you have a single post URL; use user/posts to list everything an account has posted. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | no | Full URL of the Kwai post | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile (/docs/api-reference/linkedin/profile) `GET https://api.insightsocial.app/v1/linkedin/profile` Returns a LinkedIn member's public profile: full name, headline, location, follower and connection counts, profile picture, and profile URL. Use it as the starting point for any person lookup, then call the profile sub-endpoints for their experiences, skills, or posts. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile page | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Company (/docs/api-reference/linkedin/company) `GET https://api.insightsocial.app/v1/linkedin/company` Returns a LinkedIn company page: company name, description, follower count, headquarters location, website, and logo. Use it to look up a company by its page URL, and to get the numeric company_id that the other company endpoints need. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn company page | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Company › By Domain (/docs/api-reference/linkedin/company-by-domain) `GET https://api.insightsocial.app/v1/linkedin/company/by-domain` Returns the LinkedIn company page that owns a website domain: name, description, follower count, headquarters, website, logo, and numeric company id. Use it when you have a company website rather than a LinkedIn page URL. company looks up the same record from a page URL. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `domain` | string | yes | Company website domain, with or without a scheme. `microsoft.com` and `https://www.microsoft.com/` resolve the same page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Similar (/docs/api-reference/linkedin/profile-similar) `GET https://api.insightsocial.app/v1/linkedin/profile/similar` Returns members LinkedIn groups with a given profile, each with handle, headline, profile URL, and picture. Use it after profile to find nearby people; search/people filters by title, company, or location instead. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile to find similar members for. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Companies (/docs/api-reference/linkedin/search-companies) `GET https://api.insightsocial.app/v1/linkedin/search/companies` Returns LinkedIn company pages matching a keyword, each with name, tagline, page URL, and logo. Use it to find companies by name and optional size, industry, location, or open-jobs filters, then pass a result to company. **100 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Company name or keyword. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `company_size` | string | no | Headcount bucket. One of `1-10`, `11-50`, `51-200`, `201-500`, `501-1000`, `1001-5000`, `5001-10000`, `10001+`. One of: 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+. | | `has_jobs` | boolean | no | When true, return only companies that currently have open jobs. | | `industry_ids` | string | no | Comma-separated industry ids from /v1/linkedin/search/industry. | | `geocode` | string | no | Comma-separated location ids from /v1/linkedin/search/location. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Posted Jobs (/docs/api-reference/linkedin/profile-posted-jobs) `GET https://api.insightsocial.app/v1/linkedin/profile/posted-jobs` Returns the jobs a LinkedIn member has posted, each with job id, title, hiring company, location, and posting date. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it when you have a person's profile URL and want the roles they listed, not every opening at their employer. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile whose posted jobs to list. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Job › Hiring Team (/docs/api-reference/linkedin/job-hiring-team) `GET https://api.insightsocial.app/v1/linkedin/job/hiring-team` Returns the members LinkedIn shows as the hiring team on a job, each with handle, headline, profile URL, and picture. Use it after search/jobs or company/jobs, passing a job id or the job URL. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | no | LinkedIn job ID (from /v1/linkedin/search/jobs or /v1/linkedin/company/jobs). Provide at least one of: `id`, `url`. | | `url` | string | no | Full URL of the LinkedIn job posting. Provide at least one of: `id`, `url`. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Articles (/docs/api-reference/linkedin/profile-articles) `GET https://api.insightsocial.app/v1/linkedin/profile/articles` Returns Pulse articles a LinkedIn member published, each with text, author, engagement, and date. Use it for long-form writing. profile/posts is the short-form feed; article fetches one Pulse URL. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile whose articles to list. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Article (/docs/api-reference/linkedin/article) `GET https://api.insightsocial.app/v1/linkedin/article` Returns one LinkedIn Pulse article: its text, author, like and comment counts, and publish time. Use it when you have a /pulse/ URL. Comments and reactions are article/comments and article/reactions. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn Pulse article. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Article › Comments (/docs/api-reference/linkedin/article-comments) `GET https://api.insightsocial.app/v1/linkedin/article/comments` Returns comments on a LinkedIn Pulse article, with commenter identity, text, and timestamp. Use it after article or profile/articles, passing the article URL. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn Pulse article. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Article › Reactions (/docs/api-reference/linkedin/article-reactions) `GET https://api.insightsocial.app/v1/linkedin/article/reactions` Returns members who reacted to a LinkedIn Pulse article, each with handle, name, picture, and reaction type. Use it after article, passing the same Pulse URL. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn Pulse article. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Activity (/docs/api-reference/linkedin/profile-activity) `GET https://api.insightsocial.app/v1/linkedin/profile/activity` Returns when a LinkedIn member last showed public activity. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to see recency, not the feed itself. profile/posts returns the posts. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Company › Also Viewed (/docs/api-reference/linkedin/company-also-viewed) `GET https://api.insightsocial.app/v1/linkedin/company/also-viewed` Returns company pages LinkedIn shows as people also viewed, each with name, page URL, and logo. Use it after company to find nearby pages; pass the numeric company_id from company, or the company page URL. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `company_id` | string | no | Numeric LinkedIn company id, for example 1441 for Google. It is `author.id` on `/v1/linkedin/company`. Send this or `url`. Provide at least one of: `company_id`, `url`. | | `url` | string | no | Full URL of the LinkedIn company page, for example https://www.linkedin.com/company/google/. Send this or `company_id`. Provide at least one of: `company_id`, `url`. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Company › Employees Count (/docs/api-reference/linkedin/company-employees-count) `GET https://api.insightsocial.app/v1/linkedin/company/employees-count` Returns how many LinkedIn members list a company as employer, optionally broken down by location. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for a headcount by city or country; company.ext.employee_count is the headline total. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `company_id` | string | yes | LinkedIn numeric company ID (from /v1/linkedin/company). | | `geocode` | string | no | Comma-separated location ids from /v1/linkedin/search/location. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Interests › Schools (/docs/api-reference/linkedin/profile-interests-schools) `GET https://api.insightsocial.app/v1/linkedin/profile/interests/schools` Returns the school pages a LinkedIn member follows, each with name and page URL. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it after profile. search/schools turns a university name into a school id. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Interests › Newsletters (/docs/api-reference/linkedin/profile-interests-newsletters) `GET https://api.insightsocial.app/v1/linkedin/profile/interests/newsletters` Returns the newsletters a LinkedIn member follows, each with name and page URL. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it after profile to see which newsletters they follow. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Interests › Top Voices (/docs/api-reference/linkedin/profile-interests-top-voices) `GET https://api.insightsocial.app/v1/linkedin/profile/interests/top-voices` Returns the Top Voice profiles a LinkedIn member follows, each with name and profile URL. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it after profile to see which Top Voices they follow. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Position Skills (/docs/api-reference/linkedin/profile-position-skills) `GET https://api.insightsocial.app/v1/linkedin/profile/position-skills` Returns a member's positions with the skills listed on each role. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it when you need skills per job. profile/experiences is the role list; profile/skills is the flat list. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Top Position (/docs/api-reference/linkedin/profile-top-position) `GET https://api.insightsocial.app/v1/linkedin/profile/top-position` Returns the company page of the member's current top position: company id, name, website, headcount, industries and locations, not the job title. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to find where a member works now. company returns the same company in the canonical schema; profile/experiences has titles and dates. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › People › By Url (/docs/api-reference/linkedin/search-people-by-url) `GET https://api.insightsocial.app/v1/linkedin/search/people/by-url` Returns LinkedIn members from a people-search results URL, each with handle, headline, and profile URL. Use it when you already have a LinkedIn people-search URL. Keyword search is search/people. **100 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | LinkedIn people-search results URL. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › All (/docs/api-reference/linkedin/profile-all) `GET https://api.insightsocial.app/v1/linkedin/profile/all` Returns a member's entire public profile in one call: `author` with both counts, and `background` with About, experience, education, skills, recommendations, Featured and interests. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for a one-call profile audit, in place of stacking profile, profile/complete, profile/stats, the five interests lanes and profile/similar. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | no | Full URL of the LinkedIn profile. Provide at least one of: `url`, `urls`. | | `urls` | string | no | Up to 10 full LinkedIn profile URLs in one call, comma separated. The response becomes `{items, total}` instead of a single profile. A list where nothing resolves is a free 404. Provide at least one of: `url`, `urls`. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Complete (/docs/api-reference/linkedin/profile-complete) `GET https://api.insightsocial.app/v1/linkedin/profile/complete` Returns a member's full background: `author` in the /profile shape, and `background` with About, experiences, educations, skills and recommendations in the profile/* item shapes. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for background checks and enrichment, where one premium call replaces profile, profile/experiences, profile/educations, profile/skills and profile/recommendations. **100 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › With Posts (/docs/api-reference/linkedin/profile-with-posts) `GET https://api.insightsocial.app/v1/linkedin/profile/with-posts` Returns a member's profile with follower and connection counts in `author`, recent `posts` in the profile/posts item shape, and experiences, educations and skills under `background`. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for one call covering the counts, recent posts and career history. Use profile/complete when you need recommendations. **100 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post › With Comments (/docs/api-reference/linkedin/post-with-comments) `GET https://api.insightsocial.app/v1/linkedin/post/with-comments` Returns one LinkedIn post packed with its comments in a single payload. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to fetch a post and its thread together. Prefer post plus post/comments when you want each on its own schema. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Activity URL of the LinkedIn post. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post (/docs/api-reference/linkedin/post) `GET https://api.insightsocial.app/v1/linkedin/post` Returns one LinkedIn post: its text, author name and picture, like, comment and share counts, attached media, and the publish time. Use it when you have a post URL and want the post itself, not its comments, reactions, or reposts. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn post. It has to carry the post's ACTIVITY id, either `https://www.linkedin.com/feed/update/urn:li:activity:` or `https://www.linkedin.com/posts/-activity--`. Every endpoint that lists posts publishes the activity form as `post.url`, so copy that field rather than rebuilding the URL from `post.id`, which is not always the activity id. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › People (/docs/api-reference/linkedin/search-people) `GET https://api.insightsocial.app/v1/linkedin/search/people` Returns LinkedIn members matching a name or filters, each with handle, headline, location, follower count, profile URL, and member id. Use it to build a prospect list by job title, company, school, or location; use company/people to list one employer's staff. **Metered: 100–500 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Name or display-name keyword to search for (e.g. 'Bill Gates'). | | `page` | integer | no | Page number for pagination (default 1). | | `first_name` | string | no | Filter by first name. | | `last_name` | string | no | Filter by last name. | | `title` | string | no | Filter by job title or headline. | | `current_company` | string | no | Filter by current company, using a numeric company id from /v1/linkedin/company (`author.id`). Comma-separated for multiple. | | `past_company` | string | no | Filter by a previously-worked company, using a numeric company id from /v1/linkedin/company (`author.id`). | | `school` | string | no | Filter by school, using a school id from /v1/linkedin/search/schools (`id`). | | `industry` | string | no | Filter by industry, using an industry id from /v1/linkedin/search/industry (`industry_id`). | | `geocode_location` | string | no | Filter by location, using a geocode id from /v1/linkedin/search/location (`geocode`). | | `profile_language` | string | no | Filter by profile language (ISO 2-letter code, e.g. 'en'). | | `service_category` | string | no | Filter by service category, using a numeric service-category id. No endpoint resolves these, so pass one you already hold. | | `follower_of` | string | no | Return people who follow a specific member, using the member's URN from /v1/linkedin/profile (`author.ext.urn`). This one is a URN and not a numeric id. | | `include` | string | no | Set to `profile` (one token only) to join every row to the member's profile lookup in this one call: `author.followers` becomes the exact count and `followers_approximate` reads false on every row the lookup filled, `author.following` is filled with the member's connection count, and the location, joined date, country, website, cover image and profile flags land where the row lacks them. One of: profile. | | `limit` | integer | no | Take the top N rows of this page (1 to 10). The page cursor still advances past the full page of 10, so the rows past your limit are skipped, not carried to the next page. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Company › People (/docs/api-reference/linkedin/company-people) `GET https://api.insightsocial.app/v1/linkedin/company/people` Returns the members who list a company as their employer, each with handle, headline, location, profile picture, and follower count. Use it when you already have a company_id and want its staff; use search/people to filter across all of LinkedIn instead. **Metered: 100–500 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `company_id` | string | yes | LinkedIn numeric company ID (from /v1/linkedin/company). | | `page` | integer | no | Page number for pagination (default 1). | | `include` | string | no | Set to `profile` (one token only) to join every row to the member's profile lookup in this one call: `author.followers` becomes the exact count and `followers_approximate` reads false on every row the lookup filled, `author.following` is filled with the member's connection count, and the location, joined date, country, website, cover image and profile flags land where the row lacks them. One of: profile. | | `limit` | integer | no | Take the top N rows of this page (1 to 10). The page cursor still advances past the full page of 10, so the rows past your limit are skipped, not carried to the next page. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post › Comments (/docs/api-reference/linkedin/post-comments) `GET https://api.insightsocial.app/v1/linkedin/post/comments` Returns the comments on a LinkedIn post: commenter name, comment text, reaction counts, reply count, pinned and edited flags, and timestamps. Use it for the top-level comments on a post, then pass a comment's id to post/comments/replies to open one thread. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn post. It has to carry the post's ACTIVITY id, either `https://www.linkedin.com/feed/update/urn:li:activity:` or `https://www.linkedin.com/posts/-activity--`. Every endpoint that lists posts publishes the activity form as `post.url`, so copy that field rather than rebuilding the URL from `post.id`, which is not always the activity id. | | `page` | integer | no | Page number for pagination (default 1). | | `post_type` | string | no | Post type: 'activity' (default) or 'ugc'. One of: activity, ugc. | | `sort_order` | string | no | Comment ordering: 'relevance' or 'recent'. One of: recent, relevance. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off the page, and the page that reaches one ends the walk: `next_cursor` is not returned and `pagination.stopped_at` is `since`. Sending it sets the newest-first sort shown in this endpoint's sort parameter (any other sort value is a free 400). The page still costs what a page costs, so you pay for the pages you walk and no more. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Posts (/docs/api-reference/linkedin/profile-posts) `GET https://api.insightsocial.app/v1/linkedin/profile/posts` Returns the posts a LinkedIn member published, each with text, author name, like, comment and share counts, media, and publish time. Use it for what a person posted themselves; profile/reactions covers posts they only reacted to, profile/comments their comments. **Metered: 50–2000 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `limit` | integer | no | How many posts to return in the one call, 1 to 100. Defaults to the platform's 20. 100 is the platform's hard ceiling. Ask for the depth you need up front - there is no second page to fetch. | | `urn` | string | no | The member's opaque LinkedIn URN, as returned in `author.ext.urn` by /v1/linkedin/profile. Optional, and a pure optimisation: pass it ALONGSIDE `url` (which stays required) and this call skips the internal handle lookup, so it answers faster. Verified on the deployed API 05/09/2026. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Reactions (/docs/api-reference/linkedin/profile-reactions) `GET https://api.insightsocial.app/v1/linkedin/profile/reactions` Returns the posts a LinkedIn member reacted to, each with the post text, its original author, like, comment and share counts, and date. Use it to see what a person engages with rather than what they publish, which profile/posts returns. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `urn` | string | no | The member's opaque LinkedIn URN, as returned in `author.ext.urn` by /v1/linkedin/profile. Optional, and a pure optimisation: pass it ALONGSIDE `url` (which stays required) and this call skips the internal handle lookup, so it answers faster. Verified on the deployed API 05/09/2026. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post › Reposts (/docs/api-reference/linkedin/post-reposts) `GET https://api.insightsocial.app/v1/linkedin/post/reposts` Returns the reposts of a LinkedIn post, each with the resharer's name, any added commentary, engagement counts, and publish time. Use it to see who amplified a post; post/reactions lists who reacted and post/comments lists who replied. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn post. It has to carry the post's ACTIVITY id, either `https://www.linkedin.com/feed/update/urn:li:activity:` or `https://www.linkedin.com/posts/-activity--`. Every endpoint that lists posts publishes the activity form as `post.url`, so copy that field rather than rebuilding the URL from `post.id`, which is not always the activity id. | | `cursor` | string | no | LinkedIn cursor. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Group › Posts (/docs/api-reference/linkedin/group-posts) `GET https://api.insightsocial.app/v1/linkedin/group/posts` Returns the posts inside a LinkedIn group, each with text, author name, like, comment and share counts, media, and publish time. Use it to read a group's discussion feed; call group first if you also need the group's own details. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `group_id` | string | yes | LinkedIn numeric group ID. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Company › Affiliated Pages (/docs/api-reference/linkedin/company-affiliated-pages) `GET https://api.insightsocial.app/v1/linkedin/company/affiliated-pages` Returns a company's affiliated and showcase pages, each with page name, LinkedIn URL, speciality, follower count, and logo. Use it to map a parent brand to its regional and product pages before pulling posts or jobs for each one. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `company_id` | string | yes | LinkedIn numeric company ID (from /v1/linkedin/company). | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post › Comments › Replies (/docs/api-reference/linkedin/post-comments-replies) `GET https://api.insightsocial.app/v1/linkedin/post/comments/replies` Returns the replies under one LinkedIn comment, each with the replier's name, reply text, reaction and reply counts, and timestamps. Use it after post/comments: pass that comment's comment_id together with the post url to expand a single thread. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn post. It has to carry the post's ACTIVITY id, either `https://www.linkedin.com/feed/update/urn:li:activity:` or `https://www.linkedin.com/posts/-activity--`. Every endpoint that lists posts publishes the activity form as `post.url`, so copy that field rather than rebuilding the URL from `post.id`, which is not always the activity id. | | `comment_id` | string | yes | The parent comment's `comment.id` from /v1/linkedin/post/comments, or its `comment.ext.urn` (urn:li:comment:(ugcPost:,)). | | `cursor` | string | no | LinkedIn cursor. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Experiences (/docs/api-reference/linkedin/profile-experiences) `GET https://api.insightsocial.app/v1/linkedin/profile/experiences` Returns a LinkedIn member's work history, with each role's job title, company, employment dates, location, and description. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for the full career list, which the main profile endpoint condenses down to the current company only. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `urn` | string | no | The member's opaque LinkedIn URN, as returned in `author.ext.urn` by /v1/linkedin/profile. Optional, and a pure optimisation: pass it ALONGSIDE `url` (which stays required) and this call skips the internal handle lookup, so it answers faster. Verified on the deployed API 05/09/2026. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Educations (/docs/api-reference/linkedin/profile-educations) `GET https://api.insightsocial.app/v1/linkedin/profile/educations` Returns a LinkedIn member's education history, with each entry's school, degree, field of study, and the years attended. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for schooling detail; profile/experiences covers jobs, and search/schools turns a school name into a filter id. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `urn` | string | no | The member's opaque LinkedIn URN, as returned in `author.ext.urn` by /v1/linkedin/profile. Optional, and a pure optimisation: pass it ALONGSIDE `url` (which stays required) and this call skips the internal handle lookup, so it answers faster. Verified on the deployed API 05/09/2026. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Skills (/docs/api-reference/linkedin/profile-skills) `GET https://api.insightsocial.app/v1/linkedin/profile/skills` Returns the skills listed on a LinkedIn member's profile, with each skill's name and the endorsements shown against it. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to score a person against a skill requirement, separately from the roles returned by profile/experiences. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `urn` | string | no | The member's opaque LinkedIn URN, as returned in `author.ext.urn` by /v1/linkedin/profile. Optional, and a pure optimisation: pass it ALONGSIDE `url` (which stays required) and this call skips the internal handle lookup, so it answers faster. Verified on the deployed API 05/09/2026. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Honors (/docs/api-reference/linkedin/profile-honors) `GET https://api.insightsocial.app/v1/linkedin/profile/honors` Returns the honors and awards on a LinkedIn member's profile, with each award's title, issuer, date, and description. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for awards only: certifications live in profile/certifications and published work in profile/publications. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `urn` | string | no | The member's opaque LinkedIn URN, as returned in `author.ext.urn` by /v1/linkedin/profile. Optional, and a pure optimisation: pass it ALONGSIDE `url` (which stays required) and this call skips the internal handle lookup, so it answers faster. Verified on the deployed API 05/09/2026. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Certifications (/docs/api-reference/linkedin/profile-certifications) `GET https://api.insightsocial.app/v1/linkedin/profile/certifications` Returns the licenses and certifications on a LinkedIn member's profile, with each one's name, issuer, and issue or expiry dates. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to check formal credentials, as opposed to self-listed skills in profile/skills or degrees in profile/educations. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `urn` | string | no | The member's opaque LinkedIn URN, as returned in `author.ext.urn` by /v1/linkedin/profile. Optional, and a pure optimisation: pass it ALONGSIDE `url` (which stays required) and this call skips the internal handle lookup, so it answers faster. Verified on the deployed API 05/09/2026. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Publications (/docs/api-reference/linkedin/profile-publications) `GET https://api.insightsocial.app/v1/linkedin/profile/publications` Returns the publications on a LinkedIn member's profile, with each one's title, publisher, publication date, description, and link. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for articles, papers, and books a person published, not for their LinkedIn posts, which profile/posts returns. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `urn` | string | no | The member's opaque LinkedIn URN, as returned in `author.ext.urn` by /v1/linkedin/profile. Optional, and a pure optimisation: pass it ALONGSIDE `url` (which stays required) and this call skips the internal handle lookup, so it answers faster. Verified on the deployed API 05/09/2026. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Volunteers (/docs/api-reference/linkedin/profile-volunteers) `GET https://api.insightsocial.app/v1/linkedin/profile/volunteers` Returns the volunteer experience on a LinkedIn member's profile, with each entry's role, organisation, cause, and dates. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for unpaid and community roles, which the paid work history in profile/experiences does not cover. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `urn` | string | no | The member's opaque LinkedIn URN, as returned in `author.ext.urn` by /v1/linkedin/profile. Optional, and a pure optimisation: pass it ALONGSIDE `url` (which stays required) and this call skips the internal handle lookup, so it answers faster. Verified on the deployed API 05/09/2026. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Recommendations (/docs/api-reference/linkedin/profile-recommendations) `GET https://api.insightsocial.app/v1/linkedin/profile/recommendations` Returns the recommendations on a LinkedIn member's profile, with the recommender's name and headline, the recommendation text, and date. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for written references, and set type to received or given to choose which side of the relationship you want. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `type` | string | no | Filter by kind. See the allowed values. One of: received, given. | | `urn` | string | no | The member's opaque LinkedIn URN, as returned in `author.ext.urn` by /v1/linkedin/profile. Optional, and a pure optimisation: pass it ALONGSIDE `url` (which stays required) and this call skips the internal handle lookup, so it answers faster. Verified on the deployed API 05/09/2026. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Interests › Companies (/docs/api-reference/linkedin/profile-interests-companies) `GET https://api.insightsocial.app/v1/linkedin/profile/interests/companies` Returns the companies a LinkedIn member follows, with each company's name, LinkedIn URL, follower count, and logo. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to infer a person's interests and the brands they follow; profile/interests/groups covers the groups they follow. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `urn` | string | no | The member's opaque LinkedIn URN, as returned in `author.ext.urn` by /v1/linkedin/profile. Optional, and a pure optimisation: pass it ALONGSIDE `url` (which stays required) and this call skips the internal handle lookup, so it answers faster. Verified on the deployed API 05/09/2026. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Interests › Groups (/docs/api-reference/linkedin/profile-interests-groups) `GET https://api.insightsocial.app/v1/linkedin/profile/interests/groups` Returns the LinkedIn groups a member follows, with each group's name, URL, and the size of its membership. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to find the communities a person belongs to, then pass a group_id to group or group/posts to go deeper. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `urn` | string | no | The member's opaque LinkedIn URN, as returned in `author.ext.urn` by /v1/linkedin/profile. Optional, and a pure optimisation: pass it ALONGSIDE `url` (which stays required) and this call skips the internal handle lookup, so it answers faster. Verified on the deployed API 05/09/2026. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Images (/docs/api-reference/linkedin/profile-images) `GET https://api.insightsocial.app/v1/linkedin/profile/images` Returns the image posts on a LinkedIn member's profile, with each post's text, image links, engagement counts, and publish time. Use it when you only want photo posts; profile/posts returns every format and profile/videos returns the videos. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `urn` | string | no | The member's opaque LinkedIn URN, as returned in `author.ext.urn` by /v1/linkedin/profile. Optional, and a pure optimisation: pass it ALONGSIDE `url` (which stays required) and this call skips the internal handle lookup, so it answers faster. Verified on the deployed API 05/09/2026. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Videos (/docs/api-reference/linkedin/profile-videos) `GET https://api.insightsocial.app/v1/linkedin/profile/videos` Returns the video posts on a LinkedIn member's profile, with each post's text, video and thumbnail links, engagement counts, and date. Use it to collect a person's videos, then pass a video post's URL to post/transcript to read what was said. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `urn` | string | no | The member's opaque LinkedIn URN, as returned in `author.ext.urn` by /v1/linkedin/profile. Optional, and a pure optimisation: pass it ALONGSIDE `url` (which stays required) and this call skips the internal handle lookup, so it answers faster. Verified on the deployed API 05/09/2026. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Comments (/docs/api-reference/linkedin/profile-comments) `GET https://api.insightsocial.app/v1/linkedin/profile/comments` Returns the comments a LinkedIn member left on other people's posts, with the comment text, the post it sits under, and the timestamp. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to track someone's activity in other conversations; post/comments returns the comments on one specific post. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `urn` | string | no | The member's opaque LinkedIn URN, as returned in `author.ext.urn` by /v1/linkedin/profile. Optional, and a pure optimisation: pass it ALONGSIDE `url` (which stays required) and this call skips the internal handle lookup, so it answers faster. Verified on the deployed API 05/09/2026. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post › Reactions (/docs/api-reference/linkedin/post-reactions) `GET https://api.insightsocial.app/v1/linkedin/post/reactions` Returns the people who reacted to a LinkedIn post, each with their name, headline, profile URL, and the reaction they left. Use it to see who liked or praised a post, optionally filtered by type; post/comments covers the people who wrote a comment. **Metered: 100–500 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn post. It has to carry the post's ACTIVITY id, either `https://www.linkedin.com/feed/update/urn:li:activity:` or `https://www.linkedin.com/posts/-activity--`. Every endpoint that lists posts publishes the activity form as `post.url`, so copy that field rather than rebuilding the URL from `post.id`, which is not always the activity id. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `type` | string | no | Filter by kind. See the allowed values. One of: all, like, praise, empathy, appreciation, interest. | | `include` | string | no | Set to `profile` (one token only) to join every row to the member's profile lookup in this one call: `author.followers` becomes the exact count and `followers_approximate` reads false on every row the lookup filled, `author.following` is filled with the member's connection count, and the location, joined date, country, website, cover image and profile flags land where the row lacks them. One of: profile. | | `limit` | integer | no | Take the top N rows of this page (1 to 10). The page cursor still advances past the full page of 10, so the rows past your limit are skipped, not carried to the next page. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Company › Jobs (/docs/api-reference/linkedin/company-jobs) `GET https://api.insightsocial.app/v1/linkedin/company/jobs` Returns the jobs a company has posted, each with job id, title, location, hiring company details, posting date, and Easy Apply flag. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for one employer's openings; search/jobs looks across all companies and job returns one posting's full text. **100 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `company_id` | string | yes | LinkedIn numeric company ID (from /v1/linkedin/company). | | `page` | integer | no | 1-based page number. Defaults to 1. | | `date_posted` | string | no | How recently the job was listed. One of `anytime`, `past_24_hours`, `past_week`, `past_month`. Note the job lanes use `past_24_hours` while /v1/linkedin/search/posts uses `past_24h`; they are different vocabularies and are not interchangeable. One of: anytime, past_24_hours, past_week, past_month. | | `experience_level` | string | no | Required seniority for the role. One of: internship, entry_level, associate, mid_senior, director, executive. | | `job_type` | string | no | Contract type for the role. One of: full_time, part_time, contract, temporary, volunteer, internship, other. | | `remote` | string | no | Workplace type: onsite, remote, or hybrid. One of: onsite, remote, hybrid. | | `easy_apply` | boolean | no | When true, return only jobs that support LinkedIn Easy Apply. | | `sort_by` | string | no | Result ordering. One of: recent, relevant. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Jobs (/docs/api-reference/linkedin/search-jobs) `GET https://api.insightsocial.app/v1/linkedin/search/jobs` Returns LinkedIn job postings matching a keyword, each with job id, title, hiring company, location, posting date, and Easy Apply flag. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to search openings across employers with filters like remote, job type, and experience level, then pass an id to job. **100 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keyword. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `date_posted` | string | no | How recently the job was listed. One of `anytime`, `past_24_hours`, `past_week`, `past_month`. Note the job lanes use `past_24_hours` while /v1/linkedin/search/posts uses `past_24h`; they are different vocabularies and are not interchangeable. One of: anytime, past_24_hours, past_week, past_month. | | `experience_level` | string | no | Required seniority for the role. One of: internship, entry_level, associate, mid_senior, director, executive. | | `job_type` | string | no | Contract type for the role. One of: full_time, part_time, contract, temporary, volunteer, internship, other. | | `remote` | string | no | Workplace type: onsite, remote, or hybrid. One of: onsite, remote, hybrid. | | `easy_apply` | boolean | no | When true, return only jobs that support LinkedIn Easy Apply. | | `sort_by` | string | no | Result ordering. One of: recent, relevant. | | `company` | string | no | Filter by company, using a numeric company id from /v1/linkedin/company (`author.id`). | | `geocode` | string | no | Filter by location, using a geocode id from /v1/linkedin/search/location. | | `industry_ids` | string | no | Comma-separated industry ids from /v1/linkedin/search/industry. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Location (/docs/api-reference/linkedin/search-location) `GET https://api.insightsocial.app/v1/linkedin/search/location` Returns LinkedIn locations matching a place name, each with the location's display name and the geocode id LinkedIn filters on. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it first to turn a city or country name into the id that search/people and search/jobs expect for location filters. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keyword. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Schools (/docs/api-reference/linkedin/search-schools) `GET https://api.insightsocial.app/v1/linkedin/search/schools` Returns LinkedIn school pages matching a name, each with the school's name, page URL, and the id used in search filters. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to turn a university name into the school id that search/people accepts as a filter. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keyword. | | `page` | integer | no | 1-based page number. Defaults to 1. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Industry (/docs/api-reference/linkedin/search-industry) `GET https://api.insightsocial.app/v1/linkedin/search/industry` Returns LinkedIn industries matching a keyword, each with the industry name and the id LinkedIn uses to identify it. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to turn an industry name into the id that search/people and search/jobs need for their industry filters. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keyword. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › About (/docs/api-reference/linkedin/profile-about) `GET https://api.insightsocial.app/v1/linkedin/profile/about` Returns the month a LinkedIn member joined and how recently contact details and the profile photo were updated, plus identity verification when LinkedIn shows it for that member. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to judge how current a profile is. Verification is included only for members whose verification panel can be read. Values come back as relative text, not exact dates. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `urn` | string | no | The member's opaque LinkedIn URN, as returned in `author.ext.urn` by /v1/linkedin/profile. Optional, and a pure optimisation: pass it ALONGSIDE `url` (which stays required) and this call skips the internal handle lookup, so it answers faster. Verified on the deployed API 05/09/2026. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Contact (/docs/api-reference/linkedin/profile-contact) `GET https://api.insightsocial.app/v1/linkedin/profile/contact` Returns the contact details a LinkedIn member exposes publicly: websites, phone numbers, address, WeChat, and Twitter, alongside their name and profile urn. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it when you need a way to reach a person; most fields come back empty unless the member filled them in, and no email address is returned. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Stats (/docs/api-reference/linkedin/profile-stats) `GET https://api.insightsocial.app/v1/linkedin/profile/stats` Returns a LinkedIn member's audience size: their follower count and their connection count. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it when all you need is reach numbers and you do not want to pull the whole profile. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn profile, company, or post. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Company › Job Count (/docs/api-reference/linkedin/company-job-count) `GET https://api.insightsocial.app/v1/linkedin/company/job-count` Returns the number of jobs a LinkedIn company currently has open. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to track hiring volume over time without paging through the full list in company/jobs. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `company_id` | string | yes | LinkedIn numeric company ID (from /v1/linkedin/company). | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Company › Insights (/docs/api-reference/linkedin/company-insights) `GET https://api.insightsocial.app/v1/linkedin/company/insights` Returns headcount breakdowns of a LinkedIn company's members as name and count pairs, covering locations, schools, job functions, skills, service categories, and fields of study. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for a workforce profile of an employer without paging through staff; company/people lists the individual members. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `company_id` | string | yes | LinkedIn numeric company ID (from /v1/linkedin/company). | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Group (/docs/api-reference/linkedin/group) `GET https://api.insightsocial.app/v1/linkedin/group` Returns a LinkedIn group's profile: name, description, member count, posting rules, industries, owners, logo and cover images, and its public and active flags. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to size up a group and read its rules before pulling its feed with group/posts. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `group_id` | string | yes | LinkedIn numeric group ID. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Job (/docs/api-reference/linkedin/job) `GET https://api.insightsocial.app/v1/linkedin/job` Returns one LinkedIn job posting in full: title, hiring company, location, posting date, the job description text, and the Easy Apply flag. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it after search/jobs or company/jobs, passing a job id from those lists to read the complete description. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | LinkedIn job ID. | | `include_skills` | boolean | no | When true, include the job's required skills in `job.ext.skills`. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Company › Posts (/docs/api-reference/linkedin/company-posts) `GET https://api.insightsocial.app/v1/linkedin/company/posts` Returns the recent posts from a LinkedIn company page, each with text, author name, like, comment and share counts, media, and date. Use it for what a brand publishes; profile/posts covers an individual member and group/posts covers a group feed. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `company_id` | string | yes | LinkedIn numeric company ID (from /v1/linkedin/company). | | `page` | integer | no | Page number for pagination (default 1). | | `sort_by` | string | no | Post ordering: 'top' or 'recent'. One of: top, recent. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off the page, and the page that reaches one ends the walk: `next_cursor` is not returned and `pagination.stopped_at` is `since`. Sending it sets the newest-first sort shown in this endpoint's sort parameter (any other sort value is a free 400). The page still costs what a page costs, so you pay for the pages you walk and no more. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Ad (/docs/api-reference/linkedin/ad) `GET https://api.insightsocial.app/v1/linkedin/ad` Returns one LinkedIn ad from the Ad Library: the ad copy, creative images, the advertiser's name and logo, total impressions, and start date. Use it after ads/search, passing an ad's Ad Library URL to read that single ad in full. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn ad | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Ads › Search (/docs/api-reference/linkedin/ads-search) `GET https://api.insightsocial.app/v1/linkedin/ads/search` Returns ads from the LinkedIn Ad Library matching a company, keyword, country, or date range, with each ad's copy and the advertiser behind it. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to find what a competitor is running, then pass a result's ad URL to ad for the complete record. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `company` | string | no | The company name to search for. 'Microsoft' for example. Provide at least one of: `company`, `keyword`, `companyId`. | | `keyword` | string | no | The keyword to search for. Provide at least one of: `company`, `keyword`, `companyId`. | | `companyId` | string | no | The company id to search for. Provide at least one of: `company`, `keyword`, `companyId`. | | `countries` | string | no | Comma separated list of countries. Example: US,CA,MX | | `startDate` | string | no | Start date to search for. Format: YYYY-MM-DD | | `endDate` | string | no | End date to search for. Format: YYYY-MM-DD | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Posts › Archive (/docs/api-reference/linkedin/profile-posts-archive) `GET https://api.insightsocial.app/v1/linkedin/profile/posts/archive` Returns a LinkedIn member's deep post archive, read from their own feed rather than a search index, with the exact publish timestamp, media and the full engagement breakdown including share counts. It is metered per post returned, so ask for the limit you need. **Metered: 50–5000 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | The member's LinkedIn profile URL, for example https://www.linkedin.com/in/williamhgates/. | | `limit` | integer | no | How many posts to return, 1 to 100 (default 20). Pass 100 to walk the full archive: only a full page returns a `next_cursor`. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Posts (/docs/api-reference/linkedin/search-posts) `GET https://api.insightsocial.app/v1/linkedin/search/posts` Returns public LinkedIn posts and Pulse articles matching a keyword, with each result's text, author, media, like and comment counts, and date. Use it for broad keyword monitoring; it reads public search results, so treat coverage as best effort rather than complete. **Metered: 10–480 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | no | Keyword or phrase to search for. Optional when `from_member` or `from_company` is set: omit it to get that subject's posts unfiltered, and note that supplying a real content word narrows the results to posts matching it. Provide at least one of: `query`, `from_member`, `from_company`. | | `from_member` | string | no | Filter to posts from one member, by their LinkedIn member urn — the bare `ACoAA…` value published as `author.ext.urn` by /v1/linkedin/profile. A profile URL, a public slug (`williamhgates`) or a `urn:li:fsd_profile:`-prefixed value is rejected. Pass this on its own, with no `query`, to walk one member's back catalogue. Provide at least one of: `query`, `from_member`, `from_company`. | | `from_company` | string | no | Filter to posts from a company, by numeric LinkedIn company id (for example `1035`). A company slug or URL is rejected; read the id from `author.id` on /v1/linkedin/company. Provide at least one of: `query`, `from_member`, `from_company`. | | `page` | integer | no | 1-based page number of Google results. Defaults to 1. | | `sort_by` | string | no | Result ordering: `relevance` (default) or `date_posted`. On a subject-only call (`from_member` or `from_company` with no `query`) the results are ordered by date and `relevance` is rejected, because there is no query for them to be relevant to. One of: date_posted, relevance. | | `date_posted` | string | no | Date filter based on Google-indexed results. One of `past_24h`, `past_week`, `past_month` (underscores, not hyphens). Note the JOB lanes use `past_24_hours` for the same concept; the two vocabularies are not interchangeable. One of: past_24h, past_week, past_month. | | `content_type` | string | no | Narrow to one kind of post. One of: videos, photos, jobs, live_videos, documents, collaborative_articles. | | `limit` | integer | no | Return up to this many posts in one call, 1 to 200. Requires `query`. Cannot be combined with `page` or `cursor`: the result always starts at the top and `pagination.next_cursor` is null. `pagination.has_more` says whether more posts were available when the call stopped, and `walk.stopped` says why it stopped (`limit`, `exhausted`, `deadline` or `sources_unavailable`). | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | --- # Post › Transcript (/docs/api-reference/linkedin/post-transcript) `GET https://api.insightsocial.app/v1/linkedin/post/transcript` Returns the spoken text of a video in a LinkedIn post. A post with no transcript answers 404 with reason no_captions, and a repost is read from the original post it shares. Use it to read or search what was said in a LinkedIn video; you are only charged when a transcript actually comes back. **100 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the LinkedIn post to transcribe. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Full (/docs/api-reference/linkedin/profile-full) `GET https://api.insightsocial.app/v1/linkedin/profile/full` Returns a LinkedIn company page and its latest 10 posts in one call. Use it instead of calling company and company/posts. **Beta.** A composite: `data.profile` is a schema-2 Profile and `data.posts[].post` are schema-2 Posts, and the posts page with `cursor`. The rest of `data` is the source's own structure under our naming rules (snake_case keys, string ids). Fields outside the profile and posts may change. See [Schema 2](/docs/schema-2). **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full LinkedIn company profile or page URL. One of the identity params is required. | | `posts` | integer | no | How many of the fetched recent posts to return and compute the metrics over (1-100, default 25). | | `cursor` | string | no | Pass a prior response's posts_cursor to read the next page of posts. | | `include` | string | no | | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Business (/docs/api-reference/nextdoor/business) `GET https://api.insightsocial.app/v1/nextdoor/business` Returns one local business listed on Nextdoor: name, phone, email, website, street address, categories and how many neighbours recommend it. Use it when you have a business page URL; to find businesses by city and trade use search. **30 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `slug` | string | yes | The last segment of the business page URL, nextdoor.com/pages//. | | `market` | string | no | us (nextdoor.com, default), gb (nextdoor.co.uk) or ca (ca.nextdoor.com). One of: us, gb, ca. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search (/docs/api-reference/nextdoor/search) `GET https://api.insightsocial.app/v1/nextdoor/search` Returns local businesses on Nextdoor for a city and trade, each with name, address, categories and, where listed, phone, email and website. Use it to build a local lead list; for one business you already know use business. **Metered: 30–170 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `city` | string | yes | City slug: the city and its state or region joined by two hyphens, lowercase, e.g. austin--tx or york--england. | | `query` | string | yes | The trade to look for, e.g. plumber, bakery, electrician. | | `limit` | integer | no | Businesses to return, 1 to 20. Default 20. Billed per business returned. | | `market` | string | no | us (nextdoor.com, default), gb (nextdoor.co.uk) or ca (ca.nextdoor.com). One of: us, gb, ca. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search (/docs/api-reference/pinterest/search) `GET https://api.insightsocial.app/v1/pinterest/search` Returns Pinterest pins matching a keyword, each with its text, original image, pinner and pin date; include=engagement adds save, reaction, comment and share counts. Use it to discover pins on a topic; add include=engagement for each pin's saves, or call pin when you already have one pin URL. **Metered: 10–260 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Keyword or phrase to search Pinterest pins for. | | `cursor` | string | no | Cursor to get the next page. Take it from `pagination.next_cursor` on the previous response. | | `trim` | boolean | no | Set to true for a lighter record with fewer fields. | | `include` | string | no | Set to `engagement` (one token only) to fill `post.engagement.saves`, `.likes` (reactions), `.comments` and `.shares` on every row in this one call. One of: engagement. | | `limit` | integer | no | Take the top N rows of the page (1 to 25) after the search has run. It is not a page size: `next_cursor` still advances past the full page, so rows beyond N on this page are not returned by the next page. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Pin (/docs/api-reference/pinterest/pin) `GET https://api.insightsocial.app/v1/pinterest/pin` Returns one Pinterest pin: its text, original image, pinner, pin date, and its save, reaction, comment and share counts. Use it when you have a pin URL and want everything about that single pin rather than a list. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the Pinterest pin | | `trim` | boolean | no | Set to true for a lighter record with fewer fields. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Url Stats (/docs/api-reference/pinterest/url-stats) `GET https://api.insightsocial.app/v1/pinterest/url-stats` Returns how many times each of up to 10 external URLs has been saved to Pinterest through the Save Button. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to measure a page's pull on Pinterest, passing URLs exactly as used, since http vs https and a trailing slash count as different URLs. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `urls` | string | yes | Comma-separated list of 1-10 absolute http(s):// URLs, passed to Pinterest verbatim. Variants (https vs http, with/without trailing slash, with/without query string) are counted as different URLs. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Board (/docs/api-reference/pinterest/board) `GET https://api.insightsocial.app/v1/pinterest/board` Returns the pins on a Pinterest board with text, image URL, author, and save, comment and share counts; include=engagement adds each pin's date and reaction count. Use it when you have a board URL: about 15 pins a page, cursor for the rest, include=engagement for pin dates. user/boards finds the boards. **Metered: 10–160 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the Pinterest board | | `trim` | boolean | no | Set to true for a lighter record with fewer fields. | | `cursor` | string | no | Cursor to get the next page of pins. Take it from `pagination.next_cursor` on the previous response. | | `include` | string | no | Set to `engagement` (one token only) to fill `post.published_at` and `post.engagement.likes` (plus any save, comment or share count the board row lacked) on every row in this one call. One of: engagement. | | `limit` | integer | no | Take the top N pins of the page (1 to 15). It is not a page size: `next_cursor` still advances past the full page, so pins beyond N on this page are not returned by the next page. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # User › Boards (/docs/api-reference/pinterest/user-boards) `GET https://api.insightsocial.app/v1/pinterest/user/boards` Returns the boards a Pinterest user has created, each with its title, description, pin count, and cover image. Use it to list someone's boards from their handle, then pass a board URL to board to get that board's pins. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | The username of the user to get boards for. (e.g. broadstbullycom from https://www.pinterest.com/broadstbullycom/) | | `trim` | boolean | no | Set to true for a lighter record with fewer fields. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Trends (/docs/api-reference/pinterest/trends) `GET https://api.insightsocial.app/v1/pinterest/trends` Returns the Pinterest Trends list for one country: ranked search terms with a relative search index, for growing, seasonal, monthly or yearly tables. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it when you want what a market is searching for on Pinterest right now, with no keyword to start from. **100 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `country` | string | no | ISO country code, in any case: AR, AU, BR, CA, CO, DE, EG, ES, FR, GB, ID, IE, IN, IT, KR, MX, MY, NZ, PH, SA, TH, TR, US. Pinterest publishes no list for other countries, and one of them is a free 400. IE reads Pinterest's GB+IE list and AU and NZ read AU+NZ; GB alone has its own list. Defaults to US. One of: AR, AU, BR, CA, CO, DE, EG, ES, FR, GB, ID, IE, IN, IT, KR, MX, MY, NZ, PH, SA, TH, TR, US. | | `type` | string | no | Which Pinterest Trends table: growing (the default), seasonal, top_monthly or top_yearly. One of: growing, seasonal, top_monthly, top_yearly. | | `limit` | integer | no | How many terms to return, from the top, 1 to 50. Defaults to 25. The price is the same at any depth. | | `include` | string | no | Keep only terms containing one of these keywords, comma-separated (up to 10, e.g. nails,wedding). | | `exclude` | string | no | Drop terms containing any of these keywords, comma-separated (up to 10, e.g. fall). | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search (/docs/api-reference/quora/search) `GET https://api.insightsocial.app/v1/quora/search` Returns Quora questions matching a keyword: title, URL, answer count, follower count, and publish time. Use it to find questions on a topic; use answers to read written answers on the same topic. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keywords, for example learn programming. | | `time` | string | no | Recency window: all, hour, day, week, month, or year. Default all. One of: all, hour, day, week, month, year. | | `limit` | integer | no | Maximum rows to return, 1 to 10. Default 10. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post (/docs/api-reference/quora/post) `GET https://api.insightsocial.app/v1/quora/post` Returns one Quora question: title, body text, and published date. Quora questions rarely carry a separate body beyond the title. Use it when you have a question URL; use answers to find written answers on that topic by keyword. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the Quora question, for example https://www.quora.com/What-is-the-best-alternative-to-SendGrid-Email-API. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Answers (/docs/api-reference/quora/answers) `GET https://api.insightsocial.app/v1/quora/answers` Returns Quora answers matching a keyword: the answer text, author name and credential, upvotes, views, and the parent question title. Use it when you want written answers on a topic; use search for the questions themselves. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keywords, for example learn programming. | | `time` | string | no | Recency window: all, hour, day, week, month, or year. Default all. One of: all, hour, day, week, month, year. | | `limit` | integer | no | Maximum rows to return, 1 to 10. Default 10. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Posts (/docs/api-reference/quora/posts) `GET https://api.insightsocial.app/v1/quora/posts` Returns posts from Quora Spaces matching a keyword: URL, author, upvotes, comments, and publish time. Body text is often absent on this surface. Use it for Quora Space posts rather than Q&A content; use answers for written answers to questions. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keywords. | | `time` | string | no | Recency window: all, hour, day, week, month, or year. Default all. One of: all, hour, day, week, month, year. | | `limit` | integer | no | Maximum rows to return, 1 to 10. Default 10. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profiles (/docs/api-reference/quora/profiles) `GET https://api.insightsocial.app/v1/quora/profiles` Returns Quora profiles matching a keyword: display name, profile URL, credential, follower count, and avatar. Use it to find a person by name; use answers or posts to read what they have written. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keywords, for example a topic or a person's name. | | `time` | string | no | Recency window: all, hour, day, week, month, or year. Default all. One of: all, hour, day, week, month, year. | | `limit` | integer | no | Maximum rows to return, 1 to 10. Default 10. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Spaces (/docs/api-reference/quora/spaces) `GET https://api.insightsocial.app/v1/quora/spaces` Returns Quora Spaces matching a keyword: name, URL, description, member count, and icon. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to find Quora Spaces, topic communities, by name; use posts for what has been posted inside one. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keywords. | | `time` | string | no | Recency window: all, hour, day, week, month, or year. Default all. One of: all, hour, day, week, month, year. | | `limit` | integer | no | Maximum rows to return, 1 to 10. Default 10. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Topics (/docs/api-reference/quora/topics) `GET https://api.insightsocial.app/v1/quora/topics` Returns Quora topics matching a keyword: name, URL, follower count, and topic photo. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to find a topic page by name; use search to find the questions tagged under it. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keywords. | | `time` | string | no | Recency window: all, hour, day, week, month, or year. Default all. One of: all, hour, day, week, month, year. | | `limit` | integer | no | Maximum rows to return, 1 to 10. Default 10. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Subreddit (/docs/api-reference/reddit/subreddit) `GET https://api.insightsocial.app/v1/reddit/subreddit` Returns posts from a subreddit, each with title, body, score, comment count, author, permalink, and creation timestamp. Use it to read a community's feed, noting timeframe works only with sort=top, which is auto-selected when you omit sort; subreddit/search filters that same community by keyword. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `subreddit` | string | yes | Subreddit name without the r/ prefix | | `timeframe` | string | no | Timeframe to get posts from. Applied with sort=top (auto-selected when you omit sort). One of: all, day, week, month, year. | | `sort` | string | no | Sort order One of: best, hot, new, top, rising. | | `trim` | boolean | no | Set to true for a lighter record with fewer fields. This also skips the enrichment pass, so `author.avatar_url`, `content.media_urls`, `flags.spoiler`, `post.url` and the `ext.*` fields are omitted along with the rest of the trimmed leaves. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off the page, and the page that reaches one ends the walk: `next_cursor` is not returned and `pagination.stopped_at` is `since`. Sending it sets the newest-first sort shown in this endpoint's sort parameter (any other sort value is a free 400). The page still costs what a page costs, so you pay for the pages you walk and no more. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | --- # Subreddit › Details (/docs/api-reference/reddit/subreddit-details) `GET https://api.insightsocial.app/v1/reddit/subreddit/details` Returns a subreddit's own details: subscriber count, active user count, description, creation date, rules, and icon URL. Use it to size up a community before pulling its posts; the name is case-sensitive here, so spell it exactly as Reddit does. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `subreddit` | string | no | Subreddit name without the r/ prefix. Case-sensitive: use the subreddit's canonical casing (e.g. `AskReddit`). Provide at least one of: `subreddit`, `url`. | | `url` | string | no | Subreddit URL. Provide at least one of: `subreddit`, `url`. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search (/docs/api-reference/reddit/search) `GET https://api.insightsocial.app/v1/reddit/search` Returns posts matching a keyword from across Reddit, each with title, score, comment count, subreddit, permalink, and the body at ext.selftext. Use it to search all of Reddit at once. Bodies arrive free here, so include_body=true is rarely needed and refunds what it does not spend. subreddit/search searches inside one community. **Metered: 10–300 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search words or a phrase. Words match any, not all: vision pro also returns posts that mention only one of them. Wrap a phrase in double quotes to match it exactly (query="vision pro"). Reddit operators such as subreddit:name work too. | | `sort` | string | no | Sort by One of: relevance, new, top, comment_count. | | `timeframe` | string | no | Only return posts from this window. Applied on sort=relevance, sort=top and sort=comment_count. It has no effect with sort=new, which is already ordered newest-first and returns recent posts regardless. One of: all, day, week, month, year. | | `trim` | boolean | no | Set to true for a lighter record with fewer fields. On this endpoint it also skips the extra pass that widens the page, so a trimmed page is usually a few rows shorter. It does not drop `author.avatar_url` or `ext.*` where the first read already carried them. Use it to skip the widening pass, not to strip fields. | | `include_body` | boolean | no | Set to true to include each post's body (selftext) on the search page. Rarely needed now: bodies arrive on the rows themselves. Link posts have no body, so they are looked up and not charged for. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off the page, and the page that reaches one ends the walk: `next_cursor` is not returned and `pagination.stopped_at` is `since`. Sending it sets the newest-first sort shown in this endpoint's sort parameter (any other sort value is a free 400). The page still costs what a page costs, so you pay for the pages you walk and no more. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `max_age_days` | integer | no | Keep only rows published within this many days (`post.published_at`), 1 to 3650. A row with no date is discarded. | | `max_pages` | integer | no | 1 to 5 (default 1). Walk up to this many pages in one call and return the rows from all of them (after any filter). Each page walked is billed as one call to this endpoint; the whole walk counts once against your rate limit. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | --- # Post (/docs/api-reference/reddit/post) `GET https://api.insightsocial.app/v1/reddit/post` Returns one post from its URL including the body text, plus score, comment count, share count, author, author avatar, thumbnail, and creation timestamp. Use it when you have a post URL and want that one post's body. Search rows carry their own bodies now, so you rarely need to fan out per post. post/comments returns the discussion. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the Reddit post | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post › Comments (/docs/api-reference/reddit/post-comments) `GET https://api.insightsocial.app/v1/reddit/post/comments` Returns the full comment tree for a post, each comment with author, body, score, direct-reply count, nesting depth, timestamp, and its nested replies. Use it when you want the whole discussion rather than only top-level comments. Read data.truncated: true means the thread is incomplete, so keep paging while a cursor comes back. **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the Reddit post to fetch comments for | | `cursor` | string | no | Cursor to get more comments, or replies. | | `trim` | boolean | no | Accepted, but not honoured on this endpoint: there is no trimmed shape here, so the response is the same either way. Kept because removing an accepted parameter would break existing calls. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | --- # Subreddit › Search (/docs/api-reference/reddit/subreddit-search) `GET https://api.insightsocial.app/v1/reddit/subreddit/search` Returns posts matching a query inside one subreddit, each with title, score, comment count, and permalink. Post bodies are not included, so ext.selftext is null without include_body. Use it to search one community. Post bodies cost extra here, so for bodies prefer search with query=subreddit:name plus your terms, where bodies come with each row. That returns a different set of rows. **Metered: 10–260 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `subreddit` | string | yes | Subreddit name (e.g. 'Fitness', not 'r/Fitness' or a full URL) | | `query` | string | no | Search query to find matching content | | `sort` | string | no | Sort order. For posts/media: relevance, hot, top, new, comments. For comments: relevance, top, new One of: relevance, hot, top, new, comments. | | `timeframe` | string | no | Only return posts from this window. Applied on sort=relevance, sort=top and sort=comments. It has no effect with sort=new, which is already ordered newest-first and returns recent posts regardless. One of: all, year, month, week, day, hour. | | `cursor` | string | no | Cursor to get more results. Get 'cursor' from previous response. | | `include_body` | boolean | no | Set to true to include each post's body (selftext) on the search page. Link posts have no body, so they are looked up and not charged for. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile (/docs/api-reference/reddit/profile) `GET https://api.insightsocial.app/v1/reddit/profile` Returns one Reddit account: total karma, the post/comment/award karma split, cake day, bio, avatar, banner, trophy count and profile title. Use it to size or vet an account before reading its posts. author.followers is null on purpose: Reddit publishes no public follower count, so karma is the reach signal. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | Reddit username without the u/ prefix. Case-insensitive. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Posts (/docs/api-reference/reddit/profile-posts) `GET https://api.insightsocial.app/v1/reddit/profile/posts` Returns the posts one account has submitted, newest first, with the body at ext.selftext, score, comment count, upvote ratio, flair, media and ext.subreddit. Use it to read one person's submissions across communities. An account with no posts and one that does not exist both return an empty list, so call profile to tell them apart. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | Reddit username without the u/ prefix. Case-insensitive. | | `sort` | string | no | Sort order for the account's submissions. `top` defaults to the all-time window; pass `timeframe` to narrow it. One of: hot, new, top. | | `timeframe` | string | no | Only return posts from this window. Applied on `sort=top`. Omitted `sort=top` is treated as `timeframe=all` so the documented call is not an empty page. One of: all, year, month, week, day, hour. | | `cursor` | string | no | Cursor to get more results. Get 'cursor' from the previous response. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off the page, and the page that reaches one ends the walk: `next_cursor` is not returned and `pagination.stopped_at` is `since`. Sending it sets the newest-first sort shown in this endpoint's sort parameter (any other sort value is a free 400). The page still costs what a page costs, so you pay for the pages you walk and no more. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Comments (/docs/api-reference/reddit/profile-comments) `GET https://api.insightsocial.app/v1/reddit/profile/comments` Returns an account's own comment history, newest first, each with the text, score, permalink, parent_id, the post it sits under and ext.subreddit. Use it when you need a real comment history rather than a sample. **Metered: 20–2000 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | Reddit username without the u/ prefix. Case-insensitive. | | `limit` | integer | no | How many comments to return, 1-100, default 25. This is a depth control, not a page size: a higher limit reaches further back into the account's history at the same speed. | | `before` | string | no | Only return comments older than this date (YYYY-MM-DD). Use it to walk a long history in windows instead of raising limit. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Comments (/docs/api-reference/reddit/search-comments) `GET https://api.insightsocial.app/v1/reddit/search/comments` Returns comments matching a phrase from Reddit's comment index, each with its parent post inline: ext.post_title, ext.subreddit, ext.post_score and ext.post_url. Use it when the phrase lives in a reply rather than a title, and for author:username or subreddit:name sweeps. parent_id is null: search results do not report thread position. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search phrase. Reddit's operators work here: `author:username` for one account's comments, `subreddit:name terms` to scope to a community, and quotes for an exact phrase. | | `sort` | string | no | Sort order for the comment hits. One of: relevance, top, new. | | `cursor` | string | no | Cursor to get more results. Get 'cursor' from the previous response. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off the page, and the page that reaches one ends the walk: `next_cursor` is not returned and `pagination.stopped_at` is `since`. Sending it sets the newest-first sort shown in this endpoint's sort parameter (any other sort value is a free 400). The page still costs what a page costs, so you pay for the pages you walk and no more. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Subreddits › Search (/docs/api-reference/reddit/subreddits-search) `GET https://api.insightsocial.app/v1/reddit/subreddits/search` Returns up to 25 communities matching a topic, each with the name at author.id, subscriber count, description and icon. include=details adds the creation date, weekly activity, rules and language. Use it to find which communities discuss a subject. **Metered: 10–260 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Topic or keyword to find communities for. | | `cursor` | string | no | Cursor to get more results. Get 'cursor' from the previous response. | | `include` | string | no | Set to `details` (one token only) to fill `author.joined_at`, `author.ext.weekly_active_users`, `author.ext.weekly_contributions`, `author.ext.rules_text` and `author.ext.language` on every row in this one call (a row the details lookup cannot fully answer gets only the creation date and the language, and is still billed). One of: details. | | `limit` | integer | no | Take the top N communities of the page (1 to 25). It is not a page size: the cursor still advances past the whole page, so rows beyond N are not returned by the next page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Media (/docs/api-reference/reddit/search-media) `GET https://api.insightsocial.app/v1/reddit/search/media` Returns up to 25 Reddit posts that carry an image, video or gallery, with the media at content.media_urls plus title, score, comment count and subreddit. Use it for visual posts on a topic without filtering a mixed page yourself. subreddit:name terms scopes it to one community; timeframe has no effect on sort=new. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search phrase. Reddit's operators work here: `subreddit:name terms` scopes the sweep to one community, and quotes force an exact phrase. | | `sort` | string | no | Sort by One of: relevance, new, top, comment_count. | | `timeframe` | string | no | Only return posts from this window. Applied on sort=relevance, sort=top and sort=comment_count. It has no effect with sort=new, which is already ordered newest-first. One of: all, day, week, month, year. | | `cursor` | string | no | Cursor to get more results. Get 'cursor' from the previous response. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post › Transcript (/docs/api-reference/reddit/post-transcript) `GET https://api.insightsocial.app/v1/reddit/post/transcript` Returns the transcript of a Reddit video post, both the raw caption file and a plain-text version, when Reddit publishes captions for it. Use it for video posts; when Reddit exposes no captions the transcript comes back empty and flagged rather than as an error. **100 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Reddit post URL or direct v.redd.it video URL. | | `language` | string | no | 2-letter language code. Defaults to `en`. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Omni Search (/docs/api-reference/reddit/omni-search) `GET https://api.insightsocial.app/v1/reddit/omni-search` Returns threads from across Reddit for one keyword with their top comments inline at top_comments, plus a roll-up of which subreddits are talking, their weekly active users and tone. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for a customer-listening sweep in one call rather than running search then post/comments per thread; it is slow and relevance is loose. **Metered: 50–90 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Keyword or phrase to sweep across Reddit. | | `threads` | integer | no | How many top threads to expand comments for (1-8, default 8). | | `sort` | string | no | Search sort order (relevance \| new \| top \| comment_count). One of: relevance, new, top, comment_count. | | `timeframe` | string | no | Time window for the search (all \| day \| week \| month \| year). One of: all, day, week, month, year. | | `subreddit` | string | no | Scope the sweep to one subreddit (bare name, no r/ prefix). | | `cursor` | string | no | Opaque cursor from a prior response's next_cursor to page deeper. | | `include` | string | no | CSV subset of subreddits,comments (default both). The comments block is returned as `threads[].top_comments`. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search (/docs/api-reference/rumble/search) `GET https://api.insightsocial.app/v1/rumble/search` Returns Rumble videos and shorts matching a keyword: title, URL, thumbnail, channel, published date, and view count. Use it to find videos by keyword; use channel/videos when you already know the channel. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search query. | | `cursor` | string | no | Cursor from the previous response: the next page number (e.g. `2`). | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Channel › Videos (/docs/api-reference/rumble/channel-videos) `GET https://api.insightsocial.app/v1/rumble/channel/videos` Returns a Rumble channel's metadata and a page of its videos and shorts. Use it when you have a channel handle or URL and want its videos; use search to find videos across Rumble by keyword. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | no | Rumble channel handle. Provide at least one of: `handle`, `url`. | | `url` | string | no | Rumble channel URL. Provide at least one of: `handle`, `url`. | | `cursor` | string | no | Cursor from the previous response: the next page number (e.g. `2`). | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Video (/docs/api-reference/rumble/video) `GET https://api.insightsocial.app/v1/rumble/video` Returns one Rumble video's title, description, thumbnail, channel, publish date, view count, likes, dislikes, captions, and media metadata. Use it when you have a single video URL and need its full details; use video/comments for the discussion, or video/transcript for the spoken words. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Rumble video URL. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Video › Transcript (/docs/api-reference/rumble/video-transcript) `GET https://api.insightsocial.app/v1/rumble/video/transcript` Returns the transcript of a Rumble video when captions are available. If Rumble exposes no captions, transcript is null and nothing is charged. Use it when you need what was said in a video rather than its metadata; use video for the title, description, and engagement counts. **100 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Rumble video URL. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Video › Comments (/docs/api-reference/rumble/video-comments) `GET https://api.insightsocial.app/v1/rumble/video/comments` Returns the top-level comments on a Rumble video: comment text, author, created time, like and dislike counts, and reply count. Use it to read a video's comments; use video for the video's own details. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Rumble video URL. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile (/docs/api-reference/snapchat/profile) `GET https://api.insightsocial.app/v1/snapchat/profile` Returns a Snapchat user's public profile: display name, Bitmoji avatar URL, subscriber count, and bio description. Use it for a quick profile check; use spotlight/comments when you have a Spotlight snap URL instead. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | Snapchat username | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Spotlight › Comments (/docs/api-reference/snapchat/spotlight-comments) `GET https://api.insightsocial.app/v1/snapchat/spotlight/comments` Returns comments on a Snapchat Spotlight snap: text, display name, reaction count, nested reply count, and timestamp. Use it when you have a Spotlight snap URL and want its comments; use profile for the poster's own public info. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the Snapchat Spotlight snap. | | `cursor` | string | no | Cursor from the previous response to fetch the next page. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Posts (/docs/api-reference/substack/posts) `GET https://api.insightsocial.app/v1/substack/posts` Returns a publication’s recent posts, or one post: title, full text and Markdown, author, reactions, comments, restacks, word count and whether it is paid. Use it with a publication URL (or custom domain) for its archive, or a /p/ post URL for one post. **Metered: 10–120 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | A Substack publication URL or custom domain, or one post URL (…/p/slug). | | `limit` | integer | no | Most recent posts to read, 1 to 100. Default 25. Billed per post returned. | | `start_date` | string | no | Only posts published on or after this date (YYYY-MM-DD). Applied to the `limit` most recent posts, so raise `limit` to reach further back. | | `end_date` | string | no | Only posts published on or before this date (YYYY-MM-DD). Applied to the `limit` most recent posts, so raise `limit` to reach further back. | | `only_free` | boolean | no | true for free (non-paywalled) posts only. | | `content_type` | string | no | Only one post type. Default all. One of: all, newsletter, podcast, thread. | | `min_comments` | integer | no | Only posts with at least this many comments. | | `min_reactions` | integer | no | Only posts with at least this many reactions. | | `min_word_count` | integer | no | Only posts with at least this many words. | | `include_content` | boolean | no | Include the article body (text and Markdown). Default true; false is faster. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile (/docs/api-reference/telegram/profile) `GET https://api.insightsocial.app/v1/telegram/profile` Returns a public Telegram channel or group's profile: display name, description, avatar URL, verification status, and subscriber count. Use it for a channel's subscriber count and basic info; use profile/posts for its recent posts. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | Public Telegram handle, with or without the leading @, or a t.me channel URL | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Posts (/docs/api-reference/telegram/profile-posts) `GET https://api.insightsocial.app/v1/telegram/profile/posts` Returns one page of recent public posts from a Telegram channel or group, each with its text, publish time, view count, reaction breakdown, and media URLs. Use it to list a channel's recent posts; use post when you already have a single post's URL. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | Public Telegram handle, with or without the leading @, or a t.me channel URL | | `cursor` | string | no | Cursor from the previous page's pagination block. Omit it for the most recent posts. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post (/docs/api-reference/telegram/post) `GET https://api.insightsocial.app/v1/telegram/post` Returns one public Telegram post: text, publish time, view count, the per-emoji reaction breakdown, and direct media URLs. Use it when you have a single t.me post URL; use profile/posts to list a channel's recent posts instead. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Public Telegram post URL, in the form https://t.me/{handle}/{id} | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile (/docs/api-reference/tiktok/profile) `GET https://api.insightsocial.app/v1/tiktok/profile` Returns a TikTok account's public profile: display name, bio, follower count on author.followers (or the rounded figure with followers_approximate), likes, verification, and user id. Use it when you have a handle and want a quick snapshot of an account before pulling its videos or followers. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | no | TikTok username without the @ symbol. Provide at least one of: `handle`, `user_id`. | | `user_id` | string | no | TikTok numeric user ID. Use this for faster responses. Provide at least one of: `handle`, `user_id`. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Videos (/docs/api-reference/tiktok/profile-videos) `GET https://api.insightsocial.app/v1/tiktok/profile/videos` Returns a page of an account's recent public videos, each with caption, view, like, comment and share counts, and a thumbnail URL. Handle lookup covers login or age-walled profiles. Use it to list what one account has posted and page through it. Results come back in TikTok's own order, so sort_by does not reorder them. To find videos from many accounts by keyword, use search. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | no | TikTok username without the @ symbol. Provide at least one of: `handle`, `user_id`. | | `user_id` | string | no | TikTok user id. Use this for faster responses. Provide at least one of: `handle`, `user_id`. | | `since` | string | no | Only videos published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Older videos are left off the page, and the page that reaches one ends the walk: `next_cursor` is not returned and `pagination.stopped_at` is `since`. Pinned videos sit out of date order and never end the walk. The page still costs what a page costs, so a daily poll pays for the pages it walks and no more. | | `stop_at_id` | string | no | The id (`post.id`) or URL (`post.url`) of the newest video you already hold. The page stops just before it: that video and everything after it are left off, `next_cursor` is not returned, and `pagination.stopped_at` is `known_id`. A pinned video never counts as the stop point. If it is not on this page the page is returned in full with its cursor, so keep walking. `pagination.stopped_at` is `end` when the list ran out first and `null` while there is more to walk. | | `sort_by` | string | no | Accepted for compatibility and ignored on this endpoint: neither `latest` nor `popular` reorders the page. Videos come back in TikTok's own order. To rank a creator's videos by views or likes, page through with `cursor` and sort the collected rows yourself. One of: latest, popular. | | `region` | string | no | Two-letter country code that localises the request. Defaults to US. It does not filter the videos. The country TikTok registers each video to is post.ext.region. | | `trim` | boolean | no | Accepted for compatibility; the response is already the canonical shape, so this flag has no effect. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | --- # Post (/docs/api-reference/tiktok/post) `GET https://api.insightsocial.app/v1/tiktok/post` Returns one TikTok video in full: caption, engagement counts, author, sound, video metadata, and any on-screen text the creator typed with TikTok's text tool (post.ext.on_screen_texts). Use it when you already have a video URL and want that single video's numbers, rather than a list from profile/videos or search. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the TikTok video | | `region` | string | no | Two-letter country code (US, GB, FR, PH). Used only to retry a region-locked video, commonly one from the Philippines, as seen from that country. | | `trim` | boolean | no | Accepted for compatibility; the response is already the canonical shape, so this flag has no effect. | | `download_media` | boolean | no | Set to true to also download the video/images and get back durable hosted media URLs under `data.post.ext.download_media_urls` (`[{ post_id, cdn_url, type, cached }]`). Use these for archiving; the raw `media_urls` are short-lived signed CDN links that expire. Adds a few seconds of latency while the media is fetched. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post › Comments (/docs/api-reference/tiktok/post-comments) `GET https://api.insightsocial.app/v1/tiktok/post/comments` Returns a page of comments on one TikTok video, each with the commenter's username, comment text, like count, reply count, and timestamp. Use it to read a video's comment section; to expand one thread, take a comment's id and call video/comment/replies. **Metered: 10–30 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the TikTok video to fetch comments for | | `cursor` | string | no | Cursor to get more comments. Get 'cursor' from previous response. | | `trim` | boolean | no | Accepted for compatibility; the response is already the canonical shape, so this flag has no effect. | | `sort` | string | no | Optional. Without it, comments come in TikTok's own order (a relevance ranking, not newest first). `recent` returns them newest first by published_at; `top` returns them by like count. TikTok has no newest-first order of its own, so `recent` sorts the comments that were read: set scan_pages to read more of the thread. One of: top, recent. | | `scan_pages` | integer | no | Optional, 1 to 3, default 1. Reads that many pages, drops comments repeated across pages, and returns them all in the `sort` order (TikTok's own order when sort is absent). | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off the page, and the page that reaches one ends the walk: `next_cursor` is not returned and `pagination.stopped_at` is `since`. Sending it sets the newest-first sort shown in this endpoint's sort parameter (any other sort value is a free 400). The page still costs what a page costs, so you pay for the pages you walk and no more. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | --- # Video › Comment › Replies (/docs/api-reference/tiktok/video-comment-replies) `GET https://api.insightsocial.app/v1/tiktok/video/comment/replies` Returns the replies under a single TikTok comment, with each reply's text, author, likes, and timestamps. Use it after post/comments: pass the comment_id it returned together with the same video url to expand one thread. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `comment_id` | string | yes | TikTok comment ID. This is the cid from the comments endpoint. | | `url` | string | yes | TikTok video URL. This is the url from the comments endpoint. | | `cursor` | integer | no | Cursor to get more replies. Get 'cursor' from previous response. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | --- # Comment (/docs/api-reference/tiktok/comment) `GET https://api.insightsocial.app/v1/tiktok/comment` Returns one TikTok comment with its current like count, reply count, pinned flag, author, and timestamp, found by link, by id, or by its text. Use it to re-check a single known comment without paging the whole section; use post/comments when you want the section itself. **Metered: 20–60 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `comment_url` | string | no | A TikTok comment URL: `https://www.tiktok.com/@{handle}/video/{videoId}?comment_id={cid}`, the `m.tiktok.com/v/{id}.html?...&share_comment_id={cid}` share form, or a `vm.tiktok.com/{code}` / `tiktok.com/t/{code}` shortlink. The `cid`/`comment_id`/`share_comment_id` query value may be numeric or the base64 form TikTok's share sheet emits (`?cid=NzY1...`): both are accepted; base64 is decoded automatically. Mutually exclusive with `post_url`+`comment_id`. Provide at least one of: `comment_url`, `post_url`. | | `post_url` | string | no | The post URL (`https://www.tiktok.com/@{handle}/video/{videoId}`). Combine with `comment_id`, or with `author_username`/`text_contains` for a search. Provide at least one of: `comment_url`, `post_url`. | | `comment_id` | string | no | The target comment's numeric id (the `cid` from the comments endpoint). Requires `post_url`. Note that TikTok share links carry a base64-encoded `cid`: pass such a link as `comment_url` instead (decoded automatically), or base64-decode the value to its digits before passing it here. | | `parent_comment_id` | string | no | The parent comment's numeric id: supply this when the target is a reply so it can be resolved directly via the native replies endpoint. | | `author_username` | string | no | Return up to `max` comments authored by this username (no comment id needed). Mutually exclusive with `text_contains` and any comment id. | | `text_contains` | string | no | Return up to `max` comments whose text contains this snippet (case-insensitive). Mutually exclusive with `author_username` and any comment id. | | `deep_scan` | boolean | no | Widen the scan budget for deeply-buried comments (raises the page ceiling and deadline). | | `position_hint` | string | no | Opaque token from a prior lookup's `lookup.position_hint`. Passing it back probes the comment's last-known location first, making a re-check of an already-found comment cheap. | | `max` | integer | no | For `author_username`/`text_contains` search: max matches to return (1-20, default 5). | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search (/docs/api-reference/tiktok/search) `GET https://api.insightsocial.app/v1/tiktok/search` Returns TikTok videos matching a keyword, each with caption, view and like counts, author details, a thumbnail, and post.ext.region (the country the video is registered to). Use it for a video keyword search you can page and sort. region= localises the request but does not filter; filter on post.ext.region for one country. limit=120 returns one page of up to 120. search/top is the Top tab. **Metered: 10–370 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keyword or phrase to find TikTok videos | | `date_posted` | string | no | Time Frame One of: yesterday, this-week, this-month, last-3-months, last-6-months, all-time. | | `sort_by` | string | no | Sort by One of: relevance, most-liked, date-posted. | | `region` | string | no | Two-letter country code (ISO 3166-1 alpha-2) that localises the results. It does not filter the page to that country. Each row already carries post.ext.region, the country the video is registered to; filter on that leaf when you need only one country. | | `cursor` | integer | no | Cursor to get more videos. Get 'cursor' from previous response. Ignored when `limit` is set: that call is a single page. | | `trim` | boolean | no | Accepted for compatibility; the response is already the canonical shape, so this flag has no effect. | | `limit` | integer | no | Bulk labeled page: up to 120 videos in one call, each with post.ext.region. The value rounds up to the next multiple of 30 (30, 60, 90 or 120). TikTok can repeat a video; repeats are removed, so a 120 page is often a little under 120 unique videos. Omit limit for the default page of about 30, which pages with cursor and carries the same post.ext.region. Does not filter by country; drop rows yourself on post.ext.region. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `min_views` | integer | no | Keep only rows with at least this many views (`post.engagement.views`). A row whose view count is unknown is discarded, so every returned row meets the floor. | | `max_age_days` | integer | no | Keep only rows published within this many days (`post.published_at`), 1 to 3650. A row with no date is discarded. | | `country` | string | no | Comma-separated two-letter ISO 3166-1 codes, for example `US,GB`. Keep only videos TikTok registers to one of these countries (`post.ext.region`); a row with no country is discarded. This filters rows; it does not change where the search runs (that is `region`). | | `exclude_country` | string | no | Comma-separated two-letter ISO 3166-1 codes, for example `IN`. Discard videos TikTok registers to any of these countries (`post.ext.region`); a row with no country is kept. | | `sort_rows` | string | no | `views`: return the kept rows ordered by view count, highest first, across every page walked. Rows without a view count go last. One of: views. | | `max_pages` | integer | no | 1 to 5 (default 1). Walk up to this many pages in one call and return the rows from all of them (after any filter). Each page walked is billed as one call to this endpoint; the whole walk counts once against your rate limit. | --- # Trending (/docs/api-reference/tiktok/trending) `GET https://api.insightsocial.app/v1/tiktok/trending` Returns a page of popular TikTok videos with caption, view and like counts, author and thumbnail. Every row carries post.ext.region, the country the video is registered to. Use it with feed=local for videos mostly from one country (57% measured). The default feed is largely worldwide whatever region you pass, so filter on post.ext.region. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `region` | string | yes | ISO 3166-1 alpha-2 country code (e.g., US, GB, DE). On the default feed it sets the country the request is routed through and does not filter videos; with `feed=local` it sets the country the For You feed is built for. Either way, check `ext.region` on each row for the country a video is actually from. | | `trim` | boolean | no | Accepted for compatibility; it has no effect with `feed=local`. | | `feed` | string | no | `global` (default): the web trending feed routed through `region`, mostly worldwide content, about 13 videos in 3 to 12 seconds. One of: global, local. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Hashtag (/docs/api-reference/tiktok/search-hashtag) `GET https://api.insightsocial.app/v1/tiktok/search/hashtag` Returns TikTok videos posted under a given hashtag, each with caption, view, like, comment and share counts, author details, and a thumbnail. Use it to track one tag such as a campaign or challenge; use search when you want a free text keyword rather than a tag. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `hashtag` | string | yes | Hashtag to search for without the # symbol | | `region` | string | no | Two-letter country code that localises the results. It does not filter by country: use `post.ext.region`. | | `cursor` | integer | no | Cursor to get more videos. Get 'cursor' from previous response. | | `trim` | boolean | no | Accepted for compatibility; the response is already the canonical shape, so this flag has no effect. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `min_views` | integer | no | Keep only rows with at least this many views (`post.engagement.views`). A row whose view count is unknown is discarded, so every returned row meets the floor. | | `max_age_days` | integer | no | Keep only rows published within this many days (`post.published_at`), 1 to 3650. A row with no date is discarded. | | `sort_rows` | string | no | `views`: return the kept rows ordered by view count, highest first, across every page walked. Rows without a view count go last. One of: views. | | `max_pages` | integer | no | 1 to 5 (default 1). Walk up to this many pages in one call and return the rows from all of them (after any filter). Each page walked is billed as one call to this endpoint; the whole walk counts once against your rate limit. | --- # Search › Top (/docs/api-reference/tiktok/search-top) `GET https://api.insightsocial.app/v1/tiktok/search/top` Returns the videos TikTok ranks highest for a keyword on its Top tab, each with caption, author, engagement counts, a music id, and post.ext.region (the country the video is registered to). Use it for TikTok's own relevance ranking. region= localises the request but does not filter; filter on post.ext.region for one country. search/users returns accounts, which this endpoint does not include. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keyword or phrase | | `publish_time` | string | no | Time Frame TikTok was posted One of: yesterday, this-week, this-month, last-3-months, last-6-months, all-time. | | `sort_by` | string | no | Sort by One of: relevance, most-liked, date-posted. | | `region` | string | no | Two-letter country code (ISO 3166-1 alpha-2) that localises the results. It does not filter the page to that country. Each row already carries post.ext.region, the country the video is registered to; filter on that leaf when you need only one country. | | `cursor` | integer | no | Cursor to get more videos. Get 'cursor' from previous response. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `min_views` | integer | no | Keep only rows with at least this many views (`post.engagement.views`). A row whose view count is unknown is discarded, so every returned row meets the floor. | | `max_age_days` | integer | no | Keep only rows published within this many days (`post.published_at`), 1 to 3650. A row with no date is discarded. | | `country` | string | no | Comma-separated two-letter ISO 3166-1 codes, for example `US,GB`. Keep only videos TikTok registers to one of these countries (`post.ext.region`); a row with no country is discarded. This filters rows; it does not change where the search runs (that is `region`). | | `exclude_country` | string | no | Comma-separated two-letter ISO 3166-1 codes, for example `IN`. Discard videos TikTok registers to any of these countries (`post.ext.region`); a row with no country is kept. | | `sort_rows` | string | no | `views`: return the kept rows ordered by view count, highest first, across every page walked. Rows without a view count go last. One of: views. | | `max_pages` | integer | no | 1 to 5 (default 1). Walk up to this many pages in one call and return the rows from all of them (after any filter). Each page walked is billed as one call to this endpoint; the whole walk counts once against your rate limit. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Users (/docs/api-reference/tiktok/search-users) `GET https://api.insightsocial.app/v1/tiktok/search/users` Returns TikTok accounts for a search term with username, name, avatar, followers, verification. include=profile adds bio, region, link and category. Use it to find accounts by name or topic. Add country=KR (or US, DE, …) when you need creators in one country. The video searches, search and search/top, give you posts rather than accounts. **Metered: 10–1310 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keyword or phrase to find TikTok users | | `cursor` | integer | no | Cursor to get more users. Get 'cursor' from previous response. | | `trim` | boolean | no | Accepted for compatibility; the response is already the canonical shape, so this flag has no effect. | | `include` | string | no | Set to `profile` (one token only) to fill `author.bio`, `author.location` (the ISO region), `external_url` and `author.ext.business_category` on every row in this one call. One of: profile. | | `limit` | integer | no | Take the top N rows of the page (1 to 30) after the search has run. On the global page it is not a page size: `next_cursor` still advances past the full page, so rows beyond N on this page are not returned by the next page. | | `country` | string | no | ISO 3166-1 alpha-2 account region to filter by (KR, US, DE, …). Omit it for the global default page. A code this endpoint does not accept is a free 400. One of: US, GB, CA, AU, NZ, IE, DE, FR, ES, IT, PT, NL, BE, CH, AT, SE, NO, DK, FI, IS, PL, CZ, SK, HU, RO, BG, GR, HR, RS, SI, UA, RU, TR, IL, AE, SA, QA, KW, EG, MA, ZA, NG, KE, GH, TZ, ET, BR, MX, AR, CO, CL, PE, VE, EC, UY, PY, BO, CR, PA, DO, JM, JP, KR, CN, TW, HK, MO, SG, MY, ID, TH, VN, PH, IN, PK, BD, LK, NP, MM, KH. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Similar (/docs/api-reference/tiktok/similar) `GET https://api.insightsocial.app/v1/tiktok/similar` Returns about 30 TikTok accounts similar to a given creator, each with username, display name, avatar, bio, verification, and follower, following, video and like counts. Use it to find lookalike creators for one you already know; it returns a single fixed list, so call it again on a result to go wider. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | TikTok username of the seed creator, without the @ symbol. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # User › Audience (/docs/api-reference/tiktok/user-audience) `GET https://api.insightsocial.app/v1/tiktok/user/audience` Returns where a creator's followers are: the top countries in their audience, with sampled follower counts and each country's share. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for audience geography only. TikTok does not publish its followers' age or gender. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | TikTok username without the @ symbol | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # User › Followers (/docs/api-reference/tiktok/user-followers) `GET https://api.insightsocial.app/v1/tiktok/user/followers` Returns a page of accounts that follow a TikTok user, each with username, display name, avatar, and its own follower count. Use it to list who follows an account and page through them; user/following returns the reverse, the accounts they follow. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | no | TikTok username without the @ symbol. Provide at least one of: `handle`, `user_id`. | | `user_id` | string | no | User id. Use this for faster response times. Provide at least one of: `handle`, `user_id`. | | `min_time` | integer | no | Used to paginate. Get 'min_time' from previous response. | | `trim` | boolean | no | Accepted for compatibility; the response is already the canonical shape, so this flag has no effect. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # User › Following (/docs/api-reference/tiktok/user-following) `GET https://api.insightsocial.app/v1/tiktok/user/following` Returns a page of accounts a TikTok user follows, each with username, display name, avatar, and its own follower count. Use it to list who an account follows and page through them; user/followers returns the reverse, the accounts that follow it. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | no | TikTok username without the @ symbol. Provide at least one of: `handle`, `user_id`. | | `user_id` | string | no | TikTok user id. Use this for faster responses. Provide at least one of: `handle`, `user_id`. | | `min_time` | integer | no | Used to paginate. Get 'min_time' from previous response. | | `trim` | boolean | no | Accepted for compatibility; the response is already the canonical shape, so this flag has no effect. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # User › Live (/docs/api-reference/tiktok/user-live) `GET https://api.insightsocial.app/v1/tiktok/user/live` Returns a TikTok account's live room in the platform's own shape: cover image, title, start time, status code, viewer and entry counts, stream ids, and the host's profile. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to read a creator's live room state, but check status and start time yourself, since a room may still be returned after the broadcast has ended. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | TikTok username without the @ symbol | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post › Transcript (/docs/api-reference/tiktok/post-transcript) `GET https://api.insightsocial.app/v1/tiktok/post/transcript` Returns the spoken text of a TikTok video from its captions, with an option to fall back to AI transcription when no captions exist. Use it when you need what was said rather than the numbers; post gives you the video's caption and metrics but no transcript. **100 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the TikTok video | | `language` | string | no | Language of the transcript, as a two-letter code such as en, es, fr, de, it, ja, ko or zh. | | `use_ai_as_fallback` | string | no | Set to 'true' to fall back to AI transcription when the video has no captions. AI transcription covers videos up to 10 minutes (600 seconds): a longer video with no captions returns 400 INVALID_REQUEST with `error.details.reason: video_too_long`, `duration_seconds` and `max_seconds`, free and deterministic, so retrying returns the same answer. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Video › Screen Text (/docs/api-reference/tiktok/video-screen-text) `GET https://api.insightsocial.app/v1/tiktok/video/screen-text` Returns the text shown on the video itself: native text stickers plus AI OCR of the cover frame, so burned-in editor captions are caught too. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for the on-screen overlay text; the caption lives on post and the spoken words on post/transcript. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the TikTok video or photo post (a `/video/` or `/photo/` link) | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Song (/docs/api-reference/tiktok/song) `GET https://api.insightsocial.app/v1/tiktok/song` Returns one TikTok sound's details: title, artist, duration, how many videos use it, and its cover image. Use it when you have a sound's clipId and want the sound itself; song/videos returns the videos made with it. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `clipId` | string | yes | TikTok sound/song clip ID | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Song › Videos (/docs/api-reference/tiktok/song-videos) `GET https://api.insightsocial.app/v1/tiktok/song/videos` Returns videos that use a given TikTok sound, each with caption, author details, and engagement counts. Use it to see how a sound is being used and page through those videos; song returns only the sound's own details. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `clipId` | string | yes | TikTok sound/song clip ID | | `cursor` | integer | no | The cursor to get the next page of results. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Hashtags › Popular (/docs/api-reference/tiktok/hashtags-popular) `GET https://api.insightsocial.app/v1/tiktok/hashtags/popular` Returns TikTok's trending-hashtag board for one of 27 markets over 7, 30 or 90 days: each hashtag's rank, window post and view counts, daily popularity curve, industry board and top creators. Use it for seed-free trend collection by market. One board is three hashtags; pass industry=all for the overall board plus all 15 industry boards in one call. **Metered: 60–960 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `countryCode` | string | no | Market to read the board for, as an ISO country code. One of the 27 markets TikTok publishes the board for. Defaults to US. One of: US, FR, DE, IT, ES, GB, AR, AU, BR, CA, CO, EG, ID, IL, JP, KR, MY, MX, PH, SA, SG, ZA, TW, TH, TR, AE, VN. | | `period` | string | no | Window in days: 7, 30 or 90. Defaults to 7. Each window is a different board, not a longer list. One of: 7, 30, 90. | | `industry` | string | no | Which board to read. Omit for the overall board (3 hashtags). Pass an industry slug for that industry's board (3 hashtags), or `all` for the overall board plus all 15 industry boards in one call. One of: all, education, vehicle-and-transportation, baby-kids-and-maternity, beauty-and-personal-care, tech-and-electronics, travel, household-products, pets, home-improvement, apparel-and-accessories, news-and-entertainment, games, food-and-beverage, sports-and-outdoor, health. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Videos › Popular (/docs/api-reference/tiktok/videos-popular) `GET https://api.insightsocial.app/v1/tiktok/videos/popular` Returns TikTok's Top Videos board for the US, Japan, Vietnam, Thailand or Indonesia over 7 or 30 days: each video's rank, lifetime and window views, organic views, engagement rate and creator. Use it for the videos TikTok ranks highest in those five markets. Other markets have no board and return a free 400; use hashtags/popular there. **Metered: 260–450 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `countryCode` | string | no | Market: US, JP, VN, TH or ID, the only markets TikTok publishes this board for. Defaults to US. One of: US, JP, VN, TH, ID. | | `period` | string | no | Window in days: 7 or 30. Defaults to 7. One of: 7, 30. | | `orderBy` | string | no | How TikTok ranks the board: views (the default), engagement, or six_second_views. One of: views, engagement, six_second_views. | | `limit` | integer | no | How many videos to return, 1-20, default 20. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Region (/docs/api-reference/tiktok/profile-region) `GET https://api.insightsocial.app/v1/tiktok/profile/region` Returns the two letter country code for a public TikTok profile, for example US or MX. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it when all you need is an account's country, for routing or de-duplicating by market; profile returns the full account. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | TikTok username without the @ symbol | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Adlibrary › Search (/docs/api-reference/tiktok/adlibrary-search) `GET https://api.insightsocial.app/v1/tiktok/adlibrary/search` Returns TikTok Ad Library ads matching a keyword or advertiser name, each with creative, title, advertiser, impressions and date; include=ad adds the brand, landing page and advertiser link. Use it to find ads by query or advertiser_name; pass an ad id from the results to adlibrary/ad for the full record. **Metered: 50–170 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | no | Keyword or phrase to search the TikTok Ad Library. Provide at least one of: `query`, `advertiser_name`. | | `advertiser_name` | string | no | Advertiser name as it appears in the TikTok Ad Library. Provide at least one of: `query`, `advertiser_name`. | | `cursor` | string | no | Cursor from the previous response to fetch the next page. | | `include` | string | no | Set to `ad` (one token only) to fill the registered brand name, the landing page, the advertiser's TikTok profile link and avatar (`post.ext.ad.brand_name`, `post.ext.ad.landing_page`, `post.ext.ad.profile_web_link`, `post.author.avatar_url`), plus the objectives, countries and source where the library has them, on every ad in this one call. One of: ad. | | `limit` | integer | no | Take the top N ads of the page (1 to 12) after the search has run. It is not a page size: `next_cursor` still advances past the full page. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Adlibrary › Ad (/docs/api-reference/tiktok/adlibrary-ad) `GET https://api.insightsocial.app/v1/tiktok/adlibrary/ad` Returns one TikTok Ad Library ad: creative video, title, advertiser account, landing page, brand name, and first-shown date. Use it when you already have an ad id or library URL; use adlibrary/search to find ads by keyword or advertiser name first. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `ad_id` | string | no | TikTok Ad Library ad id, or a library.tiktok.com ads/detail URL. Provide at least one of: `ad_id`, `url`. | | `url` | string | no | TikTok Ad Library ads/detail URL. Provide at least one of: `ad_id`, `url`. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Suggestions (/docs/api-reference/tiktok/search-suggestions) `GET https://api.insightsocial.app/v1/tiktok/search/suggestions` Returns the autocomplete suggestions TikTok's own search box shows for a partial query, as a list of suggestion rows. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for keyword research, or to expand a seed term before running search or search/top. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Partial search query to autocomplete. | | `region` | string | no | ISO 3166-1 alpha-2 country code to localize suggestions. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Collection › Videos (/docs/api-reference/tiktok/collection-videos) `GET https://api.insightsocial.app/v1/tiktok/collection/videos` Returns the public videos inside a TikTok collection, each with caption, play like comment share and save counts, author, and a playable URL. Use it when you have a collection URL and want the videos saved there, paging with max_cursor. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the TikTok collection. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Playlists (/docs/api-reference/tiktok/profile-playlists) `GET https://api.insightsocial.app/v1/tiktok/profile/playlists` Returns the playlists a TikTok creator has published on their profile, each with its playlist id, its name, and the number of videos it holds. Use it to find a playlist id before calling playlist/videos. TikTok does not publish a view total for a playlist, so engagement stays null on every row. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | no | TikTok username without the @ symbol. Provide at least one of: `handle`, `user_id`. | | `user_id` | string | no | TikTok numeric user ID. Use this for faster responses. Provide at least one of: `handle`, `user_id`. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Playlist › Videos (/docs/api-reference/tiktok/playlist-videos) `GET https://api.insightsocial.app/v1/tiktok/playlist/videos` Returns the videos inside one of a creator's profile playlists, in playlist order, each with engagement counts, caption, author, and a playable URL. Use it with a playlist id from profile/playlists. Send the cursor back unchanged, because it is TikTok's item index and not a count of the rows you hold. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `playlist_id` | string | yes | Playlist id from /v1/tiktok/profile/playlists (`post.id` on that response). | | `handle` | string | no | TikTok username of the playlist owner, without the @ symbol. Provide at least one of: `handle`, `user_id`. | | `user_id` | string | no | TikTok numeric user ID of the playlist owner. Use this for faster responses. Provide at least one of: `handle`, `user_id`. | | `cursor` | string | no | Cursor from the previous response to fetch the next page of videos. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # User › Liked (/docs/api-reference/tiktok/user-liked) `GET https://api.insightsocial.app/v1/tiktok/user/liked` Returns the videos a TikTok account has liked, newest first, each carrying its own third party author, engagement counts, caption, and a playable URL. Use it for what an account likes, not for who liked a post: that direction does not exist on TikTok. Most accounts hide the list, and a hidden list is a refunded not found. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | no | TikTok username without the @ symbol. Provide at least one of: `handle`, `user_id`. | | `user_id` | string | no | TikTok numeric user ID. Use this for faster responses. Provide at least one of: `handle`, `user_id`. | | `cursor` | string | no | Cursor from the previous response to fetch the next page of liked videos. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Location › Posts (/docs/api-reference/tiktok/location-posts) `GET https://api.insightsocial.app/v1/tiktok/location/posts` Returns public TikTok videos tagged at a place, each with engagement counts, caption, author, and a playable URL. Use it with TikTok's own place id from a place page URL. An unknown place is a refunded not found, while a real place with nothing recent returns an empty list. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `location_id` | string | yes | TikTok place id, as it appears in the place page URL. | | `cursor` | string | no | Cursor from the previous response to fetch the next page of videos. | | `region` | string | no | Two-letter country code that localises the results. Defaults to US. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Effects (/docs/api-reference/tiktok/effects) `GET https://api.insightsocial.app/v1/tiktok/effects` Returns TikTok camera effects by id, each with its name, its designer, the views of videos made with it, and how many such videos exist. Use it to look several effects up in one call, and match results by the returned id. Repeated ids collapse and unknown ids drop, so the response can be shorter. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `ids` | string | yes | Comma-separated TikTok effect ids, up to 50 per request. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Effect › Videos (/docs/api-reference/tiktok/effect-videos) `GET https://api.insightsocial.app/v1/tiktok/effect/videos` Returns public TikTok videos created with a camera effect, each with engagement counts, caption, author, and a playable URL. Use it with an effect id from effects, and send the cursor back unchanged. TikTok picks its own page size here and ignores the one you ask for. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `effect_id` | string | yes | TikTok effect id, as returned by /v1/tiktok/effects. | | `cursor` | string | no | Cursor from the previous response to fetch the next page of videos. | | `region` | string | no | Two-letter country code that localises the results. Defaults to US. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Music (/docs/api-reference/tiktok/search-music) `GET https://api.insightsocial.app/v1/tiktok/search/music` Returns TikTok sounds matching a keyword, each with title, artist, duration, cover art, a preview audio URL, and how many videos use it. Use it to size a sound trend, or to join a TikTok sound to Apple Music, Spotify and Amazon through the store ids on ext.dsp_ids. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keyword, matched against sound titles and creators. | | `cursor` | string | no | Cursor from the previous response to fetch the next page of sounds. | | `sort_by` | string | no | Result ordering: relevance (default), most-used, most-recent, shortest or longest. One of: relevance, most-used, most-recent, shortest, longest. | | `filter_by` | string | no | Which field the keyword is matched against: all (default), title or creators. One of: all, title, creators. | | `region` | string | no | Two-letter country code that localises the results. Defaults to US. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Hashtag (/docs/api-reference/tiktok/hashtag) `GET https://api.insightsocial.app/v1/tiktok/hashtag` Returns TikTok's own record for a hashtag, with its display name, its description where one exists, the live total views under the tag, and how many videos carry it. Use it to size a tag before pulling its posts. Pass the tag name and the id lookup happens for you, or pass hashtag_id when you already hold it. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `hashtag` | string | no | Hashtag name, with or without the leading # symbol. Provide at least one of: `hashtag`, `hashtag_id`. | | `hashtag_id` | string | no | TikTok numeric hashtag id. Skips the name lookup when you already have it. Provide at least one of: `hashtag`, `hashtag_id`. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Ads › Top (/docs/api-reference/tiktok/ads-top) `GET https://api.insightsocial.app/v1/tiktok/ads/top` Returns TikTok's Creative Center leaderboard of top-performing ads for a market and time window, each with click-through rate, board rank, like count, industry, objective, and the ad video. Use it to find ad creative that actually performed. It is one window with no cursor, so set limit for depth and change country, period, or order_by for a different board. **Metered: 100–1000 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `country` | string | no | Creative Center market to read the board for. Defaults to US. This is the market the ads ran in, not the language they are in. One of: US, CA, MX, BR, GB, DE, FR, IT, ES, NL, PL, SE, TR, SA, AE, AU, JP, KR, ID, TH, VN, MY, PH, SG. | | `period` | string | no | Lookback window in days: 7, 30 or 180. Defaults to 30. A longer window is a different board, not more rows. One of: 7, 30, 180. | | `order_by` | string | no | How TikTok ranks the board: for_you (TikTok's own blend, the default), ctr, impression, like, cvr, play_2s_rate or play_6s_rate. One of: for_you, impression, ctr, play_2s_rate, play_6s_rate, cvr, like. | | `ad_format` | string | no | Restrict to Spark ads (ads boosted from an organic post) or Non-Spark ads. Defaults to all. One of: All ad types, Spark ads, Non-Spark ads. | | `ad_language` | string | no | Filter by the language of the ad copy. One of: en, ja, zh, vi, th, pt, id. | | `like_tier` | string | no | TikTok's engagement percentile band, 1 (top) to 5. Use it to read further down the ranking without raising limit. One of: 1, 2, 3, 4, 5. | | `industry` | string | no | Creative Center sub-category label, for example 'Skincare' or 'Cosmetics'. Use a sub-category, not a top-level group: the board returns nothing for the broad groups such as 'Financial Services' or 'Education'. Omit for all industries. | | `keyword` | string | no | Search the board by brand or product keyword. | | `limit` | integer | no | How many ads to return, 1-100, default 20. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Full (/docs/api-reference/tiktok/profile-full) `GET https://api.insightsocial.app/v1/tiktok/profile/full` Returns a TikTok profile plus its latest 10 videos in one call. Use it instead of calling profile and profile/videos. **Beta.** A composite: `data.profile` is a schema-2 Profile and `data.posts[].post` are schema-2 Posts, and the posts page with `cursor`. The rest of `data` is the source's own structure under our naming rules (snake_case keys, string ids). Fields outside the profile and posts may change. See [Schema 2](/docs/schema-2). **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | no | TikTok username or handle, with or without a leading @. One of the identity params is required. Provide at least one of: `handle`, `user_id`. | | `user_id` | string | no | Numeric TikTok user id. Use it instead of the handle when you already have the stable id, which survives a rename. One of the identity params is required. Provide at least one of: `handle`, `user_id`. | | `posts` | integer | no | How many of the fetched recent posts to return and compute the metrics over (1-100, default 25). | | `cursor` | string | no | Pass a prior response's posts_cursor to read the next page of posts. | | `include` | string | no | | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Product (/docs/api-reference/tiktokshop/product) `GET https://api.insightsocial.app/v1/tiktokshop/product` Returns one TikTok Shop product in full: description, price and discount, rating, review count, brand, specs, stock, seller details, shipping estimate, and images. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it when you have a product URL or ID and need the full listing; use products to list a storefront's catalogue, or search to find products by keyword. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | no | Full URL of the TikTok Shop product page. Provide this or `product_id`. Provide at least one of: `url`, `product_id`. | | `product_id` | string | no | Numeric TikTok Shop product id, as returned in `product.id` by tiktokshop/search, tiktokshop/products and tiktokshop/user/showcase. Provide this or `url`. Provide at least one of: `url`, `product_id`. | | `region` | string | no | ISO 3166-1 alpha-2 region for the lookup. Default US. Served: US, SG, MY, TH, VN, PH. GB and ID are temporarily unavailable (503, no charge). Other values are rejected before billing. One of: US, GB, ID, MY, TH, SG, VN, PH. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Product › Reviews (/docs/api-reference/tiktokshop/product-reviews) `GET https://api.insightsocial.app/v1/tiktokshop/product/reviews` Returns reviews on a TikTok Shop product: rating, text, author, buyer country, verified-purchase and incentivized-review flags, the purchased SKU, and a timestamp. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it when you have a product URL or ID and want what buyers say; use product for the listing itself. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | no | Full URL of the TikTok Shop product page. Provide this or `product_id`. Provide at least one of: `url`, `product_id`. | | `product_id` | string | no | The ID of the product (required if url is not provided). Provide at least one of: `url`, `product_id`. | | `region` | string | no | ISO 3166-1 alpha-2 region for the product (e.g. `US`). Important when the product is regionally scoped. One of: US, GB, DE, FR, IT, ID, MY, MX, PH, SG, ES, TH, VN, BR, JP, IE. | | `page` | integer | no | Page number to retrieve, 10 reviews per page. Prefer passing back `pagination.next_cursor`, which carries the same position and stays correct if the underlying paging mechanism changes. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | --- # Products (/docs/api-reference/tiktokshop/products) `GET https://api.insightsocial.app/v1/tiktokshop/products` Returns the products listed on a TikTok Shop storefront: title, images, canonical URL, price and discount, sold count, review count, rating, SKU ID, and the shop's own profile. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it when you have a storefront URL and want everything it sells; use search to find products across storefronts by keyword. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the TikTok Shop page | | `sort_by` | string | no | Sort products by best-selling (`top`) or newest (`new_releases`). Defaults to `top`. One of: top, new_releases. | | `region` | string | no | Region to get shop products from. A storefront is only reachable from its own market, so a GB shop needs `region=GB`; the default is US. One of: US, GB, DE, FR, IT, ID, MY, MX, PH, SG, ES, TH, VN, BR, JP, IE. | | `cursor` | string | no | Pagination cursor. Pass back `pagination.next_cursor` from the previous response. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search (/docs/api-reference/tiktokshop/search) `GET https://api.insightsocial.app/v1/tiktokshop/search` Returns TikTok Shop products matching a keyword across every storefront, each with price, rating, sold count, seller trust label, ship-from location, and promotion badges. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to find products by keyword across every storefront; use products when you already know the storefront. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keyword or phrase to find TikTok Shop products | | `page` | integer | no | Page number to retrieve. Prefer passing back `pagination.next_cursor`, which carries the same position. | | `region` | string | no | Region to search shop products in. Results, prices and currency follow the market; defaults to US. One of: US, GB, DE, FR, IT, ID, MY, MX, PH, SG, ES, TH, VN, BR, JP, IE. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # User › Showcase (/docs/api-reference/tiktokshop/user-showcase) `GET https://api.insightsocial.app/v1/tiktokshop/user/showcase` Returns the products featured in a TikTok user's public showcase: title, price and discount, rating, sold count, images, and SKU ID. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it when you have a creator's handle and want the products they promote; use product for one of those listings in full. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | The handle of the user | | `region` | string | no | Region the lookup is served from. US only for now; other regions are rejected before billing. One of: US. | | `cursor` | string | no | The cursor to the next page of products | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Sales (/docs/api-reference/tiktokshop/sales) `GET https://api.insightsocial.app/v1/tiktokshop/sales` Returns, per market, listings found, their units sold added up, an estimated sales figure in local currency, and the top listings by units for a keyword. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to compare a keyword's unit sales across several markets in one call; use search directly when you only need one market's listings. **Metered: 0–80 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Product keyword, sent unchanged to each market's search (1-200 characters). | | `regions` | string | no | Comma-separated markets, up to 8: US, GB, DE, FR, IT, ES, IE, ID, MY, MX, PH, SG, TH, VN, BR, JP. Default US. | | `top` | integer | no | How many top listings by units to return per market, 1 to 20. Default 5. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile (/docs/api-reference/truthsocial/profile) `GET https://api.insightsocial.app/v1/truthsocial/profile` Returns a Truth Social user's public profile: display name, follower count, following count, truth count, bio, and profile image URL. Use it for a quick profile snapshot; use user/posts for that account's recent truths. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | Truth Social username without the @ symbol | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # User › Posts (/docs/api-reference/truthsocial/user-posts) `GET https://api.insightsocial.app/v1/truthsocial/user/posts` Returns a Truth Social user's recent truths: text content, like count, retruth count, reply count, media attachments, and creation timestamp. Use it to list an account's recent truths; use post when you already have a single truth's URL. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | no | Truth Social username without the @ symbol. Provide at least one of: `handle`, `user_id`. | | `user_id` | string | no | Truth Social user id, the `id` field from /v1/truthsocial/profile. Faster than handle. Provide at least one of: `handle`, `user_id`. | | `trim` | boolean | no | Set to true for a lighter record with fewer fields. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post (/docs/api-reference/truthsocial/post) `GET https://api.insightsocial.app/v1/truthsocial/post` Returns one Truth Social post: text content, like count, retruth count, reply count, media attachments, author info, and creation timestamp. Use it when you have a single post URL; use user/posts to list an account's recent truths. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the Truth Social post | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile (/docs/api-reference/twitch/profile) `GET https://api.insightsocial.app/v1/twitch/profile` Returns a Twitch streamer's public profile: display name, follower count, bio, profile image URL, broadcast language, and partner or affiliate status. Use it for a streamer's public profile; use user/videos for their past broadcasts and highlights. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | Twitch username | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Clip (/docs/api-reference/twitch/clip) `GET https://api.insightsocial.app/v1/twitch/clip` Returns one Twitch clip's title, view count, duration, creator name, broadcaster name, game name, thumbnail URL, and creation timestamp. Use it when you have a clip URL and need its stats; use profile for the streamer's own public info. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the Twitch clip | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # User › Videos (/docs/api-reference/twitch/user-videos) `GET https://api.insightsocial.app/v1/twitch/user/videos` Returns up to 100 of a Twitch user's videos: id, slug, URL, embed URL, title, view count, language, duration, game info, broadcaster details, thumbnail, and available qualities. Use it to list a streamer's highlights and uploads; use clip for a single short clip's own details. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | Twitch username. | | `filter_by` | string | no | Filter the returned videos by type: `HIGHLIGHT` or `UPLOAD`. Past broadcasts are not available. One of: HIGHLIGHT, UPLOAD. | | `sort_by` | string | no | Sort order: `TIME` (newest first) or `VIEWS`. One of: TIME, VIEWS. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # User › Schedule (/docs/api-reference/twitch/user-schedule) `GET https://api.insightsocial.app/v1/twitch/user/schedule` Returns a Twitch user's upcoming stream schedule, each entry with start time, end time, title, description, and thumbnail URL. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to see when a streamer goes live next; use profile for their follower count and bio. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | Twitch username. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile (/docs/api-reference/twitter/profile) `GET https://api.insightsocial.app/v1/twitter/profile` Returns an X (Twitter) account's public profile: follower count, following count, tweet count, bio, profile and banner image URLs, and verification status. Use it when you have a handle and want a quick account snapshot before pulling its tweets. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | Twitter username without the @ symbol | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # User › Tweets (/docs/api-reference/twitter/user-tweets) `GET https://api.insightsocial.app/v1/twitter/user/tweets` Returns an account's most recent tweets in descending order, with full text, like, retweet, reply, bookmark and view counts, media, and creation time. Around 20 tweets per page. Use it to read a timeline: pages come newest first, retweets and self-threads included, and you can page deeper by sending pagination.next_cursor back as cursor. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | Twitter username without the @ symbol | | `since` | string | no | Only tweets published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Older tweets are left off the page, and the page that reaches one ends the walk: `next_cursor` is not returned and `pagination.stopped_at` is `since`. Pinned tweets sit out of date order and never end the walk. The page still costs what a page costs, so a daily poll pays for the pages it walks and no more. | | `stop_at_id` | string | no | The id (`post.id`) or URL (`post.url`) of the newest tweet you already hold. The page stops just before it: that tweet and everything after it are left off, `next_cursor` is not returned, and `pagination.stopped_at` is `known_id`. A pinned tweet never counts as the stop point. If it is not on this page the page is returned in full with its cursor, so keep walking. `pagination.stopped_at` is `end` when the list ran out first and `null` while there is more to walk. | | `trim` | boolean | no | Accepted for backwards compatibility and ignored. | | `cursor` | string | no | Cursor from the previous response's pagination.next_cursor to fetch the next page | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | --- # Tweet (/docs/api-reference/twitter/tweet) `GET https://api.insightsocial.app/v1/twitter/tweet` Returns one tweet in full: its text, like, retweet, reply and quote counts, media attachments, author info, and creation timestamp. Use it when you have a tweet URL and need its complete record, including the quote count that the user timeline does not carry. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the tweet. The numeric status id is what identifies it; the handle in the path is not checked | | `trim` | boolean | no | Accepted for backwards compatibility and ignored. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Community (/docs/api-reference/twitter/community) `GET https://api.insightsocial.app/v1/twitter/community` Returns an X (Twitter) community's details: name, description, member count, rules, and creation date. Use it when you have a community URL and want the group itself; community/tweets returns what has been posted inside it. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the Twitter/X community, in the form https://x.com/i/communities/{id} | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Community › Tweets (/docs/api-reference/twitter/community-tweets) `GET https://api.insightsocial.app/v1/twitter/community/tweets` Returns recent tweets posted inside an X (Twitter) community, each with its text, engagement counts, and author info. Use it to read a community's activity; it returns a single page, while community returns the group's own details. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the Twitter/X community, in the form https://x.com/i/communities/{id} | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Tweet › Transcript (/docs/api-reference/twitter/tweet-transcript) `GET https://api.insightsocial.app/v1/twitter/tweet/transcript` Returns the transcript of a video attached to a tweet, including auto-generated captions. Use it when a tweet carries video and you need the spoken words; tweet returns the media attachment but not its speech. **100 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the tweet containing a video | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Ai Search (/docs/api-reference/twitter/ai-search) `GET https://api.insightsocial.app/v1/twitter/ai-search` Returns a written answer to a plain-English question about X (Twitter), the X posts cited as sources, and how many searches the model ran. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for open questions such as what an account has said about a topic this week. A thin answer means thin retrieval, not an empty corpus, so confirm coverage with search/tweets. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Natural-language prompt describing what you want to learn from X. The model autonomously searches X using the x_search tool with any handle / date filters you provide. | | `from_handles` | string | no | Comma-separated X handles (max 10). Restricts the search to posts from these accounts only. Mutually exclusive with exclude_handles. | | `exclude_handles` | string | no | Comma-separated X handles (max 10) to exclude from search results. Mutually exclusive with from_handles. | | `from_date` | string | no | ISO 8601 start date (YYYY-MM-DD). Limits the search window to posts on or after this date. | | `to_date` | string | no | ISO 8601 end date (YYYY-MM-DD). Limits the search window to posts on or before this date. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Tweets (/docs/api-reference/twitter/search-tweets) `GET https://api.insightsocial.app/v1/twitter/search/tweets` Returns tweets matching a keyword or phrase, each with the full text, like, retweet, reply, bookmark and view counts, media attachments, author info, and creation time. Use it to track a topic or brand across X. Operators like from:, quoted phrases, filter:images, and since:/until: work inside query; sort picks latest (default) or top, the cursor pages deeper. **Metered: 10–50 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Keyword or phrase to search tweets for. X operators inside this string narrow the search itself, for example since:YYYY-MM-DD, until:YYYY-MM-DD, from:handle, quoted phrases, min_faves:20, filter:images, and filter:videos. Quote a multi-word phrase when you want relevance rather than engagement ranking from sort=top | | `sort` | string | no | Result ranking: latest (default) for the newest matches first, top for the most popular matches. top ranks by engagement, not relevance, so an unquoted multi-term query can return popular posts that match none of your terms. Quote the phrase or add an operator to tighten it One of: latest, top. | | `cursor` | string | no | Cursor from the previous response's pagination.next_cursor to fetch the next page | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off the page, and the page that reaches one ends the walk: `next_cursor` is not returned and `pagination.stopped_at` is `since`. Sending it sets the newest-first sort shown in this endpoint's sort parameter (any other sort value is a free 400). The page still costs what a page costs, so you pay for the pages you walk and no more. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `min_views` | integer | no | Keep only rows with at least this many views (`post.engagement.views`). A row whose view count is unknown is discarded, so every returned row meets the floor. | | `max_age_days` | integer | no | Keep only rows published within this many days (`post.published_at`), 1 to 3650. A row with no date is discarded. | | `sort_rows` | string | no | `views`: return the kept rows ordered by view count, highest first, across every page walked. Rows without a view count go last. One of: views. | | `max_pages` | integer | no | 1 to 5 (default 1). Walk up to this many pages in one call and return the rows from all of them (after any filter). Each page walked is billed as one call to this endpoint; the whole walk counts once against your rate limit. | --- # Tweet › Replies (/docs/api-reference/twitter/tweet-replies) `GET https://api.insightsocial.app/v1/twitter/tweet/replies` Returns the replies to a tweet, each with the reply text, author info, like and reply counts, and creation time. The tweet itself is not in the list. Use it with a tweet URL to read the conversation under it; the cursor walks deeper threads, and a tweet with no replies returns an empty list. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the tweet to fetch replies for | | `cursor` | string | no | Cursor from the previous response's pagination.next_cursor to fetch more replies | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | --- # User › Media (/docs/api-reference/twitter/user-media) `GET https://api.insightsocial.app/v1/twitter/user/media` Returns the tweets on an account's Media tab, only those carrying a photo or video, with media URLs, engagement counts, and creation time. View and bookmark counts are null here. Use it to pull an account's visual output without the text-only tweets user/tweets includes; the cursor pages deeper into the media grid. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | Twitter username without the @ symbol | | `cursor` | string | no | Cursor from the previous response's pagination.next_cursor to fetch the next page | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # User › Followers (/docs/api-reference/twitter/user-followers) `GET https://api.insightsocial.app/v1/twitter/user/followers` Returns the accounts following an X (Twitter) user, each with the handle, display name, bio, follower and tweet counts, privacy flag, and join date. Use it to sample an account's audience. Page size is set by X, around 70 accounts, and the cursor pages deeper; verification status is not readable here and returns null. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | Twitter username without the @ symbol | | `cursor` | string | no | Cursor from the previous response's pagination.next_cursor to fetch the next page | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # User › Following (/docs/api-reference/twitter/user-following) `GET https://api.insightsocial.app/v1/twitter/user/following` Returns the accounts an X (Twitter) user follows, each with the handle, display name, bio, follower and tweet counts, privacy flag, and join date. Use it to map who an account pays attention to. Page size is set by X and the cursor pages deeper; verification status is not readable here and returns null. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | Twitter username without the @ symbol | | `cursor` | string | no | Cursor from the previous response's pagination.next_cursor to fetch the next page | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Tweet › Retweeters (/docs/api-reference/twitter/tweet-retweeters) `GET https://api.insightsocial.app/v1/twitter/tweet/retweeters` Returns the accounts that retweeted a tweet, each with the handle, display name, bio, follower and tweet counts, privacy flag, and join date. Use it with a tweet URL to see who amplified it. Page size is set by X and the cursor pages deeper; verification status is not readable here and returns null. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the tweet whose retweeters you want | | `cursor` | string | no | Cursor from the previous response's pagination.next_cursor to fetch the next page | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Users (/docs/api-reference/twitter/search-users) `GET https://api.insightsocial.app/v1/twitter/search/users` Returns X (Twitter) accounts matching a name, handle or keyword, with handle, display name, bio, avatar, follower, following and tweet counts, location, verification, join date, and a private flag. Use it to resolve a handle you half know before calling profile or user/tweets. There is no spelling correction, so verify the returned handle. About 20 accounts a page, and the cursor pages deeper. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Name, handle, or keyword to search accounts for | | `cursor` | string | no | Cursor from the previous response's pagination.next_cursor to fetch the next page | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Full (/docs/api-reference/twitter/profile-full) `GET https://api.insightsocial.app/v1/twitter/profile/full` Returns an X account's profile and its recent tweets in one call. Use it instead of calling profile and user/tweets yourself. **Beta.** A composite: `data.profile` is a schema-2 Profile and `data.posts[].post` are schema-2 Posts, and the posts page with `cursor`. The rest of `data` is the source's own structure under our naming rules (snake_case keys, string ids). Fields outside the profile and posts may change. See [Schema 2](/docs/schema-2). **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | X (Twitter) username or handle, with or without a leading @. One of the identity params is required. | | `posts` | integer | no | How many of the fetched recent posts to return and compute the metrics over (1-100, default 25). | | `cursor` | string | no | Pass a prior response's posts_cursor to read the next page of posts. | | `include` | string | no | | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post (/docs/api-reference/weibo/post) `GET https://api.insightsocial.app/v1/weibo/post` Returns one public Weibo post: its text, author, like, comment and repost counts, image count and publish time. Use it when you have a post id; to list an account’s posts use user/posts. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `post_id` | string | yes | Weibo post id (the number in the post URL). | | `include_long_text` | string | no | Whether to fetch the full text of a long post. Default true. One of: true, false. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile (/docs/api-reference/weibo/profile) `GET https://api.insightsocial.app/v1/weibo/profile` Returns a public Weibo account: name, bio, avatar, follower, following and post counts, verification, location and website. Use it when you have a numeric user id; for the account’s posts use user/posts. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `user_id` | string | yes | Numeric Weibo user id (weibo.com/u/). | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # User › Posts (/docs/api-reference/weibo/user-posts) `GET https://api.insightsocial.app/v1/weibo/user/posts` Returns a page of an account’s recent public posts, each with text, engagement counts and publish time. Use it to follow one account; for a single post use post, and for a keyword use search. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `user_id` | string | yes | Numeric Weibo user id (weibo.com/u/). | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post › Comments (/docs/api-reference/weibo/post-comments) `GET https://api.insightsocial.app/v1/weibo/post/comments` Returns a page of first-level comments on a post, each with text, author, likes, reply count and time. Use it when you have a post id and want the conversation under it. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `post_id` | string | yes | Weibo post id (the number in the post URL). | | `limit` | integer | no | Comments per page, 1 to 20. Default 10. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search (/docs/api-reference/weibo/search) `GET https://api.insightsocial.app/v1/weibo/search` Returns public Weibo posts matching a keyword, each with text, author, engagement counts and URL. Use it to find posts on a topic; for what is trending right now use trending. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keyword. | | `search_type` | string | no | Which posts to search: all (default), hot, original, verified, media or viewpoint. One of: all, hot, original, verified, media, viewpoint. | | `include_type` | string | no | Only posts with this media: all (default), pic, video, music or link. One of: all, pic, video, music, link. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Trending (/docs/api-reference/weibo/trending) `GET https://api.insightsocial.app/v1/weibo/trending` Returns the current Weibo hot-search ranking: each topic’s keyword, rank, heat and label, pinned topics marked. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to see what China is talking about right now; to read the posts on a topic use search. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search (/docs/api-reference/xiaohongshu/search) `GET https://api.insightsocial.app/v1/xiaohongshu/search` Returns Xiaohongshu notes matching a keyword: title, short summary, creator, likes, comments, saves, shares, and cover image. Use it to find notes by keyword; use post for a note's full body once you have its ID. **Metered: 50–1000 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keywords, for example 护肤 or camping. | | `limit` | integer | no | Rows to return, 1 to 20. Default 10. | | `cursor` | string | no | Continuation token from a previous response's pagination block. Omit for the first page. | | `sort` | string | no | Result ordering: relevance, latest, most_liked, most_commented, or most_collected. Default relevance. One of: relevance, latest, most_liked, most_commented, most_collected. | | `type` | string | no | Note type: all, image, or video. Default all. One of: all, image, video. | | `published` | string | no | Recency window: all, day, week, or half_year. Default all. One of: all, day, week, half_year. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Trending (/docs/api-reference/xiaohongshu/trending) `GET https://api.insightsocial.app/v1/xiaohongshu/trending` Returns the live Xiaohongshu hot search board: ranked topics with a hot value. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to see what is trending on Xiaohongshu right now; there is no keyword filter, and there is no next page. **Metered: 50–1000 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `limit` | integer | no | Topics to return, 1 to 20. Default 10. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile (/docs/api-reference/xiaohongshu/profile) `GET https://api.insightsocial.app/v1/xiaohongshu/profile` Returns a Xiaohongshu (RedNote) creator's profile: display name, RedNote ID, bio, avatar, followers, following, notes posted, likes received, and IP province. Use it to check a creator's follower count; use profile/posts for their notes. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | no | Xiaohongshu profile URL, for example https://www.xiaohongshu.com/user/profile/6a59f257000000000f03b000. Provide at least one of: `url`, `id`. | | `id` | string | no | User id, the author_user_id on a note. Not the RedNote id. Provide at least one of: `url`, `id`. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Posts (/docs/api-reference/xiaohongshu/profile-posts) `GET https://api.insightsocial.app/v1/xiaohongshu/profile/posts` Returns a Xiaohongshu creator's notes, newest first: title, short summary, engagement counts, and pinned flag. Use it to list a creator's notes; use post for one note's full body text. **Metered: 50–1000 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | no | Xiaohongshu profile URL. Provide at least one of: `url`, `id`. | | `id` | string | no | User id, the author_user_id on a note. Not the RedNote id. Provide at least one of: `url`, `id`. | | `limit` | integer | no | Rows to return, 1 to 20. Default 10. | | `cursor` | string | no | Continuation token from a previous response's pagination block. Omit for the first page. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post (/docs/api-reference/xiaohongshu/post) `GET https://api.insightsocial.app/v1/xiaohongshu/post` Returns one Xiaohongshu note in full: body text, images or video, creator, likes, comments, saves, shares, and the IP province. Use it when you have a note URL and need the full body text; search and profile/posts only carry a short summary. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Note URL, for example https://www.xiaohongshu.com/explore/6aac8143000000002a007389, or the bare note id. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Post › Comments (/docs/api-reference/xiaohongshu/post-comments) `GET https://api.insightsocial.app/v1/xiaohongshu/post/comments` Returns top-level comments on a Xiaohongshu note: text, commenter, likes, reply count, pin flag, and the commenter's IP province. Use it to read a note's top-level comments; reply threads are not expanded on this call. **Metered: 50–1000 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Note URL or the bare note id the comments sit under. | | `limit` | integer | no | Rows to return, 1 to 20. Default 10. | | `cursor` | string | no | Continuation token from a previous response's pagination block. Omit for the first page. | | `sort` | string | no | Comment ordering: relevance, latest, or most_liked. Default relevance. One of: relevance, latest, most_liked. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Channel (/docs/api-reference/youtube/channel) `GET https://api.insightsocial.app/v1/youtube/channel` Returns a YouTube channel's public profile: subscriber count on author.followers (rounded above 1,000), video and view totals, description, banner and avatar URLs, and author.ext.public_email. Use it when you have a handle, channel id, or channel URL and want an account snapshot before pulling its videos. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `channelId` | string | no | YouTube channel ID. Can pass a channelId, handle or url. Provide at least one of: `channelId`, `handle`, `url`. | | `handle` | string | no | YouTube channel handle without the @ symbol. Provide at least one of: `channelId`, `handle`, `url`. | | `url` | string | no | YouTube channel URL. Can pass a channelId, handle or url. Provide at least one of: `channelId`, `handle`, `url`. | | `hl` | string | no | Preferred response language for localized text (ISO 639-1, e.g. 'en', 'es', 'fr'). | | `forUsername` | string | no | Legacy YouTube username (pre-handle) to look up. | | `contact_email` | string | no | Optional. When 1, also returns author.ext.contact_email: when the bio lists two or more email addresses, the one the creator gives for contacting them personally, copied verbatim from the bio. Null when there is one address or none, when every address belongs to a manager, agency or brand, or when the choice was not confident. author.ext.public_email is unchanged. No extra credits. One of: 1. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Channel › About (/docs/api-reference/youtube/channel-about) `GET https://api.insightsocial.app/v1/youtube/channel/about` Returns the address behind a channel's View email address control on author.ext.public_email, its listed country, and the profile: id, handle, name, avatar, bio, URL, subscribers, join date, views. Use it for outreach when GET /v1/youtube/channel returned no email: that lane reads only the public description, this one reads the About tab control. Premium priced, so shortlist first. **250 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `channelId` | string | no | YouTube channel ID. Can pass a channelId, handle or url. Provide at least one of: `channelId`, `handle`, `url`. | | `handle` | string | no | YouTube channel handle without the @ symbol. Provide at least one of: `channelId`, `handle`, `url`. | | `url` | string | no | YouTube channel URL. Can pass a channelId, handle or url. Provide at least one of: `channelId`, `handle`, `url`. | | `contact_email` | string | no | Optional. When 1, also returns author.ext.contact_email: when the bio lists two or more email addresses, the one the creator gives for contacting them personally, copied verbatim from the bio. Null when there is one address or none, when every address belongs to a manager, agency or brand, or when the choice was not confident. author.ext.public_email is unchanged. No extra credits. One of: 1. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Channel › Videos (/docs/api-reference/youtube/channel-videos) `GET https://api.insightsocial.app/v1/youtube/channel/videos` Returns recent videos published by a channel, each with title, view count, duration, thumbnail, and publish date; pass includeExtras=true to add like and comment counts. Use it for a channel's regular uploads; channel/shorts covers Shorts, channel/lives covers streams, channel/community-posts covers text posts. **Metered: 10–20 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `channelId` | string | no | YouTube channel ID. Provide at least one of: `channelId`, `handle`. | | `handle` | string | no | YouTube channel handle without the @ symbol. Provide at least one of: `channelId`, `handle`. | | `since` | string | no | Only videos published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Older videos are left off the page, and the page that reaches one ends the walk: `next_cursor` is not returned and `pagination.stopped_at` is `since`. Pinned videos sit out of date order and never end the walk. The page still costs what a page costs, so a daily poll pays for the pages it walks and no more. | | `stop_at_id` | string | no | The id (`post.id`) or URL (`post.url`) of the newest video you already hold. The page stops just before it: that video and everything after it are left off, `next_cursor` is not returned, and `pagination.stopped_at` is `known_id`. A pinned video never counts as the stop point. If it is not on this page the page is returned in full with its cursor, so keep walking. `pagination.stopped_at` is `end` when the list ran out first and `null` while there is more to walk. | | `sort` | string | no | Sort by latest or popular One of: latest, popular. | | `includeExtras` | string | no | Set to `true` to add the like count and comment count (`post.engagement.likes` / `.comments`) and the video description (`post.ext.description`). For the full per-video detail use /v1/youtube/video. Slows the response slightly. | | `is_paid_promotions` | string | no | Set to 'true' to search YouTube's public paid product placement / sponsorship / endorsement surface: returns normal videos where the creator disclosed a paid promotion. | | `include` | string | no | Set to `channel` (one token only) to add the channel's subscriber count to every row (`post.ext.author_followers`, YouTube's own figure, rounded to three significant figures above 1,000) plus `post.author.display_name`, `.avatar_url` and `author.id` where missing. Adds well under a second (never more than 8). One of: channel. | | `exact_dates` | string | no | Exact publish dates are on by default and free. Set to `false` to skip the lookup: rows then carry YouTube's own date estimate (a day-granular or coarser label truncated to midnight UTC), marked by `post.ext.published_precision` and `post.ext.published_label`, and the listing title, marked by `post.ext.title_maybe_translated`. One of: true, false. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Video (/docs/api-reference/youtube/video) `GET https://api.insightsocial.app/v1/youtube/video` Returns full details for one video: title, view, like and comment counts, description, tags, duration, channel info, and publish date. Use it when you have a video URL and need its complete record; the list endpoints return lighter entries without the description or tags. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the YouTube video | | `language` | string | no | Preferred response language (mapped to Accept-Language header; not guaranteed due to YouTube localization behavior). Two-letter language code, such as en, es or fr. | | `hl` | string | no | Preferred response language for localized text (ISO 639-1, e.g. 'en', 'es', 'fr'). | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Video › Sponsors (/docs/api-reference/youtube/video-sponsors) `GET https://api.insightsocial.app/v1/youtube/video/sponsors` Returns whether a video carries a paid-promotion disclosure plus the brands likely sponsoring it, each with supporting evidence and a confidence score. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to spot sponsored videos and who paid; sponsors are inferred from the description, links, promo codes, and transcript, not stated by YouTube. **100 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the YouTube video or short | | `language` | string | no | Two-letter language code used for the transcript lookup, such as en, es or fr. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Video › Comments (/docs/api-reference/youtube/video-comments) `GET https://api.insightsocial.app/v1/youtube/video/comments` Returns comments on a video, each with the author name, comment text, like count, reply count, and publish timestamp. Use it for a video's top-level comments, then pass a comment's `id` as `continuationToken` to video/comment/replies to open a single thread. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the YouTube video to fetch comments for | | `order` | string | no | Order of comments: 'top' (default, YouTube's relevance ranking) or 'newest' (exact newest-first on `comment.published_at`; each next page continues strictly older with no overlap: the lane for date-window and recency pulls). One of: top, newest. | | `searchTerm` | string | no | Filter comments to those containing this search term. | | `format` | string | no | Text format for comment bodies: 'html' (default) or 'plainText'. One of: html, plainText. | | `max_results` | integer | no | Comments per page, 1-100. The default page is already 100, so set this only to shrink a page; out-of-range values are rejected with a free 400 rather than degrading the response. | | `channel_id` | string | no | YouTube channel id to fetch channel-level community comments for (instead of a video's comments). | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off the page, and the page that reaches one ends the walk: `next_cursor` is not returned and `pagination.stopped_at` is `since`. Sending it sets the newest-first sort shown in this endpoint's sort parameter (any other sort value is a free 400). The page still costs what a page costs, so you pay for the pages you walk and no more. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | --- # Video › Comment › Replies (/docs/api-reference/youtube/video-comment-replies) `GET https://api.insightsocial.app/v1/youtube/video/comment/replies` Returns the replies under one comment, each with the reply text, author details, like count, and publish date. Use it after video/comments: pass a comment's `id` as `continuationToken`, and keep paging until no replies remain to get the whole thread. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `continuationToken` | string | yes | Where to start. The id of a top-level comment: a top-level comment id (e.g. the `comment.id` of any row from /v1/youtube/video/comments). For the next page of replies, send `pagination.next_cursor` as `cursor` with the same continuationToken. | | `format` | string | no | Text format for reply bodies: 'html' (default) or 'plainText'. One of: html, plainText. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | Universal pagination cursor. Send `pagination.next_cursor` from the previous response back verbatim: the API maps it to this endpoint's native `continuationToken` (cursor style). You never construct, decode, or look up a cursor. Omit it for page 1. | --- # Search (/docs/api-reference/youtube/search) `GET https://api.insightsocial.app/v1/youtube/search` Returns YouTube search results for a keyword: videos, channels, playlists, shorts, and live streams, each with title, thumbnail, views, and channel. Use it for a general keyword search across every content kind; search/advanced returns videos only but adds date, license, and country filters. **Metered: 10–150 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keyword or phrase. | | `uploadDate` | string | no | Upload date filter. Reliable on its own (no `type`). With `type=shorts`, windows narrower than `this_year` are rejected with a 400 because YouTube returns an empty set for them; `this_year` is accepted but measured to return ~5x fewer unique Shorts across a paginated walk (the platform re-serves the same items under an advancing `continuationToken`), so the recommended pattern for Shorts recency is no `uploadDate` at all plus `includeExtras=true` and a client-side filter on `post.published_at`. With other `type` values the platform currently ignores the date filter and may mix content kinds; filter client-side there too. For an EXACT date window rather than these coarse buckets, use `/v1/youtube/search/advanced`, whose `published_after`/`published_before` take RFC-3339 bounds and are genuinely applied. One of: today, this_week, this_month, this_year. | | `sortBy` | string | no | Sort order: relevance or popular. `popular` cannot be combined with `type=shorts` (rejected with a 400. YouTube serves that combination unreliably); it also caps the page at ~20 results. It is also NOT a strict view-count sort: `popular` is a popularity-weighted ranking, and results do not come back in descending view order. Measured on 4 of 4 test keywords: a `new york` search returned 9.5M, then 502.9M, then 66K views in that order. If you need a view-faithful ordering, use `/v1/youtube/search/advanced` with `order=viewCount` and `includeExtras=true`: its ranking leads with the true top results, and the returned `engagement.views` lets you sort the page exactly client-side. One of: relevance, popular. | | `type` | string | no | Type of content to return. NOTE on Shorts results (`type=shorts`, and the Shorts an untyped search mixes in): the Shorts shelf item carries no channel object (`includeExtras=true` does not add it). By default the free per-video lookup that supplies the exact date also fills `author.id` and `post.author.display_name` on those rows, at no extra credit. `post.author.username` (the @handle) and `post.author.avatar_url` stay null on them: send `include=engagement,channel` to fill both and the subscriber count. With `exact_dates=false` no lookup runs and the whole author stays null on Shorts. Video results are unaffected (20/20 carry the full author). `/v1/youtube/search/advanced` also carries `channel_id` on every result, though it has no Shorts filter. One of: videos, shorts, channels, playlists. | | `duration` | string | no | Video duration filter. Known issue: currently not applied by the platform and it can degrade the `type` filter; prefer filtering client-side on `post.content.duration_seconds`. One of: under_3_min, between_3_and_20_min, over_20_min. | | `region` | string | no | Two-letter country code that localises the results, such as US or GB. | | `includeExtras` | string | no | Set to `true` to add the like count and comment count (`post.engagement.likes` / `.comments`) and the video description (`post.ext.description`) to each video result. Left off, those three are null. Dates do not need it: `post.published_at` is exact by default either way (see `exact_dates`). For Shorts results it additionally supplies `post.content.duration_seconds`, which those items never carry otherwise. It does NOT add channel identity to Shorts results (see `type`) and it never adds a subscriber count. For both, send `include=engagement,channel` instead: the video join supplies every row's channel id, and the channel join adds the subscriber count, in this same call. For full per-video details use `/v1/youtube/video`. | | `include` | string | no | Set to `engagement`, `channel`, or both (`engagement,channel`) to fill more of every row in this one call. `engagement` fills `post.engagement.views`, `.likes` and `.comments`, `post.content.duration_seconds`, `author.id` and `post.author.display_name` where the row lacks them, and replaces a date derived from a label such as "4 months ago" with the exact publish time (removing `post.ext.published_precision`). `channel` puts the channel's subscriber count on `post.ext.author_followers` (YouTube's own figure, which it rounds to three significant figures above 1,000) and fills the channel's `post.author.display_name`, `.avatar_url` and `.username` where missing. Send both to cover rows that arrive without a channel id: the video join supplies it and the channel join then uses it. Channel and playlist result rows are not videos: the video join skips them. Each join adds 0.2 to 0.7 seconds on a fresh page (one lookup per 50 ids, never more than 8 seconds). | | `exact_dates` | string | no | Exact publish dates are on by default and free. Set to `false` to skip the lookup: rows then carry YouTube's own date estimate (a day-granular or coarser label truncated to midnight UTC), marked by `post.ext.published_precision` and `post.ext.published_label`, and the listing title, marked by `post.ext.title_maybe_translated`. One of: true, false. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `min_views` | integer | no | Keep only rows with at least this many views (`post.engagement.views`). A row whose view count is unknown is discarded, so every returned row meets the floor. | | `max_age_days` | integer | no | Keep only rows published within this many days (`post.published_at`), 1 to 3650. A row with no date is discarded. | | `sort_rows` | string | no | `views`: return the kept rows ordered by view count, highest first, across every page walked. Rows without a view count go last. One of: views. | | `max_pages` | integer | no | 1 to 5 (default 1). Walk up to this many pages in one call and return the rows from all of them (after any filter). Each page walked is billed as one call to this endpoint; the whole walk counts once against your rate limit. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | --- # Channel › Shorts (/docs/api-reference/youtube/channel-shorts) `GET https://api.insightsocial.app/v1/youtube/channel/shorts` Returns the Shorts published by a channel, each with title, view count, like count, and thumbnail. Use it when you want only a channel's Shorts; channel/videos returns its regular uploads instead. **Metered: 10–20 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `channelId` | string | no | Can pass channelId or handle. Provide at least one of: `channelId`, `handle`. | | `handle` | string | no | YouTube channel handle without the @ symbol. Provide at least one of: `channelId`, `handle`. | | `since` | string | no | Only shorts published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Older shorts are left off the page, and the page that reaches one ends the walk: `next_cursor` is not returned and `pagination.stopped_at` is `since`. Pinned shorts sit out of date order and never end the walk. The page still costs what a page costs, so a daily poll pays for the pages it walks and no more. | | `stop_at_id` | string | no | The id (`post.id`) or URL (`post.url`) of the newest short you already hold. The page stops just before it: that short and everything after it are left off, `next_cursor` is not returned, and `pagination.stopped_at` is `known_id`. A pinned short never counts as the stop point. If it is not on this page the page is returned in full with its cursor, so keep walking. `pagination.stopped_at` is `end` when the list ran out first and `null` while there is more to walk. | | `sort` | string | no | Sort by newest (descending publish date) or popular (descending view count). Both orderings are genuinely applied, unlike `/v1/youtube/search`'s `popular`, which is a popularity-weighted ranking rather than a view sort. One of: newest, popular. | | `include` | string | no | Set to `channel` (one token only) to add the channel's subscriber count to every row (`post.ext.author_followers`, YouTube's own figure, rounded to three significant figures above 1,000) plus `post.author.display_name`, `.avatar_url` and `author.id` where missing. Adds well under a second (never more than 8). One of: channel. | | `exact_dates` | string | no | On by default and free: every row is joined to the per-video lookup, one lookup per page (two on a page past 50 rows, side by side), adding about 0.2 to 0.7 seconds (never more than 3). Set to `false` to skip the lookup and keep the listing title, marked by `post.ext.title_maybe_translated`. The dates on this endpoint are exact either way. One of: true, false. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Community Post (/docs/api-reference/youtube/community-post) `GET https://api.insightsocial.app/v1/youtube/community-post` Returns one YouTube community post: its text, like count, comment count, attached images, and author info. Use it when you have a single community post URL; channel/community-posts lists them for a whole channel. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the YouTube community post | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Playlist (/docs/api-reference/youtube/playlist) `GET https://api.insightsocial.app/v1/youtube/playlist` Returns the videos in a playlist in playlist order: video id, title, thumbnail, channel and publish date. include=engagement adds views, likes, comments and duration. Use it when you have a playlist id. Same rows as playlist/items, and the more reliable of the two when availability matters. **Metered: 10–110 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `playlist_id` | string | yes | YouTube playlist ID | | `cursor` | string | no | Pagination cursor from a previous response: fetches the next page. | | `channel_id` | string | no | YouTube channel id: pages that channel's uploads instead of a playlist. | | `include` | string | no | Set to `engagement`, `channel`, or both (`engagement,channel`) to fill more of every row in this one call. `engagement` fills `post.engagement.views`, `.likes` and `.comments`, `post.content.duration_seconds`, `author.id` and `post.author.display_name` where the row lacks them, and replaces a date derived from a label such as "4 months ago" with the exact publish time (removing `post.ext.published_precision`). `channel` puts the channel's subscriber count on `post.ext.author_followers` (YouTube's own figure, which it rounds to three significant figures above 1,000) and fills the channel's `post.author.display_name`, `.avatar_url` and `.username` where missing. Send both to cover rows that arrive without a channel id: the video join supplies it and the channel join then uses it. Each join adds 0.2 to 0.7 seconds on a fresh page (one lookup per 50 ids, never more than 8 seconds). | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Hashtag (/docs/api-reference/youtube/search-hashtag) `GET https://api.insightsocial.app/v1/youtube/search/hashtag` Returns videos posted under a hashtag, each with view count, channel info, and publish date. Use it to read a hashtag feed rather than a keyword query; set type to shorts to limit the results to Shorts. **Metered: 10–110 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `hashtag` | string | yes | Hashtag to search for without the # symbol | | `type` | string | no | Search for all types of content or only shorts One of: all, shorts. | | `include` | string | no | Set to `engagement`, `channel`, or both (`engagement,channel`) to fill more of every row in this one call. `engagement` fills `post.engagement.views`, `.likes` and `.comments`, `post.content.duration_seconds`, `author.id` and `post.author.display_name` where the row lacks them, and replaces a date derived from a label such as "4 months ago" with the exact publish time (removing `post.ext.published_precision`). `channel` puts the channel's subscriber count on `post.ext.author_followers` (YouTube's own figure, which it rounds to three significant figures above 1,000) and fills the channel's `post.author.display_name`, `.avatar_url` and `.username` where missing. Send both to cover rows that arrive without a channel id: the video join supplies it and the channel join then uses it. Each join adds 0.2 to 0.7 seconds on a fresh page (one lookup per 50 ids, never more than 8 seconds). | | `exact_dates` | string | no | Exact publish dates are on by default and free. Set to `false` to skip the lookup: rows then carry YouTube's own date estimate (a day-granular or coarser label truncated to midnight UTC), marked by `post.ext.published_precision` and `post.ext.published_label`, and the listing title, marked by `post.ext.title_maybe_translated`. One of: true, false. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `min_views` | integer | no | Keep only rows with at least this many views (`post.engagement.views`). A row whose view count is unknown is discarded, so every returned row meets the floor. | | `max_age_days` | integer | no | Keep only rows published within this many days (`post.published_at`), 1 to 3650. A row with no date is discarded. | | `sort_rows` | string | no | `views`: return the kept rows ordered by view count, highest first, across every page walked. Rows without a view count go last. One of: views. | | `max_pages` | integer | no | 1 to 5 (default 1). Walk up to this many pages in one call and return the rows from all of them (after any filter). Each page walked is billed as one call to this endpoint; the whole walk counts once against your rate limit. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Shorts › Trending (/docs/api-reference/youtube/shorts-trending) `GET https://api.insightsocial.app/v1/youtube/shorts/trending` Returns the Shorts trending on YouTube right now, each with view count, like count, channel info, and thumbnail. Use it for a snapshot of what is trending in Shorts; videos/trending covers regular videos and can be narrowed by country. **Metered: 50–150 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `include` | string | no | Set to `channel` (one token only) to add each row's channel stats in this one call. `channel` puts the channel's subscriber count on `post.ext.author_followers` (YouTube's own figure, which it rounds to three significant figures above 1,000) and fills the channel's `post.author.display_name`, `.avatar_url` and `.username` where missing. Each join adds 0.2 to 0.7 seconds on a fresh page (one lookup per 50 ids, never more than 8 seconds). One of: channel. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Video › Transcript (/docs/api-reference/youtube/video-transcript) `GET https://api.insightsocial.app/v1/youtube/video/transcript` Returns the spoken transcript of a video as timestamped segments, each with text, start time and duration, plus language, word count, and speech rate. Use it for a single video URL; when the video has no captions the reply is a 404 naming the reason, which is expected rather than a failure. **30 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the YouTube video | | `language` | string | no | Two-letter language code, such as en, es or fr. If no caption track matches the language you specify, the request returns 404 RESOURCE_NOT_FOUND (reason `no_captions`). | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Channel › Playlists (/docs/api-reference/youtube/channel-playlists) `GET https://api.insightsocial.app/v1/youtube/channel/playlists` Returns the playlists on a channel's Playlists tab, each with playlist id, title, thumbnail, video count, channel info, and playlist URL. Use it to discover a channel's playlists, then pass a returned playlist id to playlist or playlist/items to read the videos inside one. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `channelId` | string | no | YouTube channel ID. Provide at least one of: `channelId`, `handle`. | | `handle` | string | no | YouTube channel handle (with or without @). Provide at least one of: `channelId`, `handle`. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Channel › Lives (/docs/api-reference/youtube/channel-lives) `GET https://api.insightsocial.app/v1/youtube/channel/lives` Returns the live and past streams on a channel's Live tab, each with title, URL, thumbnail, view count, publish time, and duration. Use it to track a channel's streaming output; channel/videos returns regular uploads and leaves the Live tab out. **Metered: 10–70 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `channelId` | string | no | YouTube channel ID. Provide at least one of: `channelId`, `handle`. | | `handle` | string | no | YouTube channel handle (with or without @). Provide at least one of: `channelId`, `handle`. | | `include` | string | no | Set to `engagement`, `channel`, or both (`engagement,channel`) to fill more of every row in this one call. `engagement` fills `post.engagement.views`, `.likes` and `.comments`, `post.content.duration_seconds`, `author.id` and `post.author.display_name` where the row lacks them, and replaces a date derived from a label such as "4 months ago" with the exact publish time (removing `post.ext.published_precision`). Each join adds 0.2 to 0.7 seconds on a fresh page (one lookup per 50 ids, never more than 8 seconds). | | `exact_dates` | string | no | Exact publish dates are on by default and free. Set to `false` to skip the lookup: rows then carry YouTube's own date estimate (a day-granular or coarser label truncated to midnight UTC), marked by `post.ext.published_precision` and `post.ext.published_label`, and the listing title, marked by `post.ext.title_maybe_translated`. One of: true, false. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Channel › Community Posts (/docs/api-reference/youtube/channel-community-posts) `GET https://api.insightsocial.app/v1/youtube/channel/community-posts` Returns the posts on a channel's Posts tab, each with post id, URL, text, images, attached video, like count, publish time, and channel info. Use it to read a channel's text and image posts in bulk; community-post fetches one post when you already have its URL. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `channelId` | string | no | YouTube channel ID. Provide at least one of: `channelId`, `handle`. | | `handle` | string | no | YouTube channel handle (with or without @). Provide at least one of: `channelId`, `handle`. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Videos › Trending (/docs/api-reference/youtube/videos-trending) `GET https://api.insightsocial.app/v1/youtube/videos/trending` Returns the trending videos for a country and category, each with title, thumbnail, duration, view, like and comment counts, channel, and publish time. Use it to see what is popular in a given country right now; shorts/trending covers Shorts and takes no filters. **Metered: 10–60 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `region` | string | no | ISO 3166-1 alpha-2 country code (e.g. US, GB, KR). | | `category` | string | no | YouTube video category id (e.g. 10 = Music, 24 = Entertainment). | | `language` | string | no | Localization language (ISO 639-1) for titles/metadata. | | `max_results` | integer | no | Maximum number of videos to return (1-50). | | `cursor` | string | no | Pagination cursor from a previous response: fetches the next page. | | `include` | string | no | Set to `channel` (one token only) to add each row's channel stats in this one call. `channel` puts the channel's subscriber count on `post.ext.author_followers` (YouTube's own figure, which it rounds to three significant figures above 1,000) and fills the channel's `post.author.display_name`, `.avatar_url` and `.username` where missing. Each join adds 0.2 to 0.7 seconds on a fresh page (one lookup per 50 ids, never more than 8 seconds). One of: channel. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Playlist › Items (/docs/api-reference/youtube/playlist-items) `GET https://api.insightsocial.app/v1/youtube/playlist/items` Returns the videos of a playlist in playlist order, each with video id, title, thumbnail, the video's own channel, its publish date, and its position and insertion time on post.ext. Use it when you have a playlist id; add include=engagement for counts and durations. Same rows as playlist, which is the more reliable of the two. **Metered: 10–110 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `playlist_id` | string | yes | YouTube playlist id (the value after `list=` in a playlist URL). | | `cursor` | string | no | Pagination cursor from a previous response: fetches the next page. | | `channel_id` | string | no | YouTube channel id: pages that channel's uploads instead of a playlist. | | `include` | string | no | Set to `engagement`, `channel`, or both (`engagement,channel`) to fill more of every row in this one call. `engagement` fills `post.engagement.views`, `.likes` and `.comments`, `post.content.duration_seconds`, `author.id` and `post.author.display_name` where the row lacks them, and replaces a date derived from a label such as "4 months ago" with the exact publish time (removing `post.ext.published_precision`). `channel` puts the channel's subscriber count on `post.ext.author_followers` (YouTube's own figure, which it rounds to three significant figures above 1,000) and fills the channel's `post.author.display_name`, `.avatar_url` and `.username` where missing. Send both to cover rows that arrive without a channel id: the video join supplies it and the channel join then uses it. Each join adds 0.2 to 0.7 seconds on a fresh page (one lookup per 50 ids, never more than 8 seconds). | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Advanced (/docs/api-reference/youtube/search-advanced) `GET https://api.insightsocial.app/v1/youtube/search/advanced` Returns video search results with the full filter set: sort order, length, live status, license, category, country, language, and publish date window. Use it when a plain keyword search is too blunt; results are always videos, so use search when you also want channels or playlists back. **Metered: 10–110 credits.** We reserve the ceiling when the call starts and charge what it actually used when it finishes. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search query. | | `order` | string | no | Sort order: date, rating, relevance (default), title, videoCount, viewCount. `order=date` is exact (measured: zero inversions against the timestamps). `order=viewCount` is YouTube's popularity-weighted ranking: the top result is the true maximum but mid-list order is approximate, so for exact ranking add `includeExtras=true` and sort the page on `engagement.views` client-side. Both are far more faithful than `/v1/youtube/search`'s `sortBy=popular`, which is not view-ordered at all. | | `duration` | string | no | Video length: short (<4m), medium (4-20m), long (>20m), any. Genuinely applied (unlike `/v1/youtube/search`'s `duration`, which the platform ignores). `short` plus a client-side `post.content.duration_seconds <= 180` filter is the documented Shorts approximation: see the endpoint description for why it is an approximation and not a Shorts filter. | | `event_type` | string | no | Broadcast type: live, upcoming, completed. | | `license` | string | no | License filter: creativeCommon, youtube, any. | | `category` | string | no | YouTube video category id (e.g. 10 = Music). | | `region` | string | no | ISO 3166-1 alpha-2 country code. | | `language` | string | no | Preferred result language (ISO 639-1). | | `published_after` | string | no | RFC-3339 datetime lower bound (e.g. 2026-01-01T00:00:00Z). Exact and genuinely applied. This is the endpoint to use for date-window work. | | `published_before` | string | no | RFC-3339 datetime upper bound. Exact and genuinely applied. | | `channel_id` | string | no | Restrict results to a single channel id. | | `max_results` | integer | no | Maximum number of videos to return (1-50). Honored exactly: a page of 50 returns 50. | | `cursor` | string | no | Pagination cursor from a previous response: fetches the next page. | | `safe_search` | string | no | Safe-search filter: none, moderate, strict. | | `video_caption` | string | no | Caption filter: any, closedCaption, none. | | `video_definition` | string | no | Quality filter: any, high, standard. | | `video_dimension` | string | no | Dimension filter: 2d, 3d, any. | | `video_embeddable` | string | no | Restrict to embeddable videos: true, any. | | `video_type` | string | no | Type filter: any, episode, movie. | | `topic_id` | string | no | Restrict to a Freebase topic id (e.g. /m/04rlf for music). | | `location` | string | no | Latitude,longitude center for a geo search (e.g. 37.42307,-122.08427). Must be used together with location_radius. | | `location_radius` | string | no | Radius around location with a unit suffix (e.g. 50km, 10mi). Must be used together with location. | | `includeExtras` | string | no | Set to `true` to add the view, like and comment counts (`post.engagement.views` / `.likes` / `.comments`) and the video length (`post.content.duration_seconds`) to every result. Left off, those four are null. YouTube's search index returns snippets only, so the counts come from a second lookup. | | `include` | string | no | Set to `channel` (one token only) to add each row's channel stats in this one call. `channel` puts the channel's subscriber count on `post.ext.author_followers` (YouTube's own figure, which it rounds to three significant figures above 1,000) and fills the channel's `post.author.display_name`, `.avatar_url` and `.username` where missing. Each join adds 0.2 to 0.7 seconds on a fresh page (one lookup per 50 ids, never more than 8 seconds). One of: channel. | | `since` | string | no | Only rows published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Rows older than it are left off each page. This list is not in date order, so the walk does not stop at the date: keep following `next_cursor`, and each page costs what a page costs even when every row on it is filtered out. A row with no date is kept. | | `until` | string | no | Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. | | `min_views` | integer | no | Keep only rows with at least this many views (`post.engagement.views`). A row whose view count is unknown is discarded, so every returned row meets the floor. | | `max_age_days` | integer | no | Keep only rows published within this many days (`post.published_at`), 1 to 3650. A row with no date is discarded. | | `sort_rows` | string | no | `views`: return the kept rows ordered by view count, highest first, across every page walked. Rows without a view count go last. One of: views. | | `max_pages` | integer | no | 1 to 5 (default 1). Walk up to this many pages in one call and return the rows from all of them (after any filter). Each page walked is billed as one call to this endpoint; the whole walk counts once against your rate limit. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Suggestions (/docs/api-reference/youtube/search-suggestions) `GET https://api.insightsocial.app/v1/youtube/search/suggestions` Returns the autocomplete suggestions YouTube's own search box shows for a partial query, as a plain list of strings. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it for keyword research, or to expand a seed term before running search or search/advanced. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Partial search query to autocomplete. | | `region` | string | no | ISO 3166-1 alpha-2 country code to localize suggestions. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Video › Audio (/docs/api-reference/youtube/video-audio) `GET https://api.insightsocial.app/v1/youtube/video/audio` Returns the downloadable audio streams for a video, each with a direct media URL, mime type, bitrate, audio quality, sample rate, channels, and duration. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it to grab a video's audio on its own; the URLs are time-limited, so fetch them straight away rather than storing them. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the YouTube video. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Video › Files (/docs/api-reference/youtube/video-files) `GET https://api.insightsocial.app/v1/youtube/video/files` Returns the downloadable video streams for a video, each with a direct media URL, mime type, resolution, quality label, frame rate, bitrate, and duration. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it when you need the video file itself; video/audio returns audio-only streams and video/thumbnails returns still images. **50 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the YouTube video. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Video › Subtitles (/docs/api-reference/youtube/video-subtitles) `GET https://api.insightsocial.app/v1/youtube/video/subtitles` Returns the caption track files for a video, each with a language code and name, file format, and a direct download URL, including auto-generated tracks. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it when you want subtitle files to download; video/transcript gives you the words themselves, already split into timed segments. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the YouTube video. | | `format` | string | no | Subtitle file format filter (e.g. srt, vtt, ttml, json3, srv1). | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Video › Thumbnails (/docs/api-reference/youtube/video-thumbnails) `GET https://api.insightsocial.app/v1/youtube/video/thumbnails` Returns a video's thumbnail images at every available size, each with a direct image URL, width, height, aspect ratio, and image format. **Beta.** The source's own structure under our naming rules (snake_case keys, string ids, ISO times where the source gives a timestamp), not one of the schema-2 entities. Fields may change. See [Schema 2](/docs/schema-2). Use it when you need a video's artwork on its own, for example to pick the largest image for your own listing or preview. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Full URL of the YouTube video. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile › Full (/docs/api-reference/youtube/profile-full) `GET https://api.insightsocial.app/v1/youtube/profile/full` Returns a channel's profile and up to 30 recent videos in one call. Use it instead of calling channel and channel/videos yourself; if the videos cannot be fetched you still get the profile. **Beta.** A composite: `data.profile` is a schema-2 Profile and `data.posts[].post` are schema-2 Posts, and the posts page with `cursor`. The rest of `data` is the source's own structure under our naming rules (snake_case keys, string ids). Fields outside the profile and posts may change. See [Schema 2](/docs/schema-2). **50 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | no | YouTube username or handle, with or without a leading @. One of the identity params is required. Provide at least one of: `handle`, `channelId`, `url`. | | `channelId` | string | no | YouTube channel id, the 24-character string starting with UC. One of the identity params is required. Provide at least one of: `handle`, `channelId`, `url`. | | `url` | string | no | Full YouTube profile or page URL. One of the identity params is required. Provide at least one of: `handle`, `channelId`, `url`. | | `posts` | integer | no | How many of the fetched recent posts to return and compute the metrics over (1-100, default 25). | | `cursor` | string | no | Pass a prior response's posts_cursor to read the next page of posts. | | `include` | string | no | | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Answer (/docs/api-reference/zhihu/answer) `GET https://api.insightsocial.app/v1/zhihu/answer` Returns one Zhihu answer: its text, author, the question it answers and its publish and update times. Use it when you have an answer id; for every answer to a question use question/answers. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `answer_id` | string | yes | Zhihu answer id (zhihu.com/answer/). | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Question (/docs/api-reference/zhihu/question) `GET https://api.insightsocial.app/v1/zhihu/question` Returns a Zhihu question: its title, views, comments, answer and follower counts, and when it was asked. Use it to size a question; to read what people answered use question/answers. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `question_id` | string | yes | Zhihu question id (zhihu.com/question/). | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Question › Answers (/docs/api-reference/zhihu/question-answers) `GET https://api.insightsocial.app/v1/zhihu/question/answers` Returns up to 20 answers to a question, each with its text, author, votes, comments, saves and times. Use it to read a question’s top or newest answers; for one answer by id use answer. It returns one page. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `question_id` | string | yes | Zhihu question id (zhihu.com/question/). | | `limit` | integer | no | Answers to return, 1 to 20. Default 5. | | `order` | string | no | default (Zhihu’s ranking) or updated (recently updated first). One of: default, updated. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Profile (/docs/api-reference/zhihu/profile) `GET https://api.insightsocial.app/v1/zhihu/profile` Returns a public Zhihu account: name, headline, avatar, follower count, and how many answers and articles it wrote. Use it when you have the handle from a zhihu.com/people/ URL. **10 credits** per call. Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `handle` | string | yes | The handle in the profile URL, zhihu.com/people/. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Search › Articles (/docs/api-reference/zhihu/search-articles) `GET https://api.insightsocial.app/v1/zhihu/search/articles` Returns Zhihu column articles matching a keyword, each with title, text, author, votes and comments. Use it to find long-form writing on a topic. **10 credits** per call. Paginates by `cursor`: see [Pagination](https://www.insightsocial.app/docs/pagination). Send your key in the `x-api-key` header. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | yes | Search keyword. | | `sort` | string | no | upvoted_count (most upvoted) or created_time (newest). Omit for Zhihu’s own ranking. One of: upvoted_count, created_time. | | `time_interval` | string | no | Only articles published within this window. One of: a_day, a_week, a_month, three_months, half_a_year, a_year. | | `limit` | integer | no | Articles per page, 1 to 20. Default 20. | | `cursor` | string | no | The `pagination.next_cursor` from the previous page, sent back unchanged. Omit it for the first page. | | `dry_run` | string | no | Set to 1 to get the price of this call without making it: data.dry_run carries credits_min and credits_max. Nothing is charged. One of: 1. | --- # Credits (/docs/api-reference/account/credits) `GET https://api.insightsocial.app/v1/credits` The calling key owner's balance and this period's usage. Free. Send your key in the `x-api-key` header. --- # Endpoints (/docs/api-reference/account/endpoints) `GET https://api.insightsocial.app/v1/endpoints` This catalogue, with per-endpoint prices. Free, and needs no key. Send your key in the `x-api-key` header. --- # OpenAPI (/docs/api-reference/account/openapi.json) `GET https://api.insightsocial.app/v1/openapi.json` The OpenAPI 3.1 spec for every endpoint, for generating clients and agent tools. Free, and needs no key. Send your key in the `x-api-key` header.