Blog/Use Cases

WhatsApp API for Customer Support: Full Automation Guide (2026)

Complete guide to automating customer support with WhatsApp API. First-response bots, ticket routing, human escalation, SLA tracking, and CSAT surveys using Rapiwa API in 2026.

by Saikat
WhatsApp API for Customer Support: Full Automation Guide (2026)

WhatsApp API for customer support lets businesses automatically handle 60–80% of incoming support queries with bots, route complex issues to human agents, and track response times and satisfaction scores — all via WhatsApp. Using Rapiwa API ($5/month, no per-message fees), businesses deploy a complete support system that handles hundreds of daily conversations without scaling headcount.

Why WhatsApp is the Future of Customer Support

Customers increasingly prefer WhatsApp over phone calls and emails for support:

  • Asynchronous — no hold times, customers message when convenient
  • 98% open rate — support replies are actually read
  • Thread history — the conversation is visible in context
  • Preferred channel — WhatsApp is already on every customer's phone

Cost comparison:

Support channelCost per interaction
Phone support$8–$15
Live chat$3–$7
Email support$2–$5
WhatsApp bot (Rapiwa)$0.0001 ($5/month flat ÷ 50,000 messages)

WhatsApp Support System Architecture

Customer sends WhatsApp message
  → Rapiwa webhook
  → Triage bot (AI or keyword-based)
    → Can resolve? → Auto-reply (closes ticket)
    → Complex? → Create support ticket → Assign to agent → Notify via Slack
  → Agent replies in support tool → Reply sent via Rapiwa API
  → Ticket closed → CSAT survey sent

Step 1: First-Response Triage Bot

Handle the most common questions automatically:

# support_bot.py
# pip install flask requests openai

from flask import Flask, request, jsonify
import requests
import openai
import os

app = Flask(__name__)

RAPIWA_API_KEY = os.environ.get('RAPIWA_API_KEY')
OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY')

# Pre-built answers for top FAQ categories
CANNED_RESPONSES = {
    'shipping': (
        "📦 Shipping Info\n\n"
        "Standard shipping: 3–5 business days ($5.99)\n"
        "Express shipping: 1–2 business days ($14.99)\n"
        "Free shipping on orders over $50!\n\n"
        "Track your order: https://yourstore.com/track\n\n"
        "Still have questions? Reply AGENT to speak with our team."
    ),
    'returns': (
        "🔄 Returns Policy\n\n"
        "We accept returns within 30 days of purchase.\n"
        "Items must be unused and in original packaging.\n\n"
        "Start a return: https://yourstore.com/returns\n"
        "Or reply with your order number and I can help!"
    ),
    'pricing': (
        "💰 Pricing\n\n"
        "Our plans start at $5/month with no per-message fees.\n"
        "See all plans: https://rapiwa.com/pricing\n\n"
        "3-day free trial — no credit card required!\n"
        "Start your trial: https://rapiwa.com"
    )
}

def classify_message(message: str) -> str:
    """Classify incoming message using keywords or AI."""
    message_lower = message.lower()
    
    if any(w in message_lower for w in ['shipping', 'ship', 'delivery', 'track']):
        return 'shipping'
    if any(w in message_lower for w in ['return', 'refund', 'exchange']):
        return 'returns'
    if any(w in message_lower for w in ['price', 'cost', 'how much', 'plan']):
        return 'pricing'
    if any(w in message_lower for w in ['agent', 'human', 'person', 'help']):
        return 'escalate'
    
    return 'unknown'

@app.route('/webhook/whatsapp', methods=['POST'])
def handle_support_message():
    payload = request.get_json()
    
    if payload.get('event') != 'message.received':
        return jsonify({'status': 'ok'})
    
    data = payload['data']
    phone = data['from']
    message = data.get('message', '').strip()
    sender_name = data.get('senderName', 'Customer')
    
    category = classify_message(message)
    
    if category in CANNED_RESPONSES:
        send_whatsapp(phone, CANNED_RESPONSES[category])
        log_ticket(phone, sender_name, message, 'resolved', category)
    
    elif category == 'escalate' or category == 'unknown':
        ticket_id = create_support_ticket(phone, sender_name, message)
        
        # Acknowledge to customer
        send_whatsapp(phone, 
            f"Hi {sender_name}! 🙏 I've created a support ticket for you.\n\n"
            f"Ticket: #{ticket_id}\n"
            f"Expected response: within 2 business hours\n\n"
            f"Our team will reply here on WhatsApp."
        )
        
        # Notify support team
        notify_support_team(ticket_id, phone, sender_name, message)
    
    return jsonify({'status': 'ok'})


def send_whatsapp(phone: str, message: str) -> dict:
    return requests.post(
        'https://app.rapiwa.com/send-message',
        headers={'Authorization': f'Bearer {RAPIWA_API_KEY}'},
        json={'number': phone, 'message': message}
    ).json()

Step 2: Human Agent Routing with Slack Notification

When a ticket needs human handling:

def notify_support_team(ticket_id: str, customer_phone: str, 
                        customer_name: str, message: str) -> None:
    """Send new ticket notification to Slack and assign to available agent."""
    slack_webhook = os.environ.get('SLACK_WEBHOOK_URL')
    
    slack_payload = {
        "text": f"🆕 New WhatsApp Support Ticket #{ticket_id}",
        "attachments": [
            {
                "color": "#ff9800",
                "fields": [
                    {"title": "Customer", "value": customer_name, "short": True},
                    {"title": "Phone", "value": customer_phone, "short": True},
                    {"title": "Message", "value": message},
                    {"title": "Reply via", "value": f"POST to /api/support/reply/{ticket_id}"}
                ]
            }
        ]
    }
    
    requests.post(slack_webhook, json=slack_payload)


