🎉 New users get a 1-Month Free Trial!
Developer Platform & REST APIs (Pillar 10)

Build WhatsApp Superpowers Into Your App

Full-featured REST APIs and real-time outbound webhooks for messages, native interactive Meta Flows, OTP authentication, automated e-commerce orders, and appointment scheduling.

Manage API Keys & Webhooks
Base URLhttps://waisend.com/api/external
AuthenticationBearer Token (or X-API-Key)
Data FormatJSON / RFC 8259

Live Code Snippet Customizer

Paste your API key here to automatically personalize all cURL, TypeScript, Python, and PHP examples below with your live credentials.

POST/api/external/send-message 60–300 req/min (plan-dependent)

Send Plain Text Message

Sends a direct WhatsApp text message to any customer phone number with human typing delay simulation.

Headers

Authorization: Bearer <API_KEY>
Required
Content-Type: application/json
Required

Request Body (JSON)

PropertyTypeDescription
phone*stringCustomer international phone number (E.164, digits only).
message*stringText message content (up to 4096 characters). Supports emojis & line breaks.
typingbooleanSimulate natural human typing presence before dispatching.
senderPhonestringTarget connected WhatsApp sender phone number in workspace.

Response (200 OK)

{
  "success": true,
  "data": {
    "id": "wamid.HBgMMjAxMjczMzY5ODY2FQIAEhggQUMxNjdFMkMyNjVEQTY2MTM0QkJFREZGNDhCQkE4MzUA",
    "status": "sent",
    "timestamp": 1729545000
  }
}
CURL
curl -X POST "https://waisend.com/api/external/send-message" \
  -H "Authorization: Bearer wazz_sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "201273369866",
  "message": "مرحباً بك! تم استلام طلبك بنجاح وسنقوم بالتواصل معك لتأكيد الشحن 📦",
  "typing": true
}'
HTTP Status: 200 OKRate limit: 120 req/min
POST/api/external/send-template 60–300 req/min

Send Meta Approved Template

Dispatches an official Meta-approved WhatsApp template message (reaches customers outside the 24-hour service window).

Headers

Authorization: Bearer <API_KEY>
Required
Content-Type: application/json
Required

Request Body (JSON)

PropertyTypeDescription
phone*stringRecipient phone number in E.164 format.
templateName*stringApproved Meta template name.
languageCode*stringLanguage code (e.g. ar, en, en_US).
bodyVariablesstring[]Sequential values for {{1}}, {{2}}, etc. in template body.
buttonUrlParamstringDynamic suffix for URL action button.

Response (200 OK)

{
  "success": true,
  "data": {
    "id": "wamid.HBgMMjAxMjczMzY5ODY2FQIAEhgg...",
    "template": "appointment_reminder_ar",
    "status": "accepted"
  }
}
CURL
curl -X POST "https://waisend.com/api/external/send-template" \
  -H "Authorization: Bearer wazz_sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "201273369866",
  "templateName": "appointment_reminder_ar",
  "languageCode": "ar",
  "bodyVariables": [
    "أحمد",
    "غداً 4:00 مساءً",
    "د. كريم"
  ]
}'
HTTP Status: 200 OKRate limit: 120 req/min
POST/api/external/send-flow 60–300 req/min

Send Meta WhatsApp Flow (In-App Form)

Opens a native, multi-screen interactive form directly inside WhatsApp for bookings, KYC verification, lead capture, and custom surveys.

Headers

Authorization: Bearer <API_KEY>
Required
Content-Type: application/json
Required

Request Body (JSON)

PropertyTypeDescription
phone*stringRecipient phone number.
flowId*stringMeta Flow ID from Meta WhatsApp Manager.
screenstringOpening screen ID (default SCREEN_1).
bodystringInvitation text message.
ctastringButton call to action text (max 20 chars).

Response (200 OK)

{
  "success": true,
  "data": {
    "id": "wamid.HBgM...",
    "status": "sent",
    "flowId": "1122334455667788"
  }
}
CURL
curl -X POST "https://waisend.com/api/external/send-flow" \
  -H "Authorization: Bearer wazz_sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "201273369866",
  "flowId": "1122334455667788",
  "screen": "SCREEN_1",
  "body": "يرجى استكمال بيانات تأكيد الحجز أدناه 📋",
  "cta": "فتح الاستمارة"
}'
HTTP Status: 200 OKRate limit: 120 req/min
POST/api/external/otp High-priority, protected by 5 attempts/hour phone rate limiter

