tellatribe — Product Requirements Document
Version: 0.2 (two tiers; three collateral modes; commercial-shape pointer) Date: August 14, 2026 · revised October 3, 2026 Owner: Jonathan Whistman Status: Pre-build. Nothing in this document is implemented yet.
1. What this is
A single affiliate platform that sits beside your products rather than inside any one of them. Products call it; it never calls them. HealthyApp is the first tenant, GetBooked and WhoHire follow, and a product added in 2027 should require a day of work, not a rebuild.
It does four things:
- Tracks clicks and conversions from affiliate links, across any number of products.
- Calculates commissions on a two-level downline, with an auditable ledger.
- Pays affiliates on a schedule, with tax and identity handled by the payout rail.
- Equips affiliates — links, deep links, QR codes, and a collateral library that hands them promotion material already personalized with their own link.
The design constraint that shapes every decision below: simple to administer, powerful for the affiliate. Those pull in opposite directions, and the resolution is automation by default with an exceptions queue for humans. The admin's job is to handle the 3% the machine flagged, not to approve the 97% it already understood.
2. Research findings that shaped the design
Six findings from the market and regulatory scan changed decisions in this document.
2.1 Two levels is a conventional affiliate program; three would have been an MLM
This is the decision that set the depth. Two tiers is an ordinary two-tier affiliate program — the structure PartnerStack, FirstPromoter, and Tapfiliate all ship as a normal feature. A third level is what tips a compensation plan into multi-level marketing in the FTC's eyes, and brings the full MLM compliance posture with it: counsel review of the comp plan, income-claim exposure, state-level registration questions, and a permanent "is this a pyramid?" conversation with every prospective affiliate.
The platform caps at two levels. It does not implement a third. The depth limit is a configuration constant rather than a hardcoded assumption, so raising it later is possible — but it is a deliberate legal decision, not a settings change, and the schema comment says so.
Even at two tiers, the line between a legal program and a pyramid is not the number of levels — it's what the money rewards. Two rules apply regardless of depth:
- Never charge to join, and never charge to unlock recruiting. A fee paid for the right to recruit is the classic pyramid marker.
- Pay override commissions only on completed sales to genuine end customers — never on the act of recruiting, never on a signup that hasn't produced revenue.
Both are enforced structurally in this design: there is no product in the system that charges an affiliate anything, and commission events can only be created by a conversion carrying a real dollar amount. There is no code path that mints a commission from a recruitment event. (§5.3, §11)
Typical published rates for this shape: L1 10–30%, L2 override at 2–10%.
2.2 Server-side tracking is the primary path; cookies are a fallback
Cookie-only attribution loses meaningful volume to browser privacy defaults, ad blockers, and cookie clearing — server-to-server postback recovers a reported 15–35% of conversions over cookie-based tracking. The 2026 consensus architecture is hybrid: a click ID minted server-side at click time, carried in a first-party context, and redeemed by a server-to-server conversion call. That is exactly the design in §6.
The critical mechanical detail: the first-party cookie has to be set on the merchant's
own domain, not on tellatribe's. That means every integrated product ships a tiny
redirect route of its own (/r/[code]). HealthyApp already has the shape of this at
app/r/[token].
2.3 A 30-day hold is the single most effective payout protection
Every clawback guide converges on the same rule: hold commission approval for at least as long as your refund window. Pay before the refund window closes and you are chasing money back from people who have already spent it. The ledger in §7 makes the hold a first-class state rather than an operational habit.
2.4 Clawback risk concentrates in four scenarios
Refund inside the window; chargeback; duplicate/multi-account referral; and self-referral (affiliate buys through their own link). All four need automatic detection, and the third and fourth need it at conversion time, not at payout time. Fraud rule of thumb worth encoding: flag any affiliate whose referrals produce 2+ chargebacks in a rolling 30 days.
2.5 The payout rail should own KYC and tax, not us
Stripe Connect can generate and e-file 1099s from data it already holds, but charges separately for identity verification and tax tooling. Tremendous bundles 1099 e-filing, KYC, and tax-form collection at no separate line item. PayPal Payouts has the widest consumer wallet reach internationally. The recommendation in §8 is Stripe Connect Express as the primary rail, because you already run Stripe on both sides of HealthyApp and a second processor is a second reconciliation problem.
Tax threshold note: the 1099-NEC reporting threshold rose from $600 to $2,000 for payments made in 2026, filed in the 2027 season, and inflation-adjusts from 2027 forward. This is a reporting threshold only — affiliates owe tax on the first dollar regardless. Confirm the current figure with your accountant before the first payout run; the platform should treat the threshold as a config value, not a constant in code.
2.6 What the incumbents charge, and where they stop
Rewardful, FirstPromoter, and Tapfiliate all land at roughly $49–179/month for SMB SaaS. FirstPromoter is Stripe-native and the closest analog to the zero-code integration path in §6.4. Two-tier is table stakes for all of them, so depth is not the reason to build rather than buy. The reason is one affiliate identity earning across several products at once, with per-product rules and a shared downline — every incumbent scopes an account to a single product, which would mean three subscriptions, three affiliate logins, and three sets of collateral for the same person promoting HealthyApp, GetBooked, and WhoHire. The collateral vault (§9.3) is the second reason; what ships in these tools is a file list.
3. Users
| Role | Who | What they need |
|---|---|---|
| Affiliate | A coach, gym owner, consultant, or customer promoting one or more of your products | Links that work, honest numbers, material they can post today, and payment that arrives when promised |
| Downline affiliate | Someone an affiliate recruited (L2) | Identical experience — a downline affiliate is just an affiliate with a sponsor |
| Program admin | You, or an ops person | To not look at this most weeks. Exceptions only. |
| Product engineer | Whoever integrates the next app | An SDK and a webhook, integrated in under a day |
Explicitly not a user in v1: the end customer. They never see tellatribe. The redirect is invisible and the cookie is first-party on the product's own domain.
4. Scope
In scope for v1
- Multi-product, multi-program, one affiliate identity across all of them
- 2-level sponsorship tree with override commissions on the second level
- Click tracking, S2S conversion API, Stripe-webhook auto-conversion path
- Append-only commission ledger with hold, approval, reversal, and clawback
- Affiliate portal: dashboard, link builder, downline, collateral vault, payout settings
- Collateral delivered three ways: download, publish-on-their-behalf via connected social accounts, and an in-portal teleprompter video recorder (§9.3)
- Admin: exceptions queue, payout runs, program configuration
- Stripe Connect Express payouts with tax onboarding
Out of scope for v1 (named so they don't creep in)
- A third level, permanently. Not "later" — deliberately excluded to keep this a two-tier affiliate program rather than an MLM (§2.1)
- Rank advancement, volume qualifications, breakaways, or any compensation mechanic beyond flat per-level percentages plus an optional volume bonus tier
- Coupon-code attribution (link and click-ID only in v1)
- Affiliate-to-affiliate messaging
- Marketplace / public affiliate discovery
- Multi-currency (USD only in v1)
- Mobile app (the portal is responsive web)
5. Core model
5.1 Products and programs
product HealthyApp, GetBooked, WhoHire, …
└── program the commission plan for that product
└── plan_level L1 (direct) / L2 (override) rules
One product may have several programs over time (a launch program, an evergreen program). An affiliate is enrolled in a program. Decided Oct 3, 2026 (BUILD-PLAN §5, decision 2): the plan terms in force when a customer first converts are locked to that customer for the life of the subscription, so a rate change applies to new customers only and never rewrites anyone's history.
5.2 The affiliate and the tree
One affiliate record per person, globally. Enrollment in each program is a separate
row, so someone can promote HealthyApp and not GetBooked.
Sponsorship is set once at signup, from the recruiting affiliate's referral link, and is global rather than per-program — your sponsor is your sponsor everywhere. Reparenting is possible but is an admin action requiring a reason, is written to the audit log, and is never retroactive: commissions already earned stay where they landed.
At a depth of two the tree is barely a tree: the whole structure is sponsor_id on the
affiliate row, and the rollup is one indexed join. No closure table, no recursive CTE, no
ancestor_ids array. Cycle insertion is rejected at the database level.
MAX_DEPTH = 2 lives in one place in the commission engine, and the schema comment beside
it records why — that raising it to 3 converts the program into an MLM and is a legal
decision requiring counsel, not a configuration change (§2.1). Writing the reason down is
the point; a bare constant invites someone to bump it in a year.
5.3 Commission rules
Each plan_level carries:
| Field | Meaning |
|---|---|
level |
1 (direct) or 2 (override) |
kind |
percent or flat |
value |
20.00 (percent) or 50.00 (dollars) |
basis |
first_payment | recurring | lifetime |
recurring_months |
e.g. 12, or null for lifetime |
hold_days |
default 30, per §2.3 |
Structural guard (from §2.1): a commission row cannot exist without a
conversion_id, and a conversion cannot exist without a positive amount_cents traced
to a payment. There is no path from "someone joined your downline" to money.
Suggested starting plan for HealthyApp — a decision for you, not the platform: L1 25% recurring for 12 months, L2 5%, 30-day hold, $50 payout minimum. The 2% that would have gone to L3 is worth folding into L1 rather than banking; the direct promoter is who actually produces revenue.
6. Tracking and attribution
6.1 Link anatomy
Primary https://gethealthyapp.com/r/JWHIST
Deep link https://gethealthyapp.com/r/JWHIST?to=/pricing
Short https://go.tellatribe.com/JWHIST
The affiliate never hand-builds a URL. The link builder in the portal takes a product, an optional destination page, and an optional campaign label, and emits the link, a QR code, and a pre-shortened version.
Referral codes are human-readable, claimed by the affiliate at signup, unique per person across all products, and immutable once used (a dead link is worse than an ugly one).
6.2 The click
/r/[code] on the product's own domain:
- Fires a server-side call to tellatribe recording the click — code, product, IP hash, user agent, referer, campaign, timestamp.
- Receives a
click_id(UUID). - Sets a first-party cookie
ac_clickon the product's domain, 90-day expiry. - 302s to the destination.
Because the route lives on the product's domain, the cookie is first-party and survives browser privacy defaults that kill third-party cookies. The click record is written server-side, so an ad blocker cannot suppress it.
6.3 The conversion (server-to-server, primary path)
POST https://api.tellatribe.com/v1/conversions
Authorization: Bearer <product_api_key>
Idempotency-Key: <merchant event id>
{
"click_id": "…", // preferred
"ref_code": "JWHIST", // fallback if click_id unavailable
"customer_ref": "cus_…", // merchant's stable customer id
"event": "subscription_created",
"amount_cents": 9900,
"currency": "USD",
"occurred_at": "2026-08-14T18:22:11Z"
}
Idempotency key is required. Replaying the same event is a no-op, which matters because webhook delivery is at-least-once.
6.4 The zero-code path (Stripe webhooks)
For any product billing on Stripe — which is all of them — point a Stripe webhook
endpoint at tellatribe and set client_reference_id to the ac_click cookie value
at checkout. tellatribe then derives everything itself:
checkout.session.completed→ first conversioninvoice.paid→ recurring conversioncharge.refunded/charge.dispute.created→ automatic clawback
This is how FirstPromoter and Rewardful achieve one-afternoon integrations, and it means HealthyApp's total integration surface is one redirect route and one line at checkout.
Important topology note for HealthyApp specifically: affiliate commissions attach to
platform subscription revenue on your Stripe account
(organizations.stripe_customer_id / stripe_subscription_id), not to tenant Connect
charges. A coach charging their own clients through Connect Standard is not an affiliate
conversion, and the webhook subscription must be scoped so the two can never be confused.
6.5 Attribution rules
- Last click wins within the 90-day window, configurable per program.
- Customer lock on first conversion. When a customer first converts, the winning
affiliate is written to a
customer_attributionrow and every future recurring payment from that customer pays that affiliate, regardless of later clicks. Without this, month 13 of a subscription pays whoever most recently got a click, which is both wrong and a fraud invitation. - Self-referral rejected. A conversion whose customer email or payment fingerprint
matches the affiliate's own is created in
flaggedstate, notpending. - Duplicate customer rejected. A
customer_refalready attributed to another affiliate keeps its original attribution; the second claim is flagged.
7. The commission ledger
7.1 Shape
Append-only. Nothing is ever updated in place; a reversal is a new negative row pointing at the original. Balance is a sum, always reproducible, and a dispute six months later is answerable from the table.
One conversion generates up to two commission rows — L1 to the affiliate who drove it, L2
to their sponsor if one exists — each linked to the same conversion_id, each carrying the
plan_level_id in force at that moment.
7.2 States
flagged ──→ pending ──→ approved ──→ paid
│ │ │
└─→ voided └─→ voided └─→ reversed (clawback)
| State | Meaning | Transition |
|---|---|---|
flagged |
Fraud rule tripped; awaits admin | Manual only |
pending |
Earned, inside the hold window | Automatic on conversion |
approved |
Hold elapsed, refund window closed, payable | Automatic at hold_days |
paid |
Included in a completed payout | Automatic on payout run |
voided |
Cancelled before payment | Automatic on refund pre-approval, or manual |
reversed |
Clawed back after payment | Automatic on refund/chargeback post-payment |
7.3 Clawback
A refund or chargeback reverses every level of that conversion, not just L1. If the commission is not yet paid it voids; if paid, it books a negative row that nets against the affiliate's next payout. If an affiliate's balance goes negative and they stop producing, that debt sits until written off by an admin — it is never chased automatically.
7.4 Fraud flags (§2.4)
Automatic, each creating an exceptions-queue item rather than a punishment:
- Self-referral match on email or payment fingerprint
- Duplicate
customer_refacross affiliates - 2+ chargebacks from one affiliate's referrals in a rolling 30 days
- Refund rate above a configurable threshold
- Click-to-conversion time under a few seconds at volume (bot signature)
- Abnormal click volume from a single IP hash
8. Payouts
Primary rail: Stripe Connect Express. Affiliates onboard through Stripe's hosted flow; Stripe collects identity and tax forms and handles 1099 generation and e-filing. Decided Oct 3, 2026 (BUILD-PLAN §5, decision 9): payouts run from a new, dedicated tellatribe Stripe account, funded monthly from each product's revenue account — not from HealthyApp's revenue account. That adds a funding transfer and a reconciliation step to every payout run, and it is the shape the sellable platform needs.
Secondary: PayPal Payouts for international affiliates outside Stripe's supported countries. Escape hatch: CSV export for anything manual.
Payout run:
- Scheduled — monthly on the 1st, or on demand.
- Selects all
approvedcommissions per affiliate, nets any negative rows. - Skips affiliates under the minimum ($50 default) — the balance rolls forward.
- Skips affiliates who haven't completed payout onboarding, and notifies them.
- Creates one
payoutper affiliate covering many commission rows; marks thempaid. - Failures move the payout to
failedand return the rows toapproved, so a bad bank detail costs a retry, not a reconstruction.
Every payout is traceable to the exact commission rows inside it, and every commission row to the conversion, and every conversion to the click.
9. The affiliate portal
This is where "power for the affiliate" lives.
9.1 Dashboard
Clicks, unique visitors, conversions, conversion rate, EPC, and earnings for the period, across all products. Pending / approved / paid balances shown separately, with the next payout date and the amount currently projected for it. Downline counts by level. A 30-day sparkline. No vanity metrics that don't map to money.
9.2 Link builder
Product picker → optional destination page → optional campaign label → link, short link, and downloadable QR code. Per-link performance so an affiliate can tell their newsletter from their Instagram bio.
A dedicated recruiting link builds the downline. It is visually and structurally distinct from product links, and it earns nothing on its own (§2.1) — it only sets sponsorship.
9.3 Collateral vault
The differentiator. Assets are per-product, categorized (email swipes, social captions, images, video, one-pagers, webinar decks, FAQ/objection handling), and — the part that matters — rendered with the viewing affiliate's own link already substituted in.
Templates carry tokens: {{ref_link}}, {{affiliate_name}}, {{product_name}},
{{short_link}}. An affiliate hits Copy on an email swipe and gets sendable copy, not
homework.
The three delivery modes
Every asset is reachable three ways, in rising order of ease. The affiliate picks the rung they're comfortable on; the vault's job is to make sure nobody stalls because the next step was work.
Mode 1 — Take it. Download the image or video, copy the caption. The affiliate posts it themselves, wherever they post. This is the floor and it must stay excellent: one tap to copy, one tap to download, correct aspect ratios per platform, disclosure already in the caption.
Mode 2 — We post it. The affiliate connects their social accounts once (OAuth), and publishes from inside the portal. Pick the asset, pick the accounts, post now or schedule. The platform handles per-network formatting, the tracked link in the right place for each network, and the disclosure. The affiliate never opens another app.
What this requires that Mode 1 does not: an OAuth connection manager, a publish queue with retry and failure reporting, per-network asset rendition, and an honest "what we will post, exactly" preview before anything leaves. Posting on someone's behalf is a trust event — the preview is not a nicety, it is the thing that makes the feature usable by someone who has never let software touch their account.
Mode 3 — Record it. The affiliate opens a supplied script and the phone becomes a teleprompter: the script scrolls over the live camera, they hit record, and they come out with a video. From there it goes straight to Mode 2's publish step, or downloads for them to post themselves.
This is the rung that unlocks the affiliate who has nothing to post and no idea what to say. It is also the most demanding surface in the product — a camera view, a scrolling script, a record control, and a review step, all on a phone held in one hand, possibly somewhere public. Design notes that follow from that:
- Scroll speed must be adjustable during recording, because everyone reads at a different pace and discovering yours mid-take is normal.
- The script sits over the lens, not beside it, so the affiliate's eyes stay on camera.
- Retake must be one tap and must not threaten the previous take until the new one lands.
- Front and rear camera, portrait as the default, with the safe area for captions marked so the script doesn't end up where the platform will overlay its own UI.
- A countdown before record, and a visible recording state that survives a glance away.
- Scripts carry the same token substitution as every other asset, so the affiliate's own link is already in the spoken CTA and the caption that ships with it.
- Required disclosure is part of the script, not an afterthought bolted to the caption.
Scripts are authored in the admin alongside every other asset, with an estimated read time at the default scroll speed, so the admin knows they wrote a 40-second video and not a two-minute one.
Each asset shows a "new since your last visit" badge, an optional recommended-use note, and a usage count so you learn which collateral actually produces revenue. Assets are versioned, and assets can be restricted to a program or to affiliates above a performance threshold.
Every asset ships with the required disclosure language already in it, and the vault includes a short, plain-English "what you may and may not claim" page. FTC endorsement rules make an affiliate's undisclosed promotion your problem as well as theirs, and health claims around HealthyApp raise the stakes further.
Decided Oct 3, 2026 (BUILD-PLAN §5, decisions 6 and 12): in the Post-for-me composer the affiliate may edit anything, including removing the disclosure; the composer warns once and logs the removal, then posts. On recordings, the on-screen disclosure burn-in is off by default and the affiliate can turn it on per take; the spoken disclosure line in every script stays mandatory. These are the owner's calls; the guidelines page states the exposure plainly.
9.4 Downline
A single list — the affiliates this person recruited — showing name, join date, product(s), and activity level. Deliberately not shown: their earnings and contact details. Enough for an affiliate to coach the people they brought in, not enough to poach or to feel surveilled.
Two levels means this screen is a table, not a tree — no expand/collapse, no depth navigation. It also means the recruiting pitch is honest and simple: bring in someone good, earn on what they sell. There is no downline-of-a-downline to explain.
9.5 Payouts and settings
Payout method onboarding, tax status, payout history with per-payout commission detail, downloadable statements, and profile/notification preferences.
9.6 Notifications
Email on: first click, first conversion, each conversion (batched daily), commission approved, payout sent, new collateral, downline signup. Every one individually switchable, because an affiliate who mutes everything hears nothing when it matters.
10. Admin
Designed so that a normal week requires zero logins.
Exceptions queue — the home screen. Flagged conversions, failed payouts, negative balances, affiliates awaiting approval if the program is gated. Each item has the context needed to decide and two or three buttons. Empty queue is the normal state.
Programs — create a product, set the direct and override rates, hold period, minimum payout, cookie window, and terms. Rate changes apply forward only.
Affiliates — search, view, adjust, suspend, reparent (with reason, audited), impersonate-for-support in read-only.
Payout runs — review the batch total before releasing, then release. One screen.
Collateral — upload, categorize, version, and target assets. This is the admin screen that gets the most actual use.
Reports — revenue by affiliate, by product, by level; cohort retention of referred customers; collateral usage vs. revenue; commission liability outstanding.
11. Compliance requirements
These are build requirements, not advice.
- No fee of any kind may be charged to an affiliate, at signup or ever. There is no billing code in the affiliate-facing product.
- Commission rows may be created only by a conversion with a positive amount traced to a payment. Enforced by schema constraint, not convention.
- Depth is capped at two. Enforced in the commission engine and by a check constraint
on
plan_levels.level, so a misconfigured program cannot silently produce a third level. Raising the cap is a legal decision, not a deploy (§2.1, §5.2). - Program terms are versioned; an affiliate accepts a specific version, and the acceptance is recorded with a timestamp.
- Income claims are prohibited in collateral, and the collateral guidelines say so explicitly. No "affiliates earn $X" language anywhere in recruiting material.
- Required FTC disclosure language ships attached to every collateral asset.
- Right-to-delete: an affiliate can be anonymized while their commission ledger rows survive as financial records.
- Terms give you the right to withhold and reverse on fraud, and to terminate.
At two levels this is an ordinary two-tier affiliate program, and the counsel review that a three-level plan would have required is no longer a launch blocker. A standard review of the affiliate terms of service is still worth doing — but that's a normal contract review, not a compensation-plan opinion.
12. Technical architecture
Same stack as the rest of the portfolio: Next.js on Vercel, Supabase Postgres with RLS, Tailwind, TypeScript.
apps/
portal/ tellatribe affiliate-facing
admin/ admin.tellatribe admin
api/ api.tellatribe.com public tracking + conversion API
packages/
sdk/ @affiliate-coach/sdk what products install
core/ commission engine, shared types
Key tables: workspaces, products, programs, plan_levels, affiliates,
affiliate_programs, referral_codes, links, clicks, conversions,
customer_attribution, commissions, payout_runs, payouts, payout_items,
assets, asset_versions, asset_renditions, asset_uses, social_accounts,
publish_jobs, recordings, events, api_keys, webhook_events, audit_log.
Full column-level model in build-plan/01-ledger-tracking-payouts.md §1
and build-plan/02-collateral-publishing-teleprompter.md §1.
Non-negotiables:
clicksandconversionsare high-write and never updated. Partition by month early — retrofitting partitioning onto a hot table is painful.- Every inbound webhook is recorded in
webhook_eventsbefore processing and keyed for idempotency. HealthyApp's0137_stripe_connectmigration already establishes this pattern; follow it. - RLS everywhere. An affiliate reads their own rows and aggregate-only views of their downline. This is the highest-consequence security boundary in the system.
- Money is
bigintcents. Never floats. - The commission engine is a pure function —
(conversion, program, tree) → commission[]— so it can be unit-tested exhaustively and replayed against historical data.
SDK surface, complete:
// route handler — app/r/[code]/route.ts
export { GET } from '@affiliate-coach/sdk/next'
// at checkout
client_reference_id: getClickId()
// manual conversion, only if not using the Stripe path
await ac.convert({ clickId, customerRef, amountCents, event })
13. Build sequence
| Phase | Contents | Rough size |
|---|---|---|
| 1. Ledger | Schema, commission engine, 2-level rollup, states, clawback. No UI. Tested exhaustively. | Largest and most important |
| 2. Tracking | /r/[code], click API, conversion API, Stripe webhook path, SDK |
|
| 3. Portal | Dashboard, link builder, downline, settings | |
| 4. Admin | Exceptions queue, programs, affiliates, payout runs | |
| 5. Payouts | Stripe Connect Express, onboarding, payout runs, statements | |
| 6. Collateral | Vault, token substitution, versioning, usage tracking (Mode 1) | |
| 6b. Publishing | Social OAuth, publish queue, per-network rendition, post preview (Mode 2) | |
| 6c. Teleprompter | Camera capture, scrolling script, retake, review, hand-off to publish (Mode 3) | Highest craft cost |
| 7. HealthyApp | First live integration, real affiliates, first payout run |
Phase 1 is deliberately first and unglamorous. Every failure mode in an affiliate platform that costs real money or real trust is a ledger failure, and a ledger built after the UI is a ledger built to fit screens instead of accounting.
14. Success criteria
- A new product integrates in under one working day.
- A normal week requires zero admin logins; the exceptions queue is empty.
- Zero mis-attributed conversions in the first 90 days.
- Zero commission disputes that can't be answered from the ledger in under five minutes.
- Median affiliate visits the collateral vault within 48 hours of signup and posts something from it.
- An affiliate who has never made a promotional video makes one, from script to posted, without leaving the portal or asking anyone how.
15. Open questions for you
- Rates. L1 and L2 percentages, and whether L1 is recurring for 12 months or lifetime.
- Gated or open. Does anyone sign up, or does an affiliate need approval?
- Can customers become affiliates? For HealthyApp this is likely yes and is the single largest growth lever — it also raises the self-referral rate, which §7.4 handles.
- Cross-product downline. If someone recruits an affiliate for HealthyApp and that person also promotes GetBooked, does the sponsor earn on GetBooked? §5.2 assumes yes; confirm.
- Domain. Is
tellatriberegistered, and do you wantgo.tellatribe.comfor short links? - First collateral set. Building the vault before there is anything in it wastes the phase — what exists today for HealthyApp?
16. Commercial shape
This is an internal program built so it can become a sellable platform without a rewrite.
Nine decisions make that true and are taken in Phase 1, not later; they are specified in
build-plan/03-reconciliation-and-surfaces.md §A.2:
- Tenancy boundary —
workspaceswith one seeded row;workspace_idon every top-level table. - Roles —
ownerandaffiliateonly, through onecan()helper. - Programs as rows, never constants;
MAX_DEPTH = 2named once with its reason. - API keys scoped to workspace and product, with a test mode.
- Asset ownership by workspace; token substitution knows no product.
- Branding as tokens on
:rootand aworkspaces.brandingrow; no hardcoded name or hex. - Billing hooks that stay empty; the payout account is a workspace reference.
- Event instrumentation and promotional-action counting from day one.
- Config, not constants: hold, minimum, window, tax threshold, fraud thresholds.
PRD-Activation-Platform.md is kept as the frozen v2 vision of that platform. Its
requirements are reconciled one by one against this document in the same file, §A.1.
The build sequence, gates, and open decisions live in BUILD-PLAN.md.
17. Addenda — what changed after v0.1 (October 19, 2026)
The platform is live as tellatribe (tellatribe.com). These addenda record the requirements that were added or changed since this document was written; the numbered decisions live in DECISIONS-FOR-REVIEW.md.
17.1 Tax identity is a payout gate (decisions 61–65). affiliates.tax_status (missing · verified · w8_on_file) is cached from Stripe's account.updated. The payout run holds any balance whose tax identity is missing, even when payouts are enabled on the Express account. tellatribe is payer of record and files 1099-NEC (never 1099-K) at the workspace's threshold ($2,000 for 2026 payments, a setting not a constant). Every affiliate downloads an annual earnings statement per calendar year regardless of threshold; the admin's Paid by recipient · tax year report is the January reconciliation against Stripe's Connect tax reporting.
17.2 Creator Campaigns (PRD-Creator-Campaigns.md Part B; decisions 55–60, 67–106). Brands publish briefs; creators apply from the Wall; accepted applications become deals with a frozen SOW; deliverables are tasks that move draft → posted → verified; verification births a bounty commission row (§7's ledger gains the kind, with deal_task_id as its lineage) that the existing payout run pays. Gift value is recorded on the deal and reported, never paid. Usage rights are structured grants with expiry. Disputes have an admin decision and one creator appeal.
17.3 Brand funding (decisions 69, 73, 76). Brand money is a per-brand, append-only balance ledger. Brands fund it through Stripe Checkout (card or ACH, minimum $100, processing fees paid by the brand) on the payout Stripe account, which therefore accepts payments as well as sending them; escrow is reserved at acceptance and released beside each bounty; the 10 % platform fee (flat fees only) comes off the free balance at release. The manual bank top-up of §8 remains the fallback for the house brands.
17.4 Non-Stripe publishers (decision 75). §6's POST /v1/conversions is the processor-agnostic sale signal; refunds arrive as reversals through the same API. No-code connectors (Shopify, WooCommerce, webhook relay) are a later phase.
17.5 Three deployments by design (decision 66). Portal, admin and API are three Vercel projects in one monorepo: different audiences and gates (public magic link · membership + MFA · webhooks and crons), own domains and rollback. The Stripe restricted key is a team-level shared env var; webhook secrets live only on the API project.
Sources
- FTC — Business Guidance Concerning Multi-Level Marketing
- Multi-Tier Affiliate Commission Structures: 2026 Guide
- How To Run a Two-Tier Affiliate Program — Matt McWilliams
- Server-Side Affiliate Tracking Without Cookies: The 2026 Guide — iRev
- The Developer's Guide to Server-Side Affiliate Tracking — Tapfiliate
- Cookie Tracking vs Cookieless Tracking — Track360
- Affiliate Commission Clawback: Operator Payout Guide 2026 — Track360
- Refunds and Affiliate Commissions: The Clawback Workflow — TinyAffiliate
- Affiliate Fraud: 7 Common Schemes and How to Detect Them — Refgrow
- Stripe Connect — 1099 tax reporting
- Best Payment APIs for Affiliate Networks — Dots
- 1099 Reporting Threshold Updates — OnPay
- OBBBA Form 1099 Reporting Changes — Pease Bell
- Affiliate Software Pricing 2026 — StackScored
- Best Affiliate Marketing Software in 2026 — FirstPromoter
- FirstPromoter Review — Tapfiliate
Rendered from PRD.md. Edit the source, not this page.