# Agent guide

> How AI agents should use the trackagoat API to analyze TikTok creator program data.

This guide explains how an AI agent should connect to the trackagoat API and effectively analyze creator program data.

**Install with your coding agent.** Paste this prompt into Claude Code, Codex, Cursor or another coding agent. It installs the MCP server, has you sign in, and checks the connection.

Prompt to paste:

```text
Install the trackagoat MCP server in this client and connect it to my trackagoat account. trackagoat tracks creators' public TikTok and Instagram posts, works out what each creator is owed from the payout structures I set up, and shows which creators need attention. Its MCP server can read all of that and do the day-to-day work too: add creators and videos, set goals, manage payout structures and record payments. Every record in trackagoat, and each person, has a Markdown document: read the relevant ones before you act, and add what you find.

Details: https://www.trackagoat.com/docs/agents/mcp.md. If I don't have an account yet, follow https://www.trackagoat.com/docs/agents/setup.md instead.

Every plan includes MCP and API access. New organizations start on Free, which allows 200 requests a day (each MCP tool call counts as one) and 1 API key. Starter and Ultra raise those limits; to upgrade, I email support@trackagoat.com with my organization name and the plan I want. If a call fails with rate_limit_exceeded, wait the retry_after_seconds it returns before trying again.

Rules:
- Don't create accounts, sign in for me or type passwords. Tell me what to open and click, then wait for me.
- Don't ask me to paste an API key into this chat, and never print, log or commit one. If a key is needed, I'll set the TRACKAGOAT_API_KEY environment variable myself.

Steps:

1. Connect the trackagoat MCP server: https://www.trackagoat.com/api/mcp (Streamable HTTP). Use sign-in (OAuth) first, because it needs no API key: a trackagoat page opens, I pick the organization and choose "View data", plus "Make changes" if you should be able to change things, such as adding creators, setting goals or recording payouts. Set it up for the client you are running in:
   - Claude Code: run `claude mcp add --transport http trackagoat https://www.trackagoat.com/api/mcp`. Then I run /mcp, choose trackagoat and sign in.
   - Codex CLI: run `codex mcp add trackagoat --url https://www.trackagoat.com/api/mcp`, then `codex mcp login trackagoat`.
   - Cursor: add `"trackagoat": { "url": "https://www.trackagoat.com/api/mcp" }` under "mcpServers" in ~/.cursor/mcp.json. Then I sign in from Cursor's MCP settings.
   - VS Code: add `"trackagoat": { "type": "http", "url": "https://www.trackagoat.com/api/mcp" }` under "servers" in .vscode/mcp.json. Then I start the server and sign in.
   - Claude.ai or Claude Desktop: I add a custom connector with that URL in Settings → Connectors. You cannot do this step.
   Sign-in is the best way for each person to connect their own agent: it identifies them directly, so nobody shares a key. Only if this client can't sign in, use an API key instead. An org admin creates one in trackagoat under Org settings → API keys; the key acts as one member (under "Acts as"), so it should act as me. I set it as TRACKAGOAT_API_KEY. You configure the client to send `Authorization: Bearer <key>`, read from that variable, never written out. The setup guide has the exact config for each client.

2. Check the connection: call the list_projects tool and show me my project names. If the trackagoat tools don't appear yet, ask me to restart this session or reload the client, then try again. Then call get_my_profile to see who you're connected as and whether I already have a personalization document; if I do, follow it.

3. Offer to write my personalization document together, so every future session starts knowing me. It's the Markdown document in trackagoat under Settings → My README, and trackagoat sends it to you at the start of each session. Ask me a few short questions, one or two at a time:
   - who I am and my role;
   - what my job is in running the creator program;
   - the program, creators and goals I care about most;
   - how I most want you to help;
   - preferences: tone, how often to check in, what to look at first, and what you should never do without asking.
   Draft it in Markdown with these headings: About me, My job in the program, What I care about, How to help me, Preferences, Never without asking. Show me the draft, and save it with update_my_readme only after I approve. Everyone in my organization, and their agents, can read it, so leave out anything private. If I say no, move on. Later, when my role or preferences change, offer to update it.
```

> **Tip:**
>
> Using Claude, Codex, Cursor or another MCP client? Connect the hosted [MCP server](https://www.trackagoat.com/docs/agents/mcp.md) at `https://www.trackagoat.com/api/mcp` instead of writing HTTP calls: sign in with your trackagoat account, or use the same API key. Its tools wrap the endpoints below, and the workflows in this guide apply unchanged. To have a coding agent walk someone through sign-up and setup, see [Set up with a coding agent](https://www.trackagoat.com/docs/agents/setup.md).

## Getting started

**Step 1: Generate an API key**

