Skip to content

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>/partners
Authorization: Bearer <key>
Content-Type: application/json
{
"email": "[email protected]",
"name": "Alice",
"sendInvite": true,
"campaignIds": ["cmp_default"]
}
FieldTypeRequiredNotes
emailstringyesLowercased on storage. Returns 409 if already exists.
namestringyesDisplay name.
sendInvitebooleannoDefault true. When false, partner is created in active state with no email.
metadataobjectnoFree-form. The Network federation puts source info here.
campaignIdsstring[]noPrograms the partner can create share-links for. Omitted = all current campaigns. Empty array = none.
campaignGrantSource'admin' | 'offering'noAudit hint. 'offering' is what Network federation sends.
commissionSnapshotobjectnoUsed by Network federation to grandfather a partner’s commission terms at approval — see commissions.

Response

{
"id": "01HXX...",
"email": "[email protected]",
"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=100
Authorization: Bearer <key>
QueryNotes
emailExact-match filter (case-insensitive).
limit1–200, default 100.
cursorOpaque cursor from a previous nextCursor.

Response

{
"partners": [
{
"id": "01HXX...",
"email": "[email protected]",
"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.../invite
Authorization: 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.../revoke
Authorization: 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.