Send WhatsApp notifications from your app
Order confirmations, shipping updates, status alerts and reminders, sent from your own number.
Add a ‘Get updates on WhatsApp’ link at checkout — the customer writes first, and every update after that goes to someone you already talk to.
$10 per number / month · No per-message fees · Cancel anytime
No template approval · Your own number
<?php
$instanceId = 123;
$apiToken = 'your-api-token';
$ch = curl_init("https://waapi.app/api/v1/instances/{$instanceId}/client/action/send-message");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'authorization: Bearer ' . $apiToken,
'content-type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'chatId' => '[email protected]',
'message' => 'Good news, Anna! Your order #1042 has shipped.
Track it here: https://example.com/track/1042',
]),
]);
echo curl_exec($ch);
curl --request POST \
--url https://waapi.app/api/v1/instances/123/client/action/send-message \
--header 'authorization: Bearer your-api-token' \
--header 'content-type: application/json' \
--data '{
"chatId": "[email protected]",
"message": "Good news, Anna! Your order #1042 has shipped.\nTrack it here: https://example.com/track/1042"
}'
import requests
instance_id = 123
api_token = "your-api-token"
response = requests.post(
f"https://waapi.app/api/v1/instances/{instance_id}/client/action/send-message",
headers={"authorization": f"Bearer {api_token}"},
json={
"chatId": "[email protected]",
"message": "Good news, Anna! Your order #1042 has shipped.\nTrack it here: https://example.com/track/1042",
},
)
print(response.json())
const instanceId = 123;
const apiToken = 'your-api-token';
fetch(`https://waapi.app/api/v1/instances/${instanceId}/client/action/send-message`, {
method: 'POST',
headers: {
authorization: `Bearer ${apiToken}`,
'content-type': 'application/json',
},
body: JSON.stringify({
"chatId": "[email protected]",
"message": "Good news, Anna! Your order #1042 has shipped.\nTrack it here: https://example.com/track/1042",
}),
})
.then((res) => res.json())
.then(console.log);
What you can send
The messages your customers actually wait for
Orders and shipping
Confirm the order, send the tracking link when it ships, say when it’s out for delivery.
Appointment reminders
A reminder the day before cuts no-shows, and the reply lands in your system by webhook.
Payments and invoices
Payment received, payment failed, or the invoice itself as a PDF attached to the message.
Monitoring alerts
Host down, disk full, job failed — straight to the phone of whoever is on call.
Checkmk pluginAlerts to a team group
Post to a group instead of a person, so the whole team sees a new lead or a failed deploy.
Updates in a channel
Release notes, status updates or opening hours to everyone following your channel.
Sending login or verification codes? Let the user write first — see the OTP page.
Example
“Your order has shipped”
Call this from the place in your code where the order status changes. The message is plain text, so you write it exactly as you want it — no template, no placeholder syntax, no review.
Want to attach the invoice? The send-media action takes a PDF by URL with a caption.
curl --request POST \
--url https://waapi.app/api/v1/instances/123/client/action/send-message \
--header 'authorization: Bearer your-api-token' \
--header 'content-type: application/json' \
--data '{
"chatId": "[email protected]",
"message": "Good news, Anna! Your order #1042 has shipped.\nTrack it here: https://example.com/track/1042"
}'
<?php
$instanceId = 123;
$apiToken = 'your-api-token';
$ch = curl_init("https://waapi.app/api/v1/instances/{$instanceId}/client/action/send-message");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'authorization: Bearer ' . $apiToken,
'content-type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'chatId' => '[email protected]',
'message' => 'Good news, Anna! Your order #1042 has shipped.
Track it here: https://example.com/track/1042',
]),
]);
echo curl_exec($ch);
import requests
instance_id = 123
api_token = "your-api-token"
response = requests.post(
f"https://waapi.app/api/v1/instances/{instance_id}/client/action/send-message",
headers={"authorization": f"Bearer {api_token}"},
json={
"chatId": "[email protected]",
"message": "Good news, Anna! Your order #1042 has shipped.\nTrack it here: https://example.com/track/1042",
},
)
print(response.json())
const instanceId = 123;
const apiToken = 'your-api-token';
fetch(`https://waapi.app/api/v1/instances/${instanceId}/client/action/send-message`, {
method: 'POST',
headers: {
authorization: `Bearer ${apiToken}`,
'content-type': 'application/json',
},
body: JSON.stringify({
"chatId": "[email protected]",
"message": "Good news, Anna! Your order #1042 has shipped.\nTrack it here: https://example.com/track/1042",
}),
})
.then((res) => res.json())
.then(console.log);
Integrations
Trigger it from your stack
Not writing the HTTP call yourself? These send the same message.
Laravel
Send from an event listener or a queued job with the Laravel package.
n8n
Fire a message from any n8n workflow trigger, no code.
Zapier
Early access by invite, or Webhooks by Zapier today.
Checkmk
Open-source notification plugin for host and service alerts.
WispHub
Payment reminders and service notices for ISPs, from WispHub's gateway form.
How it works
Four steps, one of them is your code
-
1
Link your number
Scan the QR code of a new instance with the phone that runs your business number.
-
2
Copy your token
Create an API token in your account and keep it with your other secrets.
-
3
Call the API on an event
Order paid, parcel shipped, server down: your system calls send-message.
-
4
Get replies by webhook
Answers and delivery updates are posted to your webhook URL as JSON.
Cost
A flat rate instead of a fee per notification
On Meta’s Cloud API
Each notification is a paid template message, priced by category and by the recipient’s country. Since 1 October 2026 replies inside the 24-hour window are billed too. More orders, more invoices.
As of October 2026. Source: Meta, pricing for non-template messages.
On WaAPI
$10 a month per connected number. The tenth notification costs the same as the ten-thousandth: nothing extra.
Where the break-even sits for your volume: per-message vs. flat-rate pricing, worked through.
Limits
Limits and sending safely
There is no cap on how many messages you send. In our experience, what gets numbers restricted is contacting many people who never wrote to you — so send protection is on by default for every new number.
Notifications to people you already talk to are not new conversations: a customer who has written to your number, or whom you messaged in the last 7 days, doesn’t count. The first message to someone who never wrote to you does.
What counts as a new conversation: a person who has never written to your number and whom you have not messaged in the last 7 days. Replies to people who wrote to you first and messages to groups and channels never count, and a follow-up within those 7 days doesn’t count twice.
Need more? Spread new contacts across several numbers, or switch send protection off for a number after confirming the warning — at your own risk.
Flat rate, simple
No message quota and no per-message fees; new contacts are paced by send protection. Media, groups, channels, SDKs and MCP included. Cancel anytime.
- No per-message fees
- No per-user fees
- No setup fee
- Cancel anytime
See why our customers are excited
Trusted by developers worldwide to elevate their apps
Overall we are very happy with the reliability and general service.
Dan M.
CTO
Good and affordable. Uptime is good compared to similar services.
Ranjid E.
CEO
Great tool to send marketing campaigns, would recommend for anyone in need of a reliable service.
Daniel M.
Senior Backend Developer
Notification FAQ
Templates, consent, cost and replies.
-
No. You send plain messages with the text you choose, from the first day. There are no message templates to submit and wait for.
-
Yes, but each one counts as a new conversation, and send protection allows 60 of those a day per number by default. Only message people who asked for it — an opt-in at checkout is the usual way.
-
Nothing on top of the subscription. You pay a flat monthly price per connected number, however many notifications you send.
-
Yes. Use the group’s id (ending in @g.us) as the chat id. Messages to groups and channels never count as new conversations.
-
Through your webhook. Incoming replies arrive as JSON, and so do the delivery and read updates of the messages you sent.
-
Your own business or personal number — the one you linked to the instance.
Send the first notification today
Test free for 3 days · No credit card.