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