Search posts and actors
Search posts and actors across provider indexes, with platform-specific scopes, query limits, result fields, and cursor pagination for each supported platform.
Use social.search.posts(account, input, options?) for normalized post search.
It returns Page<JsonObject>:
const page = await social.search.posts(account, {
query: "open source",
scope: "recent",
limit: 25,
});
The input takes query, and optionally scope ("recent" or "all"),
cursor, limit, startTime, and endTime. Items keep their provider fields.
Reuse nextCursor only with the same account, query, scope, time bounds, and
page size. Cursors are bound to the query, not to an authorization grant.
iteratePosts(account, input, options) follows cursors lazily within
maxPages, maxItems, and signal bounds.
The examples assume one social client built with the platform’s adapter and an
account from connectedAccountRef. Native calls take a native handle from
social.native("default", { acknowledgeUnsafe: true }) and, where the method
requires it, the operation context your application passes to adapter calls.
Platform support
X
Normalized search.posts with recent and all scopes, plus native
searchRecentPosts and searchAllPosts. Scopes: tweet.read and
users.read.
Recent search uses auth.accessToken, covers the last 7 days, and accepts a
limit of 10 to 100. Full-archive search (scope: "all") uses appBearerToken,
needs eligible pay-per-use or Enterprise access, and accepts 10 to 500.
const page = await social.search.posts(account, {
query: "distributed systems -is:retweet",
limit: 25,
});By default the adapter requests IDs, text, author, timestamps, metrics,
language, entities, attachments, and referenced tweets. Recent queries are
limited to 512 characters and full-archive queries to 4096. Invalid bounds or
timestamps raise invalid_input; missing access raises missing_permission.
The native methods expose X tweet fields, expansions, user fields, and media
fields:
const page = await native.searchRecentPosts({
account,
search: { query: "open source", limit: 10 },
context,
});For posts as they are published, the native stream method reads X’s filtered
stream, and addStreamRules, listStreamRules, and deleteStreamRules manage
the matching rules. Both use appBearerToken and need pay-per-use or
Enterprise access. The stream opens one connection per iteration and never
reconnects on its own. See X filtered stream.
Bluesky
Normalized search.posts, plus native post and actor search. No declared
scope; the adapter calls public app.bsky endpoints.
The adapter takes service, did, and an optional accessJwt. Post results
are provider records and may include metadata.hitsTotal. Native post search
adds sort, author, mentions, language, domain, URL, and tags.
const page = await social.search.posts(account, { query: "distributed systems", limit: 25 });Actor and profile search is native only and returns actor page records:
const actors = await native.searchActors({ account, query: "opencore", limit: 10 });Invalid or missing sessions raise unauthorized or missing_permission.
Threads
Normalized search.posts, plus native keyword and tag search. Scopes:
threads_basic and threads_keyword_search.
Search uses the authorized user ID and access token. Without
threads_keyword_search approval, results are limited to the authorized user’s
posts. The normalized page holds provider post objects and a continuation
cursor.
Use native search for TOP or RECENT ordering, tag mode, media type, author, or time bounds:
const result = await native.search({
account,
query: "open source",
searchType: "RECENT",
searchMode: "KEYWORD",
context,
});Provider permission failures raise missing_permission.
Threads has no profile search, so the manifest declares profiles.search as
unsupported-by-platform. Profile discovery only matches an exact username;
use social.graph.getProfile(account, { handle }) for that.
YouTube
Normalized search.posts with recent only, plus native search.
Scope: https://www.googleapis.com/auth/youtube.readonly.
YouTube uses an OAuth accessToken and a channelId. Results are public video
search records with provider IDs and snippet.
const page = await social.search.posts(account, { query: "distributed systems", limit: 50 });scope: "all" raises invalid_input. The default limit is 25 and the maximum
is 50. Time bounds map to publishedAfter and publishedBefore. Each request
costs 100 quota units. A missing scope raises missing_permission.
Native hashtag lookup and hashtag media only. There is no normalized
search.posts. Requires Facebook Login (auth.flavor: "facebook-login").
Look up the hashtag ID first, then read its media with kind: "recent" or
"top":
const found = await native.hashtagSearch({ account, hashtag: "opensource", context });
const media = await native.hashtagMedia({ account, hashtagId, kind: "recent", limit: 25, context });The media page uses paging.cursors.after. With Instagram Login,
instagram.hashtags.search raises missing_permission.
Unsupported platforms and errors
TikTok, LinkedIn, and Facebook do not declare bundled normalized
search.posts; the facade raises unsupported_capability. Handle
invalid_input for query, scope, limit, timestamps, or cursors,
missing_permission or unauthorized for credentials,
rate_limited for provider throttling, and upstream_failure for provider
errors. Do not log tokens or private result data.