Skip to content

MCP server

Connect Claude, Cursor and other MCP clients to trackagoat with the hosted MCP server.

Updated Oct 10, 2026 · 33 min read

Overview#

trackagoat runs a hosted Model Context Protocol server. Connect Claude.ai or Claude Desktop by signing in with your trackagoat account, or point any MCP client at it with an API key. Your agent can then check a program's health, browse projects, creators, videos, campaigns, goals, conversions and payouts, pull analytics, and (with write access) do what the REST API does: add, change and remove creators, accounts, videos, campaigns, goals and content groups, record conversions, set up payout structures, assign creators to them, and record or void payments. It can also read and write the Markdown documents on every record and export any CSV the app exports.

URLhttps://www.trackagoat.com/api/mcp
TransportStreamable HTTP (stateless). The legacy HTTP+SSE transport is not supported; use mcp-remote for clients that only speak stdio.
AuthEither sign in with trackagoat (OAuth 2.1, for Claude.ai and Claude Desktop and other OAuth-capable clients), or Authorization: Bearer tga_<key> with the same org API keys as the REST API
Data scopeThe organization you pick when you sign in, or the one that owns the API key. Other organizations' data is never visible.

Every tool is a thin adapter over one /api/v2 endpoint, so MCP and REST return the same data and enforce the same permissions and limits.

A connection always acts as one member of the organization: the person who signed in, or the member an API key acts as. Everything the agent does is attributed to them, and it can never do more than they can do in the app. When the agent connects, the server sends that person's personalization document along with its instructions, so the agent starts out knowing who it is helping and how they want help.

New to trackagoat? Set up with a coding agent also covers sign-up and plan limits.

Claude.ai and Claude Desktop (custom connector)#

Claude connects natively: no API key, no config file, no mcp-remote. You sign in with your trackagoat account and choose what Claude may do.

  1. Add the connector

    In Claude, open Settings → Connectors (on claude.ai: Customize → Connectors) and choose Add custom connector. Enter:

    • Name: trackagoat
    • Remote MCP server URL: https://www.trackagoat.com/api/mcp

    Leave the advanced OAuth client ID and secret fields empty. On Team and Enterprise plans, an Owner adds the connector once for the organization and each person then connects their own account.

  2. Sign in and approve

    Click Connect. A trackagoat window opens. Sign in if you aren't already, then:

    • pick the organization Claude may see (one per connection), and
    • choose View data (always on) and, optionally, Make changes for the write tools.

    Click Allow access. You're returned to Claude and the trackagoat tools appear in the connector list.

  3. Use it

    Enable the connector in a chat (the + / tools menu) and ask about your creators. Claude Desktop, Claude mobile and claude.ai share the same connection.

Good to know:

  • Claude acts as you, limited to what you allowed and to your current role. If your role changes or you leave the organization, its access changes or stops at once.
  • If you allowed only View data and later ask Claude to change something, Claude asks you to reconnect and approve Make changes.
  • To use a second organization, add the connector again and pick the other organization.
  • To disconnect, remove the connector in Claude, or go to Settings → Connected Apps in trackagoat. Org admins can also disconnect any member's app under Org settings → API keys → Connected apps.
  • Connected apps don't use up your plan's API key limit, but every tool call counts toward the org's daily API requests, like a key. Every plan can connect apps; Free allows 200 requests a day.

The same sign-in works for other MCP clients that support OAuth, including Claude Code, Codex, Cursor and VS Code: give them the URL above and they discover everything else from it. See Connect a client.

Get an API key#

Use an API key for scripts, and for clients that can't sign in with OAuth. In trackagoat, go to Org settings → API keys → + New API key. Name it after the client (e.g. Claude Code laptop) and choose scopes:

  • read: required for every read tool.
  • write: required for the write tools. Leave it off if the agent should only read.

Copy the key: it's shown once. See Authentication and API keys for expiry and revocation. A key acts on behalf of one member: the admin who created it, or the member picked under Acts as. It can never do more than that member can in the app, and it stops working if they leave the org. A key made for someone else also stops working if the admin who created it leaves, is changed to member or is suspended (see Who a key acts as).

Connect a client#

Each client below can sign in (no key) or send an API key. Keep keys in an environment variable such as TRACKAGOAT_API_KEY, never in a committed file.

Claude Code#

Sign in:

bash
claude mcp add --transport http trackagoat https://www.trackagoat.com/api/mcp

Then run /mcp in Claude Code, select trackagoat and sign in. With an API key instead:

bash
claude mcp add --transport http trackagoat https://www.trackagoat.com/api/mcp \
  --header "Authorization: Bearer $TRACKAGOAT_API_KEY"

Add --scope user to make it available in every project. To share the setup with your team without committing a key, put this in the repo's .mcp.json and have each person export TRACKAGOAT_API_KEY:

JSON
{
  "mcpServers": {
    "trackagoat": {
      "type": "http",
      "url": "https://www.trackagoat.com/api/mcp",
      "headers": { "Authorization": "Bearer ${TRACKAGOAT_API_KEY}" }
    }
  }
}

Run /mcp in Claude Code to confirm trackagoat shows as connected.

Codex CLI#

Sign in:

bash
codex mcp add trackagoat --url https://www.trackagoat.com/api/mcp
codex mcp login trackagoat

With an API key instead, Codex reads the variable each time it starts:

bash
codex mcp add trackagoat --url https://www.trackagoat.com/api/mcp \
  --bearer-token-env-var TRACKAGOAT_API_KEY

Cursor#

Add to ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project). To sign in, leave out headers and sign in from Cursor's MCP settings. With an API key:

JSON
{
  "mcpServers": {
    "trackagoat": {
      "url": "https://www.trackagoat.com/api/mcp",
      "headers": { "Authorization": "Bearer ${env:TRACKAGOAT_API_KEY}" }
    }
  }
}

VS Code#

Add to .vscode/mcp.json, then start the server. Without headers (and inputs), VS Code asks you to sign in. With an API key, VS Code prompts for it once and stores it securely:

JSON
{
  "inputs": [
    { "type": "promptString", "id": "trackagoat-key", "description": "trackagoat API key", "password": true }
  ],
  "servers": {
    "trackagoat": {
      "type": "http",
      "url": "https://www.trackagoat.com/api/mcp",
      "headers": { "Authorization": "Bearer ${input:trackagoat-key}" }
    }
  }
}

