Partner docs

Integrate with the affiliate hub

Three steps. Same contract for internal products and future partners.

1. Send visitors through the hub

Affiliates share /r/{code}/{slug}. We record the click, mint a click id, and 302 to your website with?aff=code&aff_cid=clickId. Use aff, not ref — many products already own that param.

2. Persist first-touch for 30 days

If mk_aff is empty, store { code, clickId }. Do not overwrite an existing cookie. Cookie lifetime is MARKETPLACE_COOKIE_DAYS (default 30). Read the query param from MARKETPLACE_REFERRAL_PARAM so it matches the product setting in the hub.

// First-touch cookie. Do not overwrite an existing mk_aff.
const params = new URLSearchParams(window.location.search)
const aff = params.get('aff')
const clickId = params.get('aff_cid')
if (aff && clickId && !document.cookie.includes('mk_aff=')) {
  const value = encodeURIComponent(JSON.stringify({ code: aff, clickId }))
  document.cookie = `mk_aff=${value}; Path=/; Max-Age=${60 * 60 * 24 * 30}; SameSite=Lax`
}

3. Report conversions server-side

POST to /api/v1/events with your product API key. Never put the key in the browser. Duplicate idempotencyKey values return the original row.

curl -X POST "$MARKETPLACE_API_URL/api/v1/events" \
  -H "Authorization: Bearer mk_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "aff": "ian",
    "clickId": "clk_abc123",
    "event": "signup",
    "idempotencyKey": "user_uid:signup"
  }'
await fetch(`${process.env.MARKETPLACE_API_URL}/api/v1/events`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.MARKETPLACE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    aff: cookie.code,
    clickId: cookie.clickId,
    event: 'signup',
    idempotencyKey: `${userId}:signup`,
  }),
})

Rules

  • Unknown affiliate codes or events not in your allow-list return 422.
  • A conversion without a real hub click (aff_cid) is rejected. Code-only or cookie-only signups do not count.
  • Money events should eventually come from your payment backend, not the browser.
  • If you report from a same-origin Next route, require a signed-in session and derive the idempotency key from the user id.

Need a product added? An admin creates it in the hub and hands you the API key. Back to marketplace