Send Transactional WhatsApp OTP

Generates and delivers a cryptographically secure 6-digit one-time password via WhatsApp for login verification, password resets, and high-value orders.

Headers

Authorization: Bearer <API_KEY>
Required
Content-Type: application/json
Required

Request Body (JSON)

PropertyTypeDescription
phone*stringTarget mobile phone in international E.164 format.
lengthnumberNumber of digits (default: 6, min: 4, max: 8).
expiryMinutesnumberCode validity window in minutes (default: 5).
messageTemplatestringCustom message template. Use {code} as placeholder.

Response (200 OK)

{
  "success": true,
  "data": {
    "otpId": "otp_cmvh99x8q001",
    "phone": "201273369866",
    "expiresIn": 300,
    "message": "OTP delivered via WhatsApp"
  }
}
CURL
curl -X POST "https://waisend.com/api/external/otp" \
  -H "Authorization: Bearer wazz_sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "201273369866",
  "length": 6,
  "expiryMinutes": 5,
  "messageTemplate": "رمز التحقق الخاص بك هو: {code}. لا تشارك هذا الرمز مع أي شخص."
}'
HTTP Status: 200 OKRate limit: 120 req/min
PATCH/api/external/otp 3 verification attempts max per OTP ID

Verify WhatsApp OTP Code

Verifies the OTP entered by the user. Automatically invalidates the code upon success or after 3 failed verification attempts.

Headers

Authorization: Bearer <API_KEY>
Required
Content-Type: application/json
Required

Request Body (JSON)

PropertyTypeDescription
phone*stringPhone number that requested the code.
code*stringNumeric code entered by the user (4–8 digits).
otpIdstringOptional OTP ID returned from the POST /otp call.

Response (200 OK)

{
  "success": true,
  "verified": true,
  "message": "Phone number verified successfully"
}
CURL
curl -X PATCH "https://waisend.com/api/external/otp" \
  -H "Authorization: Bearer wazz_sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "201273369866",
  "code": "482915"
}'
HTTP Status: 200 OKRate limit: 120 req/min
POST/api/external/orders 120 req/min

Create Order (Shopify, WooCommerce, Custom Web)

Ingests an order placed on any external website. Automatically decrements inventory, links to CRM contact, and triggers WhatsApp COD confirmation buttons.

Headers

Authorization: Bearer <API_KEY>
Required
Content-Type: application/json
Required

Request Body (JSON)

PropertyTypeDescription
contactPhone*stringCustomer phone number in international format.
contactNamestringCustomer full name.
shippingAddressstringFull shipping and delivery address.
paymentMethodstringcash_on_delivery or online (default: cash_on_delivery).
idempotencyKey*stringExternal order reference ID to prevent duplicate order ingestion.
sendWhatsAppConfirmationbooleanSend interactive WhatsApp COD confirmation buttons (default: true).
items*arrayList of order items with productId or sku and quantity.

Response (200 OK)

{
  "success": true,
  "data": {
    "id": "ord_cmvh99z8e002",
    "orderNumber": "#9921",
    "contactPhone": "201012345678",
    "totalAmount": 650,
    "currency": "EGP",
    "status": "pending",
    "paymentMethod": "cash_on_delivery",
    "itemsCount": 2,
    "createdAt": "2026-10-21T18:30:00.000Z"
  }
}
CURL
curl -X POST "https://waisend.com/api/external/orders" \
  -H "Authorization: Bearer wazz_sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "contactPhone": "201012345678",
  "contactName": "يوسف المصري",
  "shippingAddress": "٤٢ شارع النصر، مدينة نصر، القاهرة",
  "paymentMethod": "cash_on_delivery",
  "idempotencyKey": "ext_order_ref_9921",
  "sendWhatsAppConfirmation": true,
  "items": [
    {
      "sku": "TSHIRT-BLK-L",
      "quantity": 2
    },
    {
      "productId": "prod_watch_classic",
      "quantity": 1
    }
  ]
}'
HTTP Status: 200 OKRate limit: 120 req/min
GET/api/external/orders 120 req/min

Query Orders by Customer or Status