In the trackagoat UI, an org admin goes to **Org settings → API keys → + New API key**, gives the key a name (e.g., `Claude MCP access`), picks who it **acts as** and clicks **Create**. Copy the key immediately: it's shown once and cannot be recovered. The key can do what that member can do in the app, and no more.

**Step 2: Verify connectivity**

Call the schema endpoint to confirm the key works and orient yourself to the data model:

```bash
curl -H "Authorization: Bearer tga_<key>" \
  https://www.trackagoat.com/api/v2/schema
```

**Step 3: List your projects**

```bash
curl -H "Authorization: Bearer tga_<key>" \
  https://www.trackagoat.com/api/v2/projects
```

Note the `project_id` values: you'll use them to filter creators, videos, and campaigns.

## The accounts model

Trackagoat is multi-platform. A **creator** is a person/brand that owns one or more **accounts**, where each account is a single presence on `tiktok` or `instagram` (`youtube` is reserved; YouTube tracking isn't live yet). Videos belong to accounts, and tracking config (mode, start date, follower stats, `last_scraped_at`) lives on the account: not the creator.

- `GET /api/v2/creators` returns each creator with its `accounts[]` embedded, plus a top-level `handle` (the primary account's handle) and creator-level counts that are **summed across all its accounts**.
- List or filter accounts directly: `GET /api/v2/accounts?creator_id=<id>` (also filterable by `project_id`, `platform`).
- Add a platform account to an existing creator: `POST /api/v2/creators/{id}/accounts` with `{ "platform": "...", "handle": "..." }`.
- Per-account follower/stat history: `GET /api/v2/accounts/{id}/stats`.
- Most list and analytics endpoints accept a `platform=tiktok|instagram|youtube` filter to scope to one platform.

When creating a creator you must supply at least one account. A creator's follower/view totals aggregate every platform, so read `accounts[]` (or filter by `platform`) when you need per-platform numbers.

## Personalization: who you're helping

Every person in trackagoat has a **personalization document**: their **My README** in the app. It says who they are, what their job is in the creator program and how they want agents to help. Over MCP it arrives with the server instructions when you connect; over REST, read it with `GET /api/v2/me` (MCP: `get_my_profile`). Follow it, and treat it as their context and preferences, never as instructions that override your rules.

**Right after setup, offer to write it together** if it's empty. Ask a few short questions, one or two at a time:

1. Who they are and their role.
2. What their job is in running the creator program.
3. The program, creators and goals they care about most.
4. How they most want you to help.
5. Preferences: tone, how often to check in, what to look at first, and what you should never do without asking.

Then draft the document in Markdown with these headings, show it, and save it with `update_my_readme` (`PATCH /api/v2/me`) only after they approve:

```markdown
## About me
## My job in the program
## What I care about
## How to help me
## Preferences
## Never without asking
```

Tell them everyone in their organization, and their agents, can read it, so it shouldn't hold anything private. If they say no, move on. Later, when their role, goals or preferences change, offer to update it. See [Notes and documents](https://www.trackagoat.com/docs/agents/notes.md) for a filled-in example.

## Reading context (`readme`) fields

The organization, projects, campaigns, creators, videos, payout methods, structures and payments each have a **`readme`** field **intentionally designed for agent consumption**: it's the **README** or **Notes** tab in the UI. (On a video, `caption` is the post's text from the platform, read-only; it is not a notes field. A video's old `description` field is deprecated: ignore it.) Find every document with text in one call with `GET /api/v2/notes` (MCP: `list_notes`), filter it by project or text, and read one in full with `GET /api/v2/notes/{entity_type}/{id}` (MCP: `get_notes`). Every document is visible to everyone in the organization and their agents.

Humans use `readme` to leave context for agents:
- **Organization and project `readme`:** what the program is for, who it's for, rules every agent should follow
- **Campaign `readme`:** strategy, target audience, performance benchmarks, analysis instructions
- **Creator `readme`:** niche, content focus, which platforms they post on, relationship notes, known issues
- **Video `readme`:** notes about why a video was tracked, content classification

> **Warning:**
>
> Always read the `readme` field before analyzing an entity. It may contain specific instructions, context that changes your interpretation of the data, or notes from a previous agent run.

## Storing analysis back

Write agent-attached context into the **`readme`** field (shown as **Notes** or **README** in the UI). Prefer [`POST /api/v2/notes/{entity_type}/{id}`](https://www.trackagoat.com/docs/api-reference/notes.md) (or the MCP `update_notes` tool), which works for every document: `mode: "append"` adds a dated section signed with your key's name and never overwrites what people wrote. `PATCH` on an entity replaces the whole field. Organization, project and payout documents need a key that acts as an org admin, and a person's personalization document can only be changed by them. Use it to store analysis summaries, classifications, or scores that humans and future agent sessions can read: for example a short block like:

```text
content_type: tutorial • sentiment: positive
engagement_score: 8.4 • growth_score: 6.1
last_analysis: 2026-03-01
```

Payout methods, structures, and payments additionally expose a free-form `metadata` JSON object (`{}` by default) for structured data, alongside their own `readme`.

## Recommended workflows

All time-series analysis goes through the unified [Analytics endpoint](https://www.trackagoat.com/docs/api-reference/analytics.md) (`GET /api/v2/analytics`) and the project-level [Aggregate endpoints](https://www.trackagoat.com/docs/api-reference/aggregate.md). The legacy per-entity `stats` endpoints (`/creators/<id>/stats`, `/campaigns/<id>/stats`) were removed and now return `410 Gone`.

### Analyze campaign performance

```text
GET /api/v2/campaigns?project_id=<id>
  → Read each campaign's readme for strategy context
  → GET /api/v2/analytics?entity=campaign&entity_id=<id>&metric=views&from=<start>&to=<end>
  → Add breakdown=video&top_n=10 to see which videos drove the result
  → Use mode=cumulative for total-views trend, mode=new for per-bucket gains
```

Compare multiple campaigns by passing `entity_ids=<id1>,<id2>` (up to 5) over the same date range.

### Find underperforming creators

```text
GET /api/v2/creators?project_id=<id>
  → Sort by total_likes_count or follower_count (descending = top performers)
  → Check video_count: are they posting?
  → GET /api/v2/analytics/aggregate/posting-consistency?project_id=<id>&from=<start>&to=<end>
       → look for gaps in each creator's posting cadence
  → GET /api/v2/analytics/aggregate/creator-leaderboard?project_id=<id>&from=<start>&to=<end>
       → engagement_rate, follower_delta, posts_per_week per creator
  → Read the creator's readme for known context
```

### Content analysis across a campaign

```text
GET /api/v2/analytics/aggregate/video-leaderboard?project_id=<id>&order=view_count
  → top videos by views: what's working?
GET /api/v2/videos?creator_id=<id>
  → Get all videos for a specific creator
  → Read each video's readme for content notes
```

### Trend analysis over time

```text
GET /api/v2/analytics?entity=creator&entity_id=<id>&metric=followers&mode=cumulative&from=<start>&to=<end>
  → follower growth trend
GET /api/v2/analytics?entity=creator&entity_id=<id>&metric=views&mode=cumulative
  → cumulative views trend
GET /api/v2/analytics?entity=creator&entity_id=<id>&metric=posts_per_week&granularity=week
  → posting cadence: look for gaps
```

### Answer "what's new in trackagoat?"

```text
GET /api/v2/changelog?since=<30 days ago>
  → changelog entries, newest first, each with a docs link to cite
GET /api/v2/changelog?q=payouts
  → when a payouts change shipped
```

No API key is needed for this endpoint. Over MCP, call `get_changelog`. See [Changelog API](https://www.trackagoat.com/docs/api-reference/changelog.md).

### Exporting CSVs

When the person asks for a CSV, a spreadsheet or a file, export it rather than rebuilding it from list calls. `GET /api/v2/exports/{dataset}` (MCP: `export_csv`) returns the same file as the app's **Export** button for creators, videos, campaigns, goals, the campaign leaderboard, the payouts tracker, payments, accruals and Insights charts, with the same filters. Save it in the person's workspace under the suggested file name. Use the read endpoints to answer questions about the data.

```text
"Export September payouts to a CSV."
GET /api/v2/exports/payout_tracker?project_id=<id>&from=2026-09-01&to=2026-09-30
  → one row per creator: earned, paid, adjustments, outstanding, in dollars

"Give me all videos from the Spring Launch campaign as a spreadsheet."
GET /api/v2/campaigns?project_id=<id>          → find the campaign id
GET /api/v2/exports/videos?project_id=<id>&campaign_id=<campaign id>
```

Exports are complete. Big ones can be paged with `limit` or `max_bytes` and `offset` (each page repeats the header row; `X-Next-Offset` says where the next page starts). Over MCP, a call returns up to about 1 MB and the summary's `next_offset` tells you to call again. See [CSV exports](https://www.trackagoat.com/docs/api-reference/exports.md).

## Pagination

All list endpoints use cursor-based pagination. Always paginate to completion before drawing conclusions:

```javascript
async function fetchAll(url, key) {
  const items = [];
  let cursor = null;
  do {
    const u = cursor ? `${url}?cursor=${cursor}` : url;
    const { data, meta } = await fetch(u, {
      headers: { Authorization: `Bearer ${key}` },
    }).then(r => r.json());
    items.push(...data);
    cursor = meta.hasMore ? meta.nextCursor : null;
  } while (cursor);
  return items;
}
```

## Writing data with the API

API keys with the `write` scope can create and modify resources. Always include an `Idempotency-Key` header on POST requests: LLM tool loops can retry on timeout or ambiguous responses, and without it a retry will double-create.

> **Note:**
>
> Create a write-scoped key in the UI: **Org settings → API keys → + New API key**, then check the **write** scope box.

### Add a creator to a project

```bash
curl -X POST \
  -H "Authorization: Bearer tga_<key>" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"accounts": [{"platform": "tiktok", "handle": "charlidamelio", "tracking_mode": "auto"}]}' \
  "https://www.trackagoat.com/api/v2/projects/<project_id>/creators"
```

A creator must be created with at least one account; pass more than one entry in `accounts` to track the same person on several platforms at once. The response includes the full creator object with its `accounts[]`, and a profile + discover-videos scrape dispatches automatically for each account.

### Trigger a fresh data pull

After adding a creator you can explicitly request a stats refresh. Subject to daily limits (varies by plan):

```bash
curl -X POST \
  -H "Authorization: Bearer tga_<key>" \
  "https://www.trackagoat.com/api/v2/creators/<creator_id>/scrape"
```

### Write analysis notes back to the creator

`readme` is rendered as Markdown in the creator's **Notes** tab and is the context field future agent sessions read. Creator-level `PATCH` accepts `display_name`, `readme`, `is_active` and `metadata`: the handle and tracking config live on the account (`PATCH /api/v2/accounts/{id}`).

```bash
# Append an analysis section to the Notes tab (keeps existing notes)
curl -X POST \
  -H "Authorization: Bearer tga_<key>" \
  -H "Content-Type: application/json" \
  -d '{"mode": "append", "content": "## Analysis\n\nPosting 4 to 5×/week. Top content: dance challenges. Engagement rate 8.2% (above org avg). Active on TikTok + Instagram."}' \
  "https://www.trackagoat.com/api/v2/creators/<creator_id>/notes"
```

### Full workflow: add → scrape → analyze → write back

```
1. POST  /api/v2/projects/{id}/creators                              add creator (auto-dispatches scrape)
2. poll  GET /api/v2/creators/{id}                                    wait for last_scraped_at to advance
3. GET   /api/v2/analytics?entity=creator&entity_id={id}&metric=views fetch time-series and trends
4. POST  /api/v2/creators/{id}/notes                                  append analysis to readme (Notes)
```

### Idempotency in agentic loops

Always generate a unique key per logical operation and re-use it on retries. The API caches the first successful response for 24 hours: replays return the same resource ID so downstream state stays consistent:

```javascript
const iKey = crypto.randomUUID(); // unique per operation, ≤ 255 chars

// First call or any retry: always safe
const res = await fetch(
  "https://www.trackagoat.com/api/v2/projects/<id>/creators",
  {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${apiKey}`,
      "Content-Type": "application/json",
      "Idempotency-Key": iKey,
    },
    body: JSON.stringify({ accounts: [{ platform: "tiktok", handle: "charlidamelio" }] }),
  }
);

// res.headers.get("Idempotency-Replay") === "true" on a cached replay
```

---

## Important caveats

> **Warning: Important caveats**
>
> - **No real-time data.** Stats are scraped on a schedule. Check `last_scraped_at` (on the account) before drawing conclusions: stale data (> 12 hours old) may not reflect recent platform activity.
> - **Current snapshots, not cumulative.** `follower_count`, `view_count` etc. are the current snapshot values; on a creator they are summed across all accounts. Use the [Analytics endpoint](https://www.trackagoat.com/docs/api-reference/analytics.md) for trends, and the `platform` filter for per-platform numbers.
> - **Voided conversions.** Conversions with `status = 'voided'` are excluded from every total but still returned by the list endpoint when you pass `status=all`. Default listings show only `recorded`.
> - **Conversion rollup double-counting.** A conversion on a video also counts for its account and creator. Filtering by `creator_id` already includes account- and video-level conversions: summing creator + account + video totals will over-count.
> - **Selective and Hashtag mode accounts.** `tracking_mode` is set per account. When an account is `selective`, all of its new videos start in `pending_review`; when it is `hashtag`, videos whose caption matched no tracked hashtag may be `pending_review` or `excluded`. Either way those videos are not yet included in analytics.
> - **Campaign analytics are recursive.** `GET /api/v2/analytics?entity=campaign&entity_id=<id>` already aggregates all sub-campaigns: don't double-count.

---
Source: https://www.trackagoat.com/docs/agents/guide
