Affiliate Partners
The four endpoints that see, search, switch and remove the partners in the program.
Overview
The affiliate program is where a client earns commission on the customers their own link brings in. This article manages the people in that program: who is there, who is on and who goes.
Every record carries two numbers. id belongs to the partner record and owner_id to the client behind it. The assignment endpoints speak the client number, so mixing the two makes a quiet wrong assignment.
The search endpoint sits here because it feeds the assignment screens: an interface that does not know the number types a name first, then hands the number it gets to the assignment.
Reference
Listing the Partners
Returns the partners in the program with their earnings and referral totals.
active or inactive.curl 'https://panel.example.com/api/v1/admin/affiliates?status=active&limit=50' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/affiliates?status=active', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const { data } = await res.json();
const owing = data.filter((a) => Number(a.balance) > 0);$ch = curl_init('https://panel.example.com/api/v1/admin/affiliates?status=active');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// id belongs to the PARTNER and owner_id to the CLIENT behind it; assignments speak owner_id.
$rows = Api::Affiliates()->GetAffiliates([], ['status' => 'active'])['data'];
$byClient = array_column($rows, 'balance', 'owner_id');Searching Partners, Clients and Services
The search behind the assignment screens; you type a name instead of an id.
affiliate, client or service. It looks for a partner by default.search as well.curl 'https://panel.example.com/api/v1/admin/affiliates/select?type=client&q=jane' \
-H "Authorization: Bearer $API_KEY"const url = new URL('https://panel.example.com/api/v1/admin/affiliates/select');
url.searchParams.set('type', 'client');
url.searchParams.set('q', term);
const res = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } });
const body = await res.json();$qs = http_build_query(['type' => 'client', 'q' => $term]);
$ch = curl_init('https://panel.example.com/api/v1/admin/affiliates/select?' . $qs);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// It returns 10 results at most: this is a search box and not a listing.
$hits = Api::Affiliates()->SelectForAffiliate([], ['type' => 'client', 'q' => $term])['data'];
$exact = count($hits['results']) === 1 ? $hits['results'][0]['id'] : 0;Turning a Partner On and Off
Turns a partner on or takes them out of the program.
curl -X PUT 'https://panel.example.com/api/v1/admin/affiliates/7/status' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"enabled":false}'const res = await fetch(`https://panel.example.com/api/v1/admin/affiliates/${aid}/status`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ enabled: false }),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/affiliates/' . $aid . '/status');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['enabled' => false]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Turning a partner off DOES NOT wipe the earnings: the balance stays and payouts can still be asked for.
Api::Affiliates()->SetAffiliateStatus(['aid' => $aid, 'enabled' => false]);Removing a Partner
Removes a partner along with every record tied to them.
curl -X DELETE 'https://panel.example.com/api/v1/admin/affiliates/7' \
-H "Authorization: Bearer $API_KEY"const res = await fetch(`https://panel.example.com/api/v1/admin/affiliates/${aid}`, {
method: 'DELETE',
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/affiliates/' . $aid);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The panel asks for an admin password here while the API needs the scope alone. Consider turning them off first.
Api::Affiliates()->SetAffiliateStatus(['aid' => $aid, 'enabled' => false]);
// Api::Affiliates()->DeleteAffiliate(['aid' => $aid]); // the earnings history goes as wellPitfalls
In the listing id is the partner record and owner_id the client behind it. The link kept on the client record also holds the client number rather than the partner one. Keep the two apart, since the assignment and status endpoints want different numbers.
The listing gives a disabled field where 0 means on. The status endpoint takes enabled where true means on. They are opposite names for one thing, and copying one into the other flips the state.
Removing a partner also takes the commission entries, the payout requests, the clicks, the history and the referral records, while the linked clients lose their link. The panel asks for an admin password at this step and the API settles for the scope. Turn a partner off rather than remove them when you mean to part ways.
The search endpoint is a search box and not a listing: it returns ten results at most no matter how many match, and there is no paging. Resting bulk work on it drops everything past the tenth without a word. Use the listing endpoint for the full set.
The total_paid field is the sum of completed payout requests. A waiting or in-flight request does not enter that number, and it is not taken out of balance either. Do not answer "what do we owe" by adding the two figures.
Related Articles
Thanks for your feedback!
Our support team is here around the clock for anything you can't find above.