trackagoat logotrackagoat/Docs

Getting started

  • Welcome
  • Quickstart
  • Core concepts

Guides

  • Creators
  • Videos
  • Campaigns
  • Creator Goals
  • Tracking Inbox
  • Content calendar
  • How scraping works
  • Analytics & metrics
  • Similar creator pools
  • Over-posting & suppression
  • Program Health
  • Sentiment Radar
  • API keys
  • Limits & plan tiers
  • Notifications
  • Payouts

API reference

  • Overview
  • Authentication
  • Errors
  • Projects
  • Creators
  • Videos
  • Campaigns
  • Analytics
  • Aggregate Analytics
  • Payouts
  • Schema

For agents

  • Agent guide
  • Data model
  • MCP & tooling

Platform

  • Brand
  • Changelog
  • Support
DocsAPI reference

Payouts

Manage payout methods, structures, assignments, accruals, and payments via the trackagoat v1 API.

PreviousAggregate AnalyticsNextSchema

On this page

  • Payout Methods
  • GET /api/v1/payout-methods
  • POST /api/v1/payout-methods
  • GET /api/v1/payout-methods/{id}
  • PATCH /api/v1/payout-methods/{id}
  • DELETE /api/v1/payout-methods/{id}
  • Payout Structures
  • GET /api/v1/payout-structures
  • POST /api/v1/payout-structures
  • GET /api/v1/payout-structures/{id}
  • PATCH /api/v1/payout-structures/{id}
  • DELETE /api/v1/payout-structures/{id}
  • Assignments
  • GET /api/v1/payout-structures/{id}/assignments
  • POST /api/v1/payout-structures/{id}/assignments
  • DELETE /api/v1/payout-structures/{id}/assignments
  • Payout Accruals
  • GET /api/v1/payout-accruals
  • GET /api/v1/payout-accruals/{id}
  • PATCH /api/v1/payout-accruals/{id}
  • Payout Payments
  • GET /api/v1/payout-payments
  • POST /api/v1/payout-payments
  • GET /api/v1/payout-payments/{id}
  • PATCH /api/v1/payout-payments/{id}
  • Error codes

All payout endpoints require a Bearer API key. Responses follow the standard { data, error, meta } envelope. Amounts are in cents (integer). Timestamps are ISO 8601 UTC.


Payout Methods

Payout methods are org-scoped. Default methods (Venmo, Cash App, PayPal) cannot be deleted — use PATCH { is_active: false } to disable.

GET /api/v1/payout-methods

List org's payout methods.

bash
curl -H "Authorization: Bearer tga_<key>" \
  "https://www.trackagoat.com/api/v1/payout-methods"
 
# Include disabled methods
curl -H "Authorization: Bearer tga_<key>" \
  "https://www.trackagoat.com/api/v1/payout-methods?include_disabled=1"

Query parameters

ParameterTypeDescription
include_disabled1 | trueInclude inactive methods (org admins only)

Response fields: id, org_id, name, icon_url, is_default, is_active, metadata, readme, created_at


POST /api/v1/payout-methods

Create a custom payout method.

bash
curl -X POST \
  -H "Authorization: Bearer tga_<key>" \
  -H "Content-Type: application/json" \
  -d '{"name": "Zelle"}' \
  https://www.trackagoat.com/api/v1/payout-methods

Body

FieldTypeRequiredDescription
namestring✓Display name (max 100 chars)
icon_pathstring | nullStorage path from a prior UI icon upload
metadataobjectAgent-writable structured data
readmestring | nullMarkdown notes

Returns 201 with the created method row.


GET /api/v1/payout-methods/

Fetch a single method.


PATCH /api/v1/payout-methods/

Update name, active state, metadata, or readme.

bash
curl -X PATCH \
  -H "Authorization: Bearer tga_<key>" \
  -H "Content-Type: application/json" \
  -d '{"is_active": false}' \
  https://www.trackagoat.com/api/v1/payout-methods/<uuid>

Body: name?, is_active?, icon_path?, metadata?, readme? (at least one required)


DELETE /api/v1/payout-methods/

Delete a custom method. Returns 409 default_method for seeded default methods.


Payout Structures

Payout structures define earning rules for creators. Scoped to a project. Rule edits create new immutable versions.

GET /api/v1/payout-structures

List structures in the org (optionally filtered to a project).

bash
curl -H "Authorization: Bearer tga_<key>" \
  "https://www.trackagoat.com/api/v1/payout-structures?project_id=<uuid>"

Query parameters

