Documentation Index Fetch the complete documentation index at: https://docs.partnero.com/llms.txt
Use this file to discover all available pages before exploring further.
Server-to-server (S2S) tracking sends sign-up and sale events directly from your backend to Partnero. Attribution is carried by a key that you capture from the referral URL and persist—no PartneroJS snippet, no partnero_partner / partnero_referral cookies, and no client-side calls to the Partnero API.
Why use S2S
Resilient to tracking blockers — ad-blockers, cookie-blocking browsers (Safari ITP, Brave, in-app browsers), and snippet load failures don’t affect attribution.
Backend-only stacks — works without any frontend JavaScript on your site.
Mobile and machine-to-machine — required for native apps and headless integrations.
Strict privacy regimes — no third-party-style storage, no extra consent banner row.
Full control — you decide where the referral key lives between landing and sign-up.
Always call the Partnero API from your backend. Keep Authorization: Bearer YOUR_API_KEY on the server—never embed it in browser or mobile code.
Endpoints used
Endpoint Purpose POST /v1/customersTrack a sign-up and attribute it to a partner or referrer POST /v1/transactionsTrack a sale and trigger commission calculation POST /v1/customers/{id}/balance/creditManually credit a referrer (refer-a-friend)
All requests use https://api.partnero.com with Authorization: Bearer YOUR_API_KEY.
How it works
Visitor lands via a referral link — for example yoursite.com?aff=REFERRAL_KEY. The exact query parameter depends on your program; confirm it under Programs → Settings → Referral links in the Partnero dashboard.
You capture the key — read it from the URL and persist it your way (server session, database row keyed by anonymous ID, your own first-party storage, etc.).
You call POST /v1/customers at sign-up with partner.key (affiliate) or referring_customer.key (refer-a-friend).
You call POST /v1/transactions at purchase—or let a connected billing integration do it for you.
Partnero ignores invalid keys, so you can call the API for every sign-up without first checking whether the visitor was referred.
Two valid paths
Both options below are server-side; they differ only in where the referral key comes from.
Path Where the key is stored When to use Pure S2S (this guide) Your storage (session, DB, mobile keystore) No PartneroJS on the site, mobile apps, strict privacy Hybrid The partnero_partner / partnero_referral cookie set by PartneroJS You already use PartneroJS and want to read the cookie server-side instead of via JS
For the hybrid path, see Affiliate API integration and Refer-a-friend API integration , which both show reading the PartneroJS cookie from the request.
Step 1: Capture the referral key
Read the parameter from the landing URL and persist it.
app . get ( '/' , ( req , res ) => {
const aff = req . query . aff ;
if ( aff ) {
req . session . affiliateKey = aff ;
}
res . render ( 'home' );
});
const params = new URLSearchParams ( window . location . search );
const aff = params . get ( 'aff' );
if ( aff ) {
fetch ( '/api/track-landing' , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({ aff })
});
}
Your /api/track-landing route stores the key against the visitor’s session or anonymous ID. Repeat the same value on every sign-up request. const aff = new URLSearchParams ( window . location . search ). get ( 'aff' );
if ( aff ) {
sessionStorage . setItem ( 'affiliate_key' , aff );
}
const aff = sessionStorage . getItem ( 'affiliate_key' );
fetch ( '/api/signup' , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({ email , name , aff })
});
sessionStorage is per-tab and not sent in cross-site requests, so it isn’t subject to cross-site cookie restrictions. If you need cross-tab persistence, store the key on your backend instead.See mobile app integration for iOS, Android, React Native, and Flutter examples that extract the key from a deep link and persist it in native storage.
Step 2: Track sign-ups
When the user creates an account, call POST /v1/customers with the key from Step 1.
Affiliate programs
Use partner.key for the affiliate program key.
curl --location 'https://api.partnero.com/v1/customers' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"partner": { "key": "PARTNER_KEY_FROM_YOUR_STORAGE" },
"key": "customer_123",
"email": "[email protected] ",
"name": "John",
"surname": "Doe",
"options": {
"referral_url": "https://yoursite.com/pricing?aff=PARTNER_KEY_FROM_YOUR_STORAGE"
}
}'
app . post ( '/signup' , async ( req , res ) => {
const user = await createUser ( req . body );
const partnerKey = req . session . affiliateKey ;
await fetch ( 'https://api.partnero.com/v1/customers' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ process . env . PARTNERO_API_KEY } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
partner: partnerKey ? { key: partnerKey } : undefined ,
key: user . id ,
email: user . email ,
name: user . firstName ,
surname: user . lastName ,
options: { referral_url: req . session . landingUrl }
})
});
res . json ({ ok: true });
});
$ch = curl_init ( 'https://api.partnero.com/v1/customers' );
curl_setopt_array ( $ch , [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv ( 'PARTNERO_API_KEY' ),
'Content-Type: application/json' ,
],
CURLOPT_POSTFIELDS => json_encode ([
'partner' => [ 'key' => $_SESSION [ 'affiliate_key' ] ?? null ],
'key' => $user -> id ,
'email' => $user -> email ,
'name' => $user -> first_name ,
'surname' => $user -> last_name ,
]),
]);
curl_exec ( $ch );
curl_close ( $ch );
import os
import requests
requests.post(
"https://api.partnero.com/v1/customers" ,
headers = {
"Authorization" : f "Bearer { os.environ[ 'PARTNERO_API_KEY' ] } " ,
"Content-Type" : "application/json" ,
},
json = {
"partner" : { "key" : session.get( "affiliate_key" )},
"key" : user.id,
"email" : user.email,
"name" : user.first_name,
"surname" : user.last_name,
},
)
See Affiliate API integration for the full request body and additional partner identifier options.
Refer-a-friend programs
Use referring_customer.key for the referrer. Omit the field entirely if the visitor was not referred.
curl --location 'https://api.partnero.com/v1/customers' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"referring_customer": { "key": "REFERRAL_KEY_FROM_YOUR_STORAGE" },
"key": "customer_456",
"email": "[email protected] ",
"name": "Alex"
}'
app . post ( '/signup' , async ( req , res ) => {
const user = await createUser ( req . body );
const referralKey = req . session . referralKey ;
const body = {
key: user . id ,
email: user . email ,
name: user . firstName
};
if ( referralKey ) {
body . referring_customer = { key: referralKey };
}
await fetch ( 'https://api.partnero.com/v1/customers' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ process . env . PARTNERO_API_KEY } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ( body )
});
res . json ({ ok: true });
});
$body = [
'key' => $user -> id ,
'email' => $user -> email ,
'name' => $user -> first_name ,
];
if ( ! empty ( $_SESSION [ 'referral_key' ])) {
$body [ 'referring_customer' ] = [ 'key' => $_SESSION [ 'referral_key' ]];
}
$ch = curl_init ( 'https://api.partnero.com/v1/customers' );
curl_setopt_array ( $ch , [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv ( 'PARTNERO_API_KEY' ),
'Content-Type: application/json' ,
],
CURLOPT_POSTFIELDS => json_encode ( $body ),
]);
curl_exec ( $ch );
curl_close ( $ch );
import os
import requests
body = {
"key" : user.id,
"email" : user.email,
"name" : user.first_name,
}
referral_key = session.get( "referral_key" )
if referral_key:
body[ "referring_customer" ] = { "key" : referral_key}
requests.post(
"https://api.partnero.com/v1/customers" ,
headers = {
"Authorization" : f "Bearer { os.environ[ 'PARTNERO_API_KEY' ] } " ,
"Content-Type" : "application/json" ,
},
json = body,
)
The response includes referral_link so you can show the new customer their share URL. See Refer-a-friend API integration for stats, balance, and reward endpoints.
Step 3: Track sales
Record purchases against the same customer.key you sent at sign-up. Partnero calculates the commission automatically.
curl --location 'https://api.partnero.com/v1/transactions' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"customer": { "key": "customer_123" },
"key": "invoice_123",
"amount": 99.99,
"action": "sale"
}'
await fetch ( 'https://api.partnero.com/v1/transactions' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ process . env . PARTNERO_API_KEY } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
customer: { key: user . id },
key: order . id ,
amount: order . amount ,
action: 'sale'
})
});
$ch = curl_init ( 'https://api.partnero.com/v1/transactions' );
curl_setopt_array ( $ch , [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv ( 'PARTNERO_API_KEY' ),
'Content-Type: application/json' ,
],
CURLOPT_POSTFIELDS => json_encode ([
'customer' => [ 'key' => $user -> id ],
'key' => $order -> id ,
'amount' => $order -> amount ,
'action' => 'sale' ,
]),
]);
curl_exec ( $ch );
curl_close ( $ch );
import os
import requests
requests.post(
"https://api.partnero.com/v1/transactions" ,
headers = {
"Authorization" : f "Bearer { os.environ[ 'PARTNERO_API_KEY' ] } " ,
"Content-Type" : "application/json" ,
},
json = {
"customer" : { "key" : user.id},
"key" : order.id,
"amount" : order.amount,
"action" : "sale" ,
},
)
Using Stripe, Paddle, or Chargebee? Connect them in Program settings → Integrations and Partnero will create transactions automatically—you can skip Step 3.
When you cannot persist the landing click
If storing the referral key between landing and sign-up is impractical (e.g., podcast or video referrals), use attribution that doesn’t depend on a remembered visit:
Comparison
Method Cookies Affected by ad-blockers / ITP Best for Server-to-server (this guide) None No Backends, mobile, strict privacy PartneroJS Yes (partnero_partner, partnero_referral) Yes Standard web sites with frontend JS Coupon-based None No Influencers, podcasts, offline channels Transaction-based None No Per-payment attribution via metadata
Checklist
Confirm your program’s referral link URL format and query parameter in the Partnero dashboard.
Persist the referral key with your session or storage between landing and sign-up.
Call POST /v1/customers from your server with partner or referring_customer.
Call POST /v1/transactions (or let a billing integration do it) using the same customer key.
Next steps
Affiliate API Cookie-based variant and full customer / transaction fields
Refer-a-friend API Referrer fields, rewards, and dashboard API calls
Mobile apps Deep links and native storage patterns
API reference Full REST API documentation