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.

01

List projects

list_projectsread

Every 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
02

Draft a project from a company website

prepare_create_projectwrite

Fills 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
03

Create a project

create_projectwrite

Creates 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.

04

List competitors

list_competitorsread

The 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
05

Draft competitors from their websites

prepare_add_competitorwrite

Reads 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
06

Add competitors

add_competitorwrite

Adds 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.

07

List tracked social accounts

list_tracked_accountsread

The 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.
08

Track a LinkedIn account

set_linkedin_handlewrite

Start 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
09

Track an X (Twitter) account

set_x_handlewrite

Start 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
10

Track a Instagram account

set_instagram_handlewrite

Start 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 articles collected for a project's tracked competitors, newest first, each with its source url and publish date.

11

Get competitor news

get_newsread

The 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.

12

Get competitor reviews

get_reviewsread

The 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.

13

Get competitor website changes

get_website_changesread

The 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

( 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.

14

Get LinkedIn posts

get_linkedin_postsread

LinkedIn 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

  • projectIdintegerRequiredProject id from list_projects. Every scoped method needs it.
  • competitorIdintegerOptionalCompetitor id from list_competitors. Omit to cover every tracked competitor in the project.
  • urlstringOptionalTracked account url from list_tracked_accounts.
  • 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

  • items[]postcontent, sourceUrl, publishedAt, author, engagement (likes, comments, shares, views), mediaUrls, accountUrl.
  • resolvedAccounts[]accountThe accounts the read actually covered: url, displayName, lastPortedAt.
  • emptyReasonstring | nullWhy a result is empty when it is: nothing tracked vs nothing collected yet.
  • nextCursorstring | nullPass back as cursor to read the next page. Null when done.
  • hasMoreboolean
15

Get X (Twitter) posts

get_twitter_postsread

Same shape and scoping as get_linkedin_posts, for X.

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.
  • urlstringOptionalTracked account url from list_tracked_accounts.
  • 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

  • items[]postcontent, sourceUrl, publishedAt, author, engagement (likes, comments, shares, views), mediaUrls, accountUrl.
  • resolvedAccounts[]accountThe accounts the read actually covered: url, displayName, lastPortedAt.
  • emptyReasonstring | nullWhy a result is empty when it is: nothing tracked vs nothing collected yet.
  • nextCursorstring | nullPass back as cursor to read the next page. Null when done.
  • hasMoreboolean
16

Get Instagram posts

get_instagram_postsread

Same shape and scoping as get_linkedin_posts, for Instagram.

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.
  • urlstringOptionalTracked account url from list_tracked_accounts.
  • 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

  • items[]postcontent, sourceUrl, publishedAt, author, engagement (likes, comments, shares, views), mediaUrls, accountUrl.
  • resolvedAccounts[]accountThe accounts the read actually covered: url, displayName, lastPortedAt.
  • emptyReasonstring | nullWhy a result is empty when it is: nothing tracked vs nothing collected yet.
  • nextCursorstring | nullPass back as cursor to read the next page. Null when done.
  • hasMoreboolean

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.

17

Get Google ads

get_google_adsread

Google 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.
18

Get Meta ads

get_meta_adsread

Meta 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.