tellatribe

Enter the access code to read the project documents.

tellatribe Docs Status: All modules built and live · Oct 19: Creator Campaigns Part B shipped (briefs, applications, deals, verification → bounties, brand balance + Stripe funding, disputes, reports) on top of the tax-identity gate and annual statements · awaiting owner inputs: tellatribe Stripe account (payments + Connect + funding webhook), HealthyApp webhook secret, Ayrshare key

Requirements · PRD.md

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:

  1. Tracks clicks and conversions from affiliate links, across any number of products.
  2. Calculates commissions on a two-level downline, with an auditable ledger.
  3. Pays affiliates on a schedule, with tax and identity handled by the payout rail.
  4. 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

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:

  1. Fires a server-side call to tellatribe recording the click — code, product, IP hash, user agent, referer, campaign, timestamp.
  2. Receives a click_id (UUID).
  3. Sets a first-party cookie ac_click on the product's domain, 90-day expiry.
  4. 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 conversion
  • invoice.paid → recurring conversion
  • charge.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_attribution row 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 flagged state, not pending.
  • Duplicate customer rejected. A customer_ref already 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_ref across 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:

  1. Scheduled — monthly on the 1st, or on demand.
  2. Selects all approved commissions per affiliate, nets any negative rows.
  3. Skips affiliates under the minimum ($50 default) — the balance rolls forward.
  4. Skips affiliates who haven't completed payout onboarding, and notifies them.
  5. Creates one payout per affiliate covering many commission rows; marks them paid.
  6. Failures move the payout to failed and return the rows to approved, 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.

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.

  1. 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.
  2. Commission rows may be created only by a conversion with a positive amount traced to a payment. Enforced by schema constraint, not convention.
  3. 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).
  4. Program terms are versioned; an affiliate accepts a specific version, and the acceptance is recorded with a timestamp.
  5. Income claims are prohibited in collateral, and the collateral guidelines say so explicitly. No "affiliates earn $X" language anywhere in recruiting material.
  6. Required FTC disclosure language ships attached to every collateral asset.
  7. Right-to-delete: an affiliate can be anonymized while their commission ledger rows survive as financial records.
  8. 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:

  • clicks and conversions are high-write and never updated. Partition by month early — retrofitting partitioning onto a hot table is painful.
  • Every inbound webhook is recorded in webhook_events before processing and keyed for idempotency. HealthyApp's 0137_stripe_connect migration 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 bigint cents. 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

  1. Rates. L1 and L2 percentages, and whether L1 is recurring for 12 months or lifetime.
  2. Gated or open. Does anyone sign up, or does an affiliate need approval?
  3. 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.
  4. 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.
  5. Domain. Is tellatribe registered, and do you want go.tellatribe.com for short links?
  6. 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:

  1. Tenancy boundary — workspaces with one seeded row; workspace_id on every top-level table.
  2. Roles — owner and affiliate only, through one can() helper.
  3. Programs as rows, never constants; MAX_DEPTH = 2 named once with its reason.
  4. API keys scoped to workspace and product, with a test mode.
  5. Asset ownership by workspace; token substitution knows no product.
  6. Branding as tokens on :root and a workspaces.branding row; no hardcoded name or hex.
  7. Billing hooks that stay empty; the payout account is a workspace reference.
  8. Event instrumentation and promotional-action counting from day one.
  9. 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

Rendered from PRD.md. Edit the source, not this page.