SDKs

Typed methods for every endpoint, with retries, pagination and errors built in.

SocialTap is the social media scraper API for developers and AI agents. Send a public link, a handle or a search and get live data back in one schema. Failed requests are free.

The TypeScript SDK for the SocialTap API: a method for every endpoint, typed models and errors, retries and pagination. Generated from the SocialTap catalog (version 1.509.29). Docs: https://socialtap.dev/docs.

Install

Shell
npm install socialtap
npm pkg set type=module   # the examples are ES modules (or name your file .mjs or .mts)

Zero runtime dependencies (fetch); Node 20.3+, Deno, Bun and Cloudflare Workers (server-side: the API key is a secret). ESM only: in Node, your project needs "type": "module" in its package.json (the second command above) or a .mjs/.mts file, else Node stops at the first import ("Cannot use import statement outside a module"). Run TypeScript directly with Node 22.18+ (node app.ts) or npx tsx app.ts. Params and models use the API's snake_case names; SDK objects (options, credits, errors) are camelCase.

null means unknown. With fields, results are typed PartialModel<T> (every member may be absent). A 2xx that is not the API's envelope (no data, not JSON) throws APIDecodeError; a retry-after longer than MAX_RETRY_AFTER_S throws RetryAfterExceededError instead of retrying early. Results keep the API's objects as sent, members this version doesn't model included. Event is a union narrowed by type; a job item's params are typed by its endpoint.

Authenticate

The client reads your API key from SOCIALTAP_API_KEY, or takes it as an option. Requests send it in the x-api-key header. Get a key at https://socialtap.dev/signup/: every account starts with 100 free credits.

First call: Exact follower and like counts, bio and country

TypeScript
import { SocialTap } from "socialtap";

const client = new SocialTap(); // apiKey defaults to process.env.SOCIALTAP_API_KEY

const res = await client.tiktok.profile.get({ handle: "nasa" });
console.log(res.data);
console.log(res.credits.charged, res.meta.request_id);

data is a Profile (example response, truncated):

JSON
{
  "approximate_fields": [],
  "avatar_url": "https://p19-common-sign.tiktokcdn-us.com/tos-useast5-avt-0068-tx/e5143212a59c09a008bf50f487d54d1f~tplv-tiktokx-cropcenter:1080:1080.jpeg?dr=9640\u0026refresh_token=29840d4e\u0026x-expires=4070908800\u0026x-signature=SCRUBBED\u0026t=4d5b0474\u0026ps=13740610\u0026shp=a5d48078\u0026shcp=81f88b70\u0026idc=useast5",
  "banner_url": null,
  "bio": "Making the seemingly impossible, possible.✨",
  "category": null,
  "country_code": "US",
  "created_at": "2026-07-20T15:55:49Z",
  "display_name": "NASA",
  "external_links": [
    {
      "title": null,
      "url": "https://science.nasa.gov/feature/artemis-ii-preliminary-lunar-science-report"
    }
  ],
  "id": "7664638705177150477",
  "is_private": false,
  "is_verified": true,
  "location": null,
  "metrics": {
    "follower_count": 2152843,
    "following_count": 23,
    "post_count": 62,
    "total_like_count": 11486661,
    "total_view_count": null
  },
  "platform": "tiktok",
  "platform_specific": {
    "tiktok": {
      "display_name_changed_at": "2026-07-20T15:58:00Z",
      "friend_count": 17,
      "is_business_account": false,
      "is_shop_seller": false,
      "language": "en",
      "liked_post_count": null,
      "sec_uid": "MS4wLjABAAAAU9BRVzC8oCaegVnia8IbqWhPb_-dbU7s00Y3wS1_Nx8g5RUaYvyXrpejgjdxTwd6"
    }
  },
  "type": "organization",
  "unknown_fields": [],
  "url": "https://www.tiktok.com/@nasa",
  "username": "nasa"
}

Every result also carries the envelope meta (request ID, source, cache status, fetch time) and credits (charged by this request, and the balance after it when the API reports it). Failed requests and cache hits are free.

