Docs

Build on Transformer

Everything in the dashboard is an API call. Brands and creators, people and agents, all use the same REST API, MCP server and CLI with a workspace key.

Quickstart

  1. Create an account. Sign in with email, Google or GitHub.
  2. Create a workspace. Choose brand if you send offers, or creator if you receive them. Creators connect their X account from the workspace page.
  3. Create an API key. On the workspace page, under API keys, create a key. It's shown once and looks like tf_live_…. Store it as TRANSFORMER_API_KEY.
  4. Connect your agent. Pick one:
Claude Code (MCP)
claude mcp add --transport http transformer https://transformer.gg/mcp --header "Authorization: Bearer $TRANSFORMER_API_KEY"
CLI
curl -fsSL https://transformer.gg/install | sh
transformer login
REST
curl https://transformer.gg/api/v1/me \
  -H "Authorization: Bearer $TRANSFORMER_API_KEY"

Authentication

Every agent-facing request carries a workspace API key as a bearer token:

Header
Authorization: Bearer tf_live_…
  • One key = one workspace. A key acts for exactly one workspace and can only see and change that workspace's offers. Create separate keys per agent or environment and revoke any of them from the workspace page.
  • Brand vs creator. The workspace's kind decides what the key can do. Brand keys search creators, create, fund and cancel offers, and report conversions. Creator keys accept or decline offers and submit the URLs of posts they published on X. Both can list offers, read an offer and read its stats.
  • Keep keys server-side. Never ship a key to a browser or mobile app. Conversion reporting in particular belongs on your backend.

Errors are JSON with an error message and a matching HTTP status: 400 invalid input, 401 missing or revoked key, 403 wrong side (e.g. a creator key creating an offer), 404 not found or not yours, 409 the offer isn't in a state that allows this, 422 a post failed verification.

401
{
  "error": "Invalid or revoked API key."
}

Concepts

Workspaces

A workspace is a brand or a creator. People join workspaces as members; agents act for a workspace through its API keys. A creator workspace has one connected X account.

Offers and their lifecycle

An offer is what a brand sends a creator: a title and note (brief), a link to promote (url), a deliverable, a quantity, a payout and an optional commission on sales. Brands address creators by X handle (or by email, or creator workspace id); the creator who accepts must own that handle. Unanswered offers expire after expiresInDays (7 by default).

sent → accepted → submitted → verified → paid
sent → declined · sent / accepted → cancelled · sent → expired
  • sent: the brand created the offer; the creator gets an invite.
  • accepted: the creator accepted; a tracked link now exists. The brand then pays within 72 hours (until it does, stage is awaiting_payment, funding.due says how much and by when, and submitting a post returns 409 payment_pending); unpaid, the offer is cancelled.
  • submitted: some, but not yet all, of the deliverables have been verified.
  • verified: every deliverable is live on X, from the right account, with the tracked link.
  • paid: the held payout was released to the creator.
  • declined by the creator, cancelled by the brand, or expired unanswered.

Deliverables

post (a single X post), thread (an X thread) or video (an X post with video). quantity (1–20) is how many of them the offer covers. X is the first platform; more will follow.

Tracked links and tf_click

When a creator accepts, the offer gets a tracked link like https://transformer.gg/r/k3v9x2. Each click is counted and redirected to the offer's url with a tf_click query parameter appended, e.g. https://acme.com/launch?tf_click=b2e7d4a1-5c3f-4e8a-9d61-7a0c2f9e8b14. That id identifies the click, and through it the offer and creator.

The link creators post: postLink

Every offer has a postLink, the exact link the creator puts in their post, and mustInclude, the list verification checks for (that link and the disclosure). The post must carry X's Paid partnership label; #ad in the text counts only where X doesn't report the label. If the brand has a landing page per creator, set a landingUrlTemplate such as https://acme.com/x/{handle} (on the brand's pricing settings, a template, or the offer itself): each offer then gets its own landingUrl, e.g. https://acme.com/x/jane, and that is the postLink. Otherwise postLink is the tracked /r/… link (which redirects to the creator's landing page, if there is one, with ?tf_click= appended). Verification accepts the link as X shows it (expanded from t.co), ignoring scheme, www., case, a trailing slash and the query string.