ParameterTypeDescription
project_iduuidFilter to a project
is_activetrue | falseFilter by active state
limitnumberItems per page (max 100, default 50)
cursorstringPagination cursor

POST /api/v1/payout-structures

Create a payout structure (creates version 1 atomically).

bash
# Recurring $50/month
curl -X POST \
  -H "Authorization: Bearer tga_<key>" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "<uuid>",
    "name": "Monthly base",
    "period": "monthly",
    "amount_cents": 5000,
    "currency": "USD",
    "criteria_type": "recurring",
    "criteria_params": {},
    "proration_mode": "skip"
  }' \
  https://www.trackagoat.com/api/v1/payout-structures
 
# Goals-based monthly with partial completion
curl -X POST \
  -H "Authorization: Bearer tga_<key>" \






























































Body

FieldTypeRequiredDescription
project_iduuid✓Target project
namestring✓Structure name
perioddaily | weekly | monthly | null✓Payout frequency. Pass null for view_threshold structures.

criteria_params shapes

typescript
// recurring — no params
criteria_params: {}
 
// goals — pay if creator met their goals
criteria_params: {
  mode: "all" | "any" | "n_of_m",
  n?: number,               // required when mode = "n_of_m"
 
  // Partial completion (only valid when mode = "all")
  partial_allowed?: boolean,      // default false — enable fractional payouts on missed goals
  partial_multiplier?: number,    // default 1.0 — scales the partial amount (can exceed 1.0)
  min_completion_pct?: number,    // default 0 — 0–100; below this avg completion%, no payout fires
}
 




















Partial completion formula (goals, mode = "all"):

When partial_allowed is true and the creator does not fully meet all goals:

  1. Each goal's completion fraction = min(actual / target, 1.0).
  2. Average those fractions → completion_pct.
  3. If completion_pct < min_completion_pct / 100 → no accrual.
  4. Otherwise: payout = amount × completion_pct × partial_multiplier.

When all goals are fully met, the full amount is paid regardless of partial_allowed.

Returns 201 with { structure_id, version_id }.


GET /api/v1/payout-structures/

Fetch structure detail including current_version, full versions[] history, and assignment_count.


PATCH /api/v1/payout-structures/

Update a structure. Use kind to distinguish cosmetic edits from rule changes.

bash
# Cosmetic — update name and metadata without creating a new version
curl -X PATCH \
  -H "Authorization: Bearer tga_<key>" \
  -H "Content-Type: application/json" \
  -d '{"kind": "cosmetic", "name": "Monthly base v2", "metadata": {"owner": "growth-team"}}' \
  https://www.trackagoat.com/api/v1/payout-structures/<uuid>
 
# Rule edit — creates a new immutable version; existing accruals keep their version
curl -X PATCH \
  -H "Authorization: Bearer tga_<key>" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "rule",
    "period": "monthly",






Rule PATCH returns { version_id, version_number }. Cosmetic PATCH returns the updated structure row.


DELETE /api/v1/payout-structures/

Archive (default) or hard-delete a structure.

bash
# Archive — stops new accruals, preserves historical ones
curl -X DELETE -H "Authorization: Bearer tga_<key>" \
  "https://www.trackagoat.com/api/v1/payout-structures/<uuid>"
 
# Hard delete — blocked with 409 has_accruals if accruals exist
curl -X DELETE -H "Authorization: Bearer tga_<key>" \
  "https://www.trackagoat.com/api/v1/payout-structures/<uuid>?mode=hard"

Assignments

Assign or unassign creators to a payout structure.

GET /api/v1/payout-structures//assignments

List currently assigned creators.

bash
curl -H "Authorization: Bearer tga_<key>" \
  "https://www.trackagoat.com/api/v1/payout-structures/<uuid>/assignments"
ParameterTypeDescription
include_inactive1 | trueInclude historically unassigned creators
limitnumberDefault 50, max 100
cursorstringPagination cursor

POST /api/v1/payout-structures//assignments

Bulk-assign creators. Returns counts of newly assigned, already-assigned, and not-in-project IDs.

bash
curl -X POST \
  -H "Authorization: Bearer tga_<key>" \
  -H "Content-Type: application/json" \
  -d '{"creator_ids": ["<uuid1>", "<uuid2>"]}' \
  https://www.trackagoat.com/api/v1/payout-structures/<uuid>/assignments

Returns { assigned, already_assigned, not_in_project, results }.


DELETE /api/v1/payout-structures//assignments

Bulk-unassign creators. Existing earned accruals remain payable.