Stdio-only clients#

For clients that only launch local (stdio) servers, bridge with mcp-remote (requires Node.js 18+). For example, in Claude Desktop's claude_desktop_config.json (Settings → Developer → Edit config), though the custom connector is simpler there:

JSON
{
  "mcpServers": {
    "trackagoat": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://www.trackagoat.com/api/mcp",
        "--header",
        "Authorization:${TRACKAGOAT_AUTH}"
      ],
      "env": { "TRACKAGOAT_AUTH": "Bearer tga_<key>" }
    }
  }
}

Keep Authorization:${TRACKAGOAT_AUTH} without spaces: some clients split arguments on spaces, so the Bearer prefix goes in the env var.

Other clients#

Any client that supports Streamable HTTP works: either let it sign in with OAuth (it discovers the authorization server from the 401 response, per the MCP authorization spec), or send Authorization: Bearer tga_<key> on every request.

Tools#

Each tool's description and input schema are served to your client, so the agent sees parameter docs directly. Schemas are strict: a parameter a tool doesn't have (say range on get_analytics, which takes from and to) is rejected with unknown_parameter instead of being silently ignored. Tool results are compact JSON: image URLs are dropped, and list tools preview long readme notes (call the matching get_* tool for the full text).

Read tools#

All require the read scope, except get_changelog, which works on any connection. Tools marked Org admin only also need the connection to act as an org admin, like the matching page in the app; for anyone else they return insufficient_role. Each tool's description says the same.

Projects, creators, accounts and videos

ToolWhat it doesREST equivalent
list_projectsProjects in the org, with their readmeGET /api/v2/projects
list_creatorsCreators with accounts and totals; filter by project, platform, searchGET /api/v2/creators
get_creatorOne creator: full readme and its readme_version, metadata, every account's stats, tracking config and last_scraped_atGET /api/v2/creators/{id}
list_accountsPlatform accounts with counts and tracking mode; filter by project, creator, platform, handleGET /api/v2/accounts
get_accountOne platform account in fullGET /api/v2/accounts/{id}
get_account_statsFollower, following, like and video-count snapshots over time for one accountGET /api/v2/accounts/{id}/stats
list_videosTracked videos, newest added first, with counts and the start of each caption; filter by project, creator, account, platform, content groupGET /api/v2/videos
get_video_statsOne video's latest counts, caption, notes (readme + readme_version), tracking status and flagsGET /api/v2/videos/{id}
list_content_groupsContent groups: the same content posted on several platforms, linked as oneGET /api/v2/content-groups
get_content_groupOne content group and its video idsGET /api/v2/content-groups/{id}
get_content_group_statsViews, likes, comments and shares summed across a content group, and per platformGET /api/v2/content-groups/{id}/stats
get_share_linkA creator's shareable page: url, enabled, sections shown. Pass include_pin: true to also get the entrance PIN, which needs the write scope. Org admin only.GET /api/v2/creators/{id}/share-link
get_schemaThe data model: entities, fields, relationshipsGET /api/v2/schema

Comments (paid plans; 403 plan_feature_unavailable on Free)

ToolWhat it doesREST equivalent
list_commentsComments collected on a project's videos, most liked first: text, likes, sentiment and signals (app_question, signup_intent, ad_disclosure, risk, pay_talk, referral_spam, brand_mention, competitor). Filter by signal (flagged = ad doubts or brand-safety words), sentiment, creator, campaign, platform, dates, text. Paginate with next_cursorGET /api/v2/projects/{id}/comments
list_video_commentsOne video's Comments tab: every collected comment with sentiment and signals, the sentiment split and per-signal counts, and coverage (platform count vs collected, last collected). Filter by signal, sentiment, text; paginate with next_offsetGET /api/v2/videos/{id}/comments
get_comment_signals_summaryComment Insights in one call: coverage, sentiment and signal counts, a row per creator (comments per 1,000 views, positive share, app questions, sign-ups, flagged, top comment) and positive share over time. creator_sort ranks creators (e.g. app_question_count for "who gets the most app questions"), creator_limit keeps the top NGET /api/v2/projects/{id}/comment-signals
get_comment_flagsThe weekly flag digest on demand: comments in the last days (default 7) asking if a post is an ad or using words like scam, the most-liked of them, and creators whose positive share fell 20+ points against the 30 days beforeGET /api/v2/projects/{id}/comment-flags
get_comment_settingsThe org's minimum comment count and brand / competitor terms (Org settings → Comments), and whether the plan collects comments. Works on every plan. Org admin only.GET /api/v2/comment-settings

Program health, goals and campaigns

ToolWhat it doesREST equivalent
get_program_healthA project's (or one campaign's) health in one call: healthy / at-risk / degraded verdict and the signals behind it, KPIs, creators who stopped posting, goal compliance, alerts (sudden view drops, tracking gaps, private accounts, disabled creators, over-posting, flagged comments), top and under-performers. Optional campaign_id and range (7d, 14d, 30d default, 90d)GET /api/v2/projects/{id}/program-health
get_goal_complianceGoal target vs actual and status per creator in a projectGET /api/v2/projects/{id}/goal-compliance
get_goal_compliance_summaryCount of a project's goals by status (on track, at risk, missed)GET /api/v2/analytics/aggregate/goal-compliance
list_campaignsCampaigns with their readmeGET /api/v2/campaigns
get_campaign_statsPer-campaign totals for tracked posts posted in a date range (default the last 30 days including today, org time zone), with prior-period delta. Don't add rows up (shared videos appear in several rows): use get_metric_totals with campaigns=all. Pass campaign_id for one campaign (project_id is then optional: it comes from the campaign), or project_id alone to compare every campaign in the projectGET /api/v2/analytics/aggregate/campaign-leaderboard
get_metric_totalsHeadline totals for a project, one campaign or every campaign at once (campaigns=all, each video counted once): tracked posts, views, likes, comments, shares, saves, weighted engagement rate, creators who posted, followers and follower growth, posts awaiting review, and stats freshness. The same numbers as the dashboard and Insights. Default window: the last 30 days including today, org time zoneGET /api/v2/analytics/aggregate/summary
get_campaign_progressEach campaign's view target, current views, percent done, days left and statusGET /api/v2/analytics/aggregate/campaign-progress
get_campaign_trendsViews gained, posts, creators posting and first-time creators per day, week, month or year, for one campaign or the whole projectGET /api/v2/analytics/aggregate/campaign-timeseries
get_member_overlapCreators or videos that are in more than one campaignGET /api/v2/analytics/aggregate/member-overlap

