Reseller
The five endpoints that manage a client's reseller status and the programme's installation-wide settings.
Overview
A reseller partnership is a client buying from you at a discount and selling on to their own customers. These endpoints run two separate layers that should not be confused.
The first three look at one client: their reseller status, credit threshold and discount tiers. The last two run the programme itself: how applications are approved, whether verification is required, whether resellers get API access. Whether the path carries a client id tells you which layer you are on.
Reference
Reading the Reseller Status
Returns the client's reseller status and the settings that belong to them.
active or inactive.curl 'https://panel.example.com/api/v1/admin/clients/42/reseller' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/reseller', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
// With no reseller record the response holds a single field.
if (!body.data.is_reseller) return;$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/reseller');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);$response = Api::Clients()->GetClientReseller(['id' => 42]);
// The other fields only arrive when a record exists - read them null-safe.
$minCredit = $response['data']['min_credit']['amount'] ?? 0;{
"data": {
"is_reseller": true,
"status": "active",
"activation_time": "2026-02-01 12:00:00",
"min_credit": { "amount": 100.00, "currency_id": 840 },
"min_discount": { "amount": 50.00, "currency_id": 840 },
"only_credit_payment": false,
"discounts": {
"5": [{ "from": 1, "to": 10, "rate": 15.0 }]
}
}
}{
"data": {
"is_reseller": false
}
}Saving the Reseller Settings
Saves the reseller settings that belong to the client and switches the partnership on or off.
curl -X PATCH 'https://panel.example.com/api/v1/admin/clients/42/reseller' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"active":true,"min_credit":{"amount":100,"currency_id":840},"only_credit_payment":true}'const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/reseller', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
active: true,
min_credit: { amount: 100, currency_id: 840 },
only_credit_payment: true,
discounts: {
5: [{ from: 1, to: 10, rate: 15 }],
},
}),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/reseller');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'active' => true,
'min_credit' => ['amount' => 100, 'currency_id' => 840],
'only_credit_payment' => true,
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// While the partnership is on, a setting you omit REMOVES that limit - read the current state first.
$current = Api::Clients()->GetClientReseller(['id' => 42])['data'];
$response = Api::Clients()->UpdateClientReseller([
'id' => 42,
'active' => true,
'min_credit' => $current['min_credit'],
'min_discount' => $current['min_discount'],
'only_credit_payment' => true,
'discounts' => $current['discounts'],
]);Changing the Reseller Status
Switches an existing reseller record on or off. The settings stay as they are.
activate or terminate.action is neither of the two values.curl -X PUT 'https://panel.example.com/api/v1/admin/clients/42/reseller/status' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"action":"activate"}'const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/reseller/status', {
method: 'PUT',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ action: 'activate' }),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/reseller/status');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['action' => 'activate']),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);$response = Api::Clients()->SetClientResellerStatus([
'id' => 42,
'action' => 'activate',
]);Reading the Programme Settings
Returns the installation-wide settings of the reseller programme. It looks at no single client.
manuel or auto.curl 'https://panel.example.com/api/v1/admin/clients/reseller/config' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/clients/reseller/config', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/clients/reseller/config');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);$response = Api::Clients()->GetResellerConfig();Saving the Programme Settings
Saves the installation-wide settings of the reseller programme.
manual, automatic or auto. An unrecognised value falls back to manual approval.curl -X PUT 'https://panel.example.com/api/v1/admin/clients/reseller/config' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"enabled":true,"activation":"manual","api_access":true}'const res = await fetch('https://panel.example.com/api/v1/admin/clients/reseller/config', {
method: 'PUT',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
enabled: true,
activation: 'manual',
api_access: true,
}),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/clients/reseller/config');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'enabled' => true,
'activation' => 'manual',
'api_access' => true,
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);$response = Api::Clients()->SaveResellerConfig([
'enabled' => true,
'activation' => 'manual',
'api_access' => true,
]);Pitfalls
Saving settings while the partnership is on drops any limit you did not send; the old value is not kept. Forgetting the credit threshold while you only meant to change the payment restriction removes that threshold. Read the current settings, edit them, and send all of it back.
With no reseller record the status endpoint returns only is_reseller and the other fields are absent. Read them null-safe rather than directly, or every non-reseller client will break your code.
The quick toggle only changes an existing record; on a client without one it returns not_reseller. Opening a new partnership is the settings endpoint's job.
Related Articles
Thanks for your feedback!
Our support team is here around the clock for anything you can't find above.