Endpoints

endpointmethodcost
amazon.deal_productsclient.amazon.dealProducts.list()1 credit
amazon.offersclient.amazon.offers.list()1 credit
amazon.productclient.amazon.product.get()1 credit
amazon.reviewsclient.amazon.reviews.list()1 credit
amazon.search_productsclient.amazon.searchProducts.list()1 credit
amazon.sellerclient.amazon.seller.get()1 credit
amazon.shopclient.amazon.shop.get()1 credit
amazon.shop_listsclient.amazon.shopLists.list()1 credit
amazon.shop_postsclient.amazon.shopPosts.list()1 credit
amazon.top_productsclient.amazon.topProducts.list()1 credit
applemusic.albumclient.applemusic.album.get()1 credit
applemusic.artistclient.applemusic.artist.get()1 credit
applemusic.search_albumsclient.applemusic.searchAlbums.list()1 credit
applemusic.search_artistsclient.applemusic.searchArtists.list()1 credit
applemusic.search_playlistsclient.applemusic.searchPlaylists.list()1 credit
applemusic.search_tracksclient.applemusic.searchTracks.list()1 credit
applemusic.top_albumsclient.applemusic.topAlbums.list()1 credit
applemusic.top_playlistsclient.applemusic.topPlaylists.list()1 credit
applemusic.top_tracksclient.applemusic.topTracks.list()1 credit
applemusic.trackclient.applemusic.track.get()1 credit
bluesky.commentsclient.bluesky.comments.list()1 credit
bluesky.postclient.bluesky.post.get()1 credit
bluesky.postsclient.bluesky.posts.list()1 credit
bluesky.profileclient.bluesky.profile.get()1 credit
bluesky.search_postsclient.bluesky.searchPosts.list()1 credit
facebook.adclient.facebook.ad.get()1 credit
facebook.ad_transcriptclient.facebook.adTranscript.get()2 credits + 2 per started minute of media
facebook.adsclient.facebook.ads.list()1 credit
facebook.commentsclient.facebook.comments.list()1 credit
facebook.engagementclient.facebook.engagement.get()1 credit
facebook.eventclient.facebook.event.get()1 credit
facebook.eventsclient.facebook.events.list()1 credit
facebook.groupclient.facebook.group.get()1 credit
facebook.group_postsclient.facebook.groupPosts.list()1 credit
facebook.listingclient.facebook.listing.get()1 credit
facebook.photosclient.facebook.photos.list()1 credit
facebook.place_eventsclient.facebook.placeEvents.list()1 credit
facebook.postclient.facebook.post.get()1 credit
facebook.postsclient.facebook.posts.list()1 credit
facebook.profileclient.facebook.profile.get()1 credit
facebook.reelsclient.facebook.reels.list()1 credit
facebook.repliesclient.facebook.replies.list()1 credit
facebook.search_adsclient.facebook.searchAds.list()1 credit
facebook.search_advertisersclient.facebook.searchAdvertisers.list()1 credit
facebook.search_eventsclient.facebook.searchEvents.list()1 credit
facebook.search_groupsclient.facebook.searchGroups.list()1 credit + 1 per result filled in
facebook.search_listingsclient.facebook.searchListings.list()1 credit
facebook.search_placesclient.facebook.searchPlaces.list()1 credit
facebook.search_postsclient.facebook.searchPosts.list()1 credit + 1 per result filled in
facebook.search_profilesclient.facebook.searchProfiles.list()1 credit + 1 per result filled in
facebook.transcriptclient.facebook.transcript.get()1 credit (captions) or 2 credits + 2 per started minute of media (speech-to-text)
google.adclient.google.ad.get()1 credit
google.adsclient.google.ads.list()1 credit
google.advertiserclient.google.advertiser.get()1 credit
google.search_adsclient.google.searchAds.list()1 credit
google.search_advertisersclient.google.searchAdvertisers.list()1 credit
google.search_suggestionsclient.google.searchSuggestions.list()1 credit
instagram.commentclient.instagram.comment.get()1 credit
instagram.commentsclient.instagram.comments.list()1 credit
instagram.embedclient.instagram.embed.get()1 credit
instagram.engagementclient.instagram.engagement.get()1 credit
instagram.hashtagclient.instagram.hashtag.get()1 credit
instagram.hashtag_postsclient.instagram.hashtagPosts.list()1 credit
instagram.highlightsclient.instagram.highlights.list()1 credit
instagram.placeclient.instagram.place.get()1 credit
instagram.place_postsclient.instagram.placePosts.list()1 credit
instagram.playlist_storiesclient.instagram.playlistStories.list()1 credit
instagram.postclient.instagram.post.get()1 credit
instagram.postsclient.instagram.posts.list()1 credit
instagram.profileclient.instagram.profile.get()1 credit
instagram.reelsclient.instagram.reels.list()1 credit
instagram.search_hashtagsclient.instagram.searchHashtags.list()1 credit
instagram.search_placesclient.instagram.searchPlaces.list()1 credit + 1 per result filled in
instagram.search_postsclient.instagram.searchPosts.list()1 credit
instagram.search_profilesclient.instagram.searchProfiles.list()1 credit + 1 per result filled in
instagram.search_soundsclient.instagram.searchSounds.list()1 credit + 1 per result filled in
instagram.search_suggestionsclient.instagram.searchSuggestions.list()1 credit
instagram.similar_profilesclient.instagram.similarProfiles.list()1 credit
instagram.soundclient.instagram.sound.get()1 credit
instagram.sound_postsclient.instagram.soundPosts.list()1 credit
instagram.storyclient.instagram.story.get()1 credit
instagram.topicclient.instagram.topic.get()1 credit
instagram.transcriptclient.instagram.transcript.get()1 credit (captions) or 2 credits + 2 per started minute of media (speech-to-text)
instagram.trending_postsclient.instagram.trendingPosts.list()1 credit
instagram.usernameclient.instagram.username.get()1 credit
kick.postclient.kick.post.get()1 credit
kick.transcriptclient.kick.transcript.get()2 credits + 2 per started minute of media
komi.pageclient.komi.page.get()1 credit
kwai.postclient.kwai.post.get()1 credit
kwai.postsclient.kwai.posts.list()1 credit
kwai.profileclient.kwai.profile.get()1 credit
linkbio.profileclient.linkbio.profile.get()1 credit
linkedin.adclient.linkedin.ad.get()1 credit
linkedin.postclient.linkedin.post.get()1 credit
linkedin.profileclient.linkedin.profile.get()1 credit (public page or web search) or 5 credits (data partner)
linkedin.search_adsclient.linkedin.searchAds.list()1 credit
linkedin.search_postsclient.linkedin.searchPosts.list()1 credit + 1 per result filled in
linkedin.search_profilesclient.linkedin.searchProfiles.list()1 credit + 1 per result filled in
linkme.profileclient.linkme.profile.get()1 credit
linktree.profileclient.linktree.profile.get()1 credit
pillar.pageclient.pillar.page.get()1 credit
pinterest.boardclient.pinterest.board.get()1 credit
pinterest.board_pinsclient.pinterest.boardPins.list()1 credit
pinterest.boardsclient.pinterest.boards.list()1 credit
pinterest.pinclient.pinterest.pin.get()1 credit
pinterest.pinsclient.pinterest.pins.list()1 credit
pinterest.profileclient.pinterest.profile.get()1 credit
pinterest.search_pinsclient.pinterest.searchPins.list()1 credit
pinterest.top_trendsclient.pinterest.topTrends.list()1 credit
pinterest.topicclient.pinterest.topic.get()1 credit
pinterest.web_pageclient.pinterest.webPage.get()1 credit
reddit.commentsclient.reddit.comments.list()1 credit
reddit.engagementclient.reddit.engagement.get()1 credit
reddit.postclient.reddit.post.get()1 credit
reddit.postsclient.reddit.posts.list()1 credit
reddit.profileclient.reddit.profile.get()1 credit
reddit.profile_commentsclient.reddit.profileComments.list()1 credit
reddit.search_commentsclient.reddit.searchComments.list()1 credit
reddit.search_postsclient.reddit.searchPosts.list()1 credit
reddit.search_profilesclient.reddit.searchProfiles.list()1 credit
reddit.search_subredditsclient.reddit.searchSubreddits.list()1 credit
reddit.subredditclient.reddit.subreddit.get()1 credit
reddit.subreddit_postsclient.reddit.subredditPosts.list()1 credit
reddit.transcriptclient.reddit.transcript.get()1 credit (captions) or 2 credits + 2 per started minute of media (speech-to-text)
rumble.commentsclient.rumble.comments.list()1 credit
rumble.engagementclient.rumble.engagement.get()1 credit
rumble.postclient.rumble.post.get()1 credit
rumble.postsclient.rumble.posts.list()1 credit
rumble.profileclient.rumble.profile.get()1 credit
rumble.search_postsclient.rumble.searchPosts.list()1 credit
rumble.transcriptclient.rumble.transcript.get()1 credit (captions) or 2 credits + 2 per started minute of media (speech-to-text)
snapchat.commentsclient.snapchat.comments.list()1 credit
snapchat.profileclient.snapchat.profile.get()1 credit
snapchat.spotlightclient.snapchat.spotlight.get()1 credit
soundcloud.artistclient.soundcloud.artist.get()1 credit
soundcloud.trackclient.soundcloud.track.get()1 credit
soundcloud.tracksclient.soundcloud.tracks.list()1 credit
spotify.albumclient.spotify.album.get()1 credit
spotify.artistclient.spotify.artist.get()1 credit
spotify.playlistclient.spotify.playlist.get()1 credit
spotify.playlist_tracksclient.spotify.playlistTracks.list()1 credit
spotify.podcastclient.spotify.podcast.get()1 credit
spotify.podcast_episodesclient.spotify.podcastEpisodes.list()1 credit
spotify.search_albumsclient.spotify.searchAlbums.list()1 credit
spotify.search_artistsclient.spotify.searchArtists.list()1 credit
spotify.search_playlistsclient.spotify.searchPlaylists.list()1 credit
spotify.search_podcastsclient.spotify.searchPodcasts.list()1 credit
spotify.search_tracksclient.spotify.searchTracks.list()1 credit
spotify.trackclient.spotify.track.get()1 credit
telegram.channelclient.telegram.channel.get()1 credit
telegram.channel_postsclient.telegram.channelPosts.list()1 credit
telegram.postclient.telegram.post.get()1 credit
telegram.search_channelsclient.telegram.searchChannels.list()1 credit + 1 per result filled in
threads.commentsclient.threads.comments.list()1 credit
threads.postclient.threads.post.get()1 credit
threads.postsclient.threads.posts.list()1 credit
threads.profileclient.threads.profile.get()1 credit
threads.search_postsclient.threads.searchPosts.list()1 credit
threads.search_profilesclient.threads.searchProfiles.list()1 credit
tiktok.adclient.tiktok.ad.get()1 credit
tiktok.commentclient.tiktok.comment.get()1 credit
tiktok.commentsclient.tiktok.comments.list()1 credit
tiktok.downloadclient.tiktok.download.get()1 credit
tiktok.effectclient.tiktok.effect.get()1 credit
tiktok.effect_postsclient.tiktok.effectPosts.list()1 credit
tiktok.engagementclient.tiktok.engagement.get()1 credit
tiktok.followersclient.tiktok.followers.list()1 credit
tiktok.followingclient.tiktok.following.list()1 credit
tiktok.hashtagclient.tiktok.hashtag.get()1 credit
tiktok.hashtag_postsclient.tiktok.hashtagPosts.list()1 credit
tiktok.liked_postsclient.tiktok.likedPosts.list()1 credit
tiktok.liveclient.tiktok.live.get()1 credit
tiktok.place_postsclient.tiktok.placePosts.list()1 credit
tiktok.playlist_postsclient.tiktok.playlistPosts.list()1 credit
tiktok.playlistsclient.tiktok.playlists.list()1 credit
tiktok.postclient.tiktok.post.get()1 credit
tiktok.postsclient.tiktok.posts.list()1 credit
tiktok.profileclient.tiktok.profile.get()1 credit
tiktok.repliesclient.tiktok.replies.list()1 credit
tiktok.search_adsclient.tiktok.searchAds.list()1 credit
tiktok.search_hashtagsclient.tiktok.searchHashtags.list()1 credit + 1 per result filled in
tiktok.search_postsclient.tiktok.searchPosts.list()1 credit
tiktok.search_profilesclient.tiktok.searchProfiles.list()1 credit + 1 per result filled in
tiktok.search_soundsclient.tiktok.searchSounds.list()1 credit + 1 per result filled in
tiktok.search_suggestionsclient.tiktok.searchSuggestions.list()1 credit
tiktok.search_topclient.tiktok.searchTop.list()1 credit + 1 per result filled in
tiktok.soundclient.tiktok.sound.get()1 credit
tiktok.sound_postsclient.tiktok.soundPosts.list()1 credit
tiktok.top_adsclient.tiktok.topAds.list()1 credit
tiktok.top_postsclient.tiktok.topPosts.list()1 credit
tiktok.transcriptclient.tiktok.transcript.get()1 credit (captions) or 2 credits + 2 per started minute of media (speech-to-text)
tiktok.trending_hashtagsclient.tiktok.trendingHashtags.list()1 credit
tiktok.trending_postsclient.tiktok.trendingPosts.list()1 credit
tiktokshop.productclient.tiktokshop.product.get()1 credit
tiktokshop.productsclient.tiktokshop.products.list()1 credit
tiktokshop.reviewsclient.tiktokshop.reviews.list()1 credit
tiktokshop.search_productsclient.tiktokshop.searchProducts.list()1 credit
truthsocial.postclient.truthsocial.post.get()1 credit
truthsocial.postsclient.truthsocial.posts.list()1 credit
truthsocial.profileclient.truthsocial.profile.get()1 credit
twitch.profileclient.twitch.profile.get()1 credit
twitch.scheduleclient.twitch.schedule.list()1 credit
twitch.transcriptclient.twitch.transcript.get()2 credits + 2 per started minute of media
twitch.videoclient.twitch.video.get()1 credit
twitch.videosclient.twitch.videos.list()1 credit
x.communityclient.x.community.get()1 credit
x.postclient.x.post.get()1 credit
x.profileclient.x.profile.get()1 credit
x.search_communitiesclient.x.searchCommunities.list()1 credit + 1 per result filled in
x.search_hashtagsclient.x.searchHashtags.list()1 credit
x.search_postsclient.x.searchPosts.list()1 credit + 1 per result filled in
x.search_profilesclient.x.searchProfiles.list()1 credit + 1 per result filled in
youtube.commentsclient.youtube.comments.list()1 credit
youtube.engagementclient.youtube.engagement.get()1 credit
youtube.postclient.youtube.post.get()1 credit
youtube.postsclient.youtube.posts.list()1 credit
youtube.profileclient.youtube.profile.get()1 credit
youtube.transcriptclient.youtube.transcript.get()1 credit (captions) or 2 credits + 2 per started minute of media (speech-to-text)

