Module Settings and Calls
The six endpoints covering one module's settings, test, methods and records.
Overview
This article gathers the endpoints reaching inside a single module: reading and writing its settings, testing its connection, calling its own methods and seeing the records it keeps.
There are two ways to write settings and the difference matters. The settings endpoint follows the road the panel saves by, so the module's filters, validation and hooks all run. The configuration endpoint writes straight to the file.
Secrets never leave the server. Every password-like value comes back as a mask, and sending that same mask back means "leave this field alone".
Reference
Reading the Raw Configuration
Returns a module's settings on disk as they stand.
curl 'https://panel.example.com/api/v1/admin/modules/mail/Mailjet/config' \
-H "Authorization: Bearer $API_KEY"const res = await fetch(`https://panel.example.com/api/v1/admin/modules/${group}/${key}/config`, {
headers: { Authorization: `Bearer ${apiKey}` },
});
const { data } = await res.json();
const masked = Object.entries(data.settings).filter(([, v]) => v === '**********');$ch = curl_init('https://panel.example.com/api/v1/admin/modules/' . $group . '/' . $key . '/config');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Secrets come back MASKED: this output is NOT a backup, and the keys do not travel to another installation.
$cfg = Api::Modules()->GetModuleConfig(['group' => $group, 'module' => $key])['data'];Writing the Raw Configuration
Merges the keys you send into the module's settings file.
curl -X PUT 'https://panel.example.com/api/v1/admin/modules/mail/Mailjet/config' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"settings":{"from_name":"Support"}}'const res = await fetch(`https://panel.example.com/api/v1/admin/modules/${group}/${key}/config`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ settings: { from_name: 'Support' } }),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/modules/' . $group . '/' . $key . '/config');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['settings' => ['from_name' => 'Support']]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// This endpoint writes STRAIGHT to the file: the module's own validation and hooks DO NOT run.
// Pick the settings endpoint for daily work; this one is for recovery and migration.
Api::Modules()->SaveModuleConfig([
'group' => $group, 'module' => $key, 'settings' => ['from_name' => 'Support'],
]);Saving the Settings
Saves the settings through the module's own validation.
curl -X PUT 'https://panel.example.com/api/v1/admin/modules/payment/Stripe/settings' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"settings":{"api_key":"sk_live_123"},"commission_rate":"2.5"}'const res = await fetch(`https://panel.example.com/api/v1/admin/modules/${group}/${key}/settings`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
settings: { api_key: 'sk_live_123' },
commission_rate: '2.5',
}),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/modules/' . $group . '/' . $key . '/settings');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['settings' => ['api_key' => $liveKey]]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The same road the panel saves by: the module's filters, validation and hooks DO run.
Api::Modules()->UpdateModuleSettings([
'group' => 'payment', 'module' => 'Stripe',
'settings' => ['api_key' => $liveKey], 'commission_rate' => '2.5',
]);Testing the Connection
Tries whether the module reaches the service behind it.
curl -X POST 'https://panel.example.com/api/v1/admin/modules/payment/Stripe/test-connection' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"settings":{"api_key":"sk_test_123"}}'const res = await fetch(`https://panel.example.com/api/v1/admin/modules/${group}/${key}/test-connection`, {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ settings: { api_key: candidate } }),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/modules/' . $group . '/' . $key . '/test-connection');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['settings' => ['api_key' => $candidate]]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The test SAVES NOTHING: try a new key here first and write it with the settings endpoint when it passes.
$out = Api::Modules()->TestModuleConnection([
'group' => $group, 'module' => $key, 'settings' => ['api_key' => $candidate],
])['data'];
if ($out['connected']) Api::Modules()->UpdateModuleSettings([
'group' => $group, 'module' => $key, 'settings' => ['api_key' => $candidate],
]);Running a Module Method
Calls a module's own panel method and returns what it gives.
curl -X POST 'https://panel.example.com/api/v1/admin/modules/product/SampleProduct/methods/crud-list' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"page":1}'const res = await fetch(`https://panel.example.com/api/v1/admin/modules/${group}/${key}/methods/${method}`, {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ page: 1 }),
});
const { data } = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/modules/' . $group . '/' . $key . '/methods/' . $method);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['page' => 1]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The result can be the PANEL's own output; its shape is the module's choice and not an API contract.
$out = Api::Modules()->RunModuleMethod([
'group' => $group, 'module' => $key, 'method' => $method, 'page' => 1,
])['data'];
$isMarkup = is_string($out['result']);Reading the Fraud Records
Returns what a fraud module flagged.
curl 'https://panel.example.com/api/v1/admin/modules/fraud/MaxMind/records?limit=50' \
-H "Authorization: Bearer $API_KEY"const res = await fetch(`https://panel.example.com/api/v1/admin/modules/fraud/${key}/records`, {
headers: { Authorization: `Bearer ${apiKey}` },
});
const { data, meta } = await res.json();
const flagged = new Set(data.map((r) => r.user_id));$ch = curl_init('https://panel.example.com/api/v1/admin/modules/fraud/' . $key . '/records');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Keeping records is the module's choice: calling without seeing it in the capabilities gives 422.
$m = Api::Modules()->GetModule(['group' => 'fraud', 'module' => $key])['data'];
if ($m['capabilities']['has_records'])
$rows = Api::Modules()->GetFraudRecords(['group' => 'fraud', 'module' => $key])['data'];Pitfalls
The configuration endpoint writes settings straight to the file: the module's field filters, checks and save hooks never run. A value that is not valid goes in without an error and breaks on first real use. Pick the settings endpoint for daily work; the configuration one is for recovery and migration.
The read endpoints return secret-looking values as a mask and never give the real one. Exporting a module's configuration and moving it to another installation carries no keys; the fields fill with masks there and the module fails. Move the secrets separately.
The connection test uses the settings you send for that call alone and writes nothing even when it passes. Testing a new key and forgetting to save means the configuration you saw working never existed. Write it with the settings endpoint afterwards.
The method endpoint calls the module's panel method and hands the result over as it stands. That result can be an object or the markup the panel would show. The module decides the shape and a version can change it, so do not build an integration that parses it.
The records endpoint answers not_supported outside the fraud group, and not every module in that group keeps records either. Look at the capabilities in the module detail before calling: when it is absent there the endpoint gives an error rather than an empty list.
Related Articles
Vielen Dank für Ihre Rückmeldung!
Unser Support-Team ist rund um die Uhr für Sie da, wenn Sie oben nicht fündig werden.