Conversions and commission

A conversion is a sale the brand reports with the tf_click id, an amount and its own order id. If the offer has a commissionPercent, commission is calculated on the amount and credited to the creator. Order ids are unique per offer, so reporting the same order twice is a no-op and retries are safe. If a sale can't be tied to a click, report it with the creator's handle (their latest live offer from you) or the offerId.

Payments

Offers go out unpaid; the brand pays when the creator accepts (POST /offers/:id/pay or POST /pay-due, within 72 hours), and the payout is held. When the creator's deliverables are verified on X, the held payout is released to the creator; the offer moves to paid once it's paid out. Each offer reports its paymentStatus: unfunded, funded, released, paid_out or refunded.

Webhooks

Not yet available. Poll GET /api/v1/offers and GET /api/v1/offers/{id}/stats for now.

MCP

Transformer runs an MCP server at https://transformer.gg/mcp over streamable HTTP, authenticated with the same workspace key. Add it to any MCP client:

mcp.json
{
  "mcpServers": {
    "transformer": {
      "url": "https://transformer.gg/mcp",
      "headers": { "Authorization": "Bearer tf_live_…" }
    }
  }
}

Claude Code:

shell
claude mcp add --transport http transformer https://transformer.gg/mcp --header "Authorization: Bearer $TRANSFORMER_API_KEY"

Tools

ToolKeyWhat it does
whoamieitherThe workspace this key acts for (brand or creator).
search_creatorsbrandFind creators by topic or handle, with filters: followers, niche, engagement, price, verified, worked with you.
create_offerbrandSend a creator an offer: what to post about, link, payout, commission.
list_offerseitherOffers sent (brand) or received (creator), optionally by status.
get_offereitherOne offer, with its tracked link, submissions and payment state.
accept_offercreatorAccept an offer and get its tracked link.
decline_offercreatorDecline an offer.
cancel_offerbrandCancel an offer that hasn't been completed.
submit_postcreatorSubmit an existing X post URL for verification.
report_conversionbrandReport a sale with the tf_click id (or an offerId). The same orderId twice is ignored.
offer_statseitherClicks, conversions, revenue and commission for an offer.
pay_offersbrandPay for offers creators accepted (you pay only on accept, within 72 hours): balance first, then a checkout link.
list_dealscreatorAccepted offers with their next step (post, submit, verified, paid) and due date.
submit_deal_postcreatorSubmit the post URL for a deal so it can be verified.
list_accountscreatorYour connected X accounts, with pending verifications.
start_account_verificationcreatorStart verifying an account: returns a code to put in the bio.
verify_accountcreatorCheck the bio for the code and connect the account.

Tool inputs mirror the REST request bodies below: offer tools take an offerId, search_creators takes a query. Results are the same JSON the REST API returns; failures come back as tool errors with the same message.

CLI

Install the transformer binary, then sign in with a workspace API key:

$curl -fsSL https://transformer.gg/install | sh
commands
transformer login                 # paste a workspace API key
transformer me
transformer creators search fitness
transformer offers create --creator @jane --deliverable post --payout 250 --url https://acme.com/launch --brief "Share what you think of Acme"
transformer offers list --status sent
transformer offers accept <id>
transformer submit <id> https://x.com/jane/status/123
transformer conversions report --click <tf_click> --amount 49 --order A-1001
transformer stats <id>

transformer login stores the key locally. In CI or agent sandboxes, set TRANSFORMER_API_KEY instead. Every command calls the REST endpoint of the same name.

REST reference

Base URL https://transformer.gg/api/v1. Requests and responses are JSON. Amounts are in US dollars. In the examples, $OFFER_ID is an offer's id.

GET/api/v1/mebrand or creator key
The workspace this key acts for, its connected X account (creators) and totals. Use it to check whether you're on the brand or creator side.
Request
curl "https://transformer.gg/api/v1/me" \
  -H "Authorization: Bearer $TRANSFORMER_API_KEY"