Endpoints newer than this package

A version has a method for every endpoint the API had when it was released. For a newer one, update the package, or send the request yourself: the raw request adds your key and retries and raises errors like a method, and returns the status, headers and body (the envelope, data and meta). Each endpoint's docs page has its path and params.

TypeScript
const res = await client.request({ method: "GET", path: "/v1/tiktok/profile", query: { handle: "nasa" } });
console.log(res.status, res.body);

Errors

Every API error is an APIError subclass named after its code, with status, code, retryable, remediation, requestId and creditsCharged (0: errors are free). Codes this SDK version doesn't know arrive as a plain APIError with their code; no response at all is an APIConnectionError (APITimeoutError for timeouts).

TypeScript
import { APIError, NotFoundError } from "socialtap";

try {
  await client.tiktok.profile.get({ handle: "nasa" });
} catch (err) {
  if (err instanceof NotFoundError) {
    // Check the link or ID. Do not retry.
  } else if (err instanceof APIError) {
    console.error(err.code, err.status, err.retryable, err.remediation, err.requestId);
  } else throw err;
}
codeclassstatusretried
invalid_inputInvalidInputError400no
invalid_cursorInvalidCursorError400no
unauthorizedUnauthorizedError401no
forbiddenForbiddenError403no
insufficient_creditsInsufficientCreditsError402no
spend_limit_reachedSpendLimitReachedError402no
rate_limitedRateLimitedError429yes
request_too_largeRequestTooLargeError413no
method_not_allowedMethodNotAllowedError405no
endpoint_retiredEndpointRetiredError410no
idempotency_key_reusedIdempotencyKeyReusedError422no
idempotency_key_in_progressIdempotencyKeyInProgressError409yes
job_not_foundJobNotFoundError404no
unknown_endpointUnknownEndpointError404no
not_foundNotFoundError404no
private_or_unavailablePrivateOrUnavailableError403no
no_transcriptNoTranscriptError404no
no_liveNoLiveError404no
no_mediaNoMediaError404no
upstream_blockedUpstreamBlockedError503yes
upstream_errorUpstreamError502yes
overloadedOverloadedError503yes
internalInternalError500yes