Analytics

ToolWhat it doesREST equivalent
get_analyticsTime series for a video, creator or campaign: any metric, granularity, prior-period comparison, top-N breakdownGET /api/v2/analytics
list_top_videosRank a project's videos by views, likes, comments, shares, saves or posted date; filter by posted date range, platform, campaignGET /api/v2/analytics/aggregate/video-leaderboard
list_top_creatorsRank creators by views on videos posted in a range, with follower change, posts per week and engagementGET /api/v2/analytics/aggregate/creator-leaderboard
list_top_accountsThe same ranking per platform account; filter by platform or campaignGET /api/v2/analytics/aggregate/account-leaderboard
list_outlier_videosVideos that beat their creator's median views by a multiple (default 1.5×)GET /api/v2/analytics/aggregate/outliers
get_creator_scatterFollower change vs engagement rate per creatorGET /api/v2/analytics/aggregate/creator-scatter
get_posting_heatmapPosts and average views by weekday and hourGET /api/v2/analytics/aggregate/posting-heatmap
get_posting_consistencyPosts per creator per dayGET /api/v2/analytics/aggregate/posting-consistency
get_over_posting_risksDays a creator posted so often that some videos were held back from trackingGET /api/v2/analytics/aggregate/over-posting-risks
get_view_distributionHistogram and percentiles of video viewsGET /api/v2/analytics/aggregate/view-distribution
list_annotationsDated notes on a creator's, campaign's or video's charts, added by people or automaticallyGET /api/v2/analytics/annotations

The heatmap, consistency, over-posting, view-distribution and campaign-trend tools default to the last 30 days when from and to are left out.

Conversions

ToolWhat it doesREST equivalent
list_conversion_eventsA project's conversion events (e.g. signup, purchase) and their default valuesGET /api/v2/projects/{id}/conversion-events
get_conversion_eventOne conversion eventGET /api/v2/projects/{id}/conversion-events/{eventId}
list_conversionsRecorded conversions; filter by event, creator, account, video, source, status and timeGET /api/v2/projects/{id}/conversions
get_conversionOne recorded conversionGET /api/v2/projects/{id}/conversions/{conversionId}
get_conversion_summaryCount and value of conversions in a range, one row per currencyGET /api/v2/analytics/aggregate/conversion-summary
list_top_convertersCreators ranked by conversion valueGET /api/v2/analytics/aggregate/conversion-leaderboard
get_conversion_timeseriesConversions per day, one row per day and currencyGET /api/v2/analytics/aggregate/conversion-timeseries

Payouts

ToolWhat it doesREST equivalent
list_payout_structuresPayout structures with their current rule: type, period, amount and criteria_params (for CPM: tiers, minimum, cap and view_lifetime_days); filter by project and active stateGET /api/v2/payout-structures
get_payout_structureOne structure with its current rule, earlier versions and assignment countGET /api/v2/payout-structures/{id}
list_payout_assignmentsCreators assigned to a structureGET /api/v2/payout-structures/{id}/assignments
list_payout_accrualsEarned / paid / rejected / voided payout accruals; filter by project, creator, structure, status, periodGET /api/v2/payout-accruals
get_payout_accrualOne accrual, including how it was calculated (inputs_snapshot)GET /api/v2/payout-accruals/{id}
list_payout_methodsThe org's payout methods (PayPal, Venmo, …)GET /api/v2/payout-methods
get_payout_methodOne payout methodGET /api/v2/payout-methods/{id}
list_payout_paymentsRecorded payments and the accruals each settled; filter by project, creator, status, dateGET /api/v2/payout-payments
get_payout_paymentOne recorded paymentGET /api/v2/payout-payments/{id}
get_payout_accountWhether a creator can be paid through the connected provider (Dots), who they're paid as, and the org's agent-payment switch and limits. Org admin only.GET /api/v2/creators/{id}/payee-links

Notes and documents

ToolWhat it doesREST equivalent
list_notesEvery document with text in the org (organization, projects, campaigns, creators, videos, payout methods, structures, payments and members), with a preview; filter by type, project or textGET /api/v2/notes
get_notesOne document in full with its readme_version; entity_type=me is the person you're helping, member a teammateGET /api/v2/notes/{entity_type}/{id}
get_my_profileWho the connection acts as: name, org and role, scopes, and their personalization documentGET /api/v2/me
list_membersThe org's members and whether each has a personalization documentGET /api/v2/members

Exports

ToolWhat it doesREST equivalent
export_csvAny CSV the app exports (creators, videos, campaigns, goals, the campaign leaderboard, the payouts tracker, payments, accruals and Insights charts) with the same columns and filters, as a file for the agent to save. See Exporting CSVsGET /api/v2/exports/{dataset}

What's new in trackagoat

ToolWhat it doesREST equivalent
get_changelogChangelog entries, newest first: date, title, link to the entry in the docs and its text as Markdown. Filter by since (a date) and q (search words). Needs no scope and doesn't count toward the daily request limit. Ask your agent "what's new in trackagoat?" and it uses this toolGET /api/v2/changelog

The data model is also available as the MCP resource trackagoat://schema.

Write tools#

All require the write scope (Make changes when connecting with sign-in). A key without it gets an insufficient_scope error and nothing is changed; a signed-in client is asked to reconnect with Make changes. Tools marked can't be undone are annotated destructiveHint: true, so most clients ask before running them. Tools marked Org admin only need the connection to act as an org admin (insufficient_role otherwise).

Creators and accounts

