API v2 (beta)
Lembretes
Um lembrete envia a mesma mensagem a um destinatário várias e várias vezes, seguindo um agendamento: o aluguel todo mês, uma aula toda segunda-feira, um relatório toda noite. O agendamento é uma expressão cron de 5 partes em um fuso horário que você escolhe. Os lembretes criados pela API são os mesmos da página Lembretes do painel.
| Operação | Endpoint | Permissão |
|---|---|---|
| Criar um lembrete | POST /api/v2/reminders | reminders |
| Listar lembretes | GET /api/v2/reminders | reminders |
| Obter um lembrete | GET /api/v2/reminders/{id} | reminders |
| Alterar, pausar ou retomar | PATCH /api/v2/reminders/{id} | reminders |
| Excluir um lembrete | DELETE /api/v2/reminders/{id} | reminders |
Criar e alterar lembretes exige um plano que inclua lembretes; caso contrário, a resposta é 403 plan_required. Listar, ler, pausar e excluir funcionam em qualquer plano. Para uma mensagem que sai uma única vez em um horário definido, use send_at em Enviar uma mensagem.
Criar um lembrete#
https://wbiztool.com/api/v2/remindersCorpo: JSON (application/json)
curl -X POST https://wbiztool.com/api/v2/reminders \
-H "Authorization: Bearer $WBIZTOOL_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: rent-flat-4b" \
-d '{
"name": "Weekly rent",
"from": 101,
"to": { "phone": "+919876543210" },
"text": "Hi, a reminder that the rent is due on Friday.",
"schedule": { "cron": "0 9 * * 1", "timezone": "Asia/Kolkata" }
}'import os
import requests
response = requests.post(
"https://wbiztool.com/api/v2/reminders",
headers={
"Authorization": f"Bearer {os.environ['WBIZTOOL_API_KEY']}",
"Idempotency-Key": "rent-flat-4b",
},
json={
"name": "Weekly rent",
"from": 101,
"to": {"phone": "+919876543210"},
"text": "Hi, a reminder that the rent is due on Friday.",
"schedule": {"cron": "0 9 * * 1", "timezone": "Asia/Kolkata"},
},
timeout=30,
)
reminder = response.json()
print(response.status_code, reminder.get("id"), reminder.get("next_run_at"))// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const response = await fetch("https://wbiztool.com/api/v2/reminders", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.WBIZTOOL_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": "rent-flat-4b",
},
body: JSON.stringify({
name: "Weekly rent",
from: 101,
to: { phone: "+919876543210" },
text: "Hi, a reminder that the rent is due on Friday.",
schedule: { cron: "0 9 * * 1", timezone: "Asia/Kolkata" },
}),
});
const reminder = await response.json();
console.log(response.status, reminder.id, reminder.next_run_at);<?php
$ch = curl_init('https://wbiztool.com/api/v2/reminders');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WBIZTOOL_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: rent-flat-4b',
],
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Weekly rent',
'from' => 101,
'to' => ['phone' => '+919876543210'],
'text' => 'Hi, a reminder that the rent is due on Friday.',
'schedule' => ['cron' => '0 9 * * 1', 'timezone' => 'Asia/Kolkata'],
]),
CURLOPT_RETURNTRANSFER => true,
]);
$reminder = json_decode(curl_exec($ch), true);
curl_close($ch);
echo $reminder['id'] . ' next: ' . $reminder['next_run_at'];Resposta (201):
{
"id": 812,
"name": "Weekly rent",
"active": true,
"to": { "phone": "+919876543210" },
"from": 101,
"text": "Hi, a reminder that the rent is due on Friday.",
"media": null,
"schedule": { "cron": "0 9 * * 1", "timezone": "Asia/Kolkata" },
"next_run_at": "2026-10-19T09:00:00+05:30",
"created_at": "2026-10-18T10:20:11.004Z"
}
Corpo
namestringobrigatórioUm nome para o lembrete, com até 100 caracteres, como aparece na página Lembretes.
toobjectobrigatórioExatamente um entre
phone(formato internacional com+),group(o nome exato de um grupo de WhatsApp),contact_idouusername(Telegram), como em Mensagens → Destinatários.frominteger or nullObrigatório para uma chave limitada a alguns númerosO
iddo número que envia o lembrete. Ele precisa estar conectado quando você o define. Omitido ounull: qualquer número conectado do espaço de trabalho envia.textstringobrigatórioA mensagem, com até 3.000 caracteres. Também é a legenda quando
mediaé enviado.mediaobject or nullopcionalUma imagem ou um arquivo para enviar a cada vez:
urloumedia_ide, opcionalmente,type, como em Mensagens → Mídia.scheduleobjectobrigatóriocron(obrigatório) etimezone. Veja Agendamento.activebooleanopcionaltrue(padrão) ativa o lembrete;falsecria o lembrete pausado.
Agendamento#
schedule.cron tem cinco partes separadas por espaços: minuto, hora, dia do mês, mês e dia da semana. * significa "todo(a)". Precisa ser um agendamento que rode em algum momento (não 31 de fevereiro).
cron | Roda |
|---|---|
0 9 * * 1 | Às segundas-feiras às 09:00 |
30 18 * * * | Todos os dias às 18:30 |
0 10 1 * * | No dia 1º de cada mês às 10:00 |
0 9 * * 1-5 | De segunda a sexta às 09:00 |
0 8,20 * * * | Todos os dias às 08:00 e às 20:00 |
0 9 15 1 * | Em 15 de janeiro às 09:00, todo ano |
schedule.timezone é o nome de um fuso horário IANA, como Asia/Kolkata, Europe/London ou America/New_York (padrão UTC). Os horários do cron estão nesse fuso, e next_run_at também vem nele, com o deslocamento. Veja a referência de fusos horários.
Cada execução envia uma mensagem como qualquer outra: precisa de mensagens restantes no plano e aparece em Listar mensagens.
Erros ao criar#
| HTTP | Código | Quando |
|---|---|---|
400 | validation_failed | Um campo obrigatório está ausente ou vazio, um campo é desconhecido ou longo demais (name, to.group), ou media não é válido |
400 | text_required | text está vazio |
400 | text_too_long | text tem mais de 3.000 caracteres |
400 | invalid_cron | schedule.cron não tem 5 partes ou nunca roda |
400 | invalid_timezone | schedule.timezone não é um fuso horário IANA |
403 | plan_required | O plano não inclui lembretes |
403 | number_not_allowed | A chave está limitada a alguns números e from não é um deles, ou está ausente |
422 | invalid_phone | to.phone não é um número válido em formato internacional com + |
422 | invalid_username | to.username não é um nome de usuário do Telegram, um link nem um id tg: |
422 | username_needs_telegram | Um nome de usuário do Telegram, mas from não é uma conta do Telegram (ou, sem from, nenhuma conta do Telegram está conectada) |
422 | contact_not_found | Nenhum contato com esse to.contact_id |
422 | media_not_found | Nenhum arquivo com esse media.media_id |
422 | invalid_media_url | media.url não é um link público http(s) |
422 | number_not_connected | from não é um número conectado deste espaço de trabalho |
Listar lembretes#
https://wbiztool.com/api/v2/remindersOs lembretes do espaço de trabalho, do mais recente para o mais antigo, em páginas (limit de 1 a 100, padrão 25, e cursor). Os pausados estão incluídos, com "active": false. Uma chave limitada a alguns números vê apenas os lembretes enviados por eles.
curl "https://wbiztool.com/api/v2/reminders?limit=50" \
-H "Authorization: Bearer $WBIZTOOL_API_KEY"
A resposta é {"data": [Reminder, …], "next_cursor": "…" or null}.
Obter um lembrete#
https://wbiztool.com/api/v2/reminders/{id}curl https://wbiztool.com/api/v2/reminders/812 \
-H "Authorization: Bearer $WBIZTOOL_API_KEY"
Um lembrete que não existe, foi excluído ou é enviado por um número que a chave não pode usar responde 404 reminder_not_found.
Alterar, pausar ou retomar um lembrete#
https://wbiztool.com/api/v2/reminders/{id}Corpo: JSON (application/json)
Envie só os campos que mudam; os outros mantêm seus valores. Os campos são os de Criar um lembrete. A resposta é 200 com o lembrete como ele ficou.
- Pausar:
{"active": false}. Ele para de rodar enext_run_atpassa a sernull. Pausar funciona em qualquer plano. - Retomar:
{"active": true}. Ele volta a rodar a partir do próximo horário. Retomar exige um plano com lembretes. scheduleé substituído por inteiro: enviecronjunto. Semtimezone, o lembrete mantém o fuso atual.
# Pause
curl -X PATCH https://wbiztool.com/api/v2/reminders/812 \
-H "Authorization: Bearer $WBIZTOOL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"active": false}'
# Move it to Fridays at 10:00 and change the text
curl -X PATCH https://wbiztool.com/api/v2/reminders/812 \
-H "Authorization: Bearer $WBIZTOOL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"schedule": {"cron": "0 10 * * 5"}, "text": "Hi, the rent is due today."}'import os
import requests
headers = {"Authorization": f"Bearer {os.environ['WBIZTOOL_API_KEY']}"}
url = "https://wbiztool.com/api/v2/reminders/812"
paused = requests.patch(url, headers=headers, json={"active": False}, timeout=30).json()
print(paused["active"], paused["next_run_at"]) # False None
resumed = requests.patch(url, headers=headers, json={"active": True}, timeout=30).json()
print(resumed["active"], resumed["next_run_at"])// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const response = await fetch("https://wbiztool.com/api/v2/reminders/812", {
method: "PATCH",
headers: { Authorization: `Bearer ${process.env.WBIZTOOL_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ active: false }),
});
const reminder = await response.json();
console.log(reminder.active, reminder.next_run_at); // false null<?php
$ch = curl_init('https://wbiztool.com/api/v2/reminders/812');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('WBIZTOOL_API_KEY'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode(['active' => false]),
CURLOPT_RETURNTRANSFER => true,
]);
$reminder = json_decode(curl_exec($ch), true);
curl_close($ch);
var_dump($reminder['active']);Uma alteração responde com os mesmos erros da criação, e com 404 reminder_not_found. Se um campo estiver errado, nada é alterado.
Excluir um lembrete#
https://wbiztool.com/api/v2/reminders/{id}Exclui o lembrete: ele nunca mais roda. As mensagens que ele já enviou continuam no histórico. Para interrompê-lo só por um tempo, pause-o.
curl -X DELETE https://wbiztool.com/api/v2/reminders/812 \
-H "Authorization: Bearer $WBIZTOOL_API_KEY"
{ "id": 812, "deleted": true }
O objeto Reminder#
| Campo | Tipo | Descrição |
|---|---|---|
id | integer | O id do lembrete. |
name | string | O nome dele. |
active | boolean | true enquanto roda, false enquanto está pausado. |
to | object | O destinatário: phone (com +), group ou username. Um lembrete criado com contact_id mostra o número ou o grupo do contato. |
from | integer or null | O id do número que envia, ou null para qualquer número conectado. |
text | string | A mensagem. |
media | object or null | type (image ou file), url e file_name. |
schedule | object | cron e timezone. |
next_run_at | string or null | Quando ele roda da próxima vez, no fuso horário dele com o deslocamento, como 2026-10-19T09:00:00+05:30. null enquanto está pausado. |
created_at | string | Quando foi criado (UTC). |
Relacionados#
- Lembretes no painel
- Referência de fusos horários
- Mensagens: uma mensagem em um horário definido com
send_at - Erros