Response
{
  "workspace": {
    "id": "8d0e5b7a-1f2c-4d3e-8a9b-0c1d2e3f4a5b",
    "kind": "brand",
    "name": "Acme"
  },
  "x": null,
  "stats": {
    "offers": 4,
    "active": 1,
    "completed": 2,
    "payoutsUsd": 500,
    "clicks": 640,
    "revenueUsd": 882,
    "commissionUsd": 88.2
  }
}
GET/api/v1/creators?q=fitnessbrand key
Search creators with a connected X account, by handle or name. Up to 50 results, largest audience first.
FieldTypeDescription
qstringPart of an X handle or name.
Request
curl "https://transformer.gg/api/v1/creators?q=fitness" \
  -H "Authorization: Bearer $TRANSFORMER_API_KEY"
Response
{
  "creators": [
    {
      "workspaceId": "c41a9e2d-7b6f-4a1e-9c3d-5e8f7a6b2c10",
      "name": "Jane Park",
      "x": "@jane",
      "xName": "Jane Park",
      "followers": 48210,
      "avatar": "https://pbs.twimg.com/…"
    }
  ]
}
POST/api/v1/offersbrand key
Send a creator an offer. Returns 201. Share inviteUrl with the creator if they're not on Transformer yet.
FieldTypeDescription
creatorstringThe creator's X handle ("@jane"), an email address, or a creator workspace id.
titlestringShort name for the offer.
briefstringYour note to the creator: what to say, what to avoid.
urlstringThe page to promote. The tracked link redirects here.
deliverable"post" | "thread" | "video"What the creator publishes on X.
quantityintegerHow many deliverables, 1–20. Default 1.
payoutUsdnumberFixed payout. The brand pays it when the creator accepts; it's held and released on verification.
commissionPercentnumberOptional commission on reported sales, 0–50. Default 0.
expiresInDaysintegerDays the creator has to accept, 1–90. Default 7.
Request
curl https://transformer.gg/api/v1/offers \
  -H "Authorization: Bearer $TRANSFORMER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"creator":"@jane","title":"Launch week","brief":"Share what you think of Acme","url":"https://acme.com/launch","deliverable":"post","quantity":1,"payoutUsd":250,"commissionPercent":10}'
Response
{
  "offer": {
    "id": "3f6c1a2e-8b1d-4c3e-9a57-2d0b6f1e4c90",
    "status": "sent",
    "paymentStatus": "unfunded",
    "title": "Launch week",
    "brief": "Share what you think of Acme",
    "url": "https://acme.com/launch",
    "deliverable": "post",
    "quantity": 1,
    "payoutUsd": 250,
    "commissionPercent": 10,
    "brand": {
      "workspaceId": "8d0e5b7a-1f2c-4d3e-8a9b-0c1d2e3f4a5b",
      "name": "Acme"
    },
    "creator": {
      "x": "@jane",
      "email": null
    },
    "inviteUrl": "https://transformer.gg/claim/9QxW2mLr7Tq",
    "trackedUrl": null,
    "landingUrl": "https://acme.com/x/jane",
    "postLink": "https://acme.com/x/jane",
    "mustInclude": [
      "https://acme.com/x/jane",
      "#ad"
    ],
    "submissions": [],
    "expiresAt": "2026-11-08T14:02:11Z",
    "acceptedAt": null,
    "verifiedAt": null,
    "createdAt": "2026-10-25T14:02:11Z"
  }
}
GET/api/v1/offers?status=sentbrand or creator key
Offers this workspace sent (brand), or that were sent to this creator or its X handle, newest first.
FieldTypeDescription
statusstringOptional filter: sent, accepted, submitted, verified, paid, declined, cancelled, expired, or all.
Request
curl "https://transformer.gg/api/v1/offers?status=sent" \
  -H "Authorization: Bearer $TRANSFORMER_API_KEY"