Retries and timeouts

Retryable failures (the codes above, connection errors, timeouts) are retried 2 times by default with exponential backoff and jitter, honoring retry-after. A GET retry sends max_age set to the seconds since the first attempt: if the first response was lost in transit, the retry is served free from the cache. Timeouts are per attempt: 60 s by default, and 300 s for endpoints that may transcribe audio (facebook.ad_transcript, facebook.transcript, instagram.transcript, kick.transcript, reddit.transcript, rumble.transcript, tiktok.transcript, twitch.transcript, youtube.transcript), because speech-to-text on long media takes minutes, and for create-and-wait's long-polls. Most requests answer in a few seconds. A timeout you set, on the client or on one request, applies to every endpoint, and so does maxRetries.

Pagination

List endpoints return one page (data, page.has_more, page.next_cursor). iterate() returns a Paginator (for await over items, .byPage() for pages) with two guards, maxPages and maxCredits; afterwards pagesFetched, creditsCharged, stopReason ("end", or the guard that stopped it) and endReason (the API's page.end_reason) say what happened. Each page is checked against its catalog price before it is fetched, and an empty page with has_more is not the end.

TypeScript
const items = client.amazon.dealProducts.iterate({}, { maxPages: 10, maxCredits: 100 });
for await (const item of items) {
  console.log(item);
}
console.log(items.pagesFetched, items.creditsCharged, items.stopReason, items.endReason);

Account, API keys, jobs, webhooks and events

The gateway's own routes (account, usage, credit ledger, API keys, jobs, webhook endpoints, events) are free and have methods too, named from their operation IDs (<noun>.<verb>, or <noun>.<sub>.<verb> for a sub-resource). They answer the same envelope (data, meta, credits) with their own meta; cursor-paged list routes have iterate like list endpoints. Every POST sends an idempotency-key header (yours, or a new UUID kept for the call's retries), so it is retried like a GET and a retry never repeats the work; replayed says when the API answered from an earlier request with the same key, and status is 202 when accepted work continues. Each route needs a key with the scope below (a key never gets a scope its creator lacks).

