Docs · methods
All methods
Eighteen methods, in the order a first session uses them: find or create a project, add competitors, then read what was collected. Read methods never change anything; write methods say exactly what they queued.
( Projects )
group page →A project is the container everything else lives in: an anchor company, its competitors, and the feeds collected for them. Every other method takes a projectId from list_projects.
List projects
list_projectsreadEvery project in the connected organization, with the number of competitors each one tracks. Call this first: it maps the project name a user says to the id every other method needs.
Parameters2
- limitintegerOptionalRows to return. Defaults to 20, clamped to 100.
- cursorstringOptionalnextCursor from the previous page of this same method.
Returns4
- orgNamestring | null
- projects[]projectid, name, industry, description, competitorCount.
- nextCursorstring | nullPass back as cursor to read the next page. Null when done.
- hasMoreboolean
Draft a project from a company website
prepare_create_projectwriteFills create_project's arguments by reading one company website. Writes nothing. It scrapes and calls a model, so it takes seconds, not milliseconds. Placeholder addresses (example.com, localhost, ip addresses) come back as needs_input without being read.
Parameters2
- urlstringRequiredThe company website the project should be about. The only argument the user has to supply.
- hintstringOptionalAnything the user already said: a product to focus on, a market, a name.
Returns6
- statusenumready: show the draft, then call create_project. needs_choice: the domain hosts several products, ask which. needs_input: ask for the fields in missingFields.
- draftobject | nullcreate_project's arguments, filled from the site: name, industry, subIndustry, targetMarket, description, anchorName, anchorUrl.
- missingFields[]stringRequired arguments still empty. Ask for these and nothing else.
- saasProducts[]productSet on needs_choice: name, url, description per product found.
- feedbackstring
- sourceUrlstring
Create a project
create_projectwriteCreates a project and its anchor company (your own company) in one call, then queues competitor research automatically. Do not add the anchor again with add_competitor. Best used with a draft the user confirmed from prepare_create_project.
Parameters9
- namestringRequired
- industrystringRequiredThe industry the product competes in.
- subIndustrystring[]RequiredAt least one entry.
- targetMarketstring[]RequiredAt least one entry, e.g. ["SMB", "Mid-market"].
- descriptionstringRequiredWhat the product does. Drives the competitor-research prompt.
- anchorNamestringRequiredYour own company name.
- anchorUrlstringRequiredYour own company website. Placeholder domains are rejected.
- trackingFrequencyenumOptionalbi-weekly, weekly, monthly or manual. Defaults to manual.
- trackSeo / trackAds / trackSocial / trackWebsitebooleanOptionalWhich trackers run for this project.
Returns4
- projectprojectid, name, industry, subIndustry, targetMarket, description, trackingFrequency.
- anchorobject | nullid, name, url of the anchor company.
- competitorResearchQueuedbooleanWhether automatic competitor discovery was dispatched.
- anchorResearchQueuedbooleanWhether reviews, news and page discovery were queued for the anchor.
( Competitors )
group page →Competitors are the companies a project watches. Adding one starts the same background pipeline the app starts: reviews, news, company research, page discovery, social-handle discovery and starter battle cards.
List competitors
list_competitorsreadThe competitors tracked in a project, with the social handles and advertiser ids held for each. No googleAdvertiserId means get_google_ads has nothing to join on; no facebookPageId means the same for get_meta_ads.
Parameters3
- projectIdintegerRequiredProject id from list_projects. Every scoped method needs it.
- limitintegerOptionalRows to return. Defaults to 20, clamped to 100.
- cursorstringOptionalnextCursor from the previous page of this same method.
Returns4
- projectNamestring
- competitors[]competitorid, name, url, isTracked, companyOneLiner, linkedinHandle, instagramHandle, googleAdvertiserId, facebookPageId.
- nextCursorstring | nullPass back as cursor to read the next page. Null when done.
- hasMoreboolean
Draft competitors from their websites
prepare_add_competitorwriteReads up to 10 competitor websites and returns a draft per url: name, one-liner, LinkedIn handle. Writes nothing. Show the drafts, let the user correct them, then pass the confirmed list to add_competitor. Each url is a scrape plus a model call, so a full list takes about a minute.
Parameters2
- projectIdintegerRequiredProject id from list_projects. Every scoped method needs it.
- urlsstring[]RequiredCompetitor websites exactly as pasted, at most 10 per call. Placeholders come back as failed without being read.
Returns4
- projectNamestring
- drafts[]draftstatus (prepared or failed), url (normalized to bare domain), name, companyOneLiner, linkedinHandle, failureReason.
- preparedCountinteger
- failedCountinteger
Add competitors
add_competitorwriteAdds up to 10 competitors in one call. Pass the whole confirmed list rather than calling once per company; each row is isolated, so one failure does not cost the others. A url already in the project comes back as existing and fills any still-empty fields from what you passed. linkedinHandle and instagramHandle also start tracking that account.
Parameters2
- projectIdintegerRequiredProject id from list_projects. Every scoped method needs it.
- competitors[]objectRequiredPer entry: name and url required. Optional: companyOneLiner, headquarters, founded, companySize, revenue, marketShare, tag, context, isAnchor, isTracked, linkedinHandle, instagramHandle, tikTokHandle, youtubeHandle, googleAdvertiserId, googleAdsRegion, facebookPageId, facebookPageUrl.
Returns4
- projectNamestring
- results[]resultPer entry: status (added, existing, failed), competitor detail, filledFields, trackedAccounts, researchQueued, battleCardsQueued, failureReason.
- addedCount / existingCount / failedCountinteger
- scrapeQueued / researchQueued / battleCardsQueuedbooleanWhether social scrapes, the research pipeline and starter battle cards were actually dispatched.
( Tracked accounts )
group page →The social profiles a project scrapes. The account url stored here is the exact key the social read methods take; rebuilding it from a handle will not match.
List tracked social accounts
list_tracked_accountsreadThe accounts scraped for a project, with the url exactly as stored. A null lastPortedAt means the scraper has never run for that account yet.
Parameters2
- projectIdintegerRequiredProject id from list_projects. Every scoped method needs it.
- platformenumOptionallinkedin, x or instagram. Omit for all platforms.
Returns2
- projectNamestring
- accounts[]accountid, platform, url, displayName, lastPortedAt.
Track a LinkedIn account
set_linkedin_handlewriteStart scraping a LinkedIn profile for a project. Accepts linkedin.com/company/acme or a bare handle. A url from another platform is rejected with platform_mismatch. The returned account url is the exact value get_linkedin_posts expects. Posts take a few minutes to appear after the first scrape.
Parameters2
- projectIdintegerRequiredProject id from list_projects. Every scoped method needs it.
- handlestringRequiredA profile url or bare handle, e.g. linkedin.com/company/acme or a bare handle.
Returns4
- accountaccountid, platform, url, displayName, lastPortedAt. The url is what the read methods take.
- previousUrlstring | nullAn account already tracked on this platform, if any. Both stay tracked.
- scrapeQueuedbooleanWhether a scrape was actually dispatched.
- alreadyTrackedboolean
Track an X (Twitter) account
set_x_handlewriteStart scraping a X (Twitter) profile for a project. Accepts x.com/acme, twitter.com/acme or @acme. A url from another platform is rejected with platform_mismatch. The returned account url is the exact value get_twitter_posts expects. Posts take a few minutes to appear after the first scrape.
Parameters2
- projectIdintegerRequiredProject id from list_projects. Every scoped method needs it.
- handlestringRequiredA profile url or bare handle, e.g. x.com/acme, twitter.com/acme or @acme.
Returns4
- accountaccountid, platform, url, displayName, lastPortedAt. The url is what the read methods take.
- previousUrlstring | nullAn account already tracked on this platform, if any. Both stay tracked.
- scrapeQueuedbooleanWhether a scrape was actually dispatched.
- alreadyTrackedboolean
Track a Instagram account
set_instagram_handlewriteStart scraping a Instagram profile for a project. Accepts instagram.com/acme or @acme. A url from another platform is rejected with platform_mismatch. The returned account url is the exact value get_instagram_posts expects. Posts take a few minutes to appear after the first scrape.
Parameters2
- projectIdintegerRequiredProject id from list_projects. Every scoped method needs it.
- handlestringRequiredA profile url or bare handle, e.g. instagram.com/acme or @acme.
Returns4
- accountaccountid, platform, url, displayName, lastPortedAt. The url is what the read methods take.
- previousUrlstring | nullAn account already tracked on this platform, if any. Both stay tracked.
- scrapeQueuedbooleanWhether a scrape was actually dispatched.
- alreadyTrackedboolean
( News )
group page →News articles collected for a project's tracked competitors, newest first, each with its source url and publish date.
Get competitor news
get_newsreadThe news collected for a project, newest first. Pass competitorId to narrow to one company. Only tracked competitors are covered; list_competitors shows which are tracked.
Parameters7
- projectIdintegerRequiredProject id from list_projects. Every scoped method needs it.
- competitorIdintegerOptionalCompetitor id from list_competitors. Omit to cover every tracked competitor in the project.
- fromISO dateOptionalOnly items published on or after this date, e.g. 2026-08-01.
- toISO dateOptionalOnly items published on or before this date.
- categorystringOptionalKeep only articles carrying this category tag.
- limitintegerOptionalRows to return. Defaults to 20, clamped to 100.
- cursorstringOptionalnextCursor from the previous page of this same method.
Returns4
- projectNamestring
- items[]articletitle, summary, sourceUrl, publishedAt, categories, competitorName, competitorUrl.
- nextCursorstring | nullPass back as cursor to read the next page. Null when done.
- hasMoreboolean
( Reviews )
group page →Customer reviews collected for one competitor at a time, across G2, Capterra, Trustpilot and any custom sources, each review with its url and publish date.
Get competitor reviews
get_reviewsreadThe reviews collected for one competitor, newest first. competitorId is required: reviews are read one competitor at a time. Only tracked competitors are covered; list_competitors shows which are tracked.
Parameters7
- projectIdintegerRequiredProject id from list_projects. Every scoped method needs it.
- competitorIdintegerRequiredCompetitor id from list_competitors. Reviews are read one competitor at a time.
- minRatingintegerOptionalKeep only reviews rated at or above this, on the 1-5 scale.
- fromISO dateOptionalOnly items published on or after this date, e.g. 2026-08-01.
- toISO dateOptionalOnly items published on or before this date.
- limitintegerOptionalRows to return. Defaults to 20, clamped to 100.
- cursorstringOptionalnextCursor from the previous page of this same method.
Returns5
- projectNamestring
- competitorNamestring
- items[]reviewsource, title, text, rating (1-5, normalized), reviewerRole, sourceUrl, publishedAt. Reviewer names are never returned.
- nextCursorstring | nullPass back as cursor to read the next page. Null when done.
- hasMoreboolean
( Website changes )
group page →Dated changes observed on competitor websites: pricing pages, messaging, feature pages. Each change carries the page url it was seen on and when.
Get competitor website changes
get_website_changesreadThe website changes recorded for a project, newest first. Pass competitorId to narrow to one company, type to keep only major or minor changes. Only pages with tracking set up are covered; an empty result can mean no tracking rather than no movement.
Parameters7
- projectIdintegerRequiredProject id from list_projects. Every scoped method needs it.
- competitorIdintegerOptionalCompetitor id from list_competitors. Omit to cover every tracked competitor in the project.
- typeenumOptionalChange weight filter: "minor" or "major". Omit for both.
- fromISO dateOptionalOnly items published on or after this date, e.g. 2026-08-01.
- toISO dateOptionalOnly items published on or before this date.
- limitintegerOptionalRows to return. Defaults to 20, clamped to 100.
- cursorstringOptionalnextCursor from the previous page of this same method.
Returns4
- projectNamestring
- items[]changetitle, description, url (the page the change was seen on), type, categories (e.g. pricing_strategy, product_launch, positioning), competitorName, changedAt.
- nextCursorstring | nullPass back as cursor to read the next page. Null when done.
- hasMoreboolean
( Ads )
group page →Ads collected from the Google Transparency Center and the Meta Ad Library. A competitor produces Google ads once its googleAdvertiserId is set, Meta ads once its facebookPageId is set; list_competitors shows both.
Get Google ads
get_google_adsreadGoogle Transparency Center ads for a project's competitors. sourceGranted false means the organization does not have Google ads tracking enabled, which is different from having no ads.
Parameters8
- projectIdintegerRequiredProject id from list_projects. Every scoped method needs it.
- competitorIdintegerOptionalCompetitor id from list_competitors. Omit to cover every tracked competitor in the project.
- fromISO dateOptionalOnly items published on or after this date, e.g. 2026-08-01.
- toISO dateOptionalOnly items published on or before this date.
- formatstringOptionalCreative format filter, e.g. "text", "image", "video".
- searchstringOptionalFree-text match against the ad title and body.
- pageintegerOptional1-based page number. Defaults to 1.
- sizeintegerOptionalAds per page. Defaults to 12, clamped to 48.
Returns5
- items[]adtitle, body, ctaText, linkUrl, previewUrl, format, isActive, startedAt, endedAt, mediaUrls, competitorName.
- emptyReasonstring | nullSet when empty: missing advertiser id, no competitors, or nothing stored in range.
- totalintegerUnfiltered count.
- pageinteger
- sourceGrantedbooleanFalse means this ad source is not enabled for the organization, which is different from having no ads.
Get Meta ads
get_meta_adsreadMeta Ad Library ads for a project's competitors, with an optional surface filter (Facebook, Instagram, Messenger, Threads, Audience Network).
Parameters9
- projectIdintegerRequiredProject id from list_projects. Every scoped method needs it.
- competitorIdintegerOptionalCompetitor id from list_competitors. Omit to cover every tracked competitor in the project.
- fromISO dateOptionalOnly items published on or after this date, e.g. 2026-08-01.
- toISO dateOptionalOnly items published on or before this date.
- formatstringOptionalCreative format filter, e.g. "image", "video", "carousel".
- searchstringOptionalFree-text match against the ad title and body.
- pageintegerOptional1-based page number. Defaults to 1.
- sizeintegerOptionalAds per page. Defaults to 12, clamped to 48.
- publisherPlatformenumOptionalFACEBOOK, INSTAGRAM, MESSENGER, THREADS or AUDIENCE_NETWORK.
Returns6
- items[]adtitle, body, ctaText, linkUrl, previewUrl, format, isActive, startedAt, endedAt, mediaUrls, competitorName.
- emptyReasonstring | nullSet when empty: missing advertiser id, no competitors, or nothing stored in range.
- totalintegerUnfiltered count.
- pageinteger
- sourceGrantedbooleanFalse means this ad source is not enabled for the organization, which is different from having no ads.
- items[].publisherPlatformsstring[]The Meta surfaces each ad ran on.
( Social posts )
group page →Posts scraped from tracked accounts and competitor domains, per platform. All three methods share one shape; scope by competitorId, by a tracked account url, or read everything.
Get LinkedIn posts
get_linkedin_postsreadLinkedIn posts stored for a project, newest first. Scope with competitorId or a tracked account url from list_tracked_accounts; omit both to read every account and competitor domain on the platform.
Parameters7
Returns5
Get X (Twitter) posts
get_twitter_postsreadSame shape and scoping as get_linkedin_posts, for X.
Parameters7
Returns5
Get Instagram posts
get_instagram_postsreadSame shape and scoping as get_linkedin_posts, for Instagram.
Parameters7
Returns5