Response
{
  "offers": [
    {
      "id": "3f6c1a2e-8b1d-4c3e-9a57-2d0b6f1e4c90",
      "status": "sent",
      "paymentStatus": "unfunded",
      "title": "Launch week",
      "brief": "Share what you think of Acme",
      "url": "https://acme.com/launch",
      "deliverable": "post",
      "quantity": 1,
      "payoutUsd": 250,
      "commissionPercent": 10,
      "brand": {
        "workspaceId": "8d0e5b7a-1f2c-4d3e-8a9b-0c1d2e3f4a5b",
        "name": "Acme"
      },
      "creator": {
        "x": "@jane",
        "email": null
      },
      "inviteUrl": "https://transformer.gg/claim/9QxW2mLr7Tq",
      "trackedUrl": null,
      "landingUrl": "https://acme.com/x/jane",
      "postLink": "https://acme.com/x/jane",
      "mustInclude": [
        "https://acme.com/x/jane",
        "#ad"
      ],
      "submissions": [],
      "expiresAt": "2026-11-08T14:02:11Z",
      "acceptedAt": null,
      "verifiedAt": null,
      "createdAt": "2026-10-25T14:02:11Z"
    }
  ]
}
GET/api/v1/offers/{id}brand or creator key
One offer, including its tracked link once accepted, its submissions and its stats.
Request
curl "https://transformer.gg/api/v1/offers/$OFFER_ID" \
  -H "Authorization: Bearer $TRANSFORMER_API_KEY"
Response
{
  "offer": {
    "id": "3f6c1a2e-8b1d-4c3e-9a57-2d0b6f1e4c90",
    "status": "accepted",
    "paymentStatus": "unfunded",
    "title": "Launch week",
    "brief": "Share what you think of Acme",
    "url": "https://acme.com/launch",
    "deliverable": "post",
    "quantity": 1,
    "payoutUsd": 250,
    "commissionPercent": 10,
    "brand": {
      "workspaceId": "8d0e5b7a-1f2c-4d3e-8a9b-0c1d2e3f4a5b",
      "name": "Acme"
    },
    "creator": {
      "workspaceId": "c41a9e2d-7b6f-4a1e-9c3d-5e8f7a6b2c10",
      "name": "Jane Park",
      "x": "@jane"
    },
    "inviteUrl": "https://transformer.gg/claim/9QxW2mLr7Tq",
    "trackedUrl": "https://transformer.gg/r/k3v9x2",
    "landingUrl": "https://acme.com/x/jane",
    "postLink": "https://acme.com/x/jane",
    "mustInclude": [
      "https://acme.com/x/jane",
      "#ad"
    ],
    "submissions": [],
    "expiresAt": "2026-11-08T14:02:11Z",
    "acceptedAt": "2026-10-25T15:40:03Z",
    "verifiedAt": null,
    "createdAt": "2026-10-25T14:02:11Z",
    "stats": {
      "clicks": 312,
      "conversions": 9,
      "revenueUsd": 441,
      "commissionUsd": 44.1,
      "verifiedPosts": 0
    }
  }
}
POST/api/v1/offers/{id}/acceptcreator key
Accept an offer that's still sent. The response includes trackedUrl, the link to put in your post. Connect X first; your account must match the handle the offer was sent to.
Request
curl -X POST https://transformer.gg/api/v1/offers/$OFFER_ID/accept \
  -H "Authorization: Bearer $TRANSFORMER_API_KEY"
Response
{
  "offer": {
    "id": "3f6c1a2e-8b1d-4c3e-9a57-2d0b6f1e4c90",
    "status": "accepted",
    "paymentStatus": "unfunded",
    "title": "Launch week",
    "brief": "Share what you think of Acme",
    "url": "https://acme.com/launch",
    "deliverable": "post",
    "quantity": 1,
    "payoutUsd": 250,
    "commissionPercent": 10,
    "brand": {
      "workspaceId": "8d0e5b7a-1f2c-4d3e-8a9b-0c1d2e3f4a5b",
      "name": "Acme"
    },
    "creator": {
      "workspaceId": "c41a9e2d-7b6f-4a1e-9c3d-5e8f7a6b2c10",
      "name": "Jane Park",
      "x": "@jane"
    },
    "inviteUrl": "https://transformer.gg/claim/9QxW2mLr7Tq",
    "trackedUrl": "https://transformer.gg/r/k3v9x2",
    "landingUrl": "https://acme.com/x/jane",
    "postLink": "https://acme.com/x/jane",
    "mustInclude": [
      "https://acme.com/x/jane",
      "#ad"
    ],
    "submissions": [],
    "expiresAt": "2026-11-08T14:02:11Z",
    "acceptedAt": "2026-10-25T15:40:03Z",
    "verifiedAt": null,
    "createdAt": "2026-10-25T14:02:11Z"
  }
}
POST/api/v1/offers/{id}/declinecreator key
Decline an offer that's still sent.
Request
curl -X POST https://transformer.gg/api/v1/offers/$OFFER_ID/decline \
  -H "Authorization: Bearer $TRANSFORMER_API_KEY"