bash
curl -X DELETE \
  -H "Authorization: Bearer tga_<key>" \
  -H "Content-Type: application/json" \
  -d '{"creator_ids": ["<uuid1>"]}' \
  https://www.trackagoat.com/api/v1/payout-structures/<uuid>/assignments

Payout Accruals

Accruals are computed by the nightly cron — they cannot be created via the API.

GET /api/v1/payout-accruals

List accruals with optional filters.

bash
curl -H "Authorization: Bearer tga_<key>" \
  "https://www.trackagoat.com/api/v1/payout-accruals?project_id=<uuid>&status=earned"

Query parameters

ParameterTypeDescription
project_iduuidFilter to a project
creator_iduuidFilter to a creator
structure_iduuidFilter to a structure
statusearned | paid | rejected | voidedFilter by status
fromYYYY-MM-DD

GET /api/v1/payout-accruals/

Fetch a single accrual including inputs_snapshot.


PATCH /api/v1/payout-accruals/

Manually reject or void an earned accrual.

bash
curl -X PATCH \
  -H "Authorization: Bearer tga_<key>" \
  -H "Content-Type: application/json" \
  -d '{"status": "rejected"}' \
  https://www.trackagoat.com/api/v1/payout-accruals/<uuid>

Body: { status: "rejected" | "voided" }

Returns 409 cannot_set_status_on_paid_accrual if the accrual is already paid — void the parent payment first.


Payout Payments

GET /api/v1/payout-payments

List payments with optional filters.

bash
curl -H "Authorization: Bearer tga_<key>" \
  "https://www.trackagoat.com/api/v1/payout-payments?project_id=<uuid>&status=paid"

Query parameters

ParameterTypeDescription
project_iduuidFilter to a project
creator_iduuidFilter to a creator
statuspaid | rejected | voidedFilter by status
fromYYYY-MM-DDPaid at or after this date
toYYYY-MM-DDPaid at or before this date

Response rows include payout_payment_lines[] (linked accruals) and payout_adjustments[] (over/underpayment lines).


Idempotency key required

Always send an Idempotency-Key header (a UUID) when recording payments. If the request times out, retry with the same key — the server returns the original payment without double-counting.

POST /api/v1/payout-payments

Record a payment. Set Idempotency-Key header for safe retries.

bash
# Settle all outstanding accruals for a creator
curl -X POST \
  -H "Authorization: Bearer tga_<key>" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "project_id": "<uuid>",
    "creator_id": "<uuid>",
    "method_id": "<uuid>",
    "total_amount_cents": 15000,
    "currency": "USD",
    "auto_apply_outstanding": true,
    "note": "April batch payment"
  }' \
  https://www.trackagoat.com/api/v1/payout-payments
 
# Ad-hoc payment with no linked accruals
curl -X POST









Body

FieldTypeRequiredDescription
project_iduuid✓Target project
creator_iduuid | nullCreator receiving payment (null for true ad-hoc)
method_iduuid | nullPayout method used
total_amount_centsnumber✓Total paid in cents (≥ 0)
currency

Returns 201 with the payment row.


GET /api/v1/payout-payments/

Fetch a payment including lines and adjustments.


PATCH /api/v1/payout-payments/

Void a payment or update metadata/readme.

bash
# Void — reverts linked accruals to "earned"
curl -X PATCH \
  -H "Authorization: Bearer tga_<key>" \
  -H "Content-Type: application/json" \
  -d '{"status": "voided"}' \
  https://www.trackagoat.com/api/v1/payout-payments/<uuid>

Body: { status?: "voided", metadata?: object, readme?: string | null } (at least one field required)


Error codes

