Partners
POST /partners
Create a partner. By default, sends a magic-link invite email.
Auth: Admin API key OR scoped key with partners:write.
POST <base>/partnersAuthorization: Bearer <key>Content-Type: application/json
{ "name": "Alice", "sendInvite": true, "campaignIds": ["cmp_default"]}| Field | Type | Required | Notes |
|---|---|---|---|
email | string | yes | Lowercased on storage. Returns 409 if already exists. |
name | string | yes | Display name. |
sendInvite | boolean | no | Default true. When false, partner is created in active state with no email. |
metadata | object | no | Free-form. The Network federation puts source info here. |
campaignIds | string[] | no | Programs the partner can create share-links for. Omitted = all current campaigns. Empty array = none. |
campaignGrantSource | 'admin' | 'offering' | no | Audit hint. 'offering' is what Network federation sends. |
commissionSnapshot | object | no | Used by Network federation to grandfather a partner’s commission terms at approval — see commissions. |
Response
{ "id": "01HXX...", "name": "Alice", "activatedAt": null, "createdAt": "2026-04-24T12:00:00Z", "invited": true}activatedAt is null until the partner clicks their magic-link invite. With
sendInvite: false, it’s set to now() immediately.
GET /partners
List partners.
Auth: Admin API key OR scoped key with partners:read.
GET <base>/[email protected]&cursor=<...>&limit=100Authorization: Bearer <key>| Query | Notes |
|---|---|
email | Exact-match filter (case-insensitive). |
limit | 1–200, default 100. |
cursor | Opaque cursor from a previous nextCursor. |
Response
{ "partners": [ { "id": "01HXX...", "name": "Alice", "stripeConnectAccountId": "acct_xxx", "createdAt": "2026-04-24T12:00:00Z", "activatedAt": "2026-04-24T12:05:00Z", "revokedAt": null } ], "nextCursor": "eyJjcmVhdGVk..."}nextCursor is null on the last page.
GET /partners/:id
Get a single partner.
Auth: Admin API key OR the partner themselves (via partner-scoped key or session).
POST /partners/:id/invite
Re-issue the magic-link invite email to a partner who hasn’t accepted yet. Idempotent — multiple sends are fine; the partner can click any one (each expires in 15 minutes).
Auth: Admin API key.
POST <base>/partners/01HXX.../inviteAuthorization: Bearer <key>POST /partners/:id/revoke
Suspend a partner. Sessions end immediately, no new attribution accrues, historical
commissions stay intact. Reversible via POST /partners/:id/reinstate.
Auth: Admin API key OR scoped key with partners:write.
POST <base>/partners/01HXX.../revokeAuthorization: Bearer <key>Content-Type: application/json
{ "reason": "Violated terms" }reason (optional) is surfaced in the revoke notification email + visible if they try to
sign in again.
GET /partners/:id/commission-snapshot
Returns the partner’s PartnerCommission row — the snapshotted commission rate they were
approved under. Null when no snapshot exists (legacy or non-Network partners; falls back to
the live Campaign rule at accrual). See commissions.