Response
{
  "offer": {
    "id": "3f6c1a2e-8b1d-4c3e-9a57-2d0b6f1e4c90",
    "status": "declined",
    "paymentStatus": "unfunded",
    "title": "Launch week",
    "brief": "Share what you think of Acme",
    "url": "https://acme.com/launch",
    "deliverable": "post",
    "quantity": 1,
    "payoutUsd": 250,
    "commissionPercent": 10,
    "brand": {
      "workspaceId": "8d0e5b7a-1f2c-4d3e-8a9b-0c1d2e3f4a5b",
      "name": "Acme"
    },
    "creator": {
      "x": "@jane",
      "email": null
    },
    "inviteUrl": "https://transformer.gg/claim/9QxW2mLr7Tq",
    "trackedUrl": null,
    "landingUrl": "https://acme.com/x/jane",
    "postLink": "https://acme.com/x/jane",
    "mustInclude": [
      "https://acme.com/x/jane",
      "#ad"
    ],
    "submissions": [],
    "expiresAt": "2026-11-08T14:02:11Z",
    "acceptedAt": null,
    "verifiedAt": null,
    "createdAt": "2026-10-25T14:02:11Z"
  }
}
POST/api/v1/offers/{id}/cancelbrand key
Cancel an offer that's sent or accepted.
Request
curl -X POST https://transformer.gg/api/v1/offers/$OFFER_ID/cancel \
  -H "Authorization: Bearer $TRANSFORMER_API_KEY"
Response
{
  "offer": {
    "id": "3f6c1a2e-8b1d-4c3e-9a57-2d0b6f1e4c90",
    "status": "cancelled",
    "paymentStatus": "unfunded",
    "title": "Launch week",
    "brief": "Share what you think of Acme",
    "url": "https://acme.com/launch",
    "deliverable": "post",
    "quantity": 1,
    "payoutUsd": 250,
    "commissionPercent": 10,
    "brand": {
      "workspaceId": "8d0e5b7a-1f2c-4d3e-8a9b-0c1d2e3f4a5b",
      "name": "Acme"
    },
    "creator": {
      "x": "@jane",
      "email": null
    },
    "inviteUrl": "https://transformer.gg/claim/9QxW2mLr7Tq",
    "trackedUrl": null,
    "landingUrl": "https://acme.com/x/jane",
    "postLink": "https://acme.com/x/jane",
    "mustInclude": [
      "https://acme.com/x/jane",
      "#ad"
    ],
    "submissions": [],
    "expiresAt": "2026-11-08T14:02:11Z",
    "acceptedAt": null,
    "verifiedAt": null,
    "createdAt": "2026-10-25T14:02:11Z"
  }
}
POST/api/v1/offers/{id}/submissionscreator key
Submit a post you published on X yourself (Transformer never posts for you). It's checked on X: it must be public, from the creator's own account, and contain everything in the offer's mustInclude (its postLink and the disclosure), carry X's Paid partnership label, plus a video for video offers. If it can't be verified you get a 422 whose error says why, and the submission is kept as rejected.
FieldTypeDescription
urlstringThe URL of a post on X from your connected account.
Request
curl https://transformer.gg/api/v1/offers/$OFFER_ID/submissions \
  -H "Authorization: Bearer $TRANSFORMER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://x.com/jane/status/123"}'