Retrieves itemized order records filtered by customer phone number, order ID, or fulfillment status.

Headers

Authorization: Bearer <API_KEY>
Required

Query Parameters

FieldTypeDescription
phonestringFilter orders by customer phone number.
orderIdstringLookup exact order by ID.
statusstringpending, approved, shipped, delivered, cancelled.
limitnumberMaximum records to return (1–100, default 20).

Response (200 OK)

{
  "success": true,
  "data": {
    "orders": [
      {
        "id": "ord_cmvh99z8e002",
        "contactPhone": "201012345678",
        "contactName": "يوسف المصري",
        "totalAmount": 650,
        "currency": "EGP",
        "status": "pending",
        "createdAt": "2026-10-21T18:30:00.000Z",
        "items": [
          {
            "productName": "T-Shirt Black",
            "quantity": 2,
            "unitPrice": 200,
            "subtotal": 400
          },
          {
            "productName": "Classic Leather Belt",
            "quantity": 1,
            "unitPrice": 250,
            "subtotal": 250
          }
        ]
      }
    ]
  }
}
CURL
curl -X GET "https://waisend.com/api/external/orders?phone=201012345678&status=pending" \
  -H "Authorization: Bearer wazz_sk_live_your_api_key_here"
HTTP Status: 200 OKRate limit: 120 req/min
GET/api/external/reservations 120 req/min

Check Real-Time Available Booking Slots

Calculates live, un-booked calendar slots for a service on a given date, accounting for working hours, breaks, buffer times, and service capacity.

Headers

Authorization: Bearer <API_KEY>
Required

Query Parameters

FieldTypeDescription
serviceId*stringThe reservation service ID.
slotsForDate*stringTarget date in YYYY-MM-DD format.

Response (200 OK)

{
  "success": true,
  "data": {
    "availability": [
      {
        "date": "2026-10-25",
        "slots": [
          {
            "startTime": "10:00",
            "endTime": "10:30",
            "availableSlots": 1
          },
          {
            "startTime": "11:00",
            "endTime": "11:30",
            "availableSlots": 2
          },
          {
            "startTime": "14:30",
            "endTime": "15:00",
            "availableSlots": 1
          }
        ]
      }
    ]
  }
}
CURL
curl -X GET "https://waisend.com/api/external/reservations?serviceId=srv_clinic_dentistry&slotsForDate=2026-10-25" \
  -H "Authorization: Bearer wazz_sk_live_your_api_key_here"
HTTP Status: 200 OKRate limit: 120 req/min
POST/api/external/reservations 120 req/min

Book Service Appointment

Reserves an appointment from an external booking portal or mobile app. Enforces concurrency protection, prevents double-booking, and triggers real-time outbound webhooks.

Headers

Authorization: Bearer <API_KEY>
Required
Content-Type: application/json
Required

Request Body (JSON)

PropertyTypeDescription
serviceId*stringService identifier.
contactPhone*stringPatient or customer phone number.
contactNamestringCustomer full name.
dateTime*stringAppointment start timestamp in ISO 8601 format.
notesstringSpecial patient or client requests.
idempotencyKeystringUnique external appointment booking key.

Response (200 OK)

{
  "success": true,
  "data": {
    "id": "res_cmvh99z8e005",
    "ticketNumber": 42,
    "serviceId": "srv_clinic_dentistry",
    "serviceName": "Dental Examination & Cleaning",
    "contactPhone": "201273369866",
    "contactName": "مينا سابت",
    "dateTime": "2026-10-25T11:00:00.000Z",
    "endTime": "2026-10-25T11:30:00.000Z",
    "status": "pending",
    "createdAt": "2026-10-21T19:00:00.000Z"
  }
}
CURL
curl -X POST "https://waisend.com/api/external/reservations" \
  -H "Authorization: Bearer wazz_sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "serviceId": "srv_clinic_dentistry",
  "contactPhone": "201273369866",
  "contactName": "مينا سابت",
  "dateTime": "2026-10-25T11:00:00.000Z",
  "notes": "فحص دوري وتنظيف أسنان"
}'
HTTP Status: 200 OKRate limit: 120 req/min
PATCH/api/external/reservations 120 req/min

Cancel Appointment

Cancels an existing appointment, releases the time slot immediately for other customers, and dispatches reservation.cancelled webhook.

Headers