TypeScript
const res = await client.account.get();
console.log(res.data, res.meta.request_id);
operationmethodscope
account.getclient.account.get()account:read
account.updateclient.account.update(body)admin
usage.listclient.usage.list(params)account:read
usage.rate.listclient.usage.rate.list(params)account:read
credit_transactions.listclient.creditTransactions.list(params)account:read
billing.checkout.getclient.billing.checkout.get(id)account:read
billing.subscription.getclient.billing.subscription.get()account:read
billing.auto_topup.getclient.billing.autoTopup.get()account:read
billing.purchases.listclient.billing.purchases.list(params)account:read
billing.purchases.receiptclient.billing.purchases.receipt(id)account:read
requests.listclient.requests.list(params)account:read
requests.getclient.requests.get(id)account:read
requests.get_responseclient.requests.getResponse(id)account:read
api_keys.createclient.apiKeys.create(body)admin
api_keys.listclient.apiKeys.list(params)account:read
api_keys.getclient.apiKeys.get(id)account:read
api_keys.updateclient.apiKeys.update(id, body)admin
api_keys.rotate_secretclient.apiKeys.rotateSecret(id, body)admin
api_keys.revokeclient.apiKeys.revoke(id)admin
jobs.createclient.jobs.create(body, params)jobs
jobs.listclient.jobs.list(params)jobs:read
jobs.getclient.jobs.get(id, params)jobs:read
jobs.results.listclient.jobs.results.list(id, params)jobs:read
jobs.cancelclient.jobs.cancel(id)jobs
webhook_endpoints.createclient.webhookEndpoints.create(body)admin
webhook_endpoints.listclient.webhookEndpoints.list(params)account:read
webhook_endpoints.getclient.webhookEndpoints.get(id)account:read
webhook_endpoints.updateclient.webhookEndpoints.update(id, body)admin
webhook_endpoints.deleteclient.webhookEndpoints.delete(id)admin
webhook_endpoints.rotate_secretclient.webhookEndpoints.rotateSecret(id, body)admin
webhook_endpoints.testclient.webhookEndpoints.test(id)admin
webhook_endpoints.deliveries.listclient.webhookEndpoints.deliveries.list(id, params)account:read
events.listclient.events.list(params)account:read
events.getclient.events.get(id)account:read
events.redeliverclient.events.redeliver(id, body)admin
notification_preferences.getclient.notificationPreferences.get()account:read
notification_preferences.updateclient.notificationPreferences.update(body)admin

