Inviting partners
Two ways partners end up on your program:
- Marketplace self-join — if your program is
publicwithapprovalMode: "auto", anyone browsingpartners.apex.inc/programscan join instantly - Direct invite — you know them by email; send a magic-link invite
This page covers #2.
Send an invite
From the dashboard, via API, or via MCP — same underlying endpoint. Invites always go through a program. The program's commissionRules are the default terms; you can optionally set a custom rate at invite time using the InviteCreatorDialog flow.
Dashboard
- Open
/dashboard/partners/programs/<programId>/members - Click Invite partner
- The
InviteCreatorDialogopens — enter their email, an optional personal message, and optionally customize the commission rules for this partner - Click Send invite
The dialog pre-fills the program's default commission rules so you can see exactly what the partner will earn. Adjustments made here create an invite_override that is sticky — it survives future program default updates.
SDK
import { createManagementClient } from "@apex-inc/sdk/management";
const apex = createManagementClient({
projectKey: "your-project-key",
apiKey: process.env.APEX_API_KEY!,
});
await apex.invitePartner({
email: "sarah@example.com",
programId: "prog_abc123",
inviterName: "Alice from Acme",
inviterMessage: "I'd love to partner with you — we've got a special rate for you.",
});
The partner receives the program's default commissionRules. To set a custom rate at invite time, pass the full rules array:
await apex.invitePartner({
email: "sarah@example.com",
programId: "prog_abc123",
inviterName: "Alice from Acme",
customCommissionRules: [
{ event: "install", type: "cpa", amountUsd: 7 },
{ event: "purchase", type: "revshare", percentage: 30 },
],
});
MCP
Agents can send invites too:
invite_partner({
email: "sarah@example.com",
programId: "prog_abc123",
inviterName: "Alice from Acme",
})
What happens on Sarah's side
- Sarah gets an email: "Alice from Acme invited you to partner with them on Apex. [Accept invite]"
- She clicks the magic link → lands on
partners.apex.inc/invite/accept?token=... - If she's new to Apex: she claims a handle (
@sarah) + completes onboarding (including W-9/W-8BEN via Stripe) - If she's already a partner: the invite creates a fresh
AffiliateMembershipbound to your program — her existing handle + Stripe Express account are reused - Her new membership shows up in her portal immediately with the program's commission rules (or the custom rate, if you set one)
Handles are cross-merchant. Sarah's @sarah handle works for every merchant she partners with. She doesn't create a new account per merchant.
Custom rate at invite time
Custom commission rules set at invite time write a CommissionChangeEntry with source: "invite_override". This is sticky — it survives future program default updates. Use sparingly: it's the fastest way to land a negotiated rate, but every custom rate is a record in the commission history.
If you later want to move Sarah back to the program default:
await apex.resetMembershipRate("prof_sarah", "Custom rate expired");
There are no per-membership commission overrides outside the invite flow. If you need to change a partner's rate after they've joined, update the program's default rules (which fans out to all program_default members) or terminate and re-invite with new terms.
Invite expiry + resend
Magic-link tokens are valid for 14 days. After expiry, re-send the invite — it generates a fresh token.
Bulk invite
For larger programs, script the SDK:
const partners = [
{ email: "sarah@example.com", programId: progA },
{ email: "bob@example.com", programId: progA },
{ email: "eve@example.com", programId: progB, customCommissionRules: [...] },
];
for (const invite of partners) {
await apex.invitePartner(invite);
}
If you want self-serve applications instead
Set approvalMode: "manual" on the program. Make the program public. Partners discover it at partners.apex.inc/programs + apply with a message + audience info. You review applications at /dashboard/partners/programs/<id>/applications.