Affiliate Programs
Run an affiliate/partner program for your own product — MCP-native, affiliates enroll as orgs, no dashboards.
Affiliate Programs is a first-class realm your customers run for their products. The program owner is an org; each affiliate is also an org with its own PAT. Scoping is structural: admin tools (amba_affiliate_*) require the caller to manage the owner org; self-service tools (amba_affiliate_my_*) take no other-affiliate id and derive the affiliate from the caller's org — an affiliate literally has no parameter to read a peer's data.
The authoritative ledger is control-plane (programs, enrollments, conversions, the accrual ledger, settlements); the only tenant-side row is the in-app touchpoint, promoted to control on conversion so the payout path never reads a tenant DB.
Money-out (POST .../payouts) is a permanent surface that ships gated off behind ORG_PAYOUTS_LIVE; everything else (programs, enrollment, attribution, accrual, analytics) is live.
Admin endpoints
| Method | Path | Description |
|---|---|---|
| POST | /v1/admin/affiliate/programs | Create a program (+ terms v1). |
| GET | /v1/admin/affiliate/programs | List programs your orgs (and descendants) own. |
| GET | /v1/admin/affiliate/programs/:programId | Get a program. |
| PATCH | /v1/admin/affiliate/programs/:programId | Update status / payout config / conversion definition. |
| POST | /v1/admin/affiliate/programs/:programId/invite | Enroll an affiliate org (or guide an email to sign up). |
| GET | /v1/admin/affiliate/programs/:programId/affiliates | List affiliates + their conversion/commission totals. |
| POST | /v1/admin/affiliate/programs/:programId/affiliates/:id/:action | approve / pause / ban an enrollment. |
| POST | /v1/admin/affiliate/programs/:programId/conversions | Report a conversion (idempotent). |
| GET | /v1/admin/affiliate/programs/:programId/conversions | List conversions. |
| POST | /v1/admin/affiliate/programs/:programId/conversions/:id/:action | approve / reject a conversion. |
| GET | /v1/admin/affiliate/programs/:programId/analytics | Program totals + affiliate leaderboard. |
| POST | /v1/admin/affiliate/programs/:programId/payouts | Run payouts (gated by ORG_PAYOUTS_LIVE). |
Self-service endpoints (/v1/admin/affiliate-me)
Scoped entirely to the caller's own orgs. Financial reads require manage-level on the org.
| Method | Path | Description |
|---|---|---|
| GET | /v1/admin/affiliate-me/programs | Programs you're enrolled in. |
| GET | /v1/admin/affiliate-me/programs/:programId/referral | Your code/link for a program. |
| GET | /v1/admin/affiliate-me/stats | Conversions + earnings across enrollments. |
| GET | /v1/admin/affiliate-me/balance | Accrued-but-unpaid + paid, per currency. |
| GET | /v1/admin/affiliate-me/payouts | Settlement history. |
| POST | /v1/admin/affiliate-me/payout-account | Create a Stripe Connect payout account. |
| POST | /v1/admin/affiliate-me/payout-account/link | Hosted Connect onboarding link. |
| GET | /v1/admin/affiliate-me/payout-account | Onboarding status (manage-level). |
Commission model
commission is a versioned JSONB tagged union (data, not columns) — enrollments are grandfathered to the version they activated under:
| Type | Shape | Notes |
|---|---|---|
percentage | { "type":"percentage", "bps":2000 } | 20% of gross. |
flat | { "type":"flat", "amount_cents":5000 } | Fixed per conversion. |
recurring | { "type":"recurring", "bps":2000, "max_cycles":12 } | Percentage for the first N billing cycles. |
tiered | { "type":"tiered", "bps":1000, "tiers":[{"min_conversions":10,"bps":2000}] } | Rate rises after N prior approved conversions. |
For multi-level programs, set multi_level_enabled: true and add a "multi_level":[{"level":1,"bps":500}] ladder; upline overrides accrue to each active ancestor from the program terms (not a converter's custom rate). platform_fee_bps is Amba's cut, deducted from each payout.
Conversion definition + attribution
A program declares what counts (conversion_kind: event / payment / entitlement, with conversion_event_name / conversion_entitlement_id) and how credit is assigned (attribution_model: first_touch / last_touch, attribution_window_days). A reported conversion must carry the qualifying signal or it's rejected; first-touch credit lapses once the window expires. Conversions are idempotent per (program_id, project_id, external_id), so the same app-level order id can be reported to multiple programs independently. Self-referral is blocked at both enroll and conversion time unless allow_self_referral is set.
MCP tools
Admin: amba_affiliate_programs_{create,list,get,update}, amba_affiliate_invite, amba_affiliate_affiliates_list, amba_affiliate_affiliate_{approve,ban}, amba_affiliate_conversions_list, amba_affiliate_conversion_approve, amba_affiliate_analytics_get, amba_affiliate_payout_run. Self-service: amba_affiliate_my_{programs_list,referral_get,stats_get,balance_get,payouts_list,payout_create,payout_onboarding,payout_status}. Zero-to-enrolled: the public amba_affiliate_signup mints an org + PAT and enrolls in one browserless call.