Authorization: Bearer <API_KEY>
Required
Content-Type: application/json
Required

Request Body (JSON)

PropertyTypeDescription
reservationId*stringReservation ID to cancel.
reasonstringReason for cancellation.

Response (200 OK)

{
  "success": true,
  "data": {
    "id": "res_cmvh99z8e005",
    "ticketNumber": 42,
    "status": "cancelled",
    "notes": "Customer requested reschedule",
    "updatedAt": "2026-10-21T19:15:00.000Z"
  }
}
CURL
curl -X PATCH "https://waisend.com/api/external/reservations" \
  -H "Authorization: Bearer wazz_sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "reservationId": "res_cmvh99z8e005",
  "reason": "Customer requested reschedule"
}'
HTTP Status: 200 OKRate limit: 120 req/min
GET/api/external/contact 120 req/min

Lookup Customer CRM Profile

Retrieves a customer profile by phone number, including custom tags, lifetime order counts, and conversation status.

Headers

Authorization: Bearer <API_KEY>
Required

Query Parameters

FieldTypeDescription
phone*stringPhone number in international format.

Response (200 OK)

{
  "success": true,
  "data": {
    "id": "cnt_cmvh99a1",
    "phone": "201273369866",
    "name": "مينا سابت",
    "tags": [
      "VIP",
      "Repeat Buyer"
    ],
    "ordersCount": 4,
    "totalSpent": 2450,
    "currency": "EGP",
    "lastActiveAt": "2026-10-21T18:45:00.000Z"
  }
}
CURL
curl -X GET "https://waisend.com/api/external/contact?phone=201273369866" \
  -H "Authorization: Bearer wazz_sk_live_your_api_key_here"
HTTP Status: 200 OKRate limit: 120 req/min
GET/api/external/sessions 60 req/min

List Connected WhatsApp Numbers

Returns all active WhatsApp sessions (Meta Cloud API and WAHA) in the authenticated workspace with their phone numbers and connection health.

Headers

Authorization: Bearer <API_KEY>
Required

Response (200 OK)

{
  "success": true,
  "data": {
    "sessions": [
      {
        "id": "sess_cloud_1007",
        "name": "Camrent 1007",
        "phone": "201000000000",
        "provider": "cloud",
        "status": "connected",
        "qualityRating": "GREEN"
      }
    ]
  }
}
CURL
curl -X GET "https://waisend.com/api/external/sessions" \
  -H "Authorization: Bearer wazz_sk_live_your_api_key_here"
HTTP Status: 200 OKRate limit: 120 req/min
Pillar 10: Real-Time Event Dispatch

Outbound Webhooks & Event Handshake

wAIsend dispatches cryptographically signed HTTP POST notifications to your server whenever orders are placed, messages are delivered, appointments are confirmed, or contacts opt out.

Event TopicTrigger ConditionKey Payload Fields
order.createdCustomer submits a new order via cart or web checkoutorderId, contactPhone, totalAmount, items, status
order.status_changedOrder approved, shipped, delivered, or cancelledorderId, status, contactPhone, notes, updatedAt
reservation.bookedAppointment booked on calendarreservationId, serviceId, dateTime, ticketNumber
reservation.cancelledAppointment cancelled or rescheduledreservationId, serviceId, dateTime, reason
message.receivedInbound message received from customermessageId, sender, content, type, timestamp
message.deliveredMessage delivered receipt verified by WhatsAppmessageId, recipient, deliveredAt
contact.createdNew customer profile added to CRMcontactId, phone, name, source
contact.tag_addedTag attached to contact (VIP, Opt-Out, Lead)contactId, tagId, tagName

HMAC-SHA256 Signature Verification Example

Every webhook request includes an X-Hub-Signature-256 header computed using your webhook secret key. Always verify the signature to prevent tampering.

// Node.js / Express Webhook Verification Handler
import crypto from 'node:crypto';

export function verifyWaisendWebhook(rawBody: string, signatureHeader: string, secret: string): boolean {
  if (!signatureHeader || !signatureHeader.startsWith('sha256=')) {
    return false;
  }
  const signature = signatureHeader.replace('sha256=', '');
  const expectedHmac = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedHmac));
}

Ready to integrate your custom store or ERP?

Generate API keys with granular scopes and configure instant outbound webhooks in your settings.

Go to Workspace Settings