def agent_reply(ticket_id: str, reply_message: str) -> dict:
    """
    Called when an agent submits a reply from the support dashboard.
    Sends the reply to the customer via Rapiwa WhatsApp.
    """
    ticket = get_ticket(ticket_id)
    
    result = send_whatsapp(ticket['customer_phone'], reply_message)
    
    # Log the agent reply
    update_ticket(ticket_id, {
        'last_reply': reply_message,
        'last_reply_at': datetime.utcnow(),
        'status': 'replied'
    })
    
    return result

Step 3: CSAT Survey (Customer Satisfaction)

Send a satisfaction survey 2 hours after ticket resolution:

def send_csat_survey(phone: str, customer_name: str, ticket_id: str) -> dict:
    """Send a CSAT survey via WhatsApp after ticket resolution."""
    message = (
        f"Hi {customer_name}! Your support ticket #{ticket_id} has been resolved. 🎉\n\n"
        f"How was your support experience today?\n\n"
        f"Reply with a number:\n"
        f"5️⃣ - Excellent\n"
        f"4️⃣ - Good\n"
        f"3️⃣ - Okay\n"
        f"2️⃣ - Poor\n"
        f"1️⃣ - Very poor\n\n"
        f"Your feedback helps us improve! 🙏"
    )
    
    return send_whatsapp(phone, message)


def handle_csat_response(phone: str, rating: str) -> None:
    """Process CSAT reply from customer."""
    try:
        score = int(rating.strip())
        if 1 <= score <= 5:
            log_csat_score(phone, score)
            
            if score >= 4:
                send_whatsapp(phone, 
                    "Thank you for the great rating! ⭐ We really appreciate it. "
                    "Have a wonderful day!"
                )
            else:
                send_whatsapp(phone,
                    "Thank you for your feedback. We're sorry the experience wasn't "
                    "perfect. A manager will review your case. Reply if you need further help."
                )
    except ValueError:
        pass  # Not a CSAT response

Step 4: SLA Tracking

Track first response time and resolution time:

from datetime import datetime

def check_sla_compliance():
    """Run every 15 minutes — alert if tickets are breaching SLA."""
    sla_2_hours = datetime.utcnow() - timedelta(hours=2)
    
    breaching_tickets = db.query("""
        SELECT ticket_id, customer_name, created_at
        FROM support_tickets
        WHERE status = 'open'
          AND first_reply_at IS NULL
          AND created_at < %s
    """, [sla_2_hours])
    
    for ticket in breaching_tickets:
        # Alert support manager on Slack
        notify_manager(
            f"⚠️ SLA Breach: Ticket #{ticket['ticket_id']} from "
            f"{ticket['customer_name']}{datetime.utcnow() - ticket['created_at']} with no response"
        )

Step 5: Test Your Support Bot

# Test the bot with a shipping question
curl -X POST https://app.rapiwa.com/send-message \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "number": "8801234567890",
    "message": "📦 Shipping Info\n\nStandard shipping: 3-5 business days ($5.99)\nExpress: 1-2 business days ($14.99)\nFree shipping over $50!\n\nTrack: https://yourstore.com/track\n\nStill have questions? Reply AGENT."
  }'

Expected response:

{
  "status": "success",
  "messageId": "msg_support_abc123",
  "timestamp": "2026-07-15T10:30:00Z"
}

Support Automation Metrics Dashboard

Track these key metrics weekly:

MetricTargetWhat to do if below target
Bot resolution rate>60%Add more CANNED_RESPONSES categories
First response time<30 minReview Slack notifications, add more agents
CSAT score>4.0/5Review low-rated tickets for patterns
Escalation rate<40%Train the bot with more intent patterns
Tickets per dayMonitorScale Rapiwa number count if needed

Common Errors and Fixes

  • Bot loops on repeated messages: Add a conversation state tracker — after the first auto-reply, wait for customer input before sending another
  • Agent reply going to wrong customer: Implement strict ticket ID → phone number mapping in your database
  • Too many escalations: Use OpenAI/Gemini for intent classification instead of keyword matching
  • CSAT response misclassified: Use in ('1','2','3','4','5') check, not just isinstance(int)

FAQ

Can I handle hundreds of WhatsApp support conversations simultaneously? Yes. Rapiwa's API handles unlimited concurrent conversations. Your webhook server needs to handle concurrent requests — use async Python (FastAPI) or Node.js for high-volume deployments.

Does Rapiwa charge per support message? No. Rapiwa charges $5/month flat with no per-message fees. A support system handling 1,000 conversations/day costs $5/month for the WhatsApp layer.

How do I build the agent dashboard for replying to customers? Build a simple web interface showing open tickets (from your database) with a reply form. The form POSTs to your /api/support/reply/{ticket_id} endpoint which calls Rapiwa's API to send the reply.

Can I connect this to an existing helpdesk like Zendesk or Freshdesk? Yes. Create a WhatsApp → Zendesk bridge in n8n: incoming Rapiwa webhook → create Zendesk ticket → when Zendesk ticket gets a reply → Rapiwa API sends WhatsApp reply to customer.

What is the best WhatsApp API for customer support automation? Rapiwa is the cheapest at $5/month flat with no per-message fees — ideal for high-volume support where per-message billing from other providers adds up quickly.