Reminders API
Create reminder API
Create a recurring WhatsApp message that is sent automatically on a schedule. Use it for payment reminders, weekly check-ins, daily follow-ups and other messages that repeat.
https://wbiztool.com/api/v1/reminder/create/Body: JSON or form fields
You describe the schedule with a cron expression and a timezone. Each time the schedule matches, Wbiztool queues a message to the phone number or group, just like a message sent with Send message. Reminders you create here also appear on the Reminders page in your dashboard, where you can pause or edit them.
Quick example#
curl -X POST https://wbiztool.com/api/v1/reminder/create/ \
-H "Content-Type: application/json" \
-d '{
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"whatsapp_client": 678,
"reminder_name": "Monthly rent reminder",
"phone": "919876543210",
"message": "Hi Aman, a reminder that your rent is due on {current_date_formatted}.",
"cron_expression": "0 10 1 * *",
"timezone": "Asia/Kolkata"
}'import requests
response = requests.post(
"https://wbiztool.com/api/v1/reminder/create/",
json={
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"whatsapp_client": 678,
"reminder_name": "Monthly rent reminder",
"phone": "919876543210",
"message": "Hi Aman, a reminder that your rent is due on {current_date_formatted}.",
"cron_expression": "0 10 1 * *",
"timezone": "Asia/Kolkata",
},
timeout=60,
)
try:
result = response.json() # read the body even when the HTTP code is 400
except ValueError:
raise SystemExit(f"HTTP {response.status_code}: not JSON. Check that your api_key exists.")
if result["status"] == 1:
print("Reminder created with reminder_id", result["reminder_id"])
else:
print("Failed:", result["message"])// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const response = await fetch("https://wbiztool.com/api/v1/reminder/create/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
client_id: 12345,
api_key: "YOUR_API_KEY",
whatsapp_client: 678,
reminder_name: "Monthly rent reminder",
phone: "919876543210",
message: "Hi Aman, a reminder that your rent is due on {current_date_formatted}.",
cron_expression: "0 10 1 * *",
timezone: "Asia/Kolkata",
}),
});
// Read the body even when the HTTP code is 400. A non-JSON reply means the api_key wasn't found.
const text = await response.text();
let result;
try {
result = JSON.parse(text);
} catch {
throw new Error(`HTTP ${response.status}: not JSON. Check that your api_key exists.`);
}
if (result.status === 1) {
console.log("Reminder created with reminder_id", result.reminder_id);
} else {
console.error("Failed:", result.message);
}<?php
$payload = [
'client_id' => 12345,
'api_key' => 'YOUR_API_KEY',
'whatsapp_client' => 678,
'reminder_name' => 'Monthly rent reminder',
'phone' => '919876543210',
'message' => 'Hi Aman, a reminder that your rent is due on {current_date_formatted}.',
'cron_expression' => '0 10 1 * *',
'timezone' => 'Asia/Kolkata',
];
$ch = curl_init('https://wbiztool.com/api/v1/reminder/create/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 60,
]);
$result = json_decode(curl_exec($ch), true);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($result === null) {
echo "HTTP $httpCode: not JSON. Check that your api_key exists.";
} elseif ($result['status'] === 1) {
echo 'Reminder created with reminder_id ' . $result['reminder_id'];
} else {
echo 'Failed: ' . $result['message'];
}This reminder is sent at 10:00 India time on the 1st of every month. Replace 12345, YOUR_API_KEY and 678 with your own values. See Authentication for where to find them.
Request parameters#
Send the parameters as a JSON body or as form fields. In JSON, send every text value (api_key, reminder_name, phone, message, cron_expression, timezone, img_url, file_name) as a string.
Authentication
client_idintegerrequiredYour API Client ID from Settings → API keys.
api_keystringrequiredYour API key from the same page.
Sender
whatsapp_clientintegeroptionalID of the WhatsApp number to send from, from WhatsApp settings. If you leave it out, or the ID isn't in your workspace, each reminder is sent from the first connected number in your workspace at the time it runs.
Reminder
reminder_namestringrequiredA name for the reminder, shown on the Reminders page and available in the message as
{reminder_name}.phonestringrequiredThe recipient's WhatsApp number with its country code, for example
919876543210. There's no separatecountry_codeparameter. Spaces,+,-,.and brackets are removed, and a leading0is removed (up to two leading zeros in a JSON body). A value that isn't all digits is treated as a WhatsApp group name.messagestringrequiredThe message text. It can include template variables that are filled in each time the reminder runs. WhatsApp formatting works:
*bold*,_italic_,~strikethrough~.cron_expressionstringrequiredWhen to send, as a five-field cron expression such as
0 9 * * 1-5. See Cron expressions.timezonestringoptionalThe timezone the cron expression runs in, as an IANA timezone name such as
Asia/Kolkata,America/New_YorkorEurope/London. Leave it out to useUTC. An empty string returnsInvalid timezone. See the Timezone reference for the full list.
Images and files
msg_typeintegeroptional0text (default),1image or2file, withmessageas the caption. Any other value is treated as0.img_urlstringRequired when msg_type is 1 or 2Public
httporhttpsURL of the image, or of the file formsg_type2, up to 1,000 characters. It's downloaded each time the reminder runs, so keep the link working. You can host files with the Upload media API.file_namestringRequired when msg_type is 2For
msg_type2, the file's name with its extension, up to 100 characters, for exampleinvoice.pdf. Ignored for other message types.
Cron expressions#
A cron expression is five values separated by spaces. The reminder runs whenever the current time in timezone matches all five:
┌───────── minute (0-59)
│ ┌─────── hour (0-23)
│ │ ┌───── day of month (1-31)
│ │ │ ┌─── month (1-12)
│ │ │ │ ┌─ day of week (0-7, where 0 and 7 are Sunday)
│ │ │ │ │
0 9 * * 1-5
| Symbol | Meaning | Example |
|---|---|---|
* | Every value | * in the hour field means every hour. |
, | A list of values | 9,18 in the hour field means 9:00 and 18:00. |
- | A range | 1-5 in the day-of-week field means Monday to Friday. |
/ | A step | */6 in the hour field means every 6 hours. |
Common examples#
| Expression | Runs |
|---|---|
0 9 * * * | Every day at 9:00 |
0 9 * * 1-5 | Monday to Friday at 9:00 |
0 9 * * 1 | Every Monday at 9:00 |
30 18 * * 0 | Every Sunday at 18:30 |
0 9,18 * * * | Every day at 9:00 and 18:00 |
0 */6 * * * | Every 6 hours, on the hour |
*/30 9-17 * * 1-5 | Every 30 minutes from 9:00 to 17:30, Monday to Friday |
0 9 1 * * | The 1st of every month at 9:00 |
0 10 15 * * | The 15th of every month at 10:00 |
0 8 1 1 * | Every 1 January at 8:00 |
Times are in the reminder's timezone. Use five fields only: don't add a seconds field or shortcuts such as @daily.
Template variables#
These placeholders in message are replaced each time the reminder runs. Dates and times are in the reminder's timezone.
| Variable | Replaced with | Example |
|---|---|---|
{current_date} | Date | 2026-10-01 |
{current_date_formatted} | Date in words, day padded with a zero | October 01, 2026 |
{current_time} | 24-hour time | 09:00:00 |
{current_time_12h} | 12-hour time | 09:00 AM |
{current_datetime} | Date and time | 2026-10-01 09:00:00 |
{timezone} | The timezone value | Asia/Kolkata |
{timezone_short} | Timezone abbreviation | IST |
{reminder_name} | The reminder_name value | Monthly rent reminder |
{to_number} | The saved phone value | 919876543210 |
{client_name} | Name of the workspace owner | |
{organisation_name} | Name of your workspace |
Image reminder#
curl -X POST https://wbiztool.com/api/v1/reminder/create/ \
-H "Content-Type: application/json" \
-d '{
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"whatsapp_client": 678,
"reminder_name": "Weekly class timetable",
"phone": "919876543210",
"msg_type": 1,
"img_url": "https://example.com/timetable.png",
"message": "Here is this week'\''s timetable.",
"cron_expression": "0 8 * * 1",
"timezone": "Asia/Kolkata"
}'import requests
response = requests.post(
"https://wbiztool.com/api/v1/reminder/create/",
json={
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"whatsapp_client": 678,
"reminder_name": "Weekly class timetable",
"phone": "919876543210",
"msg_type": 1,
"img_url": "https://example.com/timetable.png",
"message": "Here is this week's timetable.",
"cron_expression": "0 8 * * 1",
"timezone": "Asia/Kolkata",
},
timeout=60,
)
print(response.status_code, response.text)// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const response = await fetch("https://wbiztool.com/api/v1/reminder/create/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
client_id: 12345,
api_key: "YOUR_API_KEY",
whatsapp_client: 678,
reminder_name: "Weekly class timetable",
phone: "919876543210",
msg_type: 1,
img_url: "https://example.com/timetable.png",
message: "Here is this week's timetable.",
cron_expression: "0 8 * * 1",
timezone: "Asia/Kolkata",
}),
});
console.log(response.status, await response.text());<?php
$ch = curl_init('https://wbiztool.com/api/v1/reminder/create/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query([
'client_id' => 12345,
'api_key' => 'YOUR_API_KEY',
'whatsapp_client' => 678,
'reminder_name' => 'Weekly class timetable',
'phone' => '919876543210',
'msg_type' => 1,
'img_url' => 'https://example.com/timetable.png',
'message' => "Here is this week's timetable.",
'cron_expression' => '0 8 * * 1',
'timezone' => 'Asia/Kolkata',
]),
CURLOPT_RETURNTRANSFER => true,
]);
echo curl_exec($ch);
curl_close($ch);The PHP example sends form fields instead of JSON. Both work.
Response#
A successful request returns HTTP 200:
{
"reminder_id": 3187,
"message": "Reminder created successfully",
"status": 1
}
| Field | Type | Description |
|---|---|---|
status | integer | 1 if the reminder was created, 0 if the request failed. |
message | string | Reminder created successfully, otherwise the error. |
reminder_id | integer | ID of the new reminder. Save it to cancel the reminder later. Only present on success. |
New reminders are active straight away.
Errors#
Errors return HTTP 400 with status set to 0, unless noted:
{ "status": 0, "message": "Invalid timezone" }
| Message | How to fix it |
|---|---|
Invalid JSON format: … | The JSON body isn't valid, often because of a trailing comma or an unescaped line break in message. Use \n for new lines. You also get this for a form request without client_id, or for any GET request. |
Invalid client id. | Send client_id as a number. |
Reminder name cannot be null | Add reminder_name. |
Phone number cannot be null | Add phone. |
Message template cannot be null | Add message. |
Cron expression cannot be null | Add cron_expression. |
Auth Error - Please send correct API key and Client id | Send a non-empty api_key. |
Invalid cron expression | Check the expression has five valid fields. See Cron expressions. |
Invalid timezone | Use an IANA name such as Asia/Kolkata, not an abbreviation such as IST. |
Image URL cannot be null for image messages | For msg_type 1, send img_url. |
File URL cannot be null for file messages | For msg_type 2, send file_name. |
Auth Error: invalid api key | The key belongs to a different client_id. |
Auth Error: please check client id | The key isn't linked to a workspace. Create a new key in the workspace you want to use. |
Demo Account cannot access APIs | Use a regular account. |
Not enough credits | Your plan has no messages left. |
Upgrade your plan to use reminders feature | Your plan doesn't include reminders. Upgrade your plan. |
WhatsApp Logged Out. Please Reconnect!! | The whatsapp_client number is disconnected. Reconnect it in WhatsApp settings. |
Invalid WhatsApp client id | Send whatsapp_client as a number. |
Error creating reminder: … (HTTP 500) | The reminder couldn't be saved. Check the values you sent, for example that img_url is 1,000 characters or fewer and file_name is 100 or fewer. |
How reminders run#
- The schedule is checked in the reminder's
timezone, and the message is queued when the current time matches the cron expression. - Each run creates a normal message that is sent from your WhatsApp number, so the number must stay connected.
- A run is skipped if your workspace has no credits left, or if no
whatsapp_clientwas set and no number in your workspace is connected at that moment. - If
whatsapp_clientis set, each run is queued on that number even if it has been disconnected since, and waits there. There's no fallback to another number. - Reminders are checked periodically, not to the second, and the message then waits in the sending queue like any other. Don't rely on exact timing. If a check runs late, the run is still sent up to 10 minutes late (up to 1 minute late for a reminder's first run); after that it's skipped. The same run is never sent twice.
Tips#
- List and clean up: get your reminders and their IDs with List reminders, and stop one with Cancel reminder.
- Pausing and editing isn't available through the API. Use the Reminders page in your dashboard.
- Many reminders at once: the Reminders page can also import reminders from a CSV file.
- New lines in JSON: write them as
\ninsidemessage. A raw line break makes the JSON invalid.
