Manifold consolidates SEO research, AI search visibility tracking, social media intelligence, advertising research, and B2B lead discovery in one platform. Analyze Google rankings and backlinks, monitor brand mentions in ChatGPT and Perplexity, research social content across Reddit, YouTube, TikTok, LinkedIn, and X, and find business contacts with verified work emails.
Encrypted at rest, isolated from the model
Resolved from an AES-256-GCM vault at the moment of the call and attached to the request — the model never sees the secrets.
Try asking
Candidate keywords around a seed, with volume, difficulty, intent, CPC and trend for each. Use when: "find keywords for X", "what should I target around X", "keyword ideas for a page about X". Not for: metrics on keywords the user already has, use seo_get_keyword_metrics (this tool already returns those metrics, so do not call it afterwards). Prompts people ask AI engines, use aeo_search_prompts. The top-10 page for one query, use seo_get_serp. Returns: List. rows[]: keyword, volume, kd (0 to 100), intent, cpc (USD), competition, trend[12] (month, volume). volume, kd, cpc null = provider has no data; 0 = measured zero. Params: seed (required), mode ("suggestions" contains the seed | "related" SERP-similar | "ideas" same category, default suggestions), location ("United States"), language ("en"), limit (100, max 1000), cursor, provider, max_credits, dry_run. Cost: 5 + 5 per 100 rows. Default 100 rows = 10 credits. Cached 7 days. Example: {"seed": "crm for startups", "mode": "suggestions", "limit": 50}
Volume, difficulty, intent, CPC and 12-month trend for keywords you already have, with AI-engine prompt volume on request. Use when: the user supplies keywords, or you need numbers for a list from elsewhere. ai_volume true when the question is how often AI engines see the keyword. Not for: discovering keywords, use seo_search_keywords (it already includes these metrics, do not call this after it). AI-engine prompts, use aeo_search_prompts. Checking rankings, use seo_get_position. Returns: List. rows[]: keyword, volume, kd, intent, cpc, competition, trend[12], ai_volume, ai_trend[12]. One row per input keyword in the order given. volume/kd null = provider has no data; 0 = measured zero. With source google_ads, kd and intent are always null and keywords over 80 characters come back all null. ai_volume and ai_trend are null unless ai_volume is true. Params: keywords[] (required, max 1000), source ("labs" | "google_ads", default labs; google_ads is Google Keyword Planner's own volume, slower), ai_volume (false), location ("United States"), language ("en"), provider, max_credits, dry_run. Cost: 5 + 5 per 100 keywords with source labs; 24 flat with source google_ads; ai_volume adds 4 + 4 per 100 keywords. Default 100 keywords = 10 credits. Cached 7 days. Example: {"keywords": ["crm for startups", "hubspot alternative"], "ai_volume": true}
The top organic results and SERP features Google shows for one query. Use when: "what ranks for X", "who is on page one for X", "is there a featured snippet or AI overview for X". Not for: where one site ranks for a keyword, use seo_get_position (it scans the top 100 for you). General web retrieval to read pages, use web_search_pages. Keyword ideas, use seo_search_keywords. Returns: Record. keyword, location, language, device, check_url, results_count, features[] (featured_snippet, people_also_ask, video, ai_overview and others), results[] (rank, organic_rank, type, url, domain, title, snippet), ai_overview (text, references[]) or null. Params: keyword (required), location ("United States"), language ("en"), device ("desktop" | "mobile"), depth (10, max 100), ai_overview (false; true adds Google's AI overview and its cited sources), provider, max_credits, dry_run. Cost: 1 credit per 10 results, +1 with ai_overview. Default top 10 = 1 credit. Cached 24 hours. Example: {"keyword": "hubspot alternative", "depth": 10, "ai_overview": true}
Where one target ranks for one keyword, scanning the top 100 server-side. Use when: "where does example.com rank for X", "did we make page one for X", a rank check for a handful of keywords. Not for: every keyword a domain ranks for, use seo_get_ranked_keywords. The full page-one list, use seo_get_serp. Tracking over time: call this on a schedule from the host; the server keeps no history. Returns: Record. keyword, target, rank (absolute, null when not in the top 100), organic_rank, url, title, scanned_depth, above[] (rank, domain, url of the organic results ahead, at most 10). Params: keyword (required), target (required; example.com covers subdomains, www.example.com is that host, a URL is that page), location ("United States"), language ("en"), device ("desktop"), provider, max_credits, dry_run. Cost: 6 credits flat. Cached 24 hours. Example: {"keyword": "hubspot alternative", "target": "example.com"}
Traffic estimate, ranked keyword count, position spread, top pages and domain rank for one domain. The canonical source of domain rank. Use when: "how strong is competitor.com", "how much traffic does X get", sizing a site before a deeper look. Not for: the keywords behind the traffic, use seo_get_ranked_keywords. Link counts, use seo_get_backlink_summary (its domain_rank equals this one). Many domains at once, use seo_get_domain_ratings for domain rank or seo_get_traffic_estimates for traffic. Returns: Record. target, domain_rank (0 to 1000 on DataForSEO, the same kind of number as Ahrefs DR or Moz DA but not the same scale), organic_traffic, organic_keywords, organic_traffic_cost (USD), positions (top_3, top_10, top_100), top_pages[] (url, organic_traffic, organic_keywords), history[] (12 months: month, organic_traffic, organic_keywords) only with history true. null = provider has no data. Params: target (required), location ("United States"), language ("en"), history (false), provider, max_credits, dry_run. Cost: 5 credits; +56 with history. Cached 7 days. Example: {"target": "competitor.com"}
Keywords a domain or one page ranks for in the top 100, with position, URL and metrics. Use when: "what does competitor.com rank for", "which keywords send traffic to this page", building a list of a site's topics. Not for: keywords a competitor has that you do not, use seo_get_keyword_gap. One keyword's position, use seo_get_position. New keyword ideas, use seo_search_keywords. Returns: List. rows[]: keyword, rank, url, volume, kd, cpc, intent, traffic (estimated monthly visits from this keyword). Sorted by traffic. null = provider has no data. Params: target (required; a domain covers subdomains, a URL is that page only), location ("United States"), language ("en"), limit (100, max 1000), cursor, provider, max_credits, dry_run. Cost: 5 + 5 per 100 rows. Default 100 rows = 10 credits. Cached 7 days. Example: {"target": "competitor.com", "limit": 200}
Domains that share search results with a target, with how many keywords overlap. SERP competitors, not business competitors. Use when: "who competes with example.com in search", "which sites show up for the same queries as X", choosing competitors for a keyword gap. Not for: the keywords themselves, use seo_get_keyword_gap. A single domain's strength, use seo_get_domain_overview. Returns: List. rows[]: domain, shared_keywords, avg_position, organic_traffic, organic_keywords. Sorted by shared keywords. The target itself is excluded. Params: target (required), location ("United States"), language ("en"), limit (100, max 1000), cursor, provider, max_credits, dry_run. Cost: 5 + 5 per 100 rows. Default 100 rows = 10 credits. Cached 7 days. Example: {"target": "example.com", "limit": 20}
Keywords one competitor ranks for in the top 100 that the target does not rank for at all. Use when: "what does competitor.com rank for that we do not", "find gaps against X", content opportunities from a rival. Not for: everything a domain ranks for, use seo_get_ranked_keywords. Finding who the competitors are, use seo_get_serp_competitors. Fresh ideas around a topic, use seo_search_keywords. Returns: List. rows[]: keyword, competitor, competitor_rank, competitor_url, volume, kd, cpc, intent. Sorted by volume. Params: target (required), competitor (required, one domain), location ("United States"), language ("en"), limit (100, max 1000), cursor, provider, max_credits, dry_run. Cost: 5 + 5 per 100 rows. Default 100 rows = 10 credits. Cached 7 days. Example: {"target": "example.com", "competitor": "competitor.com", "limit": 100}
Link totals for a domain or page: backlinks, referring domains, dofollow share, link types and domain rank. Use when: "how many links does X have", "what is X's link profile like", a quick authority check alongside seo_get_domain_overview. Not for: the individual links or their anchor text, use seo_get_backlinks. The sites linking, use seo_get_referring_domains. Domain rank for many domains, use seo_get_domain_ratings. Returns: Record. target, domain_rank (equals seo_get_domain_overview's domain_rank), backlinks, referring_domains, referring_main_domains, referring_ips, dofollow_backlinks, dofollow_share (0 to 1), broken_backlinks, first_seen, link_types (anchor, image, redirect, canonical counts). null = provider has no data. Params: target (required; a domain includes subdomains unless include_subdomains is false), include_subdomains (true), provider, max_credits, dry_run. Cost: 10 credits flat. Cached 7 days. Example: {"target": "competitor.com"}
Individual backlinks pointing at a domain or page, strongest referring domain first. Use when: "show me the links to this page", "which pages link to competitor.com", finding link sources to replicate. Not for: totals only, use seo_get_backlink_summary. One row per linking site, use seo_get_referring_domains. Rating the linking sites, use seo_get_domain_ratings. Returns: List. rows[]: url_from, url_to, domain_from, dr_from, page_title, anchor, dofollow, type, first_seen, last_seen, lost. Params: target (required), include_subdomains (true), limit (100, max 1000), cursor, provider, max_credits, dry_run. Cost: 10 + 1.5 per 100 rows. Default 100 rows = 12 credits. Cached 7 days. Example: {"target": "https://competitor.com/blog/best-crm", "limit": 50}
Domains linking to a target, one row per domain, with domain rank, link counts and spam score. Use when: "who links to competitor.com", "build a list of sites to pitch for links", link prospecting from a rival's profile. Not for: every individual link, use seo_get_backlinks. Totals, use seo_get_backlink_summary. Rating your own list of domains, use seo_get_domain_ratings. Returns: List. rows[]: domain, domain_rank, backlinks, referring_pages, dofollow_backlinks, spam_score, first_seen, lost. Sorted by domain_rank. Params: target (required), include_subdomains (true), limit (100, max 1000), cursor, provider, max_credits, dry_run. Cost: 10 + 1.5 per 100 rows. Default 100 rows = 12 credits. Cached 7 days. Example: {"target": "competitor.com", "limit": 200}
Domain rank and Ahrefs DR only, for up to 1,000 domains in one call. The cheap way to rate a list. Use when: "rate these domains", "which of these sites are worth a link", filtering a prospect list by authority. Not for: traffic numbers, use seo_get_traffic_estimates (10x the cost). A full profile of one domain, use seo_get_domain_overview or seo_get_backlink_summary. Returns: List. rows[]: domain, domain_rank (0 to 1000 on DataForSEO, for the host as given; 0 for a domain the index does not know), ahrefs_dr (Ahrefs Domain Rating, 0 to 100, always for the registered domain, so www.github.com and gist.github.com both get github.com's; 0 for a domain Ahrefs does not know, null when it did not answer). One row per distinct domain, in the order first given: duplicates and case variants are merged, and a full URL is rated by its host. ahrefs_status says what a null ahrefs_dr means: ok (Ahrefs has no rating), partial (the domains in ahrefs_unanswered got no answer), failed or not_configured (Ahrefs did not answer; the null says nothing). ahrefs_attribution: wherever you show ahrefs_dr, show its text linked to its url next to it. errors[] lists inputs that were not valid domains. Params: targets[] (required, max 1000), provider, max_credits, dry_run. Cost: 1 + 2.5 per 100 domains, for domain_rank; ahrefs_dr adds nothing. Default 100 domains = 4 credits. Cached 7 days, or 1 hour when ahrefs_status is not ok. Example: {"targets": ["example.com", "competitor.com", "blog.example.net"]}
Estimated monthly organic and paid traffic for up to 1,000 domains in one call. Use when: "how much traffic do these sites get", comparing a list of domains by size, checking a prospect list for reach. Not for: authority, use seo_get_domain_ratings (a tenth of the cost). One domain in depth, use seo_get_domain_overview. Returns: List. rows[]: domain, organic_traffic, organic_keywords, paid_traffic. One row per input domain in the order given. null = provider has no data. errors[] lists inputs that were not valid domains. Params: targets[] (required, max 1000), location ("United States"), language ("en"), provider, max_credits, dry_run. Cost: 50 + 50 per 100 domains. Default 100 domains = 100 credits. Cached 7 days. Example: {"targets": ["example.com", "competitor.com"]}
An on-page snapshot of one URL: title, meta description, canonical, robots, headings, word count, schema types and link counts. Fetched live, free. Use when: "check the on-page SEO of this URL", "what schema does this page use", a quick look before a crawl. Not for: a whole site, use seo_run_technical_crawl. Rankings for the page, use seo_get_ranked_keywords with the URL. What the page ranks against, use seo_get_serp. Returns: Record. url, final_url, status, title, meta_description, canonical, robots_meta, lang, h1[], h2[], word_count, schema_types[], links_internal, links_external, images, images_without_alt. null = the tag is absent. Params: url (required, http or https), max_credits, dry_run. Cost: 0 credits, rate limited. Cached 1 hour. Example: {"url": "https://example.com/pricing"}
Crawl a site for technical SEO issues. Slow: returns a task_id, then read the result with get_task. Use when: "audit example.com", "crawl the site for broken links and duplicate titles", a technical health check. Not for: one page, use seo_get_page. Rankings or traffic, use seo_get_domain_overview. Returns: Task. task_id now; get_task returns target, pages_requested, pages_crawled, rendered, onpage_score, status_codes, broken_links, broken_resources, non_indexable, duplicate_titles, duplicate_descriptions, issues[] (check, pages, sample_urls[]). Results expire after 30 days. Params: target (required, a domain), max_pages (required, max 1000 on the Free plan), render (false; true executes JavaScript and costs 10x), max_credits, dry_run. Lighthouse is not available in this phase. Cost: 3 credits per 100 pages; 30 per 100 pages rendered. The charge is on max_pages requested, not pages crawled. Default 1,000 pages = 30 credits. Example: {"target": "example.com", "max_pages": 500}
The result of a run_* tool, or TaskPending while it runs. Use when: you hold a task_id from seo_run_technical_crawl or aeo_run_ai_answers. Not for: starting work; call the run_* tool first. Returns: Record. The same shape the synchronous tool would return, under result, with meta.credits_charged as settled. TaskPending carries poll_after_s; wait that long before calling again. TaskFailed carries the reason. Params: task_id (required), max_credits, dry_run. Cost: 0 credits. Example: {"task_id": "task_01J..."}
Sends a report to the Manifold team: an error a tool returned, data that looks wrong, a tool or parameter that is missing, or anything the user asks you to pass on. Free. Use when: a call failed in a way its typed error does not explain, a result contradicts itself or the source, the same ProviderUnavailable keeps coming back, no tool answers what the user needs, "tell Manifold that...". Tell the user what you sent. Not for: retrying a call; follow the typed error first. Asking for help with a task; this sends no reply. Contacting a person or a company; this reaches only the Manifold team. Returns: Record. feedback_id, to quote if the user contacts support. Params: kind (required: error | wrong_data | feature_request | other), message (required, up to 4000 characters: what was asked, what came back, what was expected; no passwords, keys or tokens), tool (the tool the report is about), request_id (meta.request_id of the call it is about), max_credits, dry_run. Cost: 0 credits. Up to 20 reports per workspace per day; over that, ProviderUnavailable with retry_after_s. Example: {"kind": "error", "tool": "seo_get_serp", "request_id": "3f1c9a2e-8d4b-4c6f-9e1a-7b2d5c8f0a13", "message": "seo_get_serp returned ProviderUnavailable five times in ten minutes for the keyword crm for startups."}
What AI engines answer for a prompt, with the brands they mention and the sources they cite. Slow: returns a task_id, then read the result with get_task. Use when: "does ChatGPT recommend us for X", "who do AI engines cite for X", an AI visibility baseline for a brand across engines. Not for: which prompts people ask, use aeo_search_prompts. Google's ten blue links, use seo_get_serp (ai_overview: true adds the overview to it at 1 credit). Whether a site is ready for AI crawlers, use aeo_get_site_readiness. Returns: Task. task_id now; get_task returns prompts[], engines[], brands[], rows[] (prompt, engine, model, answer, mentions[] (brand, mentioned, position, cited), citations[] (position, url, domain, title), answered_at) and errors[] for cells that failed. answer null = the engine showed no AI answer. chatgpt and gemini are what their apps show a person, model chosen by the app; claude and perplexity come from their model APIs. Answers are live and non-deterministic; results are kept 30 days and never cached. Params: prompts[] (required, max 10, each max 500 characters), engines[] (default chatgpt, claude, gemini, perplexity, ai_overview; also ai_mode), brands[] (names or domains to detect, max 10), location ("United States"), language ("en"), max_credits, dry_run. Cost: per prompt, 6 credits each for claude and perplexity, 2 each for chatgpt, gemini, ai_overview and ai_mode. Default 1 prompt on the five default engines = 18 credits. A cell that fails is not charged. Example: {"prompts": ["best crm for startups"], "brands": ["HubSpot", "pipedrive.com"]}
Prompts people ask an AI engine (ChatGPT or Google AI Overview) about a topic or brand, from the provider's index of observed answers. Not keywords. Use when: "what do people ask ChatGPT about X", "which prompts mention our brand", building an AI visibility baseline. Not for: Google keywords and volumes, use seo_search_keywords. What the AI engines answer right now, use aeo_run_ai_answers. Web pages to read, use web_search_pages. Returns: List. rows[]: prompt, ai_search_volume (a People Also Ask proxy, not query logs), engines[], mentions_brand (a domain input is cited, a keyword input appears in the answer), cited_domains[], answer_preview, last_seen. Params: keyword or domain (one required), engine ("chatgpt" | "ai_overview", default chatgpt), location ("United States"), language ("en"), limit (50, max 500), cursor, provider, max_credits, dry_run. Cost: 30 + 30 per 100 rows. Default 50 rows = 45 credits. Cached 7 days. Example: {"domain": "example.com", "limit": 50}
Whether a site is set up for AI answer engines, from about seventeen live fetches of its origin, free. Checks what the engines document as gating their answers: robots.txt access for every known AI crawler (search, user fetch, training), CDN or WAF rules that turn away the answer crawlers' user agents before robots.txt is read, content present in the raw HTML without JavaScript on the homepage and on one page sampled from the sitemap, noindex and snippet directives, then freshness signals, redirect chains, sitemap, title and description, structured data, and llms.txt. Use when: "is our site ready for AI search", "do we block GPTBot", "are we blocking ChatGPT at Cloudflare", "do we have an llms.txt", before an AI visibility push. Not for: what the engines answer, use aeo_run_ai_answers. A full technical audit, use seo_run_technical_crawl. One page's on-page tags, use seo_get_page. Returns: Record. checks[] (check, ok, tier, detail, source) with failing checks first. tier says how much a check is worth: blocks_citations is documented by an engine, evidence_backed is measured, hygiene is standard practice, policy is a legitimate choice that never fails, unproven is reported but never fails on absence (llms.txt, schema presence). Plus robots_txt (ai_bots[] with kind and honours_robots, sitemaps, content_signal), edge (probes[] per answer crawler user agent), homepage (status, response_ms, word_count and js_shell from the raw HTML, canonical, robots_meta, x_robots_tag, schema_types, same_as, date_modified, last_modified_header), sample_page (the same rendering and date fields for the first content URL in the sitemap, null when there is none), markdown (whether the origin answers Accept: text/markdown with the content, which passes the JavaScript check), redirects[], sitemap, llms_txt (present, issues[]), llms_full_txt. No crawl, no LLM call. Params: target (required, a domain or URL; fetches go to its origin), max_credits, dry_run. Cost: 0 credits, rate limited. Cached 1 hour. Example: {"target": "example.com"}
The Search Console and Bing Webmaster properties the workspace's connected accounts can read. The first console call; every other console tool takes a property from here. Use when: "what sites are in my Search Console", before any console_get_* call, or to check which engine is connected. Not for: third-party sites the user does not own, use seo_get_domain_overview. Live rankings, use seo_get_serp. Returns: List. rows[]: engine (google | bing), property (the id to pass on: sc-domain:example.com, https://example.com/ or a Bing site URL), permission (Google: siteOwner, siteFullUser, siteRestrictedUser, siteUnverifiedUser; Bing: null), verified. NotConnected when no account of that engine is connected; its connect_url is where the user connects one. Params: engine ("all" | google | bing), max_credits, dry_run. Cost: 0 credits. The user's own data is free; 60 console calls per minute per workspace. Cached 1 hour. Example: {"engine": "all"}
Clicks, impressions, CTR and average position from the user's own Search Console or Bing data, grouped by query, page, country, device or date. Use when: "which queries bring traffic to my site", "how did page X do last month", "impressions by country", finding queries that rank on page two, a rank check on the user's own site. Not for: a site the user does not own, use seo_get_ranked_keywords. Search volume or difficulty, use seo_get_keyword_metrics. Why a page is not indexed, use console_inspect_url. Returns: List, most clicks first, ties broken by impressions descending. rows[]: query, page, country (ISO alpha-3), device, date (the dimensions asked for; null otherwise), clicks, impressions, ctr (0 to 1), position (average, 1-based). Google data lags about two days and keeps 16 months; Bing query and page rows are the last weeks with no date range, its date rows are daily totals. Totals (sum of clicks, impressions) differ by grouping due to Google's aggregation; this is normal Google behaviour. Params: property (required), engine ("google" | bing), dimensions[] (["query"]; Bing takes one of query, page, date), start_date (default 28 days before end_date), end_date (default 3 days ago, the freshest complete day), search_type ("web"; Google), filters[] (dimension, operator, expression; Google), limit (100, cap 1000; Google serves 25,000 per query), cursor, max_credits, dry_run. Cost: 0 credits. Cached 6 hours. Example: {"property": "sc-domain:example.com", "dimensions": ["query", "page"], "start_date": "2026-08-01", "end_date": "2026-08-31"}
The sitemaps submitted for one of the user's properties, with when they were read, how many URLs they carry and their errors. Use when: "is my sitemap picked up", "how many URLs did Google read from the sitemap", checking a submission after a site change. Not for: whether one URL is indexed, use console_inspect_url. Finding pages a sitemap misses, use seo_run_technical_crawl. Returns: List. rows[]: path, type, submitted_at, last_read_at, pending, is_index, urls_submitted, urls_indexed (Google reports 0 today), warnings, errors. null = the engine does not say. Params: property (required), engine ("google" | bing), max_credits, dry_run. Cost: 0 credits. Cached 6 hours. Example: {"property": "https://www.example.com/"}
Google's index status for one URL of the user's property: indexed or not and why, last crawl, canonical, mobile usability and rich results. Use when: "why is this page not in Google", "when was this page last crawled", "which canonical did Google pick", checking a page after a fix. Not for: many URLs at once (Google allows 2,000 inspections per property per day, shared by everyone on the property), use console_get_search_analytics with dimension page to find which pages get impressions. The page's own HTML, use seo_get_page. Bing, which has no inspection. Returns: Record. url, property, verdict (PASS | PARTIAL | FAIL | NEUTRAL), coverage_state (Google's sentence, for example Submitted and indexed), indexing_state, robots_txt_state, page_fetch_state, last_crawl_at, crawled_as, google_canonical, user_canonical, referring_urls[], sitemaps[], mobile_usability (verdict, issues[]), rich_results (verdict, detected_items[]), inspection_link. null = Google did not report it. Params: property (required), url (required, under the property), max_credits, dry_run. Cost: 0 credits, Google only. Cached 24 hours. Example: {"property": "sc-domain:example.com", "url": "https://www.example.com/pricing"}
URLs Bing had trouble crawling on the user's property: HTTP errors, redirects, robots.txt blocks, DNS and timeouts, with the inbound link count of each. Use when: "what is Bing failing to crawl", "which of my pages 404", a Bing-side health check. Not for: Google, which exposes nothing equivalent outside console_inspect_url. A crawl of the whole site with our crawler, use seo_run_technical_crawl. Returns: List, one row per URL and issue. rows[]: url, issue (Code301, Code302, Code4xx, Code5xx, BlockedByRobotsTxt, ContainsMalware, ImportantUrlBlockedByRobotsTxt, DnsErrors, TimeOutErrors), http_status, inlinks, seen_at. Fixed issues stay listed a few days. Params: property (required; a Bing site URL), limit (100), cursor, max_credits, dry_run. Cost: 0 credits, Bing only. Cached 6 hours. Example: {"property": "https://example.com"}
The Google Analytics 4 properties the workspace's connected Google account can read, with the account each sits under. The first analytics call; the other analytics tools take a property from here. Use when: "what's in my Google Analytics", "which GA4 property is example.com", before any analytics_get_* call. Not for: Search Console sites, use console_list_properties. Traffic to a site the user does not own, use seo_get_traffic_estimates. Returns: List. rows[]: property (the id to pass on: properties/123456789), property_name, property_type (PROPERTY_TYPE_ORDINARY, SUBPROPERTY or ROLLUP), account (accounts/123), account_name. NotConnected when no Google account is connected, or when the connected one has not granted Analytics; its connect_url is where the user connects or reconnects. Params: max_credits, dry_run. Cost: 0 credits. The user's own data is free; it shares the console's 60 calls per minute per workspace. Cached 1 hour. Example: {}
Every dimension and metric one Google Analytics 4 property reports, with the api_name analytics_get_report takes, custom dimensions and metrics included. Use when: a report needs a field outside the common ones, "what custom dimensions do we track", checking a conversion or event-scoped field's name before asking for it, or after analytics_get_report rejected a field name. Not for: the numbers themselves, use analytics_get_report. Returns: List, dimensions then metrics, in Google's order. rows[]: kind (dimension | metric), api_name, ui_name, description, category, custom (defined on this property: customEvent:x, customUser:x), metric_type (metrics only: TYPE_INTEGER, TYPE_FLOAT, TYPE_SECONDS, TYPE_CURRENCY and so on). Several hundred rows; filter with custom or category. Params: property (required, from analytics_list_properties), limit (100, cap 1000), cursor, max_credits, dry_run. Cost: 0 credits. Cached 1 day. Example: {"property": "properties/123456789", "limit": 1000}
A Google Analytics 4 report from the user's own property: any metrics by any dimensions over a date range, optionally against a second range. Use when: "how much traffic did we get last month", sessions or conversions by channel, landing page or campaign, "which pages convert", revenue by source, a traffic drop by channel against the period before, organic sessions next to Search Console clicks. Not for: Google search queries, use console_get_search_analytics. A site the user does not own, use seo_get_traffic_estimates. Returns: List. rows[]: one object per row keyed by api_name, dimensions as strings and metrics as numbers; with a comparison each row also carries dateRange (current | previous). metric_types (TYPE_SECONDS is seconds, TYPE_CURRENCY is in currency_code), currency_code, time_zone, subject_to_thresholding (Google withheld small rows for privacy), data_loss_from_other_row (rows folded into (other)). meta.rows_available is Google's row count. Rates such as engagementRate are 0 to 1. Data settles within about a day. Params: property (required), metrics[] (["sessions"], up to 10: sessions, totalUsers, newUsers, engagedSessions, engagementRate, averageSessionDuration, screenPageViews, keyEvents, conversions, eventCount, totalRevenue, purchaseRevenue, transactions), dimensions[] ([], up to 9: date, sessionDefaultChannelGroup, sessionSource, sessionMedium, sessionSourceMedium, sessionCampaignName, landingPage, landingPagePlusQueryString, pagePath, pageTitle, eventName, country, deviceCategory; analytics_get_fields lists the rest), start_date (default 28 days before end_date), end_date (default yesterday), compare_start_date and compare_end_date (both or neither), filters[] (dimension, operator equals | not_equals | contains | not_contains | begins_with | ends_with | regex | not_regex, value; case-insensitive, all must match), order_by (field, desc true; default the first metric, highest first), limit (100, cap 1000), cursor, max_credits, dry_run. Cost: 0 credits. Cached 1 hour. Example: {"property": "properties/123456789", "metrics": ["sessions", "keyEvents"], "dimensions": ["sessionDefaultChannelGroup"], "start_date": "2026-09-01", "end_date": "2026-09-30", "compare_start_date": "2026-08-01", "compare_end_date": "2026-08-31"}
Companies matching a name, keywords, location or headcount. Use when: "find fintech companies in London with 50 to 200 staff", "companies that do X", building an account list by firmographics. Not for: one known company, use leads_get_company (by domain). People at companies, use leads_search_people. A site's traffic, use seo_get_domain_overview. Returns: List. rows[]: id, name, domain, website, linkedin_url, industry, employees, location, founded_year. rows_available is the provider's total before the keyword check. A row is kept only when one of the keywords or unlisted industries appears in its name, industry, description or specialties, so a page can return fewer rows than limit; the charge counts the rows fetched. Params: name, keywords[], industries[], locations[], employee_ranges[] ("min,max"), limit (100), cursor, provider, max_credits, dry_run. At least one of them. Cost: 4 credits per page of 100. Default 4 credits. Cached 30 days. Example: {"keywords": ["payments"], "locations": ["London"], "employee_ranges": ["51,200"]}
The full firmographic record of one company, by domain. Use when: "tell me about acme.com", sizing a company, the industry, revenue and funding stage behind a domain, filling in a search row. Not for: search traffic and rankings, use seo_get_domain_overview. Who works there, use leads_search_people. Email addresses, use leads_get_domain_emails. Returns: Record. id, name, domain, website, linkedin_url, industry, industries[], employees, location, founded_year, description, keywords[], revenue (USD), total_funding (USD), funding_stage, technologies[], phone, ticker. null = the provider does not hold it. NoData when the provider does not know the domain. Params: domain (required), provider, max_credits, dry_run. Cost: 1 credit. Cached 30 days. Example: {"domain": "acme.com"}
People matching title, seniority and company filters. No email. Use when: "find heads of marketing at fintech startups", building a target list by role, prospecting by ICP. Not for: someone to email at a specific website about a link, use leads_get_domain_emails (keyed by domain). One person's full record, use leads_get_person. An email for a named person, use leads_get_email. Returns: List. rows[]: id (the LinkedIn profile URL; null when the person has no profile, so look them up by name and domain), first_name, last_name, title, company, company_domain, location, linkedin_url. rows_available is the provider's total. Params: titles[], seniority[] (junior | senior | executive), company_domains[], industries[], locations[], keywords (a job title word such as "marketing" is matched against the current title; other words against the whole profile), limit (100), cursor, provider, max_credits, dry_run. At least one of them. Cost: 4 credits per page of 100. Default 4 credits. Cached 7 days. Example: {"titles": ["head of marketing"], "industries": ["fintech"], "locations": ["London"], "limit": 50}
The full record of one person: real name, title, seniority, company, location, LinkedIn and employment history. No email. Use when: filling in a search row by id, "who is the head of growth at acme.com", checking a person's current role before outreach. Not for: the email, use leads_get_email (the paid reveal). Many people at once, use leads_search_people. Returns: Record. id, first_name, last_name, title, seniority, company, company_domain, company_id, company_linkedin_url, location, linkedin_url, headline, has_email, employment_history[] (company, title, start, end, current). null or empty = the provider does not hold it. NoData when nobody matches. Params: id (the LinkedIn profile URL a leads_search_people row gives as id; anything else is InvalidTarget at no charge), or first_name + last_name + domain, or linkedin_url; provider, max_credits, dry_run. Cost: 3 credits when matched, 1 on NoData. Cached 30 days. Example: {"first_name": "Jordan", "last_name": "Blake", "domain": "northstaranalytics.io"}
Find and verify the work email of one named person. The only paid reveal keyed by a person; it runs a waterfall of sources and stops at the first verified hit. Use when: you have a person and their company and need an address to send to, "get me the email of Jordan Blake at acme.com", after leads_search_people found the person. Not for: anyone at a website (no name), use leads_get_domain_emails. Checking an address you already hold, use leads_get_email_status. The person's role and history, use leads_get_person. Returns: Record. first_name, last_name, domain, email, confidence (0 to 100 or null), verification_status (valid | accept_all | invalid | unknown), found_by (the source that hit). NoData when no source finds one; do not retry. meta.providers_tried lists the sources asked, in order. A source that does not answer in time is skipped; when none answers, ProviderUnavailable at no charge. Params: id (the LinkedIn profile URL from leads_search_people, which also fills the name and domain), or first_name + last_name + domain; provider (one of findymail, hunter, icypeas to skip the waterfall), max_credits, dry_run. Cost: 6 credits on a hit, 1 on NoData. Cached 90 days. Example: {"first_name": "Jordan", "last_name": "Blake", "domain": "acme.com"}
Whether an email address the user already has will deliver. Use when: "is jane@acme.com still valid", cleaning a list before a send, checking a shortlist from leads_get_domain_emails. Not for: finding an address, use leads_get_email or leads_get_domain_emails. Returns: Record. email, status (valid | invalid | accept_all | unknown; accept_all means the server takes anything, so the address is unproven), result (deliverable | undeliverable | risky | unknown), score (0 to 100), mx_records. disposable, webmail and smtp_check are null: the verifier does not report them, so judge free-mail and throwaway domains by the domain. Params: email (required), provider, max_credits, dry_run. Cost: 1 credit. Cached 30 days. Example: {"email": "jane@acme.com"}
Email addresses known for a website's domain, with name, role, confidence and where each was seen. The contact-finding tool for link outreach. Use when: "find someone to email at these sites about a backlink", "who runs content at example.com", "get contacts for the referring domains of X". Not for: one named person, use leads_get_email. People by title across many companies, use leads_search_people. Checking an address works, use leads_get_email_status. Choosing which sites to contact, use seo_get_referring_domains, seo_get_backlinks, seo_get_domain_ratings. Returns: List, highest confidence first. rows[]: domain, email, first_name, last_name, position, department, seniority, type (personal | generic), confidence (0 to 100), verification_status, sources[] (url, last_seen_at; empty = inferred from the domain's pattern), linkedin_url. domains[]: domain, pattern (the address format, for example {first}.{last}), organization, rows_available. errors[] lists domains that failed. Addresses come back unverified for the most part; verify the shortlist with leads_get_email_status, not the whole list. Params: domains[] (required, max 20), department[] (all; one of Hunter's departments, and any other value is InvalidTarget; outreach usually wants marketing and communication, and editors at publications usually sit under communication), seniority[] (all), type ("all"; generic means role addresses such as press@, often the only working one on a small site), limit (30 per domain, cap 100), cursor (one domain only), provider, max_credits, dry_run. Cost: 2 credits per domain + 6 per 10 addresses returned. Default one domain with 30 addresses = 20 credits. Cached 30 days. Example: {"domains": ["example.com"], "department": ["marketing", "communication"], "type": "all"}
Reddit posts matching a query, ranked by the search, across all of Reddit or inside one community. Use when: "what do people on Reddit say about X", "find threads complaining about Y", "who is asking for a tool like ours". Not for: everything new in a community since you last looked, use reddit_get_new_posts (ranked search is never complete). Reading one thread, use reddit_get_post and reddit_get_comments. Choosing communities to watch, use reddit_search_subreddits. Returns: List, one page per call, ranked, not exhaustive. rows[]: id, subreddit, title, author, created_at, score, comments, upvote_ratio, url, link_url, body (cut at 2000 characters), flair, over_18. meta.cursor pages the next set. Params: query (required, 2 to 200 characters), subreddit (optional, search one community), sort ("relevance" | "new" | "top" | "comment_count", default relevance), time_range ("all" | "day" | "week" | "month" | "year", default all), cursor, provider, max_credits, dry_run. Cost: 1 credit per call, one page. Cached 1 hour. Example: {"query": "hubspot alternative", "sort": "new", "time_range": "month"}
Reddit comments matching a query, ranked by the search, across all of Reddit or inside one community. Use when: "what do people reply when someone asks about X", "find recommendations of a competitor inside threads", mining opinions rather than thread titles. Not for: thread titles and bodies, use reddit_search_posts. Every comment on one thread, use reddit_get_comments. New activity in a community, use reddit_get_new_posts. Returns: List, one page per call, ranked, not exhaustive. rows[]: id, post_id, subreddit, author, created_at, score, body (cut at 2000 characters), url, depth. meta.cursor pages the next set. Params: query (required, 2 to 200 characters), subreddit (optional, search one community), sort ("relevance" | "new" | "top" | "comment_count", default relevance), time_range ("all" | "day" | "week" | "month" | "year", default all), cursor, provider, max_credits, dry_run. Cost: 1 credit per call, one page. Cached 1 hour. Example: {"query": "best crm for a two person team", "time_range": "year"}
Every post created in the given subreddits inside a time window, oldest first. The check-in tool: complete for the window it reports, unlike search. Use when: "anything new in r/startups since yesterday", "watch these subreddits for mentions of our category", any repeated look at the same communities. Not for: keyword search across all of Reddit, use reddit_search_posts (ranked, not complete). Reading a thread, use reddit_get_post and reddit_get_comments. Choosing which subreddits to watch, use reddit_search_subreddits. Returns: List, oldest first. rows[]: id, subreddit, title, author, created_at, score, comments, upvote_ratio, url, link_url, body, flair, over_18. coverage[] per subreddit: covered_from, complete, pages_fetched. covered_from later than since, or complete false, means the window was cut: raise pages, shorten since, or pass meta.cursor. next_since is the value to send as since next time; it overlaps by two minutes, so dedupe rows on id. Params: subreddits[] (required, up to 10), since ("24h"; "30m", "6h", "2d" or an ISO 8601 timestamp, max 7 days), pages (1 to 3, default 1, per subreddit), match[] (optional terms; keeps posts whose title or body holds one, case insensitive), cursor, provider, max_credits, dry_run. Cost: 1 credit per subreddit per page. Three subreddits at the default is 3 credits. Never cached. Example: {"subreddits": ["startups", "SaaS"], "since": "24h", "match": ["crm", "pipeline"]}
One Reddit thread in full: the whole post body, its score, its flair and how big the community is. Use when: a row from a search or a check-in is worth reading properly, or you need the full text a row cut at 2000 characters. Not for: the replies, use reddit_get_comments. Finding threads in the first place, use reddit_search_posts or reddit_get_new_posts. Returns: Record. id, subreddit, title, author, created_at, score, comments, upvote_ratio, url, link_url, body (full), flair, over_18, subreddit_subscribers, locked, archived. Params: url (required, the thread URL from a row's url), provider, max_credits, dry_run. Cost: 1 credit. Cached 1 hour. Example: {"url": "https://www.reddit.com/r/startups/comments/1lfbo7u/what_crm_do_you_use/"}
The comments on one Reddit thread, flattened in reading order with their reply depth. Use when: "what did people reply", judging whether a thread is worth answering, pulling the objections out of a discussion. Not for: comments across many threads, use reddit_search_comments. The post itself, use reddit_get_post. Returns: List, in reading order: a reply follows the comment it answers. rows[]: id, post_id, subreddit, author, created_at, score, body (cut at 2000 characters), url, depth (0 is top level). meta.cursor loads more of the thread. Params: url (required, the thread URL from a row's url), cursor, provider, max_credits, dry_run. Cost: 1 credit per call, one page of the thread. Cached 1 hour. Example: {"url": "https://www.reddit.com/r/startups/comments/1lfbo7u/what_crm_do_you_use/"}
The communities that discuss a topic, counted from one page of search results. Use when: "which subreddits talk about X", picking the communities to pass to reddit_get_new_posts, sizing where a conversation happens. Not for: a full directory of subreddits about a topic (this counts a sample of posts, so a quiet community can be missing). One community's rules and size, use reddit_get_subreddit. The posts themselves, use reddit_search_posts. Returns: List, most posts in the sample first. rows[]: name, url, subscribers, posts_in_sample, example_post_url. Params: query (required, 2 to 200 characters), time_range ("all" | "day" | "week" | "month" | "year", default all), provider, max_credits, dry_run. Cost: 1 credit. Cached 1 hour. Example: {"query": "cold email deliverability", "time_range": "year"}
One community: how big it is, how busy it is, and the rules it posts, as the moderators wrote them. Use when: before you post or reply anywhere, to read the rules on self promotion; sizing a community found by reddit_search_subreddits. Not for: the posts in the community, use reddit_get_new_posts or reddit_search_posts. Finding communities, use reddit_search_subreddits. Returns: Record. name, url, subscribers, weekly_active_users, weekly_contributions, description, rules (the text as written; read it, it is not parsed into flags), submit_text, created_at. Params: subreddit (required, the name without the r/ prefix, for example "startups"), provider, max_credits, dry_run. Cost: 1 credit. Cached 7 days. Example: {"subreddit": "SaaS"}
One TikTok account: its follower count, its lifetime likes and how many videos it has posted. Use when: sizing a creator or a brand on TikTok, checking a handle is real, reading a bio before outreach. Not for: the account's videos, use tiktok_get_videos. Where its audience is, use tiktok_get_audience. Finding accounts by topic, use tiktok_search_videos and read the authors. Returns: Record. platform, kind, id, handle, name, url, bio, verified, followers, following, posts_count, likes, views, location, website, employees, industry, created_at. A field the platform does not publish is null. Params: handle (required, with or without the @), provider, max_credits, dry_run. Cost: 1 credit. Cached 24 hours. Example: {"handle": "@gymshark"}
The videos one TikTok account has posted, newest or most viewed first. Use when: "what has this creator posted", judging how often a brand posts, pulling a creator's recent work before a partnership. Not for: one video in full, use tiktok_get_video. What was said in it, use tiktok_get_transcript. Videos by topic rather than by account, use tiktok_search_videos. Returns: List, one page per call. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. meta.cursor pages the next set. Params: handle (required), sort ("latest" | "popular", default latest), cursor, provider, max_credits, dry_run. Cost: 1 credit per page. Cached 6 hours. Example: {"handle": "gymshark", "sort": "popular"}
One TikTok video with its engagement: views, likes, comments, shares and its length. Use when: a row from a search or a listing is worth the detail, or you have a URL and nothing else. Not for: what was said in it, use tiktok_get_transcript. The replies, use tiktok_get_comments. Returns: Record. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. Params: url (required, the video URL), provider, max_credits, dry_run. Cost: 10 credits when the vendor has to fetch the media, 1 when it does not. The estimate is the higher one, so max_credits never surprises you. Cached 6 hours. Example: {"url": "https://www.tiktok.com/@gymshark/video/7517114944362499342"}
The comments on one TikTok video. Use when: reading what an audience actually said, finding objections and questions under a creator's post. Not for: comments across many videos (there is no such search on TikTok). The video itself, use tiktok_get_video. Returns: List, one page per call. rows[]: platform, id, post_id, author, created_at, text (cut at 2000 characters), likes, replies, depth. meta.cursor pages the next set. Params: url (required, the video URL), cursor, provider, max_credits, dry_run. Cost: 1 credit per page. Cached 6 hours. Example: {"url": "https://www.tiktok.com/@gymshark/video/7517114944362499342"}
TikTok videos matching a keyword, ranked by the platform's own search. Use when: "what is TikTok saying about X", finding creators in a category, watching a product or a brand name. Not for: one account's own videos, use tiktok_get_videos. A complete window of everything posted (TikTok search is ranked and never complete). Returns: List, one page per call, ranked. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. meta.cursor pages the next set. Params: query (required), since ("day" | "week" | "month" | "year" | "all", default month), sort ("relevance" | "latest" | "popular", default relevance), cursor, provider, max_credits, dry_run. Cost: 1 credit per page. Cached 6 hours. Example: {"query": "creatine gummies", "since": "month", "sort": "popular"}
What is said out loud in one TikTok video, as text. Use when: reading a video without watching it, pulling the claims or the hook out of an ad or a review. Not for: the video's numbers, use tiktok_get_video. The written caption, which tiktok_get_video already returns as text. Returns: Record. platform, url, language, text (the full transcript, uncut). NoData when the video carries no speech the platform kept. Params: url (required), language (optional, for a video with several), ai_fallback (false; true transcribes the audio when TikTok holds no transcript, adds 10 credits and covers videos up to 2 minutes), provider, max_credits, dry_run. Cost: 1 credit, or 11 with ai_fallback. Cached 30 days. Example: {"url": "https://www.tiktok.com/@gymshark/video/7517114944362499342"}
The accounts that follow one TikTok account, with their own follower counts. Use when: judging whether a creator's audience is real, looking for the notable accounts in a following. Not for: where an audience is in the world, use tiktok_get_audience. How big the account is, use tiktok_get_profile. Returns: List, one page per call. rows[]: platform, handle, name, url, followers, bio. meta.cursor pages the next set. Params: handle (required), cursor, provider, max_credits, dry_run. Cost: 1 credit per page. Cached 7 days. Example: {"handle": "gymshark"}
Where one TikTok account's audience is, by country. Use when: checking a creator reaches the market you sell in, before paying for a partnership. Not for: who the followers are, use tiktok_get_followers. The account's size, use tiktok_get_profile. Returns: List, largest share first. rows[]: country, country_code, share (percent, a decimal), count. The split comes from a sample of followers, a few hundred for an account of millions: count is followers in that sample, not in the account, so read share and ignore count as a size. Params: handle (required), provider, max_credits, dry_run. Cost: 26 credits, because the vendor charges 26 for this one call. Check the handle with tiktok_get_profile first. Cached 7 days. Example: {"handle": "gymshark"}
One Instagram account: followers, posts and whether it is a business account. Use when: sizing a creator or a brand, checking a handle, reading a bio and its link before outreach. Not for: the account's posts, use instagram_get_posts or instagram_get_reels. Posts by topic, use instagram_search_posts. Returns: Record. platform, kind, id, handle, name, url, bio, verified, followers, following, posts_count, likes, views, location, website, employees, industry, created_at. A field the platform does not publish is null. kind is company for a business account. Params: handle (required, with or without the @), provider, max_credits, dry_run. Cost: 1 credit. Cached 24 hours. Example: {"handle": "gymshark"}
The posts on one Instagram account, newest first. Use when: "what has this account been posting", judging cadence and engagement before a partnership. Not for: reels only, use instagram_get_reels. One post in full, use instagram_get_post. Posts by hashtag, use instagram_search_posts. Returns: List, one page per call. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. meta.cursor pages the next set. Params: handle (required), cursor, provider, max_credits, dry_run. Cost: 1 credit per page. Cached 6 hours. Example: {"handle": "gymshark"}
The reels on one Instagram account, newest first. Use when: video is what matters: watching a brand's reel cadence, pulling a creator's recent reels. Not for: every post type, use instagram_get_posts. What is said in a reel, use instagram_get_transcript. Returns: List, one page per call. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. meta.cursor pages the next set. Params: handle (required), cursor, provider, max_credits, dry_run. Cost: 1 credit per page. Cached 6 hours. Example: {"handle": "gymshark"}
One Instagram post or reel with its caption and its engagement. Use when: a row is worth the detail, or you have a URL and nothing else. Not for: the comments, use instagram_get_comments. What is said in a reel, use instagram_get_transcript. Returns: Record. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. Params: url (required, the post or reel URL), provider, max_credits, dry_run. Cost: 10 credits when the vendor has to fetch the media, 1 when it does not. The estimate is the higher one. Cached 6 hours. Example: {"url": "https://www.instagram.com/p/DKSMEpKRd6h/"}
The comments on one Instagram post or reel. Use when: reading what an audience said, finding the questions a product post keeps getting. Not for: the post itself, use instagram_get_post. Comments across many posts, which Instagram does not offer. Returns: List, one page per call. rows[]: platform, id, post_id, author, created_at, text (cut at 2000 characters), likes, replies, depth. depth is 1 for a reply, and replies only come back when you ask for them. Params: url (required), include_replies (false; true costs 15 credits and is charged even when no reply comes back, because the vendor looks up every comment separately), cursor, provider, max_credits, dry_run. Cost: 1 credit per page, or 15 with include_replies. Cached 6 hours. Example: {"url": "https://www.instagram.com/p/DKSMEpKRd6h/"}
Instagram posts under one hashtag. Use when: "who is posting about X on Instagram", watching a campaign hashtag or a product tag. Not for: free-text search (Instagram search is by hashtag here). One account's posts, use instagram_get_posts. Returns: List, one page per call, ranked by Instagram. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. meta.cursor pages the next set. Params: query (required, the hashtag, with or without the #), since ("day" | "week" | "month" | "year" | "all", default month), cursor, provider, max_credits, dry_run. Cost: 1 credit per page. Cached 6 hours. Example: {"query": "#gymshark", "since": "week"}
What is said out loud in one Instagram reel, as text. Use when: reading a reel without watching it, pulling the claims out of a creator's video. Not for: the caption, which instagram_get_post already returns. The numbers, use instagram_get_post. Returns: Record. platform, url, language, text (the full transcript, uncut). NoData when the reel carries no speech. The vendor transcribes reels up to two minutes long; a longer one is refused as InvalidTarget with the reason. Params: url (required), language (optional), provider, max_credits, dry_run. Cost: 1 credit. Cached 30 days. Example: {"url": "https://www.instagram.com/reel/DKSMEpKRd6h/"}
One Facebook page: its followers, its category, its address and its website. Use when: checking a business page is real and current, reading its category and contact details. Not for: its posts, use facebook_get_posts. Its ads, use ads_get_advertiser_ads with platform facebook. Returns: Record. platform, kind, id, handle, name, url, bio, verified, followers, following, posts_count, likes, views, location, website, employees, industry, created_at. A field the platform does not publish is null. kind is company, because these are pages rather than people. Params: handle (a page name) or url (the full page URL); give one. provider, max_credits, dry_run. Cost: 1 credit. Cached 24 hours. Example: {"url": "https://www.facebook.com/gymshark"}
The posts on one Facebook page, newest first. Use when: watching what a business page publishes, judging cadence and reactions. Not for: a group's posts, use facebook_get_group_posts. One post in full, use facebook_get_post. Returns: List, one page per call. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. Facebook publishes no share count, so shares is null. Params: handle (a page name) or url (the full page URL); give one. cursor, provider, max_credits, dry_run. Cost: 1 credit per page. Cached 6 hours. Example: {"url": "https://www.facebook.com/gymshark"}
One Facebook post with its reactions, comments, shares and views. Use when: a row is worth the detail, or you have a URL and nothing else. Not for: the comments themselves, use facebook_get_comments. What is said in a video, use facebook_get_transcript. Returns: Record. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. Params: url (required, the post or reel URL), provider, max_credits, dry_run. Cost: 1 credit. Cached 6 hours. Example: {"url": "https://www.facebook.com/reel/1535656380759655"}
The comments on one Facebook post. Use when: reading what people replied to a page or a group post. Not for: the post itself, use facebook_get_post. Comments across many posts, which Facebook does not offer. Returns: List, one page per call. rows[]: platform, id, post_id, author, created_at, text (cut at 2000 characters), likes, replies, depth. meta.cursor pages the next set. Params: url (required), cursor, provider, max_credits, dry_run. Cost: 1 credit per page. Cached 6 hours. Example: {"url": "https://www.facebook.com/reel/1535656380759655"}
The posts in one Facebook group, newest first. Use when: watching a community you sell into, the way reddit_get_new_posts watches a subreddit. Not for: a page's own posts, use facebook_get_posts. A complete window since a moment, which Facebook does not offer: page with the cursor and dedupe on id. Returns: List, one page per call. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. meta.cursor pages the next set. Params: url (required, the group URL), cursor, provider, max_credits, dry_run. Cost: 1 credit per page. Cached 6 hours. Example: {"url": "https://www.facebook.com/groups/742354120555345"}
What is said out loud in one Facebook video or reel, as text. Use when: reading a video without watching it, pulling the claims out of a page's ad or clip. Not for: the post's text, which facebook_get_post already returns. Returns: Record. platform, url, language, text (the full transcript, uncut). NoData when the post carries no speech. Params: url (required), language (optional), provider, max_credits, dry_run. Cost: 1 credit. Cached 30 days. Example: {"url": "https://www.facebook.com/reel/1535656380759655"}
One YouTube channel: subscribers, total views and when it joined. Use when: sizing a channel before a sponsorship, checking a handle, reading a channel description. Not for: its videos, use youtube_get_videos. Videos by topic, use youtube_search_videos. Returns: Record. platform, kind, id, handle, name, url, bio, verified, followers, following, posts_count, likes, views, location, website, employees, industry, created_at. A field the platform does not publish is null. kind is channel, followers is the subscriber count. Params: handle (required, with or without the @), provider, max_credits, dry_run. Cost: 1 credit. Cached 24 hours. Example: {"handle": "@ThePatMcAfeeShow"}
The videos on one YouTube channel, newest or most viewed first. Use when: "what does this channel publish", judging cadence and view counts before a sponsorship. Not for: one video in full, use youtube_get_video. What is said in it, use youtube_get_transcript. Returns: List, one page per call. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. A listing carries views and length; likes and comments come with youtube_get_video. Params: handle (required), sort ("latest" | "popular", default latest), cursor, provider, max_credits, dry_run. Cost: 1 credit per page. Cached 6 hours. Example: {"handle": "@ThePatMcAfeeShow", "sort": "popular"}
One YouTube video with its views, likes, comments and length. Use when: a row is worth the detail, or you have a URL and nothing else. Not for: what is said in it, use youtube_get_transcript. The comments, use youtube_get_comments. Returns: Record. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. Params: url (required), provider, max_credits, dry_run. Cost: 1 credit. Cached 6 hours. Example: {"url": "https://www.youtube.com/watch?v=5EWaxmWgQMI"}
The comments on one YouTube video, most liked first. Use when: reading what an audience said, finding the objections under a review or a tutorial. Not for: the video itself, use youtube_get_video. What is said in it, use youtube_get_transcript. Returns: List, one page per call. rows[]: platform, id, post_id, author, created_at, text (cut at 2000 characters), likes, replies, depth. depth is the reply level. meta.cursor pages the next set. created_at is approximate: the platform shows an age such as "3 weeks ago", so it is exact only to that unit. Params: url (required), cursor, provider, max_credits, dry_run. Cost: 1 credit per page. Cached 6 hours. Example: {"url": "https://www.youtube.com/watch?v=5EWaxmWgQMI"}
YouTube videos matching a keyword, ranked by YouTube's own search. Use when: "what videos cover X", finding review and tutorial coverage of a product or a competitor. Not for: one channel's own videos, use youtube_get_videos. Text pages about X, use seo_get_serp. Returns: List, one page per call, ranked. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. meta.cursor pages the next set. created_at is approximate: the platform shows an age such as "3 weeks ago", so it is exact only to that unit. Params: query (required), since ("day" | "week" | "month" | "year" | "all", default month), sort ("relevance" | "popular", default relevance; YouTube has no newest-first search, so "latest" runs as relevance and since does the narrowing), cursor, provider, max_credits, dry_run. Cost: 1 credit per page. Cached 6 hours. Example: {"query": "best crm for agencies", "since": "year"}
The transcript of one YouTube video, as text. Use when: reading a video instead of watching it, pulling claims, chapters or quotes out of long content. Not for: the video's numbers, use youtube_get_video. The comments, use youtube_get_comments. Returns: Record. platform, url, language, text (the full transcript, uncut). NoData when the video has no captions. Params: url (required), language (optional, for a video with several), provider, max_credits, dry_run. Cost: 1 credit. Cached 30 days. Example: {"url": "https://www.youtube.com/watch?v=5EWaxmWgQMI"}
One LinkedIn person: their headline, location, followers and connections. Use when: checking a person before outreach, reading how they describe themselves. Not for: a company page, use linkedin_get_company. An email address, use leads_get_email. A person's full employment record, use leads_get_person. Returns: Record. platform, kind, id, handle, name, url, bio, verified, followers, following, posts_count, likes, views, location, website, employees, industry, created_at. A field the platform does not publish is null. LinkedIn publishes no post count or id for a person, so those are null. Params: url (the full profile URL) or handle (the part after /in/); give one. provider, max_credits, dry_run. Cost: 1 credit. Cached 24 hours. Example: {"url": "https://www.linkedin.com/in/williamhgates"}
One LinkedIn company page: headcount, industry, location and website. Use when: sizing a company from its own page, confirming an industry and a headcount band before outreach. Not for: a company's own posts, use linkedin_get_company_posts. A richer firmographic record, use leads_get_company. A person, use linkedin_get_profile. Returns: Record. platform, kind, id, handle, name, url, bio, verified, followers, following, posts_count, likes, views, location, website, employees, industry, created_at. A field the platform does not publish is null. kind is company, employees is LinkedIn's own headcount. Params: handle (the company slug) or url (the full company URL); give one. provider, max_credits, dry_run. Cost: 1 credit. Cached 24 hours. Example: {"handle": "shopify"}
The posts on one LinkedIn company page, newest first. Use when: watching what a competitor publishes, judging cadence and engagement. Not for: posts by topic across LinkedIn, use linkedin_search_posts. One post in full, use linkedin_get_post. Returns: List, one page per call. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. LinkedIn publishes no view count, so views is null. This listing carries no engagement at all; linkedin_get_post has likes and comments for one post. created_at is approximate: the platform shows an age such as "3 weeks ago", so it is exact only to that unit. Params: handle (the company slug) or url (the full company URL); give one. cursor, provider, max_credits, dry_run. Cost: 1 credit per page. Cached 6 hours. Example: {"handle": "shopify"}
One LinkedIn post with its text, its author and its engagement. Use when: a row from a search is worth the detail, or you have a URL and nothing else. Not for: the comments (LinkedIn does not expose them here). A company's whole feed, use linkedin_get_company_posts. Returns: Record. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. Params: url (required, the post URL), provider, max_credits, dry_run. Cost: 1 credit. Cached 6 hours. Example: {"url": "https://www.linkedin.com/posts/aagupta_what-you-need-to-know-ai-agents-activity-7354600338621906944-RvXR"}
LinkedIn posts matching a keyword, ranked by LinkedIn's own search. Use when: "what is being said about X on LinkedIn", finding the people posting about a category. Not for: one company's posts, use linkedin_get_company_posts. Finding people to contact, use leads_search_people. Returns: List, one page per call, ranked. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. meta.cursor pages the next set. created_at is approximate: the platform shows an age such as "3 weeks ago", so it is exact only to that unit. Params: query (required), since ("day" | "week" | "month" | "year" | "all", default month), cursor, provider, max_credits, dry_run. Cost: 1 credit per page. Cached 6 hours. Example: {"query": "rfp automation", "since": "week"}
One X account: followers, following, how much it posts and its bio. Use when: sizing an account, checking a handle, reading a bio and its link before outreach. Not for: its posts, use twitter_get_tweets. One post, use twitter_get_tweet. Returns: Record. platform, kind, id, handle, name, url, bio, verified, followers, following, posts_count, likes, views, location, website, employees, industry, created_at. A field the platform does not publish is null. verified is true for a paid checkmark as well as a legacy one. Params: handle (required, with or without the @), provider, max_credits, dry_run. Cost: 1 credit. Cached 24 hours. Example: {"handle": "@stripe"}
The recent posts on one X account, newest first. Use when: "what has this account been saying", watching a competitor's announcements. Not for: keyword search across X, which is not covered here; use one account at a time. One post, use twitter_get_tweet. Returns: List, one page per call. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. shares carries retweets, comments carries replies. X returns one page, so meta.cursor is null. Params: handle (required), provider, max_credits, dry_run. Cost: 1 credit. Cached 6 hours. Example: {"handle": "stripe"}
One post on X with its replies, reposts, likes and views. Use when: a row is worth the detail, or you have a URL and nothing else. Not for: the replies themselves, which are not covered here. An account's feed, use twitter_get_tweets. Returns: Record. rows[]: platform, id, url, author, author_name, created_at, text (cut at 2000 characters), likes, comments, shares, views, media, duration_s, is_ad. A number the platform does not publish is null. Params: url (required, the post URL), provider, max_credits, dry_run. Cost: 1 credit. Cached 6 hours. Example: {"url": "https://x.com/stripe/status/1834021269559501236"}
Ads running on a platform's public library, by keyword or brand. Use when: "what ads is this category running", finding the angles and offers competitors are paying for. Not for: one advertiser's whole set, use ads_get_advertiser_ads. Google, whose library is keyed by advertiser: use ads_search_advertisers first. Organic posts, use the platform's own search tool. Returns: List, one page per call. rows[]: platform, id, url, advertiser, advertiser_id, headline, body, format, first_shown, last_shown, active, impressions, spend, countries, placements (where it ran: facebook, instagram), cta, destination_url, media_url. Impressions and spend are the ranges the library publishes, so they are text. meta.cursor pages the next set. Params: platform (required, "facebook" | "tiktok" | "linkedin"), query (required), country (optional, an ISO code), active_only (false), cursor, provider, max_credits, dry_run. Cost: 1 credit per page. Cached 24 hours. Example: {"platform": "facebook", "query": "creatine gummies", "active_only": true}
Every ad one advertiser is running, from a platform's public library. Use when: a competitor teardown: what they are running, since when, and with what offer. Not for: a keyword sweep across advertisers, use ads_search_ads. One creative in full, use ads_get_ad. Returns: List, one page per call. rows[]: platform, id, url, advertiser, advertiser_id, headline, body, format, first_shown, last_shown, active, impressions, spend, countries, placements (where it ran: facebook, instagram), cta, destination_url, media_url. Impressions and spend are the ranges the library publishes, so they are text. meta.cursor pages the next set. Params: platform (required, "facebook" | "tiktok" | "linkedin" | "google"), advertiser (required: a page id or name on facebook, an advertiser name on tiktok, a company name or id on linkedin, a domain or advertiser id on google), country (optional), active_only (false), details (false; google only, adds the creative text and costs 25 credits), cursor, provider, max_credits, dry_run. Cost: 1 credit per page, or 25 on google with details. Cached 24 hours. Example: {"platform": "google", "advertiser": "lululemon.com"}
One ad from a platform's public library, with its creative text and where it sends people. Use when: reading the offer and the call to action behind an ad you found in a list. Not for: a set of ads, use ads_search_ads or ads_get_advertiser_ads. What is said in an ad video, use the platform's transcript tool. Returns: Record. rows[]: platform, id, url, advertiser, advertiser_id, headline, body, format, first_shown, last_shown, active, impressions, spend, countries, placements (where it ran: facebook, instagram), cta, destination_url, media_url. Impressions and spend are the ranges the library publishes, so they are text. Params: platform (required, "facebook" | "tiktok" | "linkedin" | "google"), id (required: an ad id on facebook and tiktok, the ad URL on linkedin and google), provider, max_credits, dry_run. Cost: 1 credit. Cached 7 days. Example: {"platform": "facebook", "id": "1185617869915074"}
The advertisers matching a brand name in Google's ad library, with their ids. Use when: before ads_get_advertiser_ads on Google, because that library is keyed by advertiser id and one brand has one entry per region. Not for: the ads themselves, use ads_get_advertiser_ads with the id this returns. The other libraries, which search their ads directly with ads_search_ads. Returns: List. rows[]: platform, id, name, region, ads_estimate, website. Params: platform (required, "google"), query (required, a brand name), region (optional, an ISO country code), provider, max_credits, dry_run. Cost: 1 credit. Cached 7 days. Example: {"platform": "google", "query": "lululemon", "region": "US"}
One endpoint, the same key, whichever client you use.
~/Library/Application Support/Claude/claude_desktop_config.json (Mac) · %APPDATA%\Claude\claude_desktop_config.json (Windows)
Replace API_KEY with your own key.
Already have an "mcpServers" section in your config? Just add the server entry inside it.
Discovery, routing, credentials, tool scoping and execution logs all happen at the gateway→connections stay ACTIVE with no work from you
Manifold MCP runs through a gateway that holds the credentials, scopes the access and records every call.
Managed auth, hosted MCP servers, and every Gmail tool your agent needs.
Free to start.