Skip to content

Data model

Entity reference for AI agents: fields, relationships, and the readme documents agents read and write.

Updated Oct 9, 2026 · 11 min read

Hierarchy#

Trackagoat is multi-platform. A creator is a person or brand; each creator owns one or more accounts, where an account is a single presence on a platform (TikTok or Instagram; youtube is reserved for YouTube tracking, which isn't available yet). Videos hang off accounts. Tracking configuration (mode, start/end dates, follower stats, last_scraped_at) lives on the account, not the creator. A creator can have several accounts, even more than one on the same platform.

Organization                        : readme (the organization's document)
  ├── Member(s)                     : each with a personalization document (readme)
  └── Project(s)
        ├── Creator(s)              : a person/brand (1..n accounts)
        │     └── Account(s)        : one platform presence, tiktok | instagram | youtube
        │           └── Video(s)    : videos/posts from that account
        ├── Video(s)                : standalone videos added by URL (carry platform + account_id)
        ├── Content Group(s)        : link the same content across platforms
        └── Campaign(s)             : named groupings (can nest)
              ├── → Creator(s)
              ├── → Video(s)
              └── → Campaign(s) (recursive)

Data is scoped to the organization of the API key. A single API call fetches data across all projects unless you filter by project_id. Most list endpoints (/api/v2/creators, /api/v2/accounts, /api/v2/videos, the analytics aggregates) accept a platform filter.

The current API is /api/v2; the previous v1 API has been retired.

Entity reference#

Project#

FieldTypeNotes
iduuid
namestring
readmestring | nullAgent context: the project's document. Read it before working in the project
org_iduuid
created_atISO 8601
updated_atISO 8601

Creator#

A creator embeds its accounts[]. Creator-level counts are the aggregate across all its accounts; the top-level handle is the primary account's handle (the TikTok account if present, otherwise the earliest-added).

FieldTypeNotes
iduuid
project_iduuid
org_iduuid
handlestring | nullPrimary account's handle (without @)
display_namestring | null
avatar_urlstring | null
readmestring | nullAgent context: read before analyzing (the README on the Info tab; agents append with POST /api/v2/creators/{id}/notes)
follower_countnumber | nullSum across the creator's accounts
following_countnumber | nullSum across accounts
total_likes_countnumber | nullSum across accounts
video_countnumber | nullSum across accounts
accountsAccount[]Embedded platform accounts (see below)
is_activeboolean
created_atISO 8601
updated_atISO 8601

Creator-level writes (PATCH /api/v2/creators/{id}) accept only display_name, readme, is_active and metadata. The handle and tracking configuration live on the account: change them via PATCH /api/v2/accounts/{id}.

Account#

One platform presence owned by a creator. Tracking config and the raw follower/engagement snapshot live here.

FieldTypeNotes
iduuid
creator_iduuidOwning creator
project_iduuid
org_iduuid
platformtiktok | instagram | youtube
handlestringThe account's handle (without @)
platform_user_idstring | nullStable platform-side ID
display_namestring | null
avatar_urlstring | null
bio_linkstring | nullLink in the account's bio
follower_countnumberCurrent snapshot (followers / subscribers)
following_countnumber
total_likes_countnumber
video_countnumber
tracking_modeauto | selective | hashtagControls which discovered videos enter the system
tracking_hashtagsstring[]Hashtag-mode only: tags matched against the video caption. Stored normalized (NFC, lowercase, no #, invalid characters stripped, deduped); max 50
hashtag_inbox_non_matchingbooleanHashtag-mode only: inbox (true) vs exclude (false) for non-matching videos
tracking_start_dateISO date | nullLower bound for this account's stats history
tracking_end_dateISO date | nullLast tracked day, inclusive. The window spans each date in both UTC and the org's analytics timezone (the wider of the two)
is_activebooleanfalse when auto-disabled
last_scraped_atISO 8601 | nullWhen this account was last refreshed
created_atISO 8601
updated_atISO 8601

Fetch accounts via GET /api/v2/accounts (filter by creator_id, project_id, or platform), GET /api/v2/creators/{id}/accounts, or embedded in a creator. Per-account follower/stat history: GET /api/v2/accounts/{id}/stats.

Video#

FieldTypeNotes
iduuid
creator_iduuid | nullNull for direct-add videos with no matched creator
account_iduuid | nullThe account this video belongs to
platformtiktok | instagram | youtube
platform_video_idstringPlatform-side video/post ID
urlstringFull URL on the platform
media_typevideo | photophoto = a TikTok photo carousel or Instagram image post/carousel; otherwise video
titlestring | nullShort title. TikTok: the caption's first line (up to 100 characters). Instagram: null
captionstring | nullThe post's text as posted on the platform (YouTube: the video description). Filled by scraping, read-only
descriptionstring | nullDeprecated. An old free-text field that nothing fills and that can't be written any more. Any text it had was copied into readme. Ignore it; it will be removed
readmestring | nullAgent context / notes (agents append with POST /api/v2/videos/{id}/notes)
thumbnail_urlstring | null
view_countnumber | nullCurrent snapshot (plays on Reels/Shorts)
like_countnumber | null
comment_countnumber | null
share_countnumber | null
tracking_statusstringauto_tracked, pending_review, included, excluded, direct_add
posted_atISO 8601 | nullOriginal post date on the platform
last_scraped_atISO 8601 | null

Content Group#

Links the same logical content across platforms (e.g. the same clip posted as a TikTok, a Reel, and a Short) so its combined stats can be viewed together. A video belongs to at most one content group.

FieldTypeNotes
iduuid
project_iduuid
org_iduuid
titlestring
notesstring | nullFree-form notes
created_byuuid | null
video_idsuuid[]Member videos (across platforms)
created_atISO 8601
updated_atISO 8601

Manage via /api/v2/content-groups (list/create) and /api/v2/content-groups/{id} (get/patch/delete; add or remove members with add_video_ids / remove_video_ids). Combined stats: GET /api/v2/content-groups/{id}/stats returns summed totals plus a by_platform breakdown.

Campaign#

Campaigns are mixed-platform: the creators and videos they contain can be on any platform, and stats roll up across all of them with a per-platform breakdown.

FieldTypeNotes
iduuid
project_iduuid
namestring
readmestring | nullAgent context: strategy, benchmarks, instructions (campaigns use readme, not description)
target_viewsnumber | nullOptional total-view goal for the campaign
created_atISO 8601
updated_atISO 8601

Goal#

A per-creator performance target. Goals carry a platform scope so a target can apply to all of a creator's accounts, one platform, or one account.

FieldTypeNotes
iduuid
metricposts | views | engagement | followers
perioddaily | weekly | monthly
target_valuenumber
platform_scopeall | platform | accountall = whole creator (default)
platformtiktok | instagram | youtube | nullRequired when platform_scope is platform
account_iduuid | nullRequired when platform_scope is account
start_dateISO date | null
end_dateISO date | null
is_activeboolean

Compliance is measured only over the accounts the scope includes. Create via POST /api/v2/creators/{id}/goals.

Context field conventions#

Humans write free-text context for agents to read. The context field is readme, a Markdown document on the organization, every project, campaign, creator, video, payout method, payout structure and payout payment, and every member (their personalization document). It is the README or Notes in the app. Find them with GET /api/v2/notes (MCP list_notes), read one with GET /api/v2/notes/{entity_type}/{id} (get_notes), and add to one with POST /api/v2/notes/{entity_type}/{id} (update_notes), which appends by default and never overwrites what people wrote. Everyone in the organization, and their agents, can read every document. See Notes and documents. On a video, caption holds the post's text from the platform (read-only, not a notes field); the old description field is deprecated. Common patterns:

# Campaign readme
"Q1 creator push for Product X. Target: 1M views by March 31.
Top performers from last quarter: @creator1, @creator2.
Exclude any videos not directly about Product X."
 
# Creator readme
"Fitness creator, 3x/week posting cadence. Best content: workout tutorials.
Posts on TikTok and Instagram; YouTube is dormant.
Known issue: also posts food content unrelated to program: use selective mode.
Last contract renewal: Jan 2026."
 
# Video readme
"Strong outlier: 10x normal views. Trending audio #fitnesscheck helped.
Not representative of creator's normal performance."

When a context field contains explicit analysis instructions, follow them over your general analysis approach.


Conversion entities#

Conversion Event#

A project-scoped definition of an outcome worth tracking. Conversions reference it.

FieldTypeMeaning
keystringStable identifier, unique per project. Matches ^[a-z0-9][a-z0-9_.-]{0,62}$. Immutable after creation
namestringHuman label
default_value_centsintegerUsed when a conversion omits value_cents
currencystring(3)ISO code. Lives on the EVENT, not the conversion, so totals are always well defined. Immutable
is_activebooleanInactive events reject new conversions but keep existing ones in all totals

Plan limit max_conversion_events_per_project caps active event types (free 3, starter 25, ultra unlimited). Conversion volume is never capped.

Conversion#

FieldTypeMeaning
conversion_event_iduuidThe event this records
target_typecreator | account | videoWhat it was attributed to
creator_id / account_id / video_iduuid | nullRollup. A video-target conversion also populates account and creator
value_centsintegerFalls back to the event's default_value_cents
quantityintegerDefault 1
total_value_centsintegerGenerated: value_cents * quantity
external_idstring | nullYour id. Permanently unique per project: a repeat returns the ORIGINAL with deduped: true
statusrecorded | voidedVoided conversions are excluded from totals but retained
occurred_attimestampISO 8601 with offset required on write

Attribution is frozen at receipt. Moving a video to another account later does not rewrite its past conversions. An org admin can explicitly override this per video.

Reading totals: filtering by creator_id returns conversions recorded against that creator's accounts and videos too. Do not sum across levels or you will double count.

Payout entities#

Payout Method#

FieldTypeNotes
iduuid
org_iduuid
namestringe.g. "Venmo", "Cash App"
icon_urlstring | nullPublic icon URL
is_defaultbooleanAuto-seeded defaults cannot be deleted
is_activebooleanDisabled methods won't appear in payment dialogs
metadataobjectAgent-writable
readmestring | nullAgent-writable notes

Payout Structure#

FieldTypeNotes
iduuid
project_iduuid
namestring
is_activebooleanArchived structures stop generating accruals
current_versionobjectActive rule snapshot: period, amount_cents, currency, criteria_type, criteria_params, proration_mode, platform_scope, platform, account_id
versionsarrayFull version history (GET by ID only)
assignment_countnumberCurrently assigned creators
metadataobjectAgent-writable
readmestring | nullAgent-writable notes

criteria_type values: recurring (flat-rate every period), goals (pays when creator meets their period goals), cpm (pays per 1,000 views; each period pays for the views each video gained since it was last paid, for view_lifetime_days after posting or forever), view_threshold (one-time bonus when an individual video crosses a view-count milestone, period and top-level amount_cents are null; each threshold defines its own amount).

Platform scope: a version's platform_scope (all | platform | account, default all) limits which of an assigned creator's accounts contribute, CPM impressions, goal compliance, and view-threshold crossings are all measured only from accounts in scope. When scoped, platform or account_id is set accordingly.

Payout Accrual#

Computed by an hourly background job after relevant scrapers complete. Cannot be created via the API.

FieldTypeNotes
iduuid
creator_iduuid
structure_iduuid
structure_version_iduuidThe rule version active at period end (pinned)
period_start_atISO 8601 | nullInclusive, UTC. null for view_threshold accruals (no period)
period_end_atISO 8601 | nullExclusive, UTC. null for view_threshold accruals
video_iduuid | nullSet only for view_threshold accruals: the video that crossed the milestone
threshold_viewsnumber | nullSet only for view_threshold accruals: the milestone view count that fired
amount_centsnumberPost-proration, in cents
currencystringCurrently always USD
statusstringearned → paid (via payment) or rejected/voided (manual)
inputs_snapshotobject | nullData used to compute (goals_met, impressions, etc.)

Payout Payment#

FieldTypeNotes
iduuid
project_iduuid
creator_iduuid | nullNull for ad-hoc payments
method_iduuid | null
method_name_snapshotstring | nullCaptured at write time
total_amount_centsnumber
statusstringpaid or voided
paid_atISO 8601
payout_payment_linesarrayM2M to accruals with applied_amount_cents
payout_adjustmentsarrayOver/underpayment lines (positive = overpayment, negative = underpayment)
metadataobjectAgent-writable
readmestring | nullAgent-writable notes