In short: link your WhatsApp number to a TextBot key, then call https://api.textbot.cc/send.php with the recipient, your key and the text. Use /api/send with JSON for files, and give the key a webhook address to receive replies.
Before you start
- Get a key. Create an account on the pricing page; your first API key is ready when the payment clears.
- Link your number. Open the key in your portal, choose Connect WhatsApp and scan the QR code with the phone that holds the number, or use a pairing code.
- Copy the key. It goes in the
apikeyparameter of each request.
Send a text
One GET request with the number, your key and the text. Add json=yes to get the answer as JSON.
<?php
// Send a WhatsApp text from your own number.
$query = http_build_query([
'recipient' => '27825550199', // international format, no leading 0
'apikey' => 'YOUR_KEY',
'text' => 'Your order #1042 has shipped.',
'json' => 'yes', // answer in JSON
]);
$answer = json_decode(file_get_contents('https://api.textbot.cc/send.php?' . $query), true);
echo $answer['status'] ?? 'no answer'; // "success" when it was sent
echo ' ', $answer['comment'] ?? ''; // what happened, in words
Send a PDF or an image
POST JSON to /api/send with a public link to the file in file. The text becomes its caption.
<?php
// Send a PDF with a caption: POST JSON to /api/send.
$payload = json_encode([
'recipient' => '+27825550199',
'apikey' => 'YOUR_KEY',
'text' => 'Your invoice is attached.',
'file' => 'https://example.com/invoices/1042.pdf',
]);
$ch = curl_init('https://api.textbot.cc/api/send');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => $payload,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, ' ', $body;
Ask a question with reply buttons
Add button1, button2 and so on. When the customer taps one, the reply arrives on your webhook like any other message. typing=3 shows “typing…” for three seconds before the message arrives; typing=yes times it from the length of the text.
<?php
// A question with two reply buttons; the tap arrives on your webhook.
$query = http_build_query([
'recipient' => '27825550199',
'apikey' => 'YOUR_KEY',
'text' => 'Can we deliver tomorrow between 9 and 12?',
'button1' => 'Yes',
'button2' => 'Another day',
'typing' => 3, // show “typing…” for 3 seconds first
'json' => 'yes',
]);
$answer = json_decode(file_get_contents('https://api.textbot.cc/send.php?' . $query), true);
Receive replies on a webhook
Give your key a webhook address in the portal. Each incoming message, button tap and file is posted to it as JSON with the type, from, from_name, message and file.
<?php
// webhook.php: TextBot posts each incoming message here as JSON.
$event = json_decode(file_get_contents('php://input'), true);
if (!is_array($event)) {
http_response_code(400);
exit;
}
$from = $event['from'] ?? ''; // e.g. 27825550199
$name = $event['from_name'] ?? '';
$message = trim($event['message'] ?? '');
$file = $event['file'] ?? null; // a link, when they sent a file
if (strcasecmp($message, 'stop') === 0) {
// take $from off your list
}
http_response_code(200); // answer quickly; do slow work later
Good habits
- Keep the key on the server. Never put it in JavaScript or an app that customers can download.
- Send in the background. For many messages, queue them and send from a worker or cron job rather than while a page loads.
- Check the answer. A message that did not send says why, and the message log keeps the reason.
- Message people who expect it. Order updates and replies to customers, not cold lists. Our guide to linked numbers explains why.
The API reference lists all endpoints, including typing.php and the original send.php, status.php and webhook.php paths.