Bulk Templates
The six endpoints that manage reusable bulk notification campaigns.
Overview
A bulk template is a campaign saved for reuse: the message, the subject, the channel and the audience filters kept together. Instead of rebuilding the same announcement each time, you write it once and store it.
A template sends nothing on its own. Sending happens on a separate endpoint, and sending one on a regular basis is what scheduled tasks are for.
Reference
Listing the Templates
Returns the saved bulk notification campaigns.
mail or sms.member for clients, staff for staff.single one each, multiple all together.curl -G 'https://panel.example.com/api/v1/admin/tools/bulk/templates' \
-H "Authorization: Bearer $API_KEY" \
-d template_type=mailconst url = new URL('https://panel.example.com/api/v1/admin/tools/bulk/templates');
url.searchParams.set('template_type', 'mail');
const res = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } });
const body = await res.json();$url = 'https://panel.example.com/api/v1/admin/tools/bulk/templates?' . http_build_query(['template_type' => 'mail']);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The list carries neither the message body nor the filters; those come on the detail only.
$templates = Api::Tools()->GetBulkTemplates([], ['template_type' => 'mail'])['data'];Template Detail
Returns a campaign with its message and its audience filters.
mail or sms.member for clients, staff for staff.single one each, multiple all together.curl 'https://panel.example.com/api/v1/admin/tools/bulk/templates/5' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/tools/bulk/templates/5', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/bulk/templates/5');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// To see how many a template would reach, hand its filters to the counting endpoint.
$tpl = Api::Tools()->GetBulkTemplate(['id' => 5])['data'];
$count = Api::Tools()->GetBulkContacts([
'user_type' => $tpl['type'] === 'staff' ? 'staff' : 'client',
'user_groups' => $tpl['user_groups'],
'countries' => $tpl['countries'],
])['data']['count'];Creating a Template
Saves a campaign to reuse. Saving sends nothing.
member.curl -X POST 'https://panel.example.com/api/v1/admin/tools/bulk/templates' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"template_name":"Welcome Campaign","template_type":"mail","type":"member","subject":"Welcome","message":"Hello!","user_groups":[1]}'const res = await fetch('https://panel.example.com/api/v1/admin/tools/bulk/templates', {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
template_name: 'Welcome Campaign',
template_type: 'mail',
type: 'member',
subject: 'Welcome',
message: 'Hello!',
user_groups: [1],
}),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/bulk/templates');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'template_name' => 'Welcome Campaign',
'subject' => 'Welcome',
'message' => $html,
'user_groups' => [1],
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Saving a template SENDS NOTHING: call the bulk submit endpoint separately to send it.
$tpl = Api::Tools()->CreateBulkTemplate([
'template_name' => 'Welcome Campaign',
'subject' => 'Welcome',
'message' => $html,
'user_groups' => [1],
])['data'];Updating a Template
Applies the fields you send; the name, the message and the subject cannot be emptied.
member.curl -X PATCH 'https://panel.example.com/api/v1/admin/tools/bulk/templates/5' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"subject":"Welcome (updated)","message":"Hi there!"}'const res = await fetch('https://panel.example.com/api/v1/admin/tools/bulk/templates/5', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
subject: 'Welcome (updated)',
message: 'Hi there!',
}),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/bulk/templates/5');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'subject' => 'Welcome (updated)',
'message' => $html,
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// If a scheduled task points at this template, the change takes effect on its NEXT run.
Api::Tools()->UpdateBulkTemplate([
'id' => 5,
'subject' => 'Welcome (updated)',
]);Deleting a Template
Deletes the campaign and the send records belonging to it.
curl -X DELETE 'https://panel.example.com/api/v1/admin/tools/bulk/templates/5' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/tools/bulk/templates/5', {
method: 'DELETE',
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/bulk/templates/5');
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 delete also removes the campaign's SEND HISTORY; when it went and to whom is lost.
Api::Tools()->DeleteBulkTemplate(['id' => 5]);Deleting in Bulk
Deletes several campaigns.
curl -X POST 'https://panel.example.com/api/v1/admin/tools/bulk/templates/bulk-delete' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"ids":[5,6,7]}'const res = await fetch('https://panel.example.com/api/v1/admin/tools/bulk/templates/bulk-delete', {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ ids: [5, 6, 7] }),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/bulk/templates/bulk-delete');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['ids' => [5, 6, 7]]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The panel asks for the admin password here; on the API the key's scope is enough.
Api::Tools()->BulkDeleteBulkTemplates(['ids' => [5, 6, 7]]);Pitfalls
Creating or updating a template sends no message; it only writes the record. Sending the campaign means calling the bulk submit endpoint separately, and sending it regularly means defining a scheduled task.
The list endpoint does not return the message body or the nine filter arrays; those come only on a single template's detail. Seeing who a campaign would reach means reading the detail and handing its filters to the counting endpoint.
Deleting a template removes not only the campaign but the send records that belong to it. Which announcement went when, and to whom, is lost. If you are merely done with a campaign, consider leaving it in place rather than deleting it.
When a scheduled task points at a template, updating it sends nothing at that moment; the new text is used on the next run. Correcting a wrong text does nothing about the sends that already went out.
The bulk delete asks for the admin password in the panel. The API has no such second step: the key's scope is enough. Hand out a key carrying this scope knowing exactly who holds it.
Related Articles
Thanks for your feedback!
Our support team is here around the clock for anything you can't find above.