Blacklist and Duplicates
The five endpoints that blacklist a client, edit the record, take them off the list, and find accounts that might be the same person.
Overview
These endpoints do two jobs together: blacklisting a client, and finding other accounts that might be the same person. They belong to one decision — someone who gets blacklisted usually comes back with a second account.
Blacklisting is more than a flag: you choose which restrictions come with it. Switch none on and the client is only marked.
Reference
Blacklist Status
Returns whether the client is blacklisted, why, and which restrictions are on.
payment_fraud · chargeback · abuse · spam · tos_violation · false_info · othercurl 'https://panel.example.com/api/v1/admin/clients/42/blacklist' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/blacklist', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/blacklist');
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()->GetClientBlacklist(['id' => 42]);
if ($response['data']['blacklisted'] ?? false) {
$reason = $response['data']['reason'];
}Blacklisting a Client
Blacklists the client and applies the restrictions you choose.
payment_fraud · chargeback · abuse · spam · tos_violation · false_info · othertrue switches it on, an explicit false switches it off.201. Same shape as the status endpoint above.gate:user.blacklist_add vetoed the operation.curl -X POST 'https://panel.example.com/api/v1/admin/clients/42/blacklist' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"reason":"chargeback","notes":"Two chargebacks","restrictions":{"block_new_orders":true,"suspend_services":true}}'const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/blacklist', {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({"reason":"chargeback","notes":"Two chargebacks","restrictions":{"block_new_orders":true,"suspend_services":true}}),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/blacklist');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'reason' => 'chargeback',
'notes' => 'Two chargebacks',
'restrictions' => [
'block_new_orders' => true,
'suspend_services' => true,
],
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);$response = Api::Clients()->CreateClientBlacklist([
'id' => 42,
'reason' => 'chargeback',
'notes' => 'Two chargebacks',
'restrictions' => [
'block_new_orders' => true,
'suspend_services' => true,
],
]);Editing a Blacklist Record
Replaces the reason, note and restrictions of a standing record. Who blacklisted the client, and when, stay as they were.
block_tickets included.suspend_services goes from on to off: reactivates the services this blacklisting suspended.200. Same shape as the status endpoint above.gate:user.blacklist_update vetoed the operation.curl -X PUT 'https://panel.example.com/api/v1/admin/clients/42/blacklist' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"reason":"tos_violation","notes":"Reviewed with legal","restrictions":{"block_new_orders":true,"block_tickets":true}}'const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/blacklist', {
method: 'PUT',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({"reason":"tos_violation","notes":"Reviewed with legal","restrictions":{"block_new_orders":true,"block_tickets":true}}),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/blacklist');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'reason' => 'tos_violation',
'notes' => 'Reviewed with legal',
'restrictions' => [
'block_new_orders' => true,
'block_tickets' => true,
],
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);$current = Api::Clients()->GetClientBlacklist(['id' => 42]);
$response = Api::Clients()->UpdateClientBlacklist([
'id' => 42,
'reason' => 'tos_violation',
'notes' => 'Reviewed with legal',
'restrictions' => $current['data']['restrictions'] ?? [],
]);Removing from the Blacklist
Removes the blacklist record and lifts the client's ticket block with it. Bringing suspended services back is a separate choice.
curl -X DELETE 'https://panel.example.com/api/v1/admin/clients/42/blacklist' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"reactivate_services":true}'const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/blacklist', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ reactivate_services: true }),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/blacklist');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['reactivate_services' => true]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);$response = Api::Clients()->DeleteClientBlacklist([
'id' => 42,
'reactivate_services' => true,
]);Duplicate Account Scan
Returns other accounts that share the client's IP, name or company name.
id, full_name, company_name, ip, created_at.ip, name, company.ip match. Empty when the account matched by name or company only.curl 'https://panel.example.com/api/v1/admin/clients/42/duplicates' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/duplicates', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
const sameIp = body.data.matches.filter((m) => m.match_types.includes('ip'));$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/duplicates');
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()->GetClientDuplicates(['id' => 42]);
foreach ($response['data']['matches'] as $match) {
// Same IP a few days apart is a stronger signal than a name match.
if (in_array('ip', $match['match_types'], true) && $match['days_apart'] < 7) {
$suspects[] = $match['id'];
}
}{
"data": {
"current": {
"id": 42,
"full_name": "John Doe",
"company_name": "",
"ip": "203.0.113.10",
"created_at": "2026-01-01 10:00:00"
},
"matches": [
{
"id": 57,
"full_name": "J. Doe",
"company_name": "",
"ip": "203.0.113.10",
"created_at": "2026-01-03 09:20:00",
"days_apart": 2,
"match_types": ["ip", "name"],
"matched_ips": ["203.0.113.10"]
}
]
}
}Pitfalls
Removing the blacklist record does not reactivate suspended services on its own. Send reactivate_services if you want them back; otherwise the client is off the list while the services stay suspended.
block_tickets here and ticket_blocked on the support settings endpoint are written together. Removing the record lifts both, and an edit that leaves block_tickets out lifts both too.
To keep the block on a client you take off the list, switch it back on with PATCH /clients/{id}/support-settings. A block set on a client who is not blacklisted stays on its own.
The same IP can be a home or an office, and the same name can be a coincidence. Read match_types together with days_apart: two accounts opened from one IP days apart is a far stronger signal than two that only share a name.
IP evidence is the stored IP plus the client's own sign-in records. Addresses staff work from are left out, including sessions opened with Sign In as Client. Read matched_ips to see which address produced a match.
Related Articles
Дякуємо за відгук!
Наша служба підтримки на зв’язку цілодобово з усього, чого ви не знайшли вище.