Response
{
  "offer": {
    "id": "3f6c1a2e-8b1d-4c3e-9a57-2d0b6f1e4c90",
    "status": "verified",
    "paymentStatus": "released",
    "title": "Launch week",
    "brief": "Share what you think of Acme",
    "url": "https://acme.com/launch",
    "deliverable": "post",
    "quantity": 1,
    "payoutUsd": 250,
    "commissionPercent": 10,
    "brand": {
      "workspaceId": "8d0e5b7a-1f2c-4d3e-8a9b-0c1d2e3f4a5b",
      "name": "Acme"
    },
    "creator": {
      "workspaceId": "c41a9e2d-7b6f-4a1e-9c3d-5e8f7a6b2c10",
      "name": "Jane Park",
      "x": "@jane"
    },
    "inviteUrl": "https://transformer.gg/claim/9QxW2mLr7Tq",
    "trackedUrl": "https://transformer.gg/r/k3v9x2",
    "landingUrl": "https://acme.com/x/jane",
    "postLink": "https://acme.com/x/jane",
    "mustInclude": [
      "https://acme.com/x/jane",
      "#ad"
    ],
    "submissions": [
      {
        "id": "e19b3c7d-2a4f-4b8e-9d1c-6f0a5e2b7c84",
        "url": "https://x.com/jane/status/123",
        "status": "verified",
        "note": "Verified on X.",
        "createdAt": "2026-10-25T16:05:40Z",
        "verifiedAt": "2026-10-25T16:05:41Z"
      }
    ],
    "expiresAt": "2026-11-08T14:02:11Z",
    "acceptedAt": "2026-10-25T15:40:03Z",
    "verifiedAt": "2026-10-25T16:05:41Z",
    "createdAt": "2026-10-25T14:02:11Z"
  }
}
POST/api/v1/visitsbrand key
Record a visit to a brand's own per-creator landing page, server-side. It counts as a click on the offer. Returns 201 with a clickId: keep it in the visitor's session and send it to POST /conversions when they sign up or buy. 404 if there's no live offer to that handle. Repeat visits from the same visitor are deduplicated (duplicate: true).
FieldTypeDescription
handlestringThe creator's X handle, e.g. from your /x/{handle} landing page (with or without @, any case). Uses your latest live offer to them.
offerIdstringInstead of handle, when you know the offer.
clickIdstringOptional. The tf_click query value if the visitor came through the tracked /r link: that click is reused, not counted twice.
urlstringOptional. The landing page URL.
ipstringOptional. The visitor's IP, hashed for deduplication and never stored.
userAgentstringOptional. Bots are not counted.
referrerstringOptional.
Request
curl https://transformer.gg/api/v1/visits \
  -H "Authorization: Bearer $TRANSFORMER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"handle":"jane","ip":"203.0.113.7","userAgent":"Mozilla/5.0 …","referrer":"https://t.co/abc"}'
Response
{
  "recorded": true,
  "duplicate": false,
  "clickId": "b2e7d4a1-5c3f-4e8a-9d61-7a0c2f9e8b14",
  "offerId": "3f6c1a2e-8b1d-4c3e-9a57-2d0b6f1e4c90"
}
POST/api/v1/conversionsbrand key
Report a sale or signup (send amountUsd: 0 for a signup) that came from a creator's link. Returns 201; duplicate is true if that order was already reported. Call it from your backend; see conversion tracking.
FieldTypeDescription
clickIdstringThe tf_click value from the landing URL, or the clickId from POST /visits (preferred).
handlestringThe creator's X handle. Used when there's no clickId, or as a fallback if the clickId is unknown. Uses your latest live offer to them.
offerIdstringInstead of clickId, when the sale can't be tied to a click.
amountUsdnumberOrder value the commission is calculated on.
orderIdstringYour order id. Reporting the same order twice is a no-op.
Request
curl https://transformer.gg/api/v1/conversions \
  -H "Authorization: Bearer $TRANSFORMER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"clickId":"b2e7d4a1-5c3f-4e8a-9d61-7a0c2f9e8b14","amountUsd":49.00,"orderId":"A-1001"}'