ToolWhat it doesREST equivalent
add_creatorTrack a creator with one or more platform accounts; starts a profile + video-discovery scrapePOST /api/v2/creators
add_creatorsTrack up to 50 creators in one project in one callPOST /api/v2/projects/{id}/creators
add_accountAdd another platform account to an existing creatorPOST /api/v2/creators/{id}/accounts
update_creatorRename a creator or replace their metadataPATCH /api/v2/creators/{id}
update_accountRename an account's handle, change its tracking mode, hashtags or tracking datesPATCH /api/v2/accounts/{id}
reenable_creatorsTurn tracking back on for creators trackagoat disabled automatically. Org admin only.POST /api/v2/projects/{id}/creators/bulk-reenable
remove_creatorStop tracking a creator and all their accounts. Can't be undone through MCP or the API. Org admin only.DELETE /api/v2/creators/{id}
bulk_remove_creatorsThe same for up to 100 creators. Can't be undone. Org admin only.POST /api/v2/projects/{id}/creators/bulk-remove
remove_accountStop tracking one account of a creator. Can't be undone (re-add with add_account). Org admin only.DELETE /api/v2/accounts/{id}
trigger_scrapeRefresh one account (profile, video stats or new-video discovery), a creator's primary account, or one video now. Org admin only.POST /api/v2/accounts/{id}/scrape, POST /api/v2/creators/{id}/scrape, POST /api/v2/videos/{id}/scrape
update_notesAdd to or replace any document (readme) without overwriting human edits: creators, videos, campaigns, projects, the organization, payout records, or me. Organization, project and payout documents are org admin only. See Notes and documentsPOST /api/v2/notes/{entity_type}/{id} (creators and videos: POST /api/v2/creators/{id}/notes, POST /api/v2/videos/{id}/notes)
update_my_readmeSave the personalization document of the person you're helping, after they approve the draft. Needs expected_readme_versionPATCH /api/v2/me

Videos