Jobs and webhooks

Many requests (or one long list walk) run as a background job at the synchronous prices; failed items are free. The create-and-wait helper creates one, long-polls it until it ends and returns every result; one Idempotency-Key covers the create's retries, so a retry never runs a job twice. Webhook deliveries are signed per Standard Webhooks: verify the raw body with your endpoint's secret before trusting it, and deduplicate on the event ID.

TypeScript
const { job, results } = await client.jobs.createAndWait({ requests: [{ custom_id: "row-1", endpoint: "tiktok.profile", params: { handle: "nasa" } }] });
for (const r of results) console.log(r.custom_id, r.status, r.error?.code);

// A webhook delivery: the raw body, the request headers, your endpoint's secret.
const event = await client.webhooks.verify(rawBody, request.headers, process.env.SOCIALTAP_WEBHOOK_SECRET!);

Tools for AI agents

The SDK hands the SocialTap MCP server's tools to a model: each tool's name, description (its price and rules included) and input JSON Schema, and a call that sends one stateless MCP request with your key. A tool behaves exactly as it does for an MCP client: concise results (detail: "full" for every field), next_cursor to continue, and failures returned as the tool's output (error with retryable and remediation) so the model can act on them. Transport failures raise as for any request, and tools that may be repeated are retried.

TypeScript
// The Vercel AI SDK (ai is an optional peer dependency): the default tools (call_endpoint reaches every endpoint),
// or socialtapTools({ tools: [...] }) / socialtapTools({ tools: "all" }).
import { generateText, stepCountIs } from "ai";
import { socialtapTools } from "socialtap/ai";