Response
{
  "recorded": true,
  "duplicate": false,
  "offerId": "3f6c1a2e-8b1d-4c3e-9a57-2d0b6f1e4c90",
  "amountUsd": 49,
  "commissionUsd": 4.9,
  "stats": {
    "clicks": 312,
    "conversions": 9,
    "revenueUsd": 441,
    "commissionUsd": 44.1,
    "verifiedPosts": 1
  }
}
GET/api/v1/offers/{id}/statsbrand or creator key
Clicks on the tracked link, reported conversions, revenue, commission and verified posts for an offer.
Request
curl "https://transformer.gg/api/v1/offers/$OFFER_ID/stats" \
  -H "Authorization: Bearer $TRANSFORMER_API_KEY"
Response
{
  "stats": {
    "clicks": 312,
    "conversions": 9,
    "revenueUsd": 441,
    "commissionUsd": 44.1,
    "verifiedPosts": 1
  }
}

Conversion tracking

With the tracked /r/… link, attribution takes three small pieces on the brand's side: the click id travels in the URL, and you report the sale from your server. With your own per-creator landing pages, see below.

1. Read tf_click on your site

Visitors from a tracked link land on your offer url with ?tf_click=… appended. Read it on any page they might land on and keep it (local storage, a first-party cookie or your session) until checkout.

browser
// On every landing page: keep the click id from the tracked link.
const tfClick = new URLSearchParams(location.search).get("tf_click");
if (tfClick) localStorage.setItem("tf_click", tfClick);

// At checkout: send it with the order to your own backend.
await fetch("/checkout", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ cart, tfClick: localStorage.getItem("tf_click") }),
});

2. Store it with the order

Save the tf_click value on the order record when it's created, the same way you'd keep a coupon code.

3. Report the conversion server-side

When the order is paid, call POST /api/v1/conversions with a brand key. Use your own order id so a retry never double-counts.

server
// On your server, once the order is paid (store tfClick with the order first).
async function reportConversion(order: { id: string; totalUsd: number; tfClick: string | null }) {
  if (!order.tfClick) return; // not from a tracked link
  const res = await fetch("https://transformer.gg/api/v1/conversions", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.TRANSFORMER_API_KEY}`, // brand workspace key
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ clickId: order.tfClick, amountUsd: order.totalUsd, orderId: order.id }),
  });
  if (!res.ok) throw new Error((await res.json()).error);
}
Agents can do the same with the report_conversion MCP tool or transformer conversions report --click <tf_click> --amount 49 --order A-1001.

Per-creator landing pages

If creators post a link to your own page (e.g. https://acme.com/x/jane, from landingUrlTemplate), visitors don't pass through the tracked redirect, so tell Transformer about the visit yourself. On the server that renders /x/:handle:

server
// GET /x/:handle — record the visit, keep the clickId for the signup.
const res = await fetch("https://transformer.gg/api/v1/visits", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.TRANSFORMER_API_KEY}`, // brand workspace key
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ handle: req.params.handle, clickId: req.query.tf_click, ip: req.ip, userAgent: req.get("user-agent"), referrer: req.get("referer") }),
});
if (res.ok) req.session.tfClick = (await res.json()).clickId;

Then report the signup or sale with that clickId. If you didn't keep it, send the creator's handle instead:

signup
curl https://transformer.gg/api/v1/conversions \
  -H "Authorization: Bearer $TRANSFORMER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"clickId":"b2e7d4a1-5c3f-4e8a-9d61-7a0c2f9e8b14","amountUsd":0,"orderId":"signup-8812"}'
# or, without a clickId:  -d '{"handle":"jane","amountUsd":0,"orderId":"signup-8812"}'

Pixel

No server code? Put a 1×1 pixel on the landing page instead. Each load counts as a visit to that creator's live offer (bots and link previews aren't counted). Use your brand workspace's slug and the creator's handle:

landing page (HTML)
<img src="https://transformer.gg/p/<brand-slug>/<handle>.gif" width="1" height="1" alt="" />

The pixel only counts visits. Report signups and sales with POST /conversions and the creator's handle.