Developer docs
Get an API keyIotaBot WhatsApp API
Send and receive WhatsApp messages from your code — on every number you connected.
Send WhatsApp messages with PHP
Send with cURL, receive with a plain PHP endpoint — no framework needed.
- Create an API key (a test key never sends) and a webhook endpoint in Developers.
- Set
IOTABOT_API_KEYandIOTABOT_WEBHOOK_SECRET(the endpoint'swhsec_…secret) in your environment. - Run the program below. Point the endpoint at
/iotabot/webhookon your server.
iotabot.php
<?php
// iotabot.php — one function for every send.
const API = 'https://api.iotabot.com/v1';
function iotabot_send(array $body): array {
$ch = curl_init(API . '/messages');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('IOTABOT_API_KEY'),
'Content-Type: application/json',
// One Idempotency-Key per message: reuse it if you retry, so it is never sent twice.
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => json_encode($body),
]);
$res = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status >= 300) throw new RuntimeException($res['error']['code'] . ': ' . $res['error']['message']);
return $res['data'];
}
send.php
<?php
// send.php — start a conversation with an approved template (works for any number, any time).
require __DIR__ . '/iotabot.php';
$sent = iotabot_send([
'channel' => 'whatsapp',
'to' => '+919812345678',
'template' => ['name' => 'order_update', 'language' => 'en_US', 'parameters' => ['#1042', 'Friday']],
]);
echo "queued {$sent['id']} in conversation {$sent['conversation_id']}\n";
webhook.php
<?php
// webhook.php — receive messages and reply within the 24-hour window.
require __DIR__ . '/iotabot.php';
function iotabot_verified(string $raw, string $header, string $secret): bool {
$t = 0; $sigs = [];
foreach (explode(',', $header) as $part) {
[$k, $v] = array_pad(explode('=', $part, 2), 2, '');
if ($k === 't') $t = (int) $v;
if ($k === 'v1') $sigs[] = $v;
}
if (abs(time() - $t) > 300) return false; // older than 5 minutes
$expected = hash_hmac('sha256', $t . '.' . $raw, $secret);
foreach ($sigs as $sig) if (hash_equals($expected, $sig)) return true;
return false;
}
$raw = file_get_contents('php://input');
$event = json_decode($raw, true);
if ($event['type'] === 'endpoint.verification') { // sent once, when you add the endpoint
header('Content-Type: application/json');
echo json_encode(['challenge' => $event['data']['challenge']]);
exit;
}
if (!iotabot_verified($raw, $_SERVER['HTTP_IOTABOT_SIGNATURE'] ?? '', getenv('IOTABOT_WEBHOOK_SECRET'))) {
http_response_code(401);
exit;
}
if ($event['type'] === 'message.received') {
$conversation = $event['data']['conversation'];
error_log($conversation['contact']['phone'] . ' wrote: ' . $event['data']['message']['text']);
iotabot_send(['conversation_id' => $conversation['id'], 'text' => 'Thanks — we are on it!']);
}
http_response_code(200);