// model: any AI SDK model; prompt: the task. The model calls the tools, the SDK runs them with your key.
const { text } = await generateText({ model, tools: socialtapTools(), stopWhen: stepCountIs(5), prompt });

// Any other tool-calling API: hand TOOLS (name, description, inputSchema) to the model, run its calls with callTool.
import { SocialTap, TOOLS, callTool } from "socialtap";

const r = await callTool(new SocialTap(), "find_endpoint", { query: "Exact follower and like counts, bio and country" });
console.log(r.isError, r.output);
toolwhat it does
find_endpointFind an endpoint
get_postPost by link
list_postsPosts of a profile
get_profileProfile by handle
list_commentsComments of a post
get_transcriptTranscript by link
get_engagementEngagement by handle
searchSearch by query
call_endpointCall any endpoint
search_docsSearch the docs
read_docRead a docs page
get_accountGet account balance
get_storyStory by link
list_community_postsCommunity posts
list_hashtag_postsHashtag posts
list_place_postsPlace posts
list_playlist_postsPlaylist posts
list_reelsReels of a profile
list_sound_postsSound posts
list_top_postsTop posts
list_trending_postsTrending posts
list_channel_postsChannel posts of a profile
list_effect_postsEffect posts
list_liked_postsLiked posts of a profile
list_photosPhotos of a profile
list_pinsPins of a profile
list_playlist_storiesPlaylist stories
list_playlist_tracksPlaylist tracks
list_podcast_episodesPodcast episodes
list_shop_postsShop posts of a profile
list_tracksTracks of a profile
list_videosVideos of a profile
get_sellerSeller by handle
get_shopShop by handle
list_followersFollowers of a profile
list_followingFollowing of a profile
list_similar_profilesSimilar profiles of a profile
get_commentComment by link
list_repliesReplies of a post
list_profile_commentsProfile comments
get_ad_transcriptAd transcript by link
get_adAd by link
list_adsAds of a profile
list_top_adsTop ads
get_hashtagHashtag by link
list_trending_hashtagsTrending hashtags
get_communityCommunity by link
get_productProduct by link
get_albumAlbum by link
get_playlistPlaylist by link
get_soundSound by link
get_topicTopic by link
get_downloadDownload by link
get_effectEffect by link
get_embedEmbed by link
get_eventEvent by link
get_liveLive by handle
get_placePlace by link
get_podcastPodcast by link
get_usernameUsername by handle
get_web_pageWeb page by link
list_reviewsReviews of a product
list_boardsBoards of a profile
list_deal_productsDeal products
list_eventsEvents of a profile
list_highlightsHighlights of a profile
list_offersOffers of a product
list_place_eventsPlace events
list_playlistsPlaylists of a profile
list_productsProducts of a profile
list_scheduleSchedule of a profile
list_shop_listsShop lists of a profile
list_top_albumsTop albums
list_top_playlistsTop playlists
list_top_productsTop products
list_top_trendsTop trends
create_jobCreate a background job
get_jobGet a background job
list_job_resultsList a job's results

CLI

The package's bin: every endpoint as a command (JSON on stdout; a list walk with --all prints one item per line), the agent tools, and init, which sets up coding agents.

Shell
npx socialtap tiktok profile --handle nasa
npx socialtap endpoints          # every command, its params and price
npx socialtap tool find_endpoint '{"query":"Exact follower and like counts, bio and country"}'
npx socialtap init               # Claude Code, Codex, Cursor, Gemini CLI: the Agent Skill + the MCP server

init installs the Agent Skill the site publishes (its discovery index, digest checked) into each agent's user skills directory and registers the MCP server with your key (--api-key, or SOCIALTAP_API_KEY) in each agent's own user config: Claude Code through claude mcp add-json, Codex's config.toml, Cursor's mcp.json, Gemini CLI's settings.json. It sets up every agent it finds (--agent <id> to choose) and is safe to run again.

Versioning

The version is derived from the API contract: major = API version, minor = the contract's revision (it grows with every additive change, a new endpoint included), patch = the SDK generator's revision. Questions and bug reports: support@socialtap.dev.