CodeHTTPDescription
invalid_api_key401Missing, expired, or invalid Bearer token
rate_limit_exceeded429Daily API quota or per-minute rate limit hit
limit_reached402Org plan limit for methods or structures
invalid_body400Zod validation failed — see meta.errors
invalid_query400Bad query parameter
-H "Content-Type: application/json" \
-d '{
"project_id": "<uuid>",
"name": "Monthly goals bonus",
"period": "monthly",
"amount_cents": 50000,
"currency": "USD",
"criteria_type": "goals",
"criteria_params": {
"mode": "all",
"partial_allowed": true,
"partial_multiplier": 1.0,
"min_completion_pct": 50
},
"proration_mode": "skip"
}' \
https://www.trackagoat.com/api/v1/payout-structures
# CPM-based weekly
curl -X POST \
-H "Authorization: Bearer tga_<key>" \
-H "Content-Type: application/json" \
-d '{
"project_id": "<uuid>",
"name": "Weekly CPM",
"period": "weekly",
"amount_cents": 0,
"currency": "USD",
"criteria_type": "cpm",
"criteria_params": {
"source": "posts_in_period",
"min_impressions": 10000,
"max_payout_cents": 50000,
"tiers": [
{"up_to_impressions": 1000000, "cents_per_thousand": 50},
{"up_to_impressions": null, "cents_per_thousand": 75}
]
},
"proration_mode": "prorate"
}' \
https://www.trackagoat.com/api/v1/payout-structures
# View threshold — $20 at 1M views, $100 at 5M views
curl -X POST \
-H "Authorization: Bearer tga_<key>" \
-H "Content-Type: application/json" \
-d '{
"project_id": "<uuid>",
"name": "Viral video milestones",
"period": null,
"amount_cents": null,
"currency": "USD",
"criteria_type": "view_threshold",
"criteria_params": {
"thresholds": [
{"view_count": 1000000, "amount_cents": 2000, "currency": "USD"},
{"view_count": 5000000, "amount_cents": 10000, "currency": "USD"}
]
},
"proration_mode": "skip",
"backfill_on_assignment": false
}' \
https://www.trackagoat.com/api/v1/payout-structures
amount_cents
number | null
✓
Amount in cents. Pass null for view_threshold structures (each threshold defines its own amount).
currencyUSD✓Currently only USD
criteria_typerecurring | goals | cpm | view_threshold✓Earning rule type
criteria_paramsobject✓Rule-specific params (see below)
proration_modeskip | prorate | full✓Mid-period assignment behavior. view_threshold structures always use skip.
backfill_on_assignmentbooleanview_threshold only. If true, immediately fires any milestones already crossed by the creator's existing videos on assignment.
metadataobjectAgent-writable data
readmestring | nullMarkdown notes
// cpm — pay per 1,000 views on posts in the period
criteria_params: {
source: "posts_in_period",
min_impressions: number, // minimum views before any payout
max_payout_cents: number | null, // cap (null = unlimited)
tiers: [ // sorted ascending; last tier must have null up_to_impressions
{ up_to_impressions: number | null, cents_per_thousand: number }
]
}
// view_threshold — one-time bonus when a video crosses a view count
// period, amount_cents, and proration_mode must be null/skip for this type
criteria_params: {
thresholds: [ // 1–10 milestones; view_count values must be unique
{
view_count: number, // minimum lifetime views on the video to trigger
amount_cents: number, // bonus amount in cents
currency: "USD"
}
]
}
"amount_cents": 7500,
"currency": "USD",
"criteria_type": "recurring",
"criteria_params": {},
"proration_mode": "skip"
}' \
https://www.trackagoat.com/api/v1/payout-structures/<uuid>
Period start on or after this date
toYYYY-MM-DDPeriod end on or before this date
limitnumberDefault 50, max 100
cursorstringPagination cursor (period_end_at ISO)
limitnumberDefault 50, max 100
cursorstringPagination cursor (paid_at ISO)
\
-H "Authorization: Bearer tga_<key>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"project_id": "<uuid>",
"creator_id": "<uuid>",
"total_amount_cents": 5000,
"note": "Bonus for viral video"
}' \
https://www.trackagoat.com/api/v1/payout-payments
string
ISO 4217, default USD
tracking_urlstring | nullExternal receipt link
notestring | nullFree-form note
paid_atISO 8601Defaults to now
accrual_idsuuid[]Explicit accruals to settle (takes precedence over auto_apply_outstanding)
auto_apply_outstandingbooleanIf true and creator_id set, settles all earned accruals for that creator
adjustment_reasonstring | nullRequired when total differs from accrual sum
metadataobjectAgent-writable data
readmestring | nullMarkdown notes
default_method
409
Cannot delete a seeded default method
conflict_name409Method name already exists in org
structure_archived409Cannot assign creators to an archived structure
has_accruals409Cannot hard-delete a structure with existing accruals
cannot_set_paid_directly400Use POST /payout-payments instead
cannot_set_status_on_paid_accrual409Void the parent payment first
currency_mismatch400Payment currency doesn't match accrual currency
accrual_not_settleable409Accrual is wrong project, status, or currency
adjustment_reason_required400Total differs from accrual sum — provide adjustment_reason
already_voided400Payment is already voided
accrual_in_other_payment409Accrual has been re-paid — void that payment first
not_found404Resource not found or not in org