Amba

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 is in preview (gated off). Everything that does not move money is live: program management, enrollment, attribution (code and in-app link/touchpoint), commission accrual, clawback, analytics, and notifications. The actual payout transfer (POST .../payouts and the scheduled settlement) ships gated off behind ORG_PAYOUTS_LIVE and returns 503 PAYOUTS_NOT_ENABLED until a platform operator enables it after a customer-shoes test + counsel + per-affiliate Connect onboarding. Build and dry-run freely; don't promise affiliates same-day cash until your stack has the flag on.

Admin endpoints

MethodPathDescription
POST/v1/admin/affiliate/programsCreate a program (+ terms v1).
GET/v1/admin/affiliate/programsList programs your orgs (and descendants) own.
GET/v1/admin/affiliate/programs/:programIdGet a program.
PATCH/v1/admin/affiliate/programs/:programIdUpdate status / payout config / conversion definition / funding_source.
POST/v1/admin/affiliate/programs/:programId/inviteEnroll an affiliate org (or guide an email to sign up).
GET/v1/admin/affiliate/programs/:programId/affiliatesList affiliates + their conversion/commission totals.
GET/v1/admin/affiliate/programs/:programId/affiliates/:enrollmentIdOne affiliate's detail (codes, conversions, totals).
POST/v1/admin/affiliate/programs/:programId/affiliates/:id/:actionapprove / pause / ban an enrollment.
POST/v1/admin/affiliate/programs/:programId/conversionsReport a conversion (idempotent; code optional — link-attributed if omitted).
GET/v1/admin/affiliate/programs/:programId/conversionsList conversions.
POST/v1/admin/affiliate/programs/:programId/conversions/:id/:actionapprove / reject / clawback a conversion.
GET/v1/admin/affiliate/programs/:programId/analyticsProgram totals + clicks/EPC/conversion-rate + leaderboard.
GET/v1/admin/affiliate/programs/:programId/leaderboardStandalone affiliate leaderboard (commission + clicks + EPC).
GET/v1/admin/affiliate/programs/:programId/payoutsSettlement (payout) history for the program's affiliates.
POST/v1/admin/affiliate/programs/:programId/payoutsRun payouts (gated by ORG_PAYOUTS_LIVE).

:action = clawback reverses a conversion's commissions (the underlying sale refunded/charged back): pre-payout commissions go reversed; an already-paid (or in-flight) commission becomes negative carry-forward debt that nets against the affiliate's next payout. Separately, a transfer.reversed Connect webhook (the affiliate's bank bounced a settled transfer) marks that settlement's commissions reversed and restores any carry-forward debt that payout had cleared.

Self-service endpoints (/v1/admin/affiliate-me)

Scoped entirely to the caller's own orgs. Financial reads require manage-level on the org.

MethodPathDescription
GET/v1/admin/affiliate-me/programsPrograms you're enrolled in.
GET/v1/admin/affiliate-me/invitesPending invitations for your org(s).
POST/v1/admin/affiliate-me/invites/:enrollmentId/acceptAccept an invitation (activates + returns your code).
GET/v1/admin/affiliate-me/programs/:programId/referralYour code/link for a program.
POST/v1/admin/affiliate-me/programs/:programId/referralMint a fresh code (rotates your active code).
GET/v1/admin/affiliate-me/statsConversions + earnings across enrollments.
GET/v1/admin/affiliate-me/conversionsConversions across your enrollments.
GET/v1/admin/affiliate-me/balanceAccrued-but-unpaid + paid, per currency.
GET/v1/admin/affiliate-me/payoutsSettlement history.
POST/v1/admin/affiliate-me/payout-requestWhat you're owed + payout-account readiness (no money moves).
POST/v1/admin/affiliate-me/payout-accountCreate a Stripe Connect payout account.
POST/v1/admin/affiliate-me/payout-account/linkHosted Connect onboarding link.
GET/v1/admin/affiliate-me/payout-accountOnboarding status (manage-level).

Client endpoint (in-app attribution)

MethodPathAuthDescription
POST/v1/client/affiliate/touchpointX-Api-KeyRecord an in-app affiliate-link click / code-bind.

Record a touchpoint when a visitor lands via an affiliate link — { code, source: "code"\|"link", anonymous_id, external_id? }. No session required (a pre-auth click). anonymous_id must be an unguessable client-generated id (e.g. a random device token) that you then report the conversion's subject_ref with; the endpoint is unauthenticated, so a touchpoint is advisory last/first-touch attribution — for trusted credit, report the conversion with the affiliate code (the authoritative path) rather than relying on code-less promotion. On a conversion reported with no code, the latest touchpoint for that subject (within the attribution window) is promoted into the control ledger; clicks also drive real EPC and conversion-rate in analytics.

Commission model

commission is a versioned JSONB tagged union (data, not columns) — enrollments are grandfathered to the version they activated under:

TypeShapeNotes
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 are double-gated: the per-program flag and the platform ORG_MULTI_LEVEL_LIVE server flag (MLM/pyramid regulatory exposure), so they don't accrue until the platform has been cleared for multi-level — the direct (level-0) commission is unaffected. platform_fee_bps is Amba's cut, deducted from each payout.

funding_source records the intended source of commission money: split_at_source (default — the attributed sale ran through Amba Payments) or external (the customer funds payouts another way, e.g. a pre-funded wallet). It is metadata today, not yet enforced by the rail: the (gated) transfer always moves from Amba's platform balance via the shared payOrg. Wiring source-specific settlement — e.g. for split_at_source, transferring from the customer's connected-account balance so Amba is truly pass-through — is part of the ORG_PAYOUTS_LIVE go-live work, pending the Stripe-mechanism + pricing decision with counsel.

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.

Notifications

On a commission being approved (accrued) or paid, the affiliate org's owner is emailed automatically — affiliates don't have to poll. Best-effort: a send failure never blocks accrual or a payout.

MCP tools

Admin: amba_affiliate_programs_{create,list,get,update}, amba_affiliate_invite, amba_affiliate_affiliates_{list,get}, amba_affiliate_affiliate_{approve,pause,ban}, amba_affiliate_conversions_list, amba_affiliate_conversion_{approve,reject,clawback}, amba_affiliate_analytics_get, amba_affiliate_leaderboard_get, amba_affiliate_payouts_list, amba_affiliate_payout_run. Self-service: amba_affiliate_my_{programs_list,invites_list,invite_accept,referral_get,referral_generate,stats_get,conversions_list,balance_get,payouts_list,payout_request,payout_create,payout_onboarding,payout_status}. Zero-to-enrolled: the public amba_affiliate_signup mints an org + PAT and enrolls in one browserless call. Conversions are reported server-to-server via the API, not an MCP tool.

On this page