ToolWhat it doesREST equivalent
add_video_by_urlTrack 1 to 50 videos by URL (TikTok or Instagram; YouTube isn't live yet)POST /api/v2/projects/{id}/videos
update_videoChange a video's title or tracking status (notes go through update_notes)PATCH /api/v2/videos/{id}
review_inboxInclude or exclude videos waiting in the Tracking Inbox, by id or for a whole creatorPATCH /api/v2/projects/{id}/inbox
set_video_trackingStop or resume stats tracking for one video, or clear its age-rule exemption. Org admin only.POST /api/v2/videos/{id}/tracking-disable, …/tracking-enable, …/tracking-unexempt
bulk_set_video_trackingStop or resume tracking for up to 200 videos (optionally exempting them from age rules). Org admin only.POST /api/v2/projects/{id}/videos/bulk-tracking-disable, …/bulk-tracking-enable

Campaigns, goals, content groups and share pages

ToolWhat it doesREST equivalent
create_campaignCreate an empty campaign in a projectPOST /api/v2/projects/{id}/campaigns
update_campaignRename a campaign, replace its readme (pass expected_readme_version to get notes_conflict instead of overwriting a newer edit), or set its view target and deadlinePATCH /api/v2/campaigns/{id}
add_to_campaignAdd a creator, video or sub-campaign to a campaignPOST /api/v2/campaigns/{id}/items
remove_from_campaignTake a creator, video or sub-campaign out of a campaign (the item itself is kept)DELETE /api/v2/campaigns/{id}/items
delete_campaignPermanently delete a campaign and its membership list. Can't be undone. Org admin only.DELETE /api/v2/campaigns/{id}
create_goalGive a creator a posts / views / engagement / followers goal per day, week or monthPOST /api/v2/creators/{id}/goals
update_goalChange a goal's metric, period, target or dates, or pause it (is_active: false)PATCH /api/v2/creators/{id}/goals/{goalId}
delete_goalPermanently delete a goal. Can't be undone, and goal-based payouts for periods not yet calculated are judged without it; ending it with update_goal (end_date) is saferDELETE /api/v2/creators/{id}/goals/{goalId}
create_content_groupLink the same content posted on several platformsPOST /api/v2/content-groups
update_content_groupRename a content group, change its notes, add or remove videosPATCH /api/v2/content-groups/{id}
delete_content_groupPermanently delete a content group (its videos are kept). Can't be undoneDELETE /api/v2/content-groups/{id}
create_share_linkCreate or replace a creator's PIN-protected page; returns the url and PIN. Org admin only.POST /api/v2/creators/{id}/share-link
update_share_linkTurn a share page off or on, change its sections, or set a new PIN. Org admin only.PATCH /api/v2/creators/{id}/share-link
bulk_create_share_linksCreate share pages for up to 200 creators; returns every url and PIN. Org admin only.POST /api/v2/share-links/bulk
delete_share_linkPermanently delete a creator's share page. Can't be undone; prefer update_share_link with enabled: false. Org admin only.DELETE /api/v2/creators/{id}/share-link
create_annotationAdd a dated note to a creator's, campaign's or video's chartsPOST /api/v2/analytics/annotations
update_annotationChange an annotation someone addedPATCH /api/v2/analytics/annotations/{id}
delete_annotationPermanently delete an annotation someone added. Can't be undoneDELETE /api/v2/analytics/annotations/{id}

Comment settings

ToolWhat it doesREST equivalent
update_comment_settingsSet the minimum comment count and replace the brand or competitor terms behind the brand_mention and competitor signals. Org admin only.PATCH /api/v2/comment-settings

Conversions

ToolWhat it doesREST equivalent
create_conversion_eventDefine a kind of conversion (e.g. signup) with a default valuePOST /api/v2/projects/{id}/conversion-events
update_conversion_eventChange an event's name, description, default value or metadata, or deactivate / reactivate itPATCH /api/v2/projects/{id}/conversion-events/{eventId} (deactivating is the same as DELETE …/{eventId})
record_conversionsRecord 1 to 500 conversions credited to creators, accounts or videos; external_id dedupes repeatsPOST /api/v2/projects/{id}/conversions
void_conversionVoid a conversion (refund, chargeback, fraud): excluded from totals, kept for audit. Can't be undone. Org admin only.DELETE /api/v2/projects/{id}/conversions/{conversionId} (mode=void)

Payouts

ToolWhat it doesREST equivalent
create_payout_structureCreate a payout rule: recurring, goals, CPM, view-threshold bonus or per conversion. Org admin only.POST /api/v2/payout-structures
update_payout_ruleReplace a structure's rule with a new version, effective from the period in progress. Org admin only.PATCH /api/v2/payout-structures/{id} (kind: "rule")
set_cpm_view_lifetimeSet how long after posting a video keeps earning on a CPM structure (view_lifetime_days, or null for forever). Saves a new version with nothing else changed, effective from the period in progress. Counts as two API requests. Org admin only.GET then PATCH /api/v2/payout-structures/{id}
update_payout_structureRename a structure, replace its notes or metadata, or un-archive it. Org admin only.PATCH /api/v2/payout-structures/{id} (kind: "cosmetic")
archive_payout_structureStop a structure earning and end every assignment; past accruals stay payable. Un-archiving doesn't bring the assignments back. Org admin only.DELETE /api/v2/payout-structures/{id} (mode=archive)
delete_payout_structurePermanently delete a structure that never produced an accrual. Can't be undone. Org admin only.DELETE /api/v2/payout-structures/{id}?mode=hard
assign_payout_structurePut creators on a structure, from now or a later date. Org admin only.POST /api/v2/payout-structures/{id}/assignments
unassign_payout_structureTake creators off a structure; what they earned stays payable. Org admin only.DELETE /api/v2/payout-structures/{id}/assignments
set_accrual_statusReject or void an earned accrual so it is no longer owed. Can't be undone. Org admin only.PATCH /api/v2/payout-accruals/{id}
create_payout_methodAdd a payout method (e.g. Wise). Org admin only.POST /api/v2/payout-methods
update_payout_methodRename a method, replace its notes or metadata, set or remove its icon (icon_path), or disable / re-enable it. Org admin only.PATCH /api/v2/payout-methods/{id}
delete_payout_methodPermanently delete a payout method. Can't be undone; prefer disabling it. Org admin only.DELETE /api/v2/payout-methods/{id}
record_payout_paymentRecord a payment made outside trackagoat and mark the accruals it covers as paid, optionally with a receipt (payment_id + attachment_path). It doesn't send money. Requires idempotency_key. Org admin only.POST /api/v2/payout-payments
update_payout_paymentReplace a payment's notes or metadata. Org admin only.PATCH /api/v2/payout-payments/{id}
send_payoutSends real money through the org's connected provider (Dots) and records the payment. Only works after an org admin turns on agent payments, within the org's limits. Supports a note to the creator, SMS text, description and 1099 exemption. Requires idempotency_key. Org admin only.POST /api/v2/payout-payments/send
void_payout_paymentVoid a payment; its accruals and supplemental amounts go back to owed. Can't be undone. Org admin only.PATCH /api/v2/payout-payments/{id} (status: "voided")
get_payouts_trackerPer-creator earned, paid, adjustments and outstanding for a project, with totals (earned − paid + adjustments = outstanding)GET /api/v2/payouts/tracker
list_payout_supplementalsList supplemental amounts (owed corrections on top of paid accruals)GET /api/v2/payout-supplementals
create_payout_supplementalRecord that a creator is owed more for a paid accrual; settled by record_payout_payment. Requires idempotency_key. Org admin only.POST /api/v2/payout-supplementals
void_payout_supplementalVoid an owed supplemental amount. Can't be undone. Org admin only.PATCH /api/v2/payout-supplementals/{id} (status: "void")

Receipts and method icons

ToolWhat it doesREST equivalent
upload_receiptUpload a payment receipt (up to 3 MB) as base64; returns the path to pass to record_payout_payment. Org admin only.POST /api/v2/payouts/payment-receipts
get_receipt_upload_urlGet a signed URL to PUT a receipt of up to 5 MB to (valid 2 hours), and the path to pass back. Org admin only.POST /api/v2/payouts/payment-receipts/upload-url
upload_payout_method_iconUpload a PNG, JPEG or WebP icon (up to 1 MB) as base64 and set it on a payout method. Org admin only.POST /api/v2/payout-methods/{id}/icon
get_payout_method_icon_upload_urlGet a signed URL to PUT an icon to, and the path to set with update_payout_method. Org admin only.POST /api/v2/payout-methods/{id}/icon/upload-url

To attach a receipt, the agent generates a UUID as payment_id, uploads the file under it (upload_receipt, or get_receipt_upload_url and a PUT of the raw bytes with the same Content-Type), then calls record_payout_payment with that payment_id and attachment_path set to the returned path. A receipt can only be attached when the payment is recorded, as in the app. Allowed receipt types: PNG, JPEG, WebP, PDF, CSV, Word and Excel. Inline uploads are checked: the file's contents must match content_type.

Tools that create something or act in bulk accept an optional idempotency_key (it is sent as the REST Idempotency-Key header). Have the agent pass a fresh UUID per logical write: if a call times out and is retried with the same key and arguments within 24 hours, you get the original result (marked "replayed": true) instead of a duplicate. A retry while the first call is still running fails with idempotency_in_progress (try again in a couple of seconds), and reusing a key with different arguments fails with idempotency_key_reused. record_payout_payment, send_payout and create_payout_supplemental require a key. Tools that set a value (update_*, set_*, deletes, voids, assignments) have no key because repeating them has the same effect; set_cpm_view_lifetime takes one anyway. Three creates have no key because their REST endpoints don't support one: create_payout_structure and create_annotation (check the list before retrying) and create_payout_method (names are unique, so a repeat fails with conflict_name). trigger_scrape has no key: it's limited by the manual-scrape limits instead. The upload tools have no key either: a retry stores another copy of the file, and only the path you pass on is used.

Notes and documents#

The organization, every project, campaign, creator, video, payout method, structure and payment, and every member has a Markdown document (readme). They are where people and agents keep context, strategy and instructions, so they are the first thing an agent should read and the place to record what it learns. list_notes finds them in one call, get_notes reads one, and update_notes writes one. Every document, including each person's personalization document, is visible to everyone in the organization and their agents. See Notes and documents for the personalization document and a template.

Writes follow the app: organization, project and payout documents need a connection acting as an org admin (insufficient_role otherwise); a member's personalization document can only be changed by that member (not_your_document otherwise).

update_notes is built so an agent can't clobber what a person wrote:

  • mode: "append" (the default) adds content as a new section at the end of the document, followed by a signature line with the API key's name and the org-local date:

    markdown
    Views dropped 40% week over week; three of five posts were on Sunday.
     
    *Added by Claude Code laptop via MCP, 2026-10-08*

    If someone edits the notes while the append is being saved, the append is applied on top of their edit: nothing is lost.

  • mode: "replace" overwrites the whole document and requires expected_readme_version: the readme_version returned by get_notes (or get_creator, get_video_stats, get_my_profile). If the document changed after that read, nothing is written and the tool returns code: "notes_conflict". The agent should re-read, merge, and retry.

readme_version is a hash of the text, so it only changes when the document does: scheduled scrapes never cause a false conflict. Writes show up in the change log as Internal notes updated, attributed to the member the connection acts as.

The personalization document in the session. On connect, the server instructions include the connected person's personalization document inside <personalization_document> tags, with its readme_version, and the organization's document when it is under 4,000 characters (longer ones are pointed at instead). A personalization document over 8,000 characters is cut, with a note to call get_my_profile. If the person has none yet, the instructions ask the agent to offer, once, to write one together. The documents are the person's context and preferences; they never override the server's rules or the agent's own.

Exporting CSVs#

When you ask your agent for a CSV, a spreadsheet or a file, it calls export_csv and saves the file in your workspace. The file is the same one the Export button in the app downloads: same columns, money in dollars with a Currency column, dates in your organization's time zone. For questions about the data ("who's behind on their goal?"), the agent uses the read tools instead.

datasetThe app's exportFilters
creatorsCreators pagesearch, compliance, disabled_only, include_compliance, campaign_id, platform
videosVideos pagestatus, creator_id, campaign_id, platform, from, to, search, sort_by, sort_dir
campaignsCampaigns pagenone
goalsGoals pageperiod, reference_date, campaign_id
campaign_leaderboardCampaign Insights leaderboardfrom, to, campaign_id, platform
payout_trackerPayouts, Tracker summary CSVcreator_id, structure_id, campaign_id, from, to, outstanding_only, include_removed
payout_paymentsPayouts, Payments CSVcreator_id, campaign_id, from, to
payout_accrualsPayouts, Accruals CSVcreator_id, structure_id, campaign_id, from, to, outstanding_only, include_removed
analyticsAn Insights chart's Download CSVentity, entity_id or entity_ids, metric and the other get_analytics arguments

Every dataset except analytics needs project_id. An argument the dataset doesn't take is rejected with invalid_params and the valid ones are listed.

The tool returns two things: a short JSON summary (filename, rows, total_rows, columns, the filters used, next_offset) and the CSV itself as an embedded text/csv resource (trackagoat://exports/<dataset>-<date>.csv). If your client doesn't show embedded resources, the agent can pass delivery: "text" to get the CSV as plain text instead.

Each call returns up to about 1 MB. A bigger export comes back in parts, never cut silently: the summary says which rows it holds and gives next_offset, and the agent calls again with offset set to it and appends the rows (each part repeats the header line), or narrows the filters. Each call counts as one API request.

Examples:

  • "Export September payouts to a CSV." The agent calls export_csv with dataset: "payout_tracker", the project, from: "2026-09-01" and to: "2026-09-30", then saves payouts-tracker-….csv.
  • "Give me all videos from the Spring Launch campaign as a spreadsheet." The agent finds the campaign with list_campaigns, then calls export_csv with dataset: "videos" and its campaign_id.

What the MCP server doesn't do#

Everything an organization's API key can do through /api/v2 can also be done over MCP, except the following, which are left out on purpose:

Not available over MCPWhy
Creating and revoking API keys (/api/v2/organizations/{orgId}/api-keys)Keys are credentials. An agent shouldn't mint or revoke them; an org admin does that in Org settings → API keys.
Organization administration: creating an organization, creating or renaming projects, inviting, changing or removing members, cancelling invitations (/api/v2/user/organizations, /api/v2/organizations/{orgId}/…)These need the admin scope. Sign-in connections never get it, and MCP tools only use read and write. Creating an organization also acts outside the connected organization.
Permanently deleting a conversion or conversion event (mode=hard)Needs the admin scope, because it erases revenue history. Use void_conversion or update_conversion_event with is_active: false.
Removing a video (DELETE /api/v2/videos/{id})Use set_video_tracking or review_inbox to stop counting a video (or update_video with tracking_status: "excluded", which is what the REST DELETE does).
trackagoat staff endpoints (/api/v2/admin/…)Platform administration, not part of an organization's data.
The OpenAPI documents (/api/v2/openapi.json, /api/v2/analytics/schema)They describe the REST API itself; MCP clients get each tool's schema from the server, and get_schema describes the data model.
The retired /api/v2/creators/{id}/stats and /api/v2/campaigns/{id}/statsThey return 410 Gone. Use get_analytics.

Limits#

  • Each tool call counts as one API request toward your org's daily max_api_requests_per_day limit and the per-key limit of 60 requests per minute, the same as a REST call. Connecting and listing tools are free. A signed-in connection is limited like one key.
  • get_changelog is the exception: it reads public content, so it never counts toward the daily limit. It has its own limit of 60 calls per minute per key or connection.
  • Protocol traffic (connect, list tools, ping) is capped at 120 requests per minute per key or connection.
  • trigger_scrape also counts against your plan's daily manual-scrape limit.
  • add_creator, add_creators, add_account and add_video_by_url count against your plan's account and video limits; create_campaign, create_conversion_event, create_payout_structure and create_payout_method count against their plan limits.
  • set_cpm_view_lifetime counts as two API requests (it reads the structure, then saves it).
  • Analytics ranges can't start before your plan's data-retention window.

When a limit is hit the tool returns an error with code: "rate_limit_exceeded" and retry_after_seconds. See Limits & plan tiers.

Errors#

Tool failures come back as MCP tool errors (isError: true) whose text is JSON:

JSON
{
  "error": "add_creator requires the 'write' scope. Granted: [read]",
  "code": "insufficient_scope",
  "status": 403,
  "hint": "This API key lacks the 'write' scope. An org admin can create a key with that scope in Org settings → API keys."
}

code and status match the REST error codes; every error has a code, so an agent can branch on it instead of parsing error. When the route returns extra context, it's in details. Codes you'll see most:

CodeStatusMeaning
unknown_parameter400The call passed a parameter the tool doesn't have. error names it and lists the valid ones; details has unknown_parameters, valid_parameters and, for near-misses like projectId, did_you_mean. Nothing ran.
invalid_params400A parameter has the wrong type or value; details lists the fields.
already_tracked409add_creator: a handle is already tracked in the project. error names the handle and the creator; details has creator_id and account_id. Nothing was created.
duplicate_account400add_creator: the same platform + handle appears twice in accounts.
not_found404No such id in your organization.
insufficient_scope403The key or connection lacks the scope the tool needs.
insufficient_role403Only org admins can do this in the app, and the connection acts as a member who isn't one: for example payments and payout setup, removing or re-enabling creators, removing accounts, stopping or resuming video tracking, trigger_scrape, organization and project documents, share pages, send_payout, get_payout_account and the comment settings. Every such tool says Org admin only above and in its description.
not_your_document403update_notes on another member's personalization document. Only its owner can change it; read it with get_notes.
notes_conflict409A replace whose expected_readme_version is out of date. Nothing was written: re-read, merge, retry.
plan_feature_unavailable403The organization's plan doesn't include the feature: Comment Insights tools on the Free plan. Retrying won't help.
limit_reached402A plan limit; details has the limit and current usage.
rate_limit_exceeded429Wait retry_after_seconds.
JSON
{
  "error": "Unknown parameter 'range'. Valid parameters: entity, entity_id, entity_ids, metric, granularity, bucket_days, mode, from, to, compare, breakdown, top_n, base_metric.",
  "code": "unknown_parameter",
  "status": 400,
  "hint": "get_analytics accepts only the parameters listed above; unknown ones are rejected rather than ignored. Remove or rename them and call again.",
  "details": { "unknown_parameters": ["range"], "valid_parameters": ["entity", "entity_id", "…"] }
}

An invalid, expired or revoked key is rejected before any tool runs, with HTTP 401; your client will show the server as failing to connect. So is a key whose member left the org (key_member_removed), or a key made for someone else whose creator left, was changed to member or was suspended (key_creator_removed, key_creator_not_admin, key_creator_banned). Org settings → API keys shows why a key stopped working. A signed-in client gets the same 401 with a WWW-Authenticate challenge and refreshes or re-runs sign-in on its own; a write tool called without Make changes gets HTTP 403 insufficient_scope, which prompts it to reconnect.

Example prompts#

  • "List my trackagoat projects, then summarize which creators in Spring Launch posted least this month and whether their data is fresh."
  • "Which 10 videos got the most views in the last 30 days? Group them by creator."
  • "Compare views for my three campaigns this quarter against last quarter."
  • "How healthy is the Spring Launch program this week? What should I worry about first?"
  • "What are people saying in the comments this month? Which creators get the most questions about the app?"
  • "Is anyone in the comments asking whether our posts are ads? Show me the top ones."
  • "Who is behind on their weekly posting goal right now? Read each creator's notes first."
  • "How much do we owe creators in unpaid accruals, by creator?"
  • "Export September payouts to a CSV."
  • "Give me all videos from the Spring Launch campaign as a spreadsheet."
  • "Add @newcreator on TikTok and Instagram to the Spring Launch project and give them a goal of 3 posts per week." (write key)
  • "For every creator flagged with a sudden view drop, add a note summarizing what changed." (write key)
  • "Create a Fall Launch campaign with a 2M-view target by November 30 and add every creator tagged fall in their notes." (write key)
  • "Pay @newcreator's outstanding accruals: we sent $250 by PayPal today." (write key)

Tips for agents#

  1. Start with list_projects

    Most tools take a project_id. Read each project's readme for context.

  2. Triage with get_program_health

    For "how is the program doing?" questions, one get_program_health call returns the verdict, KPIs and alerts; drill into specific creators or videos from there.

  3. Follow the personalization document

    The connected person's document arrives with the server instructions (or call get_my_profile). It says who they are and how they want help. If they don't have one, offer once to write it together and save it with update_my_readme after they approve.

  4. Read the documents

    The organization, projects, campaigns and creators carry human notes in readme; list_notes finds them. They may contain instructions that change how to interpret the data.

  5. Paginate to completion

    Keep passing next_cursor (or next_offset for list_top_videos) until it's null before totalling or ranking.

  6. Check last_scraped_at

    Stats come from scheduled scrapes. Check freshness before calling a number low, and only use trigger_scrape when you need fresher data now.

  7. Append notes, don't overwrite them

    Record durable findings with update_notes in the default append mode. Only use replace with the readme_version you just read. Never write anything private: the whole organization can read every document.

  8. Confirm before anything that can't be undone

    Ask the person before a delete_*, remove_*, void_*, archive_* or unassign_* tool or set_accrual_status, and offer the reversible option the tool's description names (pausing a goal, disabling tracking, deactivating an event).

Using the REST API directly#

Frameworks without MCP support can call the v2 REST API with the same key. Sign-in (OAuth) connections work only with the MCP server, not the REST API. The OpenAPI document at GET /api/v2/openapi.json describes every endpoint, and the Agent guide covers recommended workflows.


Payout agent workflows#

The whole payout API is available over MCP as well as REST: structures (list_payout_structures, get_payout_structure, create_payout_structure, update_payout_rule, set_cpm_view_lifetime, update_payout_structure, archive_payout_structure, delete_payout_structure), assignments (list_payout_assignments, assign_payout_structure, unassign_payout_structure), accruals (list_payout_accruals, get_payout_accrual, set_accrual_status), methods (list_payout_methods, create_payout_method, update_payout_method, delete_payout_method) payments (list_payout_payments, get_payout_payment, record_payout_payment, update_payout_payment, void_payout_payment), the tracker (get_payouts_tracker), supplemental amounts (list_payout_supplementals, create_payout_supplemental, void_payout_supplemental), sending payouts through Dots (get_payout_account, send_payout; see Paying with Dots), and receipts and method icons (upload_receipt, get_receipt_upload_url, upload_payout_method_icon, get_payout_method_icon_upload_url). The workflows below show the REST calls; each step names the MCP tool that does the same. Reads need the read scope; writes (recording payments, voiding, assigning structures) need the write scope: a read-only key gets 403 insufficient_scope on any mutation. See the Payouts API reference for full endpoint documentation.

Workflow 1: Weekly payout review#

Goal: find all creators with outstanding accruals, summarize total owed, and surface any that have been outstanding more than 30 days.

Over MCP: list_projects, then list_payout_accruals with status: "earned".

  1. Discover the project

    bash
    curl -s -H "Authorization: Bearer $TGA_KEY" \
      "https://www.trackagoat.com/api/v2/projects" | jq '.data[0].id'

    Store the project ID as $PROJECT_ID.

  2. List outstanding accruals

    bash
    curl -s -H "Authorization: Bearer $TGA_KEY" \
      "https://www.trackagoat.com/api/v2/payout-accruals?project_id=$PROJECT_ID&status=earned" \
      | jq '{total: (.data | length), creators: [.data[] | .creator_id] | unique | length}'

    Paginate using meta.nextCursor until meta.hasMore is false.

  3. Flag stale accruals

    Filter data[].period_end_at older than 30 days ago. Report creator handle + amount + how many days outstanding.

    Expected response shape:

    JSON
    {
      "data": [{
        "id": "uuid",
        "creator_id": "uuid",
        "structure_id": "uuid",
        "amount_cents": 5000,
        "currency": "USD",
        "status": "earned",
        "period_start_at": "2026-04-07T00:00:00Z",
        "period_end_at": "2026-04-13T23:59:59Z"
      }],
      "meta": { "hasMore": false, "nextCursor": null }
    }

Workflow 2: Audit unpaid creators across an org#

Goal: identify which creators have earned money but received zero payments, broken down by project.

Over MCP: list_projects, list_payout_structures, list_payout_accruals and list_payout_payments.

  1. List all projects

    bash
    curl -s -H "Authorization: Bearer $TGA_KEY" \
      "https://www.trackagoat.com/api/v2/projects" | jq '[.data[] | {id, name}]'
  2. For each project, fetch payout structures

    bash
    curl -s -H "Authorization: Bearer $TGA_KEY" \
      "https://www.trackagoat.com/api/v2/payout-structures?project_id=$PROJECT_ID&is_active=true"
  3. Fetch earned accruals per project

    bash
    curl -s -H "Authorization: Bearer $TGA_KEY" \
      "https://www.trackagoat.com/api/v2/payout-accruals?project_id=$PROJECT_ID&status=earned"
  4. Fetch all payments

    bash
    curl -s -H "Authorization: Bearer $TGA_KEY" \
      "https://www.trackagoat.com/api/v2/payout-payments?project_id=$PROJECT_ID"
  5. Compute the gap

    Group accruals by creator_id. For each creator, sum amount_cents of earned accruals. Compare against total_amount_cents of paid payments. Report the delta.


Workflow 3: Record a payment for a creator via Venmo#

Goal: settle outstanding accruals for a specific creator and record the payment against the Venmo method.

Over MCP: list_creators with search, list_payout_accruals, list_payout_methods, optionally upload_receipt, then record_payout_payment with a fresh idempotency_key (the tool requires one).

  1. Find the creator

    bash
    curl -s -H "Authorization: Bearer $TGA_KEY" \
      "https://www.trackagoat.com/api/v2/creators?project_id=$PROJECT_ID&search=creatorhandle" \
      | jq '.data[0].id'
  2. List outstanding accruals for this creator

    bash
    curl -s -H "Authorization: Bearer $TGA_KEY" \
      "https://www.trackagoat.com/api/v2/payout-accruals?project_id=$PROJECT_ID&status=earned" \
      | jq '[.data[] | select(.creator_id == $CREATOR_ID)]'

    Sum the amount_cents values to get total_amount_cents.

  3. Find the Venmo method ID

    bash
    curl -s -H "Authorization: Bearer $TGA_KEY" \
      "https://www.trackagoat.com/api/v2/payout-methods" \
      | jq '.data[] | select(.name == "Venmo") | .id'
  4. Record the payment

    bash
    curl -s -X POST -H "Authorization: Bearer $TGA_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: $(uuidgen)" \
      "https://www.trackagoat.com/api/v2/payout-payments" \
      -d '{
        "creator_id": "CREATOR_UUID",
        "method_id": "VENMO_METHOD_UUID",
        "total_amount_cents": 5000,
        "currency": "USD",
        "accrual_ids": ["ACCRUAL_UUID_1", "ACCRUAL_UUID_2"],
        "note": "Recorded by automated weekly review agent",
        "paid_at": "2026-05-07T15:00:00Z"
      }'

    Expected 201 response:

    JSON
    {
      "data": {
        "id": "payment-uuid",
        "creator_id": "...",
        "total_amount_cents": 5000,
        "status": "paid",
        "paid_at": "2026-05-07T15:00:00Z"
      }
    }

Workflow 4: Set up a new creator with a goal-based payout structure#

Goal: assign an existing payout structure to a newly-tracked creator and confirm the assignment is active.

Over MCP: list_payout_structures, assign_payout_structure, then list_payout_assignments.

  1. Confirm the structure exists and is active

    bash
    curl -s -H "Authorization: Bearer $TGA_KEY" \
      "https://www.trackagoat.com/api/v2/payout-structures?project_id=$PROJECT_ID&is_active=true" \
      | jq '[.data[] | select(.criteria_type == "goals") | {id, name, period, amount_cents}]'

    Pick the structure ID you want to assign.

  2. Assign the creator

    bash
    curl -s -X POST -H "Authorization: Bearer $TGA_KEY" \
      -H "Content-Type: application/json" \
      "https://www.trackagoat.com/api/v2/payout-structures/$STRUCTURE_ID/assignments" \
      -d '{"creator_ids": ["CREATOR_UUID"]}'

    Expected 201 response:

    JSON
    {
      "data": {
        "assigned": 1,
        "already_assigned": 0,
        "not_in_project": 0,
        "results": [{ "creator_id": "...", "status": "assigned", "assignment_id": "..." }]
      }
    }
  3. Verify the assignment is active

    bash
    curl -s -H "Authorization: Bearer $TGA_KEY" \
      "https://www.trackagoat.com/api/v2/payout-structures/$STRUCTURE_ID/assignments" \
      | jq '[.data[] | select(.unassigned_at == null) | .creator_id]'