hooks.social

TikTok, Instagram, and TikTok Shop data over one simple API. A fresh response that returns data spends prepaid credits. A cached response is free. A failed response is free. Credits do not expire.

Base URL: https://api.hooks.social. Machine-readable contract: /openapi.json. Service status: /status.

Authentication

Send Authorization: Bearer hk_live_… and a User-Agent. The key is shown once, from POST /v1/keys or when you sign up.

Send a User-Agent. curl and browser agents already do. python3 -c and urllib.request need a header such as hooks-social.

Envelope

{
  "data": {},
  "error": null,
  "meta": {
    "credits": 1,
    "cached": false,
    "latency_ms": 840,
    "request_id": "…"
  }
}

Endpoints

MethodPathQuery
GET/v1/tiktok/profileusername
GET/v1/tiktok/videoid or url
GET/v1/tiktok/postsusername, cursor, count (max 15)
GET/v1/tiktok/commentsvideo_id, cursor, count
GET/v1/tiktok/comments/repliesvideo_id, comment_id, cursor, count
GET/v1/tiktok/search/videosq, cursor, search_id, count
GET/v1/tiktok/search/usersq, cursor, search_id
GET/v1/tiktok/hashtagname
GET/v1/tiktok/hashtag/videosid or name, cursor, count
GET/v1/tiktok/soundid
GET/v1/tiktok/sound/videosid, cursor, count
GET/v1/tiktokshop/productid or url, and market (us, uk, de, fr, it, es, ie). 1 credit only when the product has a title and a price.
GET/v1/tiktokshop/searchq, market. 1 credit only when at least one card has an id and a title.
GET/v1/tiktokshop/storeid or url, market. 1 credit only when the shop has a name or at least one card with an id and a title.
GET/v1/tiktokshop/trendingrank (sold, rising, new), days (1, 7, 30), category, trend, limit. US. Best sellers, fastest risers and new products, with units and estimated revenue. 1 credit when products come back.
GET/v1/instagram/profileusername. full_name, avatar_url (HD when present), and verified are null when the source omitted them. items are the timeline plus the first Reels page.
GET/v1/instagram/postshortcode or url. Likes, comments, taken_at; play_count for a recent Reel
GET/v1/instagram/commentsshortcode, cursor
GET/v1/instagram/postsusername, cursor. Every post: likes, comments, taken_at; videos add view_count, and play_count on page 1. Shares and saves are visible only to the owner
GET/v1/instagram/reelsusername, cursor. play_count, likes, comments, taken_at
GET/v1/instagram/audio/reelsaudio_id, cursor
GET/v1/instagram/relatedusername
GET/v1/instagram/searchq (two or more words work best), cursor
GET/v1/youtube/playerid or url. A video that can't be read costs 0.
GET/v1/youtube/transcriptid or url. An empty transcript costs 0.
GET/v1/mebalance, timezone, and email settings for this key
GET/v1/demo/:platform/profilehandle. No key. Profile and recent posts. 20 per visitor per UTC day.
GET/v1/demo/:platform/commentshandle, post. No key. Top comments on a post from a lookup. 5 per visitor per UTC day.
POST/v1/keysJSON name. Returns the full key once.
GET/v1/keysprefix, name, created, last used
DELETE/v1/keys/:idrevoke
GET/v1/ledgercursor, or format=csv
POST/v1/checkoutJSON pack: starter, builder, or scale
GET/v1/resolveurl
GET/v1/watchlistchecked at 06:00 in the account timezone
GET, POST/v1/snapshotshistory is free. A capture costs 1 credit for a fresh profile and 1 for fresh posts. A cache hit is free. A profile or posts response with meta.degraded or meta.credits 0 is free. A degraded profile is still stored. Instagram averages use the merged profile items and skip nulls.
GET/v1/snapshots/:idone stored snapshot, free
GET/v1/compareplatform+handle, or accounts=tiktok:nasa,instagram:nike. Free.
GET/v1/exports/postsCSV or JSON from a stored snapshot. Free.
GET/v1/exports/snapshotssnapshot history. Free.
GET/v1/exports/comparecompare result. Free.
GET/v1/exports/boards/:idboard spreadsheet. Free.
GET, POST/v1/boardsnamed collections of TikTok and Instagram accounts. Free.
POST/v1/boards/:id/refreshsnapshot every account. Up to 2 credits each. A cache hit is free. A degraded profile or posts response is free.
GET, POST/v1/automationsdaily or weekly refresh. Free to save. A run costs up to 2 credits per account. A cache hit is free. A degraded profile or posts response is free.

