{"openapi":"3.1.0","info":{"title":"socially.run: send a profile link, get its public data as JSON","version":"0.1.0","description":"One API for public data from Instagram, TikTok, YouTube, LinkedIn, X, Facebook and any web page: profiles, posts, page text, username search, email lookup and trends. Every lookup answers **found**, **not found** or **we could not check** (`undecided`), never a guess, and a cached answer costs 0 credits. MCP tools share these operation definitions and the same `so_` key; x-mcp-tools lists the tools available over MCP. Writing TypeScript or JavaScript? `npm i socially` is one typed method per endpoint here."},"servers":[{"url":"https://api.socially.run/v1"}],"tags":[{"name":"Resolve","description":"Turn a URL or @handle into a platform and a canonical handle. Free, no lookup happens."},{"name":"Profiles","description":"Read a public profile on Instagram, TikTok, YouTube, LinkedIn, X, Facebook or a website, one at a time or in a batch, and aggregate the batch into one intelligence report."},{"name":"Posts","description":"Read one public post by URL: caption, media type, counts where the platform shows them."},{"name":"Web","description":"Read a web page as clean text and structured data, or fetch its Open Graph card."},{"name":"Usernames","description":"Search one username across thousands of sites (a fast top-200 pass or the full database) and browse the site list."},{"name":"Emails","description":"Find which services an email address is registered on. Paid plans, after accepting the acceptable-use policy."},{"name":"Dossiers","description":"The deep run: a full username sweep with the details each site exposes, delivered as one report."},{"name":"Jobs","description":"Follow, page through, stream and cancel the asynchronous searches."},{"name":"Trending","description":"What is trending right now on Google and YouTube, by country."},{"name":"Search","description":"Find videos, popular reels, hashtag posts and news about a subject."},{"name":"Platforms","description":"Which platforms and strategies are healthy, degraded or down at this moment."},{"name":"Usage","description":"Credits charged this month, split by kind and by API key."},{"name":"Attributions","description":"The open-source datasets behind username search and what their licenses ask of you."},{"name":"Webhooks","description":"One signed-event endpoint per account: set it, test-fire it, rotate its secret, read its delivery log."}],"paths":{"/resolve":{"post":{"operationId":"resolve_target_post","tags":["Resolve"],"summary":"Resolve what a URL or @handle points at","description":"Turn a profile URL, post URL, website or @handle into what socially would read: the platform, the kind (profile, post, website), the normalized handle and the one canonical URL. No egress, no credit. Use it to validate input before a metered lookup.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"input":{"type":"string","minLength":1,"maxLength":2048,"description":"A profile URL, post URL, website or @handle."},"platform":{"description":"Required when `input` is a bare handle.","type":"string","enum":["instagram","linkedin","youtube","tiktok","x","facebook","website"]}},"required":["input"]}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Resolve what a URL or @handle points at","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"profiles.resolve","returns":"ResolvedTargetDto","repeatable":true},"x-credits":"0 credits"}},"/intelligence/aggregate":{"post":{"operationId":"aggregate_intelligence_post","tags":["Profiles"],"summary":"Aggregate profiles into social intelligence","description":"Turn one or more profile reads (the six ExtractionResult keys) into the consolidated SocialIntelligence document: engagement, sentiment, content calendar, benchmark, a pt-BR knowledge-base markdown and personality hints. Pure and free. It only computes over what you send.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"results":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"platform":{"type":"string","enum":["instagram","linkedin","youtube","tiktok","x","facebook","website"]},"url":{"type":"string"},"extractedAt":{"type":"string"},"profile":{"type":"object","properties":{"name":{"type":"string"},"username":{"type":"string"},"bio":{"type":"string"},"followers":{"type":["number","null"]},"following":{"type":["number","null"]},"postsCount":{"type":["number","null"]},"profileUrl":{"type":"string"},"avatarUrl":{"type":["string","null"]},"isVerified":{"type":["boolean","null"]},"isBusinessAccount":{"type":["boolean","null"]},"businessCategory":{"type":["string","null"]},"externalUrl":{"type":["string","null"]}},"required":["name","username","bio","followers","following","postsCount","profileUrl","avatarUrl"]},"recentPosts":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string"},"date":{"type":["string","null"]},"likes":{"type":["number","null"]},"comments":{"type":["number","null"]},"shares":{"type":["number","null"]},"views":{"type":["number","null"]},"url":{"type":["string","null"]},"thumbnail":{"type":["string","null"]},"duration":{"type":["string","null"]},"hashtags":{"type":"array","items":{"type":"string"}},"mediaType":{"anyOf":[{"type":"string","enum":["video","image","carousel","article","short","reel"]},{"type":"null"}]}},"required":["text","date","likes","comments","shares","views","url"]}},"summary":{"type":"string"}},"required":["platform","url","extractedAt","profile","recentPosts","summary"],"additionalProperties":{}}}},"required":["results"]}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Aggregate profiles into social intelligence","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"intelligence.aggregate","returns":"SocialIntelligenceDto","repeatable":true},"x-credits":"0 credits"}},"/platforms":{"get":{"operationId":"list_platforms_get","tags":["Platforms"],"summary":"List the platforms and how each one is answering","description":"List supported capabilities separately from source health. `capabilities` reports profile/post lookup, topic video search, indexed topic search, hashtag search and country trend boards. YouTube and TikTok support topic video search; only YouTube has a country board. Only Instagram has indexed topic search, the reels on its public popular page for a word, which exists for some words only. TikTok and Instagram support hashtag search. Google Trends is a separate `/trending` source. `status` and `strategies` describe profile reads; `postStatus` and `postStrategies` describe post reads, with verification dates and the last 24 hours of results. A supported capability can still have no working source here. Free.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"List the platforms and how each one is answering","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"platforms.list","returns":"PlatformStatusDto[]"},"x-credits":"0 credits"}},"/profiles/lookup":{"post":{"operationId":"lookup_profile_post","tags":["Profiles"],"summary":"Look up a public profile","description":"Read a public profile on Instagram, TikTok, YouTube, LinkedIn, X, Facebook or a website. A `found` answer includes the profile, recent posts and platform details when available: account ids, links, creation dates and public counts. Instagram's `userId` and `graphId` name different ids; neither grants permission. Missing fields are null; unsupported blocks are absent. Data outcomes answer 200: `found`, `notFound` (confirmed by the platform, cached an hour) or `undecided` (refunded, never cached). 1 credit on a miss, 0 on a hit. `extractedAt` is the original read time, including cache and snapshot hits.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"input":{"type":"string","minLength":1,"maxLength":2048,"description":"A profile URL, post URL, website or @handle."},"platform":{"type":"string","enum":["instagram","linkedin","youtube","tiktok","x","facebook","website"]},"posts":{"description":"Recent posts to return (0–15). Default 10. This limits the answer, not the source read.","type":"integer","minimum":0,"maximum":15},"refresh":{"description":"Bypass the cache and the snapshot; costs a credit even when fresh.","type":"boolean"}},"required":["input"]}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Look up a public profile","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"profiles.lookup","returns":"ProfileLookupResultDto","repeatable":true},"x-credits":"1 credit on a cache miss, 0 on a hit; refunded when we could not check"}},"/profiles/{platform}/{handle}":{"get":{"operationId":"get_profile_get","tags":["Profiles"],"summary":"Get a public profile by platform and handle","description":"The same lookup as `lookup_profile`, with the platform and handle in the URL path.","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","enum":["instagram","linkedin","youtube","tiktok","x","facebook","website"]}},{"name":"handle","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"posts","in":"query","required":false,"description":"Recent posts to return (0–15). Default 10. This limits the answer, not the source read.","schema":{"description":"Recent posts to return (0–15). Default 10. This limits the answer, not the source read.","type":"integer","minimum":0,"maximum":15}},{"name":"refresh","in":"query","required":false,"description":"Bypass the cache and the snapshot; costs a credit even when fresh.","schema":{"description":"Bypass the cache and the snapshot; costs a credit even when fresh.","type":"boolean"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Get a public profile by platform and handle","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"profiles.get","returns":"ProfileLookupResultDto"},"x-credits":"1 credit on a cache miss, 0 on a hit"}},"/profiles/batch":{"post":{"operationId":"lookup_profiles_batch_post","tags":["Profiles"],"summary":"Look up up to ten profiles in one call","description":"Read up to ten profiles at once (five in flight, 30 s each, 120 s total). Answers 200 with `results` (the found ones), `failures` (the ones not found and the ones we could not check, which are refunded) and, with `aggregate: true`, the consolidated social intelligence the siblings persist. `partial` says whether anything failed.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"targets":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"object","properties":{"input":{"type":"string","minLength":1,"maxLength":2048,"description":"A profile URL, post URL, website or @handle."},"platform":{"type":"string","enum":["instagram","linkedin","youtube","tiktok","x","facebook","website"]}},"required":["input"],"additionalProperties":false}},"posts":{"description":"Recent posts to return (0–15). Default 10. This limits the answer, not the source read.","type":"integer","minimum":0,"maximum":15},"aggregate":{"description":"Run the aggregator over the profiles that were found (0 credits).","type":"boolean"},"perTargetTimeoutMs":{"type":"integer","minimum":1000,"maximum":30000}},"required":["targets"]}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Look up up to ten profiles in one call","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"profiles.batch","returns":"ProfileBatchDto","repeatable":true},"x-credits":"1 per profile on a miss, 0 per hit; refunded for each profile we could not check"}},"/posts/lookup":{"post":{"operationId":"lookup_post_post","tags":["Posts"],"summary":"Look up a public post","description":"Read one public Instagram, TikTok, YouTube, X, LinkedIn or Facebook post by URL. Returns its caption, author id, date, media and public counts when available. X, LinkedIn and Facebook posts are read only through a paid reader, with exact counts, and a deployment with no reader configured answers 503 before it charges. A LinkedIn post's `author.profileUrl` is the person's or the company's own page, and a Facebook post's `likes` counts every reaction. A full Instagram read adds source ids and ordered `frames` with image/video URLs, dimensions, duration and alt text; missing fields are null. YouTube adds video/channel ids, title and description, not a playable stream. Every read says its `detailLevel` (`detailed` from the post's own page or API, `embed` from a thin public card that leaves what it does not show null) and its `confidence`; a cached answer keeps both. CDN URLs can expire: download the files. Answers `found` or `undecided` (refunded), never `notFound`. 1 credit on a miss, 0 on a hit. Cached answers keep the original `extractedAt`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"url":{"type":"string","minLength":1,"maxLength":2048,"description":"An http(s) URL."},"refresh":{"description":"Bypass the cache and the snapshot; costs a credit even when fresh.","type":"boolean"}},"required":["url"]}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Look up a public post","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"posts.lookup","returns":"PostLookupResultDto","repeatable":true},"x-credits":"1 credit on a cache miss, 0 on a hit; refunded when we could not check"}},"/web/read":{"post":{"operationId":"read_website_post","tags":["Web"],"summary":"Read a public web page","description":"Fetch a public page through the proxy and return its readable text, title, description, images and ld+json. Pages that render with JavaScript are rendered when the budget allows (`render: auto`). Private and internal addresses answer 400 SSRF_BLOCKED. 1 credit on a miss, 0 on a hit (24 h).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"url":{"type":"string","minLength":1,"maxLength":2048,"description":"An http(s) URL."},"maxChars":{"description":"Cap on the readable text. Default 8,000.","type":"integer","minimum":500,"maximum":50000},"render":{"description":"`always` renders every time and never falls back to a plain fetch. It spends render budget and fails closed at RENDER_BUDGET_EXHAUSTED; a deployment with no renderer answers SIDECAR_UNAVAILABLE.","type":"string","enum":["auto","never","always"]},"refresh":{"description":"Bypass the cache and the snapshot; costs a credit even when fresh.","type":"boolean"}},"required":["url"]}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Read a public web page","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"web.read","returns":"WebReadDto","repeatable":true},"x-credits":"1 credit on a cache miss, 0 on a hit"}},"/web/og":{"post":{"operationId":"fetch_og_post","tags":["Web"],"summary":"Fetch a page's Open Graph card","description":"The Open Graph card a page publishes: title, description, image, site name, type, locale, canonical URL. 1 credit on a miss, 0 on a hit (24 h).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"url":{"type":"string","minLength":1,"maxLength":2048,"description":"An http(s) URL."},"refresh":{"description":"Bypass the cache and the snapshot; costs a credit even when fresh.","type":"boolean"}},"required":["url"]}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Fetch a page's Open Graph card","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"web.og","returns":"WebOgDto","repeatable":true},"x-credits":"1 credit on a cache miss, 0 on a hit"}},"/jobs/{id}":{"get":{"operationId":"get_job_get","tags":["Jobs"],"summary":"Get a job","description":"Read a job: its status, progress and credits, plus its hits once it has finished (found and undecided by default, capped at 500; page the rest with list_job_hits) and its summary. Poll this, or attach to the stream, until status is succeeded, partial, failed or cancelled.","parameters":[{"name":"id","in":"path","required":true,"description":"The job id from the 202 that created it.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The job id from the 202 that created it."}},{"name":"include","in":"query","required":false,"description":"Also embed the notFound hits (found and undecided come by default).","schema":{"description":"Also embed the notFound hits (found and undecided come by default).","type":"string","enum":["notFound"]}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Get a job","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"jobs.get","returns":"JobResultDto"},"x-credits":"0 credits"}},"/jobs/{id}/hits":{"get":{"operationId":"list_job_hits_get","tags":["Jobs"],"summary":"List a job's hits","description":"Page through every site a job answered. It works while it is still running. Filter by outcome (found, notFound, undecided) or site category.","parameters":[{"name":"id","in":"path","required":true,"description":"The job id from the 202 that created it.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The job id from the 202 that created it."}},{"name":"outcome","in":"query","required":false,"description":"Only hits with this outcome.","schema":{"description":"Only hits with this outcome.","type":"string","enum":["found","notFound","undecided"]}},{"name":"category","in":"query","required":false,"description":"Only sites in this category.","schema":{"description":"Only sites in this category.","type":"string","enum":["archived","art","blog","business","coding","dating","finance","gaming","health","hobby","images","misc","music","news","political","search","shopping","social","tech","video","xx NSFW xx"]}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}},{"name":"offset","in":"query","required":false,"schema":{"default":0,"type":"integer","minimum":0,"maximum":9007199254740991}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"List a job's hits","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"jobs.listHits","returns":"V1ListPage<JobHitDto>"},"x-credits":"0 credits"}},"/jobs/{id}/cancel":{"post":{"operationId":"cancel_job_post","tags":["Jobs"],"summary":"Cancel a job","description":"Stop a job. A queued job is cancelled at once and fully refunded; a running one is asked to stop and lands within seconds. The hits it already has are kept and nothing is refunded. A finished job answers 409.","parameters":[{"name":"id","in":"path","required":true,"description":"The job id from the 202 that created it.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The job id from the 202 that created it."}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Cancel a job","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"jobs.cancel","returns":"JobDto","repeatable":true},"x-credits":"0 credits"}},"/usernames/search":{"post":{"operationId":"search_username_post","tags":["Usernames"],"summary":"Search a username across the web","description":"Sweep the site database for one handle and report every site's answer: found, notFound, or undecided when the site could not be read. Answers 202 with a job. Stream it or poll get_job. An identical search already running returns that same job and costs nothing.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"username":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","description":"The handle to look for. Letters, digits, dot, dash and underscore."},"tier":{"default":"fast","description":"fast sweeps the top-ranked sites inside a minute (5 credits); full sweeps the whole database (20 credits).","type":"string","enum":["fast","full"]},"categories":{"description":"Only sweep sites in these categories.","maxItems":21,"type":"array","items":{"type":"string","enum":["archived","art","blog","business","coding","dating","finance","gaming","health","hobby","images","misc","music","news","political","search","shopping","social","tech","video","xx NSFW xx"]}},"sites":{"description":"Only sweep these site ids (from list_username_sites).","maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"countries":{"description":"Only sweep sites that serve these countries (ISO 3166-1 alpha-2). A site is kept when it serves any of them.","maxItems":50,"type":"array","items":{"type":"string","pattern":"^[A-Za-z]{2}$"}},"includeNsfw":{"default":false,"description":"Include sites marked as adult. Requires a plan that allows them.","type":"boolean"},"includeUnreliable":{"default":false,"description":"Also sweep sites the nightly check distrusts. They answer, but never above low confidence.","type":"boolean"}},"required":["username"]}}}},"security":[{"bearerAuth":[]}],"responses":{"202":{"description":"Search a username across the web","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"usernames.search","returns":"JobDto","repeatable":true},"x-credits":"5 credits (fast) or 20 credits (full); a deduped or cached search costs 0"}},"/usernames/sites":{"get":{"operationId":"list_username_sites_get","tags":["Usernames"],"summary":"List the sites a username search covers","description":"The site database: what each site is, how it is classified, how much a hit there is worth, and what the nightly check currently thinks of it. Use the ids to scope a search with `sites`.","parameters":[{"name":"category","in":"query","required":false,"description":"Only sites in this category.","schema":{"description":"Only sites in this category.","type":"string","enum":["archived","art","blog","business","coding","dating","finance","gaming","health","hobby","images","misc","music","news","political","search","shopping","social","tech","video","xx NSFW xx"]}},{"name":"includeNsfw","in":"query","required":false,"description":"Include sites marked as adult in the listing.","schema":{"description":"Include sites marked as adult in the listing.","type":"boolean"}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}},{"name":"offset","in":"query","required":false,"schema":{"default":0,"type":"integer","minimum":0,"maximum":9007199254740991}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"List the sites a username search covers","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"usernames.listSites","returns":"V1ListPage<SiteDto>"},"x-credits":"0 credits"}},"/emails/lookup":{"post":{"operationId":"lookup_email_post","tags":["Emails"],"summary":"Find where an email address is registered","description":"Ask ~119 services whether an address already has an account there, using each service's own signup or recovery check, never a password reset and never a message to the address. Answers 202 with a job. A service that rate-limits us answers undecided, never 'no account'. Requires a paid plan and an accepted acceptable-use policy.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"email":{"type":"string","maxLength":254,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"The address to look up. It is never messaged, only asked about. It is kept for as long as the job that reads it, and your history keeps a masked copy."}},"required":["email"]}}}},"security":[{"bearerAuth":[]}],"responses":{"202":{"description":"Find where an email address is registered","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"emails.lookup","returns":"JobDto","repeatable":true},"x-credits":"10 credits; a deduped or cached lookup costs 0"}},"/dossiers":{"post":{"operationId":"create_dossier_post","tags":["Dossiers"],"summary":"Build a dossier for a username","description":"A deeper pass than search_username: every claimed profile is read for the details it publishes (names, locations, avatars, bios, other identifiers and the usernames it links to), and those are collected into one report. Answers 202 with a job; the per-site rows are its hits and the report is its summary.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"username":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","description":"The handle to build the dossier around."},"depth":{"default":"top500","description":"top500 covers the highest-ranked sites; all covers the whole upstream database and takes several minutes.","type":"string","enum":["top500","all"]},"recursion":{"default":true,"description":"Follow usernames the claimed profiles link to, inside the same run. Turn it off for a narrower, faster dossier.","type":"boolean"},"includeNsfw":{"default":false,"description":"Include adult sites. Requires a plan that allows them.","type":"boolean"},"includeUnreliable":{"default":false,"description":"Also check sites the upstream database has marked unreliable.","type":"boolean"}},"required":["username"]}}}},"security":[{"bearerAuth":[]}],"responses":{"202":{"description":"Build a dossier for a username","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"dossiers.create","returns":"JobDto","repeatable":true},"x-credits":"30 credits; a deduped or cached dossier costs 0"}},"/trending":{"get":{"operationId":"list_trending_get","tags":["Trending"],"summary":"Read what is trending in a country","description":"One country's board: Google's rising searches, each with the news behind it and an approximate volume, or YouTube's most popular videos. A board stays fresh in the cache for ten minutes. A cached board costs 0 credits. When the source refuses us, the last good board is served instead, flagged `stale` with the time it was captured, and it costs nothing either: you are charged for a reading, never for an attempt.","parameters":[{"name":"source","in":"query","required":false,"description":"Which board to read: `google` for what a country is searching, `youtube` for what it is watching.","schema":{"default":"google","description":"Which board to read: `google` for what a country is searching, `youtube` for what it is watching.","type":"string","enum":["google","youtube"]}},{"name":"geo","in":"query","required":true,"description":"The country, ISO 3166-1 alpha-2 (US, BR, ES). REQUIRED: a board is one country's board, and there is no honest default for whose. This used to fall back to `US`, which meant a caller in São Paulo was quietly handed the American one. A country the source does not publish answers 400 and says so. For a subject rather than a country, see `search_news` and `search_youtube`. A trending board takes no query.","schema":{"type":"string","pattern":"^[A-Za-z]{2}$","description":"The country, ISO 3166-1 alpha-2 (US, BR, ES). REQUIRED: a board is one country's board, and there is no honest default for whose. This used to fall back to `US`, which meant a caller in São Paulo was quietly handed the American one. A country the source does not publish answers 400 and says so. For a subject rather than a country, see `search_news` and `search_youtube`. A trending board takes no query."}},{"name":"category","in":"query","required":false,"description":"YouTube's video category id: `10` is Music, `17` Sport. YouTube only: Google Trends publishes no categories.","schema":{"description":"YouTube's video category id: `10` is Music, `17` Sport. YouTube only: Google Trends publishes no categories.","type":"string","minLength":1,"maxLength":20}},{"name":"limit","in":"query","required":false,"description":"Entries to return, 1–50. Google publishes ten per country.","schema":{"default":20,"description":"Entries to return, 1–50. Google publishes ten per country.","type":"integer","minimum":1,"maximum":50}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Read what is trending in a country","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"trending.list","returns":"TrendingDto"},"x-credits":"1 credit on a capture, 0 on a cached or stale board"}},"/search/youtube":{"get":{"operationId":"search_youtube_get","tags":["Search"],"summary":"Search YouTube for videos on a subject","description":"What creators are publishing about a subject, in the order YouTube ranks it: title, channel, exact view count, duration and the description snippet, plus real upload dates, likes and comments when the deployment holds a Data API key (`stats: \"exact\"`). Read from the results page rather than the API's 100-unit search, so one key's day holds thousands of these. The answer is cached for thirty minutes, and the same question again costs nothing.","parameters":[{"name":"q","in":"query","required":true,"description":"What to search for, the way you would type it into YouTube.","schema":{"type":"string","minLength":2,"maxLength":200,"description":"What to search for, the way you would type it into YouTube."}},{"name":"limit","in":"query","required":false,"description":"Videos to return, 1–20. One page is one read: a larger `limit` on the same question is served from it.","schema":{"default":10,"description":"Videos to return, 1–20. One page is one read: a larger `limit` on the same question is served from it.","type":"integer","minimum":1,"maximum":20}},{"name":"recency","in":"query","required":false,"description":"Only videos uploaded within the window: `day`, `week`, `month` or `year`. Absent means any time.","schema":{"description":"Only videos uploaded within the window: `day`, `week`, `month` or `year`. Absent means any time.","type":"string","enum":["day","week","month","year"]}},{"name":"sort","in":"query","required":false,"description":"`relevance` uses YouTube's ranking. `views` puts the most-watched videos first. Combine `views` with `recency` to find popular uploads within that window, not to measure growing views. Without a window, `views` includes all-time hits.","schema":{"default":"relevance","description":"`relevance` uses YouTube's ranking. `views` puts the most-watched videos first. Combine `views` with `recency` to find popular uploads within that window, not to measure growing views. Without a window, `views` includes all-time hits.","type":"string","enum":["relevance","views"]}},{"name":"country","in":"query","required":false,"description":"The country to rank for, ISO 3166-1 alpha-2 (BR, US, ES). Omit it for YouTube's own ranking rather than a country's.","schema":{"description":"The country to rank for, ISO 3166-1 alpha-2 (BR, US, ES). Omit it for YouTube's own ranking rather than a country's.","type":"string","pattern":"^[A-Za-z]{2}$"}},{"name":"language","in":"query","required":false,"description":"The language to ask and read the page in, ISO 639-1 (en, pt, es). Omit it and your `accept-language` header decides.","schema":{"description":"The language to ask and read the page in, ISO 639-1 (en, pt, es). Omit it and your `accept-language` header decides.","type":"string","pattern":"^[A-Za-z]{2}$"}},{"name":"refresh","in":"query","required":false,"description":"Read the page again instead of serving the half-hour cache. Charged like any read, and the fresh answer replaces the cached one.","schema":{"description":"Read the page again instead of serving the half-hour cache. Charged like any read, and the fresh answer replaces the cached one.","type":"boolean"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Search YouTube for videos on a subject","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"search.youtube","returns":"YoutubeSearchDto"},"x-credits":"2 credits on a read, 0 on a cached one"}},"/search/news":{"get":{"operationId":"search_news_get","tags":["Search"],"summary":"Search the news for stories on a subject","description":"What the press published about a subject inside a window: headline, publisher, and the date the story ran, read from Google News' public search feed. This is the subject half of trending: a trending board takes no query at all, so `q` plus `recency` is how you ask what is being said about one thing right now. Links are Google's own redirect, not the publisher's URL. Cached for ten minutes.","parameters":[{"name":"q","in":"query","required":true,"description":"The subject to read about, the way you would say it.","schema":{"type":"string","minLength":2,"maxLength":200,"description":"The subject to read about, the way you would say it."}},{"name":"limit","in":"query","required":false,"description":"Stories to return, 1–50. One feed is one read: a larger `limit` on the same question is served from it.","schema":{"default":20,"description":"Stories to return, 1–50. One feed is one read: a larger `limit` on the same question is served from it.","type":"integer","minimum":1,"maximum":50}},{"name":"recency","in":"query","required":false,"description":"Only stories published within the window: `day`, `week`, `month` or `year`. Absent means any time, which for news is rarely the question.","schema":{"description":"Only stories published within the window: `day`, `week`, `month` or `year`. Absent means any time, which for news is rarely the question.","type":"string","enum":["day","week","month","year"]}},{"name":"country","in":"query","required":false,"description":"The Google News edition, ISO 3166-1 alpha-2 (BR, US, ES). There is no worldwide edition: leave it out and one is chosen from `language`. The answer always says which one ran.","schema":{"description":"The Google News edition, ISO 3166-1 alpha-2 (BR, US, ES). There is no worldwide edition: leave it out and one is chosen from `language`. The answer always says which one ran.","type":"string","pattern":"^[A-Za-z]{2}$"}},{"name":"language","in":"query","required":false,"description":"The edition's language, ISO 639-1 (en, pt, es). Default `en`.","schema":{"description":"The edition's language, ISO 639-1 (en, pt, es). Default `en`.","type":"string","pattern":"^[A-Za-z]{2}$"}},{"name":"refresh","in":"query","required":false,"description":"Read the feed again instead of serving the ten-minute cache. Charged like any read.","schema":{"description":"Read the feed again instead of serving the ten-minute cache. Charged like any read.","type":"boolean"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Search the news for stories on a subject","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"search.news","returns":"NewsSearchDto"},"x-credits":"1 credit on a read, 0 on a cached one"}},"/search/instagram":{"get":{"operationId":"search_instagram_get","tags":["Search"],"summary":"Search Instagram's popular reels on a topic","description":"The reels Instagram lists on its public popular page for a topic: shortcode, author, caption, exact play count and the date read off the media id. This is indexed discovery, not a hashtag feed. Instagram publishes these pages for some words only (`art`, `travel` and `music` have one; `fitness` and `nasa` did not when measured), lists up to 12 reels, and says in `hasMore` when it has more that cannot be read without signing in. A word with no page answers `indexed: false` and costs nothing. Cached for thirty minutes.","parameters":[{"name":"q","in":"query","required":true,"description":"The topic, the way Instagram names its popular pages: one word or a few (\"travel\", \"street photography\"). Not every word has a page.","schema":{"type":"string","minLength":2,"maxLength":60,"description":"The topic, the way Instagram names its popular pages: one word or a few (\"travel\", \"street photography\"). Not every word has a page."}},{"name":"limit","in":"query","required":false,"description":"Reels to return, 1–12. One page is one read: a smaller `limit` on the same topic is served from it.","schema":{"default":12,"description":"Reels to return, 1–12. One page is one read: a smaller `limit` on the same topic is served from it.","type":"integer","minimum":1,"maximum":12}},{"name":"refresh","in":"query","required":false,"description":"Read the page again instead of serving the half-hour cache. Charged like any read, and the fresh answer replaces the cached one.","schema":{"description":"Read the page again instead of serving the half-hour cache. Charged like any read, and the fresh answer replaces the cached one.","type":"boolean"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Search Instagram's popular reels on a topic","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"search.instagram","returns":"InstagramSearchDto"},"x-credits":"2 credits on a read that lists reels, 0 on a cached one or a word with no page"}},"/search/tiktok":{"get":{"operationId":"search_tiktok_get","tags":["Search"],"summary":"Search TikTok for videos on a word or a hashtag","description":"What TikTok lists for a word or a hashtag: caption, author, exact views, likes, comments and shares, the date, the length and the tags, read through a paid reader. A word searches TikTok's search bar and takes a window (`recency`), an order (`sort`) and a country. A `#tag` reads that tag's own page, which lists its popular videos of any age in TikTok's order, from any country, and takes none of those. A word's page lists up to 30 videos and a tag's about 20: pass `nextCursor` back as `cursor` for the next one, which is another read. The author's follower count is on keyword results and absent from a hashtag feed. A deployment with no TikTok reader configured answers 503 before it charges. Cached for thirty minutes.","parameters":[{"name":"q","in":"query","required":true,"description":"A word or a phrase for TikTok's search bar (\"padaria artesanal\"), or a hashtag with its # (\"#padaria\").","schema":{"type":"string","minLength":2,"maxLength":200,"description":"A word or a phrase for TikTok's search bar (\"padaria artesanal\"), or a hashtag with its # (\"#padaria\")."}},{"name":"limit","in":"query","required":false,"description":"Videos to return, 1–30. One page is one read: a smaller `limit` on the same question is served from it, and a `limit` that cuts the page ends the cursor.","schema":{"default":10,"description":"Videos to return, 1–30. One page is one read: a smaller `limit` on the same question is served from it, and a `limit` that cuts the page ends the cursor.","type":"integer","minimum":1,"maximum":30}},{"name":"recency","in":"query","required":false,"description":"Words only. Only videos posted within the window: `day`, `week`, `month`, `quarter` (90 days) or `half_year` (180 days), TikTok's own filters. Absent means all time. A hashtag takes none.","schema":{"description":"Words only. Only videos posted within the window: `day`, `week`, `month`, `quarter` (90 days) or `half_year` (180 days), TikTok's own filters. Absent means all time. A hashtag takes none.","type":"string","enum":["day","week","month","quarter","half_year"]}},{"name":"sort","in":"query","required":false,"description":"Words only. `relevance` (the default) is TikTok's ranking, `likes` puts the most-liked first and `recent` the newest. Combine `likes` with `recency` to find what is working lately. A hashtag takes none.","schema":{"description":"Words only. `relevance` (the default) is TikTok's ranking, `likes` puts the most-liked first and `recent` the newest. Combine `likes` with `recency` to find what is working lately. A hashtag takes none.","type":"string","enum":["relevance","likes","recent"]}},{"name":"country","in":"query","required":false,"description":"Words only. Search as a person in this country would, ISO 3166-1 alpha-2 (BR, US, ES). Absent means no country. A code with no region behind it is not refused and filters nothing, so check `videos[].region` against the country you meant. A hashtag takes none.","schema":{"description":"Words only. Search as a person in this country would, ISO 3166-1 alpha-2 (BR, US, ES). Absent means no country. A code with no region behind it is not refused and filters nothing, so check `videos[].region` against the country you meant. A hashtag takes none.","type":"string","pattern":"^[A-Za-z]{2}$"}},{"name":"cursor","in":"query","required":false,"description":"The `nextCursor` of the page before. Each page is another read and another charge, and a cursor only works against the source that made it.","schema":{"description":"The `nextCursor` of the page before. Each page is another read and another charge, and a cursor only works against the source that made it.","type":"string","maxLength":40}},{"name":"refresh","in":"query","required":false,"description":"Read the page again instead of serving the half-hour cache. Charged like any read, and the fresh answer replaces the cached one.","schema":{"description":"Read the page again instead of serving the half-hour cache. Charged like any read, and the fresh answer replaces the cached one.","type":"boolean"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Search TikTok for videos on a word or a hashtag","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"search.tiktok","returns":"TiktokSearchDto"},"x-credits":"2 credits on a page read, 0 on a cached one"}},"/search/instagram-hashtag":{"get":{"operationId":"search_instagram_hashtag_get","tags":["Search"],"summary":"Search Instagram for the posts under a hashtag","description":"What Instagram lists under a hashtag, read through a paid reader: shortcode, author, caption, exact likes, comments and plays, the date and the cover. `sort: top` (the default) is Instagram's own mix of popular and recent posts, in its order, not a ranking by likes, and it can reach back months. `sort: recent` lists the newest posts first. A page lists 24 to 33 posts: pass `nextCursor` back as `cursor` for the next one, which is another read. A like count the owner hid reads `null`. A tag with no posts answers an empty page and costs nothing. A deployment with no Instagram reader configured answers 503 before it charges. Cached for fifteen minutes.","parameters":[{"name":"q","in":"query","required":true,"description":"A hashtag, with or without its # (\"padaria\" or \"#padaria\"). Letters, digits and underscores only.","schema":{"type":"string","minLength":2,"maxLength":200,"description":"A hashtag, with or without its # (\"padaria\" or \"#padaria\"). Letters, digits and underscores only."}},{"name":"limit","in":"query","required":false,"description":"Posts to return, 1–40. One page is one read: a smaller `limit` on the same tag is served from it, and then no `nextCursor` comes with it.","schema":{"default":40,"description":"Posts to return, 1–40. One page is one read: a smaller `limit` on the same tag is served from it, and then no `nextCursor` comes with it.","type":"integer","minimum":1,"maximum":40}},{"name":"sort","in":"query","required":false,"description":"`top` (the default) is Instagram's own mix of popular and recent posts, in its order. `recent` lists the newest posts first.","schema":{"description":"`top` (the default) is Instagram's own mix of popular and recent posts, in its order. `recent` lists the newest posts first.","type":"string","enum":["top","recent"]}},{"name":"cursor","in":"query","required":false,"description":"The `nextCursor` of the page before. Each page is another read and another charge, and a cursor only works with the source and the `sort` that made it.","schema":{"description":"The `nextCursor` of the page before. Each page is another read and another charge, and a cursor only works with the source and the `sort` that made it.","type":"string","maxLength":300}},{"name":"refresh","in":"query","required":false,"description":"Read the page again instead of serving the fifteen-minute cache. Charged like any read, and the fresh answer replaces the cached one.","schema":{"description":"Read the page again instead of serving the fifteen-minute cache. Charged like any read, and the fresh answer replaces the cached one.","type":"boolean"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Search Instagram for the posts under a hashtag","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"search.instagramHashtag","returns":"InstagramHashtagDto"},"x-credits":"2 credits on a page read, 0 on a cached one"}},"/webhooks":{"get":{"operationId":"get_webhook_get","tags":["Webhooks"],"summary":"Get your webhook endpoint","description":"The endpoint events are being POSTed to, which ones it is subscribed to, and whether it is still healthy. `null` when none is registered. `disabledReason: \"failures\"` means we switched it off after 10 failed deliveries in a row. Only a final failure counts, not an attempt that will be retried. Fix the endpoint, then save it again or send a test that succeeds to switch it back on. Free.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Get your webhook endpoint","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"webhooks.get","returns":"WebhookEndpointDto | null"},"x-credits":"Free"},"put":{"operationId":"set_webhook_put","tags":["Webhooks"],"summary":"Register your webhook endpoint","description":"Point socially.run at an https URL and start receiving events there. The answer carries the signing secret ONCE, when it is minted: keep it. Every delivery is signed with it in the `x-socially-signature` header (`t=<unix>,v1=<hmac-sha256 of \"<t>.<body>\">`), and that signature is how you know a request is really from us. Calling this again updates the URL or the subscription and keeps the same secret unless you ask to rotate it. Saving also re-enables an endpoint we had disabled. Up to 5 attempts for no answer, 5xx, 408, 425 or 429, with gaps of 30, 60, 120 and 240 seconds. A longer Retry-After extends the gap, capped at one hour. Other 4xx and all redirects are final. Free.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"url":{"type":"string","format":"uri","description":"Where to POST events, e.g. https://api.yourapp.com/hooks/socially."},"events":{"description":"Which events to receive: job.completed, job.failed. Defaults to all of them.","minItems":1,"type":"array","items":{"type":"string","enum":["job.completed","job.failed"]}},"rotateSecret":{"description":"Mint a new signing secret and return it. The old one stops working.","type":"boolean"}},"required":["url"]}}}},"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Register your webhook endpoint","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"webhooks.set","returns":"SavedWebhookDto","repeatable":true},"x-credits":"Free"},"delete":{"operationId":"delete_webhook_delete","tags":["Webhooks"],"summary":"Remove your webhook endpoint","description":"Stop sending events and forget the endpoint, its secret and its delivery history. Registering again mints a new secret. Free.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Remove your webhook endpoint","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"webhooks.remove","returns":"DeletedWebhookDto","repeatable":true},"x-credits":"Free"}},"/webhooks/test":{"post":{"operationId":"test_webhook_post","tags":["Webhooks"],"summary":"Fire a test event at your endpoint","description":"Send a `ping` event to your registered endpoint right now and wait for the answer, so you can verify the URL and your signature check without waiting for a real job. The result is the actual outcome: `ok: false` carries the HTTP status your server answered, or why we could not reach it. A ping that lands also revives an endpoint we had auto-disabled. It never retries, and it does not count against the failure streak of a real event. Free.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Fire a test event at your endpoint","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"webhooks.test","returns":"WebhookTestResultDto","repeatable":false},"x-credits":"Free"}},"/webhooks/deliveries":{"get":{"operationId":"list_webhook_deliveries_get","tags":["Webhooks"],"summary":"Recent webhook deliveries","description":"The last deliveries we attempted, newest first: what we sent, what your endpoint answered, and how many attempts it took. This is the answer to “the event never arrived”. Deliveries are kept for a week. Free.","parameters":[{"name":"limit","in":"query","required":false,"description":"How many to return, newest first. Up to 50 (the default).","schema":{"description":"How many to return, newest first. Up to 50 (the default).","type":"integer","minimum":1,"maximum":50}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Recent webhook deliveries","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"webhooks.deliveries","returns":"WebhookDeliveryDto[]"},"x-credits":"Free"}},"/attributions":{"get":{"operationId":"get_attributions_get","tags":["Attributions"],"summary":"List the projects socially is built on","description":"Every upstream project whose data socially vendors or whose tool it runs, with its licence and the credit line to display. No API key needed. These credits are a licence obligation, not a feature.","security":[],"responses":{"200":{"description":"List the projects socially is built on","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{}}}}}},"400":{"description":"VALIDATION_ERROR / INVALID_TARGET / SSRF_BLOCKED: the issues, never the values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"UNAUTHORIZED / INVALID_TOKEN: the key is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"PAYMENT_REQUIRED / PLAN_GATE: clears by upgrading or buying credits, never by waiting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"RATE_LIMIT_EXCEEDED / QUOTA_EXCEEDED: Retry-After says when it clears.","headers":{"Retry-After":{"description":"When present, how many seconds to wait before trying again.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"default":{"description":"Any other failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"x-sdk":{"method":"attributions.list","returns":"AttributionDto[]"},"x-credits":"0 credits, and no key"}}},"components":{"schemas":{"ApiError":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"What went wrong, as a word a program can check."},"message":{"type":"string","description":"What went wrong, as a sentence."},"messageKey":{"type":"string","description":"`message` as a key, to show it in your reader's language, with `params` filling its blanks."},"params":{"type":"object","additionalProperties":{"type":["string","number"]},"description":"The values that fill `messageKey`'s blanks, such as a limit."},"details":{"description":"More about this error, such as retryAfterSecs."}}}}}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"An `so_` API key from the console."}}},"x-mcp-tools":[{"name":"resolve_target","title":"Resolve what a URL or @handle points at","description":"Turn a profile URL, post URL, website or @handle into what socially would read: the platform, the kind (profile, post, website), the normalized handle and the one canonical URL. No egress, no credit. Use it to validate input before a metered lookup.","inputSchema":{"type":"object","properties":{"input":{"type":"string","minLength":1,"maxLength":2048,"description":"A profile URL, post URL, website or @handle."},"platform":{"description":"Required when `input` is a bare handle.","type":"string","enum":["instagram","linkedin","youtube","tiktok","x","facebook","website"]}},"required":["input"],"additionalProperties":false}},{"name":"aggregate_intelligence","title":"Aggregate profiles into social intelligence","description":"Turn one or more profile reads (the six ExtractionResult keys) into the consolidated SocialIntelligence document: engagement, sentiment, content calendar, benchmark, a pt-BR knowledge-base markdown and personality hints. Pure and free. It only computes over what you send.","inputSchema":{"type":"object","properties":{"results":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"platform":{"type":"string","enum":["instagram","linkedin","youtube","tiktok","x","facebook","website"]},"url":{"type":"string"},"extractedAt":{"type":"string"},"profile":{"type":"object","properties":{"name":{"type":"string"},"username":{"type":"string"},"bio":{"type":"string"},"followers":{"type":["number","null"]},"following":{"type":["number","null"]},"postsCount":{"type":["number","null"]},"profileUrl":{"type":"string"},"avatarUrl":{"type":["string","null"]},"isVerified":{"type":["boolean","null"]},"isBusinessAccount":{"type":["boolean","null"]},"businessCategory":{"type":["string","null"]},"externalUrl":{"type":["string","null"]}},"required":["name","username","bio","followers","following","postsCount","profileUrl","avatarUrl"]},"recentPosts":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string"},"date":{"type":["string","null"]},"likes":{"type":["number","null"]},"comments":{"type":["number","null"]},"shares":{"type":["number","null"]},"views":{"type":["number","null"]},"url":{"type":["string","null"]},"thumbnail":{"type":["string","null"]},"duration":{"type":["string","null"]},"hashtags":{"type":"array","items":{"type":"string"}},"mediaType":{"anyOf":[{"type":"string","enum":["video","image","carousel","article","short","reel"]},{"type":"null"}]}},"required":["text","date","likes","comments","shares","views","url"]}},"summary":{"type":"string"}},"required":["platform","url","extractedAt","profile","recentPosts","summary"],"additionalProperties":{}}}},"required":["results"],"additionalProperties":false}},{"name":"list_platforms","title":"List the platforms and how each one is answering","description":"List supported capabilities separately from source health. `capabilities` reports profile/post lookup, topic video search, indexed topic search, hashtag search and country trend boards. YouTube and TikTok support topic video search; only YouTube has a country board. Only Instagram has indexed topic search, the reels on its public popular page for a word, which exists for some words only. TikTok and Instagram support hashtag search. Google Trends is a separate `/trending` source. `status` and `strategies` describe profile reads; `postStatus` and `postStrategies` describe post reads, with verification dates and the last 24 hours of results. A supported capability can still have no working source here. Free.","inputSchema":{"type":"object","properties":{},"additionalProperties":false}},{"name":"lookup_profile","title":"Look up a public profile","description":"Read a public profile on Instagram, TikTok, YouTube, LinkedIn, X, Facebook or a website. A `found` answer includes the profile, recent posts and platform details when available: account ids, links, creation dates and public counts. Instagram's `userId` and `graphId` name different ids; neither grants permission. Missing fields are null; unsupported blocks are absent. Data outcomes answer 200: `found`, `notFound` (confirmed by the platform, cached an hour) or `undecided` (refunded, never cached). 1 credit on a miss, 0 on a hit. `extractedAt` is the original read time, including cache and snapshot hits.","inputSchema":{"type":"object","properties":{"input":{"type":"string","minLength":1,"maxLength":2048,"description":"A profile URL, post URL, website or @handle."},"platform":{"type":"string","enum":["instagram","linkedin","youtube","tiktok","x","facebook","website"]},"posts":{"description":"Recent posts to return (0–15). Default 10. This limits the answer, not the source read.","type":"integer","minimum":0,"maximum":15},"refresh":{"description":"Bypass the cache and the snapshot; costs a credit even when fresh.","type":"boolean"}},"required":["input"],"additionalProperties":false}},{"name":"lookup_profiles_batch","title":"Look up up to ten profiles in one call","description":"Read up to ten profiles at once (five in flight, 30 s each, 120 s total). Answers 200 with `results` (the found ones), `failures` (the ones not found and the ones we could not check, which are refunded) and, with `aggregate: true`, the consolidated social intelligence the siblings persist. `partial` says whether anything failed.","inputSchema":{"type":"object","properties":{"targets":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"object","properties":{"input":{"type":"string","minLength":1,"maxLength":2048,"description":"A profile URL, post URL, website or @handle."},"platform":{"type":"string","enum":["instagram","linkedin","youtube","tiktok","x","facebook","website"]}},"required":["input"],"additionalProperties":false}},"posts":{"description":"Recent posts to return (0–15). Default 10. This limits the answer, not the source read.","type":"integer","minimum":0,"maximum":15},"aggregate":{"description":"Run the aggregator over the profiles that were found (0 credits).","type":"boolean"},"perTargetTimeoutMs":{"type":"integer","minimum":1000,"maximum":30000}},"required":["targets"],"additionalProperties":false}},{"name":"lookup_post","title":"Look up a public post","description":"Read one public Instagram, TikTok, YouTube, X, LinkedIn or Facebook post by URL. Returns its caption, author id, date, media and public counts when available. X, LinkedIn and Facebook posts are read only through a paid reader, with exact counts, and a deployment with no reader configured answers 503 before it charges. A LinkedIn post's `author.profileUrl` is the person's or the company's own page, and a Facebook post's `likes` counts every reaction. A full Instagram read adds source ids and ordered `frames` with image/video URLs, dimensions, duration and alt text; missing fields are null. YouTube adds video/channel ids, title and description, not a playable stream. Every read says its `detailLevel` (`detailed` from the post's own page or API, `embed` from a thin public card that leaves what it does not show null) and its `confidence`; a cached answer keeps both. CDN URLs can expire: download the files. Answers `found` or `undecided` (refunded), never `notFound`. 1 credit on a miss, 0 on a hit. Cached answers keep the original `extractedAt`.","inputSchema":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048,"description":"An http(s) URL."},"refresh":{"description":"Bypass the cache and the snapshot; costs a credit even when fresh.","type":"boolean"}},"required":["url"],"additionalProperties":false}},{"name":"read_website","title":"Read a public web page","description":"Fetch a public page through the proxy and return its readable text, title, description, images and ld+json. Pages that render with JavaScript are rendered when the budget allows (`render: auto`). Private and internal addresses answer 400 SSRF_BLOCKED. 1 credit on a miss, 0 on a hit (24 h).","inputSchema":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048,"description":"An http(s) URL."},"maxChars":{"description":"Cap on the readable text. Default 8,000.","type":"integer","minimum":500,"maximum":50000},"render":{"description":"`always` renders every time and never falls back to a plain fetch. It spends render budget and fails closed at RENDER_BUDGET_EXHAUSTED; a deployment with no renderer answers SIDECAR_UNAVAILABLE.","type":"string","enum":["auto","never","always"]},"refresh":{"description":"Bypass the cache and the snapshot; costs a credit even when fresh.","type":"boolean"}},"required":["url"],"additionalProperties":false}},{"name":"fetch_og","title":"Fetch a page's Open Graph card","description":"The Open Graph card a page publishes: title, description, image, site name, type, locale, canonical URL. 1 credit on a miss, 0 on a hit (24 h).","inputSchema":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048,"description":"An http(s) URL."},"refresh":{"description":"Bypass the cache and the snapshot; costs a credit even when fresh.","type":"boolean"}},"required":["url"],"additionalProperties":false}},{"name":"get_job","title":"Get a job","description":"Read a job: its status, progress and credits, plus its hits once it has finished (found and undecided by default, capped at 500; page the rest with list_job_hits) and its summary. Poll this, or attach to the stream, until status is succeeded, partial, failed or cancelled.","inputSchema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The job id from the 202 that created it."},"include":{"description":"Also embed the notFound hits (found and undecided come by default).","type":"string","enum":["notFound"]}},"required":["id"],"additionalProperties":false}},{"name":"list_job_hits","title":"List a job's hits","description":"Page through every site a job answered. It works while it is still running. Filter by outcome (found, notFound, undecided) or site category.","inputSchema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The job id from the 202 that created it."},"outcome":{"description":"Only hits with this outcome.","type":"string","enum":["found","notFound","undecided"]},"category":{"description":"Only sites in this category.","type":"string","enum":["archived","art","blog","business","coding","dating","finance","gaming","health","hobby","images","misc","music","news","political","search","shopping","social","tech","video","xx NSFW xx"]},"limit":{"default":50,"type":"integer","minimum":1,"maximum":200},"offset":{"default":0,"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["id"],"additionalProperties":false}},{"name":"cancel_job","title":"Cancel a job","description":"Stop a job. A queued job is cancelled at once and fully refunded; a running one is asked to stop and lands within seconds. The hits it already has are kept and nothing is refunded. A finished job answers 409.","inputSchema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The job id from the 202 that created it."}},"required":["id"],"additionalProperties":false}},{"name":"search_username","title":"Search a username across the web","description":"Sweep the site database for one handle and report every site's answer: found, notFound, or undecided when the site could not be read. Answers 202 with a job. Stream it or poll get_job. An identical search already running returns that same job and costs nothing.","inputSchema":{"type":"object","properties":{"username":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","description":"The handle to look for. Letters, digits, dot, dash and underscore."},"tier":{"default":"fast","description":"fast sweeps the top-ranked sites inside a minute (5 credits); full sweeps the whole database (20 credits).","type":"string","enum":["fast","full"]},"categories":{"description":"Only sweep sites in these categories.","maxItems":21,"type":"array","items":{"type":"string","enum":["archived","art","blog","business","coding","dating","finance","gaming","health","hobby","images","misc","music","news","political","search","shopping","social","tech","video","xx NSFW xx"]}},"sites":{"description":"Only sweep these site ids (from list_username_sites).","maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"countries":{"description":"Only sweep sites that serve these countries (ISO 3166-1 alpha-2). A site is kept when it serves any of them.","maxItems":50,"type":"array","items":{"type":"string","pattern":"^[A-Za-z]{2}$"}},"includeNsfw":{"default":false,"description":"Include sites marked as adult. Requires a plan that allows them.","type":"boolean"},"includeUnreliable":{"default":false,"description":"Also sweep sites the nightly check distrusts. They answer, but never above low confidence.","type":"boolean"}},"required":["username"],"additionalProperties":false}},{"name":"list_username_sites","title":"List the sites a username search covers","description":"The site database: what each site is, how it is classified, how much a hit there is worth, and what the nightly check currently thinks of it. Use the ids to scope a search with `sites`.","inputSchema":{"type":"object","properties":{"category":{"description":"Only sites in this category.","type":"string","enum":["archived","art","blog","business","coding","dating","finance","gaming","health","hobby","images","misc","music","news","political","search","shopping","social","tech","video","xx NSFW xx"]},"includeNsfw":{"description":"Include sites marked as adult in the listing.","type":"boolean"},"limit":{"default":50,"type":"integer","minimum":1,"maximum":200},"offset":{"default":0,"type":"integer","minimum":0,"maximum":9007199254740991}},"additionalProperties":false}},{"name":"lookup_email","title":"Find where an email address is registered","description":"Ask ~119 services whether an address already has an account there, using each service's own signup or recovery check, never a password reset and never a message to the address. Answers 202 with a job. A service that rate-limits us answers undecided, never 'no account'. Requires a paid plan and an accepted acceptable-use policy.","inputSchema":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"The address to look up. It is never messaged, only asked about. It is kept for as long as the job that reads it, and your history keeps a masked copy."}},"required":["email"],"additionalProperties":false}},{"name":"create_dossier","title":"Build a dossier for a username","description":"A deeper pass than search_username: every claimed profile is read for the details it publishes (names, locations, avatars, bios, other identifiers and the usernames it links to), and those are collected into one report. Answers 202 with a job; the per-site rows are its hits and the report is its summary.","inputSchema":{"type":"object","properties":{"username":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","description":"The handle to build the dossier around."},"depth":{"default":"top500","description":"top500 covers the highest-ranked sites; all covers the whole upstream database and takes several minutes.","type":"string","enum":["top500","all"]},"recursion":{"default":true,"description":"Follow usernames the claimed profiles link to, inside the same run. Turn it off for a narrower, faster dossier.","type":"boolean"},"includeNsfw":{"default":false,"description":"Include adult sites. Requires a plan that allows them.","type":"boolean"},"includeUnreliable":{"default":false,"description":"Also check sites the upstream database has marked unreliable.","type":"boolean"}},"required":["username"],"additionalProperties":false}},{"name":"list_trending","title":"Read what is trending in a country","description":"One country's board: Google's rising searches, each with the news behind it and an approximate volume, or YouTube's most popular videos. A board stays fresh in the cache for ten minutes. A cached board costs 0 credits. When the source refuses us, the last good board is served instead, flagged `stale` with the time it was captured, and it costs nothing either: you are charged for a reading, never for an attempt.","inputSchema":{"type":"object","properties":{"source":{"default":"google","description":"Which board to read: `google` for what a country is searching, `youtube` for what it is watching.","type":"string","enum":["google","youtube"]},"geo":{"type":"string","pattern":"^[A-Za-z]{2}$","description":"The country, ISO 3166-1 alpha-2 (US, BR, ES). REQUIRED: a board is one country's board, and there is no honest default for whose. This used to fall back to `US`, which meant a caller in São Paulo was quietly handed the American one. A country the source does not publish answers 400 and says so. For a subject rather than a country, see `search_news` and `search_youtube`. A trending board takes no query."},"category":{"description":"YouTube's video category id: `10` is Music, `17` Sport. YouTube only: Google Trends publishes no categories.","type":"string","minLength":1,"maxLength":20},"limit":{"default":20,"description":"Entries to return, 1–50. Google publishes ten per country.","type":"integer","minimum":1,"maximum":50}},"required":["geo"],"additionalProperties":false}},{"name":"search_youtube","title":"Search YouTube for videos on a subject","description":"What creators are publishing about a subject, in the order YouTube ranks it: title, channel, exact view count, duration and the description snippet, plus real upload dates, likes and comments when the deployment holds a Data API key (`stats: \"exact\"`). Read from the results page rather than the API's 100-unit search, so one key's day holds thousands of these. The answer is cached for thirty minutes, and the same question again costs nothing.","inputSchema":{"type":"object","properties":{"q":{"type":"string","minLength":2,"maxLength":200,"description":"What to search for, the way you would type it into YouTube."},"limit":{"default":10,"description":"Videos to return, 1–20. One page is one read: a larger `limit` on the same question is served from it.","type":"integer","minimum":1,"maximum":20},"recency":{"description":"Only videos uploaded within the window: `day`, `week`, `month` or `year`. Absent means any time.","type":"string","enum":["day","week","month","year"]},"sort":{"default":"relevance","description":"`relevance` uses YouTube's ranking. `views` puts the most-watched videos first. Combine `views` with `recency` to find popular uploads within that window, not to measure growing views. Without a window, `views` includes all-time hits.","type":"string","enum":["relevance","views"]},"country":{"description":"The country to rank for, ISO 3166-1 alpha-2 (BR, US, ES). Omit it for YouTube's own ranking rather than a country's.","type":"string","pattern":"^[A-Za-z]{2}$"},"language":{"description":"The language to ask and read the page in, ISO 639-1 (en, pt, es). Omit it and your `accept-language` header decides.","type":"string","pattern":"^[A-Za-z]{2}$"},"refresh":{"description":"Read the page again instead of serving the half-hour cache. Charged like any read, and the fresh answer replaces the cached one.","type":"boolean"}},"required":["q"],"additionalProperties":false}},{"name":"search_news","title":"Search the news for stories on a subject","description":"What the press published about a subject inside a window: headline, publisher, and the date the story ran, read from Google News' public search feed. This is the subject half of trending: a trending board takes no query at all, so `q` plus `recency` is how you ask what is being said about one thing right now. Links are Google's own redirect, not the publisher's URL. Cached for ten minutes.","inputSchema":{"type":"object","properties":{"q":{"type":"string","minLength":2,"maxLength":200,"description":"The subject to read about, the way you would say it."},"limit":{"default":20,"description":"Stories to return, 1–50. One feed is one read: a larger `limit` on the same question is served from it.","type":"integer","minimum":1,"maximum":50},"recency":{"description":"Only stories published within the window: `day`, `week`, `month` or `year`. Absent means any time, which for news is rarely the question.","type":"string","enum":["day","week","month","year"]},"country":{"description":"The Google News edition, ISO 3166-1 alpha-2 (BR, US, ES). There is no worldwide edition: leave it out and one is chosen from `language`. The answer always says which one ran.","type":"string","pattern":"^[A-Za-z]{2}$"},"language":{"description":"The edition's language, ISO 639-1 (en, pt, es). Default `en`.","type":"string","pattern":"^[A-Za-z]{2}$"},"refresh":{"description":"Read the feed again instead of serving the ten-minute cache. Charged like any read.","type":"boolean"}},"required":["q"],"additionalProperties":false}},{"name":"search_instagram","title":"Search Instagram's popular reels on a topic","description":"The reels Instagram lists on its public popular page for a topic: shortcode, author, caption, exact play count and the date read off the media id. This is indexed discovery, not a hashtag feed. Instagram publishes these pages for some words only (`art`, `travel` and `music` have one; `fitness` and `nasa` did not when measured), lists up to 12 reels, and says in `hasMore` when it has more that cannot be read without signing in. A word with no page answers `indexed: false` and costs nothing. Cached for thirty minutes.","inputSchema":{"type":"object","properties":{"q":{"type":"string","minLength":2,"maxLength":60,"description":"The topic, the way Instagram names its popular pages: one word or a few (\"travel\", \"street photography\"). Not every word has a page."},"limit":{"default":12,"description":"Reels to return, 1–12. One page is one read: a smaller `limit` on the same topic is served from it.","type":"integer","minimum":1,"maximum":12},"refresh":{"description":"Read the page again instead of serving the half-hour cache. Charged like any read, and the fresh answer replaces the cached one.","type":"boolean"}},"required":["q"],"additionalProperties":false}},{"name":"search_tiktok","title":"Search TikTok for videos on a word or a hashtag","description":"What TikTok lists for a word or a hashtag: caption, author, exact views, likes, comments and shares, the date, the length and the tags, read through a paid reader. A word searches TikTok's search bar and takes a window (`recency`), an order (`sort`) and a country. A `#tag` reads that tag's own page, which lists its popular videos of any age in TikTok's order, from any country, and takes none of those. A word's page lists up to 30 videos and a tag's about 20: pass `nextCursor` back as `cursor` for the next one, which is another read. The author's follower count is on keyword results and absent from a hashtag feed. A deployment with no TikTok reader configured answers 503 before it charges. Cached for thirty minutes.","inputSchema":{"type":"object","properties":{"q":{"type":"string","minLength":2,"maxLength":200,"description":"A word or a phrase for TikTok's search bar (\"padaria artesanal\"), or a hashtag with its # (\"#padaria\")."},"limit":{"default":10,"description":"Videos to return, 1–30. One page is one read: a smaller `limit` on the same question is served from it, and a `limit` that cuts the page ends the cursor.","type":"integer","minimum":1,"maximum":30},"recency":{"description":"Words only. Only videos posted within the window: `day`, `week`, `month`, `quarter` (90 days) or `half_year` (180 days), TikTok's own filters. Absent means all time. A hashtag takes none.","type":"string","enum":["day","week","month","quarter","half_year"]},"sort":{"description":"Words only. `relevance` (the default) is TikTok's ranking, `likes` puts the most-liked first and `recent` the newest. Combine `likes` with `recency` to find what is working lately. A hashtag takes none.","type":"string","enum":["relevance","likes","recent"]},"country":{"description":"Words only. Search as a person in this country would, ISO 3166-1 alpha-2 (BR, US, ES). Absent means no country. A code with no region behind it is not refused and filters nothing, so check `videos[].region` against the country you meant. A hashtag takes none.","type":"string","pattern":"^[A-Za-z]{2}$"},"cursor":{"description":"The `nextCursor` of the page before. Each page is another read and another charge, and a cursor only works against the source that made it.","type":"string","maxLength":40},"refresh":{"description":"Read the page again instead of serving the half-hour cache. Charged like any read, and the fresh answer replaces the cached one.","type":"boolean"}},"required":["q"],"additionalProperties":false}},{"name":"search_instagram_hashtag","title":"Search Instagram for the posts under a hashtag","description":"What Instagram lists under a hashtag, read through a paid reader: shortcode, author, caption, exact likes, comments and plays, the date and the cover. `sort: top` (the default) is Instagram's own mix of popular and recent posts, in its order, not a ranking by likes, and it can reach back months. `sort: recent` lists the newest posts first. A page lists 24 to 33 posts: pass `nextCursor` back as `cursor` for the next one, which is another read. A like count the owner hid reads `null`. A tag with no posts answers an empty page and costs nothing. A deployment with no Instagram reader configured answers 503 before it charges. Cached for fifteen minutes.","inputSchema":{"type":"object","properties":{"q":{"type":"string","minLength":2,"maxLength":200,"description":"A hashtag, with or without its # (\"padaria\" or \"#padaria\"). Letters, digits and underscores only."},"limit":{"default":40,"description":"Posts to return, 1–40. One page is one read: a smaller `limit` on the same tag is served from it, and then no `nextCursor` comes with it.","type":"integer","minimum":1,"maximum":40},"sort":{"description":"`top` (the default) is Instagram's own mix of popular and recent posts, in its order. `recent` lists the newest posts first.","type":"string","enum":["top","recent"]},"cursor":{"description":"The `nextCursor` of the page before. Each page is another read and another charge, and a cursor only works with the source and the `sort` that made it.","type":"string","maxLength":300},"refresh":{"description":"Read the page again instead of serving the fifteen-minute cache. Charged like any read, and the fresh answer replaces the cached one.","type":"boolean"}},"required":["q"],"additionalProperties":false}},{"name":"get_webhook","title":"Get your webhook endpoint","description":"The endpoint events are being POSTed to, which ones it is subscribed to, and whether it is still healthy. `null` when none is registered. `disabledReason: \"failures\"` means we switched it off after 10 failed deliveries in a row. Only a final failure counts, not an attempt that will be retried. Fix the endpoint, then save it again or send a test that succeeds to switch it back on. Free.","inputSchema":{"type":"object","properties":{},"additionalProperties":false}},{"name":"set_webhook","title":"Register your webhook endpoint","description":"Point socially.run at an https URL and start receiving events there. The answer carries the signing secret ONCE, when it is minted: keep it. Every delivery is signed with it in the `x-socially-signature` header (`t=<unix>,v1=<hmac-sha256 of \"<t>.<body>\">`), and that signature is how you know a request is really from us. Calling this again updates the URL or the subscription and keeps the same secret unless you ask to rotate it. Saving also re-enables an endpoint we had disabled. Up to 5 attempts for no answer, 5xx, 408, 425 or 429, with gaps of 30, 60, 120 and 240 seconds. A longer Retry-After extends the gap, capped at one hour. Other 4xx and all redirects are final. Free.","inputSchema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Where to POST events, e.g. https://api.yourapp.com/hooks/socially."},"events":{"description":"Which events to receive: job.completed, job.failed. Defaults to all of them.","minItems":1,"type":"array","items":{"type":"string","enum":["job.completed","job.failed"]}},"rotateSecret":{"description":"Mint a new signing secret and return it. The old one stops working.","type":"boolean"}},"required":["url"],"additionalProperties":false}},{"name":"test_webhook","title":"Fire a test event at your endpoint","description":"Send a `ping` event to your registered endpoint right now and wait for the answer, so you can verify the URL and your signature check without waiting for a real job. The result is the actual outcome: `ok: false` carries the HTTP status your server answered, or why we could not reach it. A ping that lands also revives an endpoint we had auto-disabled. It never retries, and it does not count against the failure streak of a real event. Free.","inputSchema":{"type":"object","properties":{},"additionalProperties":false}},{"name":"get_attributions","title":"List the projects socially is built on","description":"Every upstream project whose data socially vendors or whose tool it runs, with its licence and the credit line to display. No API key needed. These credits are a licence obligation, not a feature.","inputSchema":{"type":"object","properties":{},"additionalProperties":false}}]}