TikTok Shop

Shop routes return the numbers on the page. A field that was not there is JSON null. A real zero stays zero. discount is a percent string such as 53% only when the original price is higher than the sale price. Reviewer names are the masked strings already shown. Creator videos are not included.

market is required: us, uk, de, fr, it, es, or ie. US and UK are served. DE, FR, IT, ES, and IE are not available: the call returns not_supported_market immediately and costs nothing. A fresh product costs 1 credit only when it has a title and a price. Search costs 1 credit only when at least one card has an id and a title. A store costs 1 credit only when it has a shop name or one such card. Anything else is free and is not cached. A response served from cache is free. UK store and search can also return not_supported_market when that page is not available.

curl -H "Authorization: Bearer hk_live_…" \
  "https://api.hooks.social/v1/tiktokshop/product?id=1729495699318543725&market=us"

curl -H "Authorization: Bearer hk_live_…" \
  "https://api.hooks.social/v1/tiktokshop/search?q=phone%20case&market=us"

curl -H "Authorization: Bearer hk_live_…" \
  "https://api.hooks.social/v1/tiktokshop/store?id=7494313903714501997&market=us"

A daily watch on a product stores sold_count. Add it with platform tiktokshop and handle us:1729495699318543725, or the shop product URL. Boards and automations cover TikTok and Instagram accounts.

Instagram media fields

Profile, posts, and reels return the same media object. likes, comments, view_count, play_count, and taken_at are JSON null when the number isn't available. They are not zero unless the count really is zero. views repeats view_count. plays repeats play_count.

A profile lookup returns the bio, avatar, follower counts, verified flag, external URL, post count and recent posts and reels. A profile read is reused for 2 minutes, so a snapshot's posts call doesn't pay twice.

YouTube

GET /v1/youtube/player and GET /v1/youtube/transcript take id or a video URL. A video that is unavailable costs 0. A playable player or a non-empty transcript costs 1 credit. They are also MCP tools.

GET /v1/youtube/search?q= searches videos, with optional period (today, week, month or year) and sort=popular. GET /v1/youtube/channel?handle=@name (or id=UC…) lists a channel's latest uploads with views and dates. 1 credit when videos come back.

What is working now

GET /v1/tiktok/viral?q=&days=7 returns the most viewed videos about a topic or hashtag from the last 1, 7 or 30 days. GET /v1/tiktok/trends?q=&days=7 returns the sounds, hashtags and creators that show up most in recent videos for a niche, or for the whole platform when q is empty, weighted by views; licensed sounds include how many TikTok videos use them. 1 credit each.

Ads

GET /v1/meta/ads?q=brand (or page_id=, optional country=) returns active ads from the Meta Ad Library: copy, headline, call to action, link, format, platforms and start date, grouped by advertiser with the matching brand first. 1 credit when ads come back.

A fresh response with counts costs 1 credit. A response served from cache costs nothing. When a response comes back without any counts, it is marked degraded: true and costs nothing. Posts pages after the first still cost 1 even though those counts are null. A snapshot of a degraded profile is still stored and marked degraded. Other failures are free.

MCP

The API is also an MCP server at https://api.hooks.social/mcp (Streamable HTTP), with a tool for every TikTok, Instagram, TikTok Shop, YouTube and Meta ads data endpoint (including viral, trends, YouTube search and channels), plus get_balance, watchlist_list, watchlist_add, watchlist_changes, snapshot_capture, snapshot_history and compare_accounts. A tool costs the same as the HTTP call: a fresh success spends credits, and cache hits and failed calls are free. Boards, exports and automations are HTTP only. Tool answers leave out image and video links unless a call sets include_media.

Tools that send headers: Authorization: Bearer hk_live_…. For example claude mcp add --transport http hooks https://api.hooks.social/mcp --header "Authorization: Bearer $HOOKS_KEY".

Chat apps that only take a URL (ChatGPT, Claude): use the private link https://api.hooks.social/mcp/hk_live_…. Make a separate key for it, so you can revoke the link without touching your code.

Credits and limits

Errors

Errors come back in error with a code and a plain message: invalid_request, unauthorized, no_credits (402), rate_limited (429), not_found, private, not_supported_market when a TikTok Shop page is not served for that market, and unavailable when data couldn't be fetched this time. None of them cost credits.