13 KiB
API Documentation
Service: mkt-whatsapp-service-net
Version: v1.0
Base URL: /api/v1/whatsapp
Authentication
All endpoints (except webhooks) require authentication via JWT token.
Authorization: Bearer <jwt_token>
Response Format
All responses follow this structure:
{
"success": true | false,
"data": { ... },
"error": "Error message" | null,
"pagination": { ... } | null
}
Webhooks
Verify Webhook
GET /webhooks
WhatsApp verification challenge.
Query Parameters:
hub.mode(string) - Should be "subscribe"hub.verify_token(string) - Your verification tokenhub.challenge(string) - Random string to echo back
Response:
(Plain text) hub.challenge value
Receive Events
POST /webhooks
Receive message events from WhatsApp.
Headers:
X-Hub-Signature-256- HMAC-SHA256 signature
Request Body:
{
"object": "whatsapp_business_account",
"entry": [{
"id": "123456",
"changes": [{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"phone_number_id": "123456789"
},
"messages": [{
"from": "84901234567",
"id": "wamid.xxx",
"timestamp": "1704000000",
"type": "text",
"text": {
"body": "Hello"
}
}]
}
}]
}]
}
Response:
{
"success": true
}
WhatsApp Accounts
Connect Account
POST /accounts
Connect a WhatsApp Business Account.
Request:
{
"shopId": "550e8400-e29b-41d4-a716-446655440000",
"phoneNumberId": "123456789",
"accessToken": "EAAxxxxx",
"webhookUrl": "https://yourdomain.com/api/v1/whatsapp/webhooks"
}
Response:
{
"success": true,
"data": {
"accountId": "660e8400-e29b-41d4-a716-446655440000",
"shopId": "550e8400-e29b-41d4-a716-446655440000",
"phoneNumberId": "123456789",
"status": "active",
"messageTier": "tier_1",
"connectedAt": "2026-01-18T10:00:00Z"
}
}
Get Account
GET /accounts/{shopId}
Get account details for a shop.
Response:
{
"success": true,
"data": {
"accountId": "660e8400-e29b-41d4-a716-446655440000",
"shopId": "550e8400-e29b-41d4-a716-446655440000",
"phoneNumberId": "123456789",
"webhookUrl": "https://yourdomain.com/api/v1/whatsapp/webhooks",
"status": "active",
"messageTier": "tier_2",
"dailyLimit": 10000,
"messagesUsedToday": 1523,
"connectedAt": "2026-01-15T10:00:00Z"
}
}
Disconnect Account
DELETE /accounts/{shopId}
Disconnect WhatsApp Business Account.
Response:
{
"success": true,
"data": {
"message": "Account disconnected successfully"
}
}
Conversations
List Conversations
GET /conversations
Get paginated list of conversations.
Query Parameters:
shopId(required) - Shop IDstatus(optional) - Filter:active,closed,expiredassignedAgentId(optional) - Filter by agentskip(default: 0) - Pagination offsettake(default: 20, max: 100) - Page size
Response:
{
"success": true,
"data": {
"conversations": [
{
"id": "conv-001",
"shopId": "shop-001",
"customerWaId": "84901234567",
"customerName": "Nguyễn Văn A",
"status": "active",
"assignedAgentId": null,
"lastMessageAt": "2026-01-18T10:30:00Z",
"messageCount": 5,
"tags": ["new-customer"],
"createdAt": "2026-01-18T10:00:00Z"
}
],
"totalCount": 42
},
"pagination": {
"page": 1,
"limit": 20,
"total": 42,
"totalPages": 3
}
}
Get Conversation
GET /conversations/{conversationId}
Get conversation details with messages.
Response:
{
"success": true,
"data": {
"id": "conv-001",
"shopId": "shop-001",
"customer": {
"waId": "84901234567",
"name": "Nguyễn Văn A",
"tags": ["vip"]
},
"status": "active",
"messages": [
{
"id": "msg-001",
"whatsAppMessageId": "wamid.xxx",
"direction": "inbound",
"content": {
"type": "text",
"text": "Xin chào"
},
"status": "read",
"timestamp": "2026-01-18T10:00:00Z"
},
{
"id": "msg-002",
"whatsAppMessageId": "wamid.yyy",
"direction": "outbound",
"content": {
"type": "text",
"text": "Xin chào! Chúng tôi có thể giúp gì cho bạn?"
},
"status": "delivered",
"timestamp": "2026-01-18T10:00:15Z"
}
],
"createdAt": "2026-01-18T10:00:00Z",
"expiresAt": "2026-01-19T10:00:00Z"
}
}
Send Message
POST /conversations/{conversationId}/messages
Send a message in a conversation.
Request:
{
"content": {
"type": "text",
"text": "Cảm ơn bạn đã liên hệ!"
}
}
Response:
{
"success": true,
"data": {
"messageId": "msg-003",
"whatsAppMessageId": "wamid.zzz",
"status": "sent",
"timestamp": "2026-01-18T10:05:00Z"
}
}
Media Message:
{
"content": {
"type": "image",
"url": "https://example.com/product.jpg",
"caption": "Check out this product!"
}
}
Interactive Message:
{
"content": {
"type": "interactive",
"interactive": {
"type": "button",
"body": {
"text": "Choose an option:"
},
"action": {
"buttons": [
{"id": "yes", "title": "Yes"},
{"id": "no", "title": "No"}
]
}
}
}
}
Assign Conversation
POST /conversations/{conversationId}/assign
Assign conversation to an agent.
Request:
{
"agentId": "agent-001"
}
Response:
{
"success": true,
"data": {
"conversationId": "conv-001",
"assignedAgentId": "agent-001",
"assignedAt": "2026-01-18T10:10:00Z"
}
}
Close Conversation
POST /conversations/{conversationId}/close
Close a conversation.
Response:
{
"success": true,
"data": {
"conversationId": "conv-001",
"status": "closed",
"closedAt": "2026-01-18T10:15:00Z"
}
}
Customers
List Customers
GET /customers
Get paginated customer list.
Query Parameters:
shopId(required)search(optional) - Search by name/phonetags(optional) - Filter by tags (comma-separated)skip/take(pagination)
Response:
{
"success": true,
"data": {
"customers": [
{
"id": "cust-001",
"waId": "84901234567",
"name": "Nguyễn Văn A",
"tags": ["vip", "frequent-buyer"],
"optInStatus": "opted_in",
"conversationCount": 12,
"lastContactedAt": "2026-01-18T10:00:00Z",
"createdAt": "2026-01-01T00:00:00Z"
}
],
"totalCount": 150
}
}
Get Customer
GET /customers/{waId}
Get customer profile.
Query Parameters:
shopId(required)
Response:
{
"success": true,
"data": {
"id": "cust-001",
"waId": "84901234567",
"shopId": "shop-001",
"name": "Nguyễn Văn A",
"profilePictureUrl": "https://...",
"consent": {
"status": "opted_in",
"timestamp": "2026-01-01T10:00:00Z",
"source": "whatsapp"
},
"tags": ["vip"],
"customFields": {
"city": "Hanoi",
"preferredLanguage": "vi"
},
"stats": {
"conversationCount": 12,
"averageResponseTime": "5m",
"lastPurchaseDate": "2026-01-15"
}
}
}
Update Customer Tags
PUT /customers/{waId}/tags
Add or remove customer tags.
Query Parameters:
shopId(required)
Request:
{
"addTags": ["vip", "electronics-buyer"],
"removeTags": ["new-customer"]
}
Response:
{
"success": true,
"data": {
"waId": "84901234567",
"tags": ["vip", "electronics-buyer"]
}
}
Update Opt-In Status
PUT /customers/{waId}/opt-in
Update customer consent.
Request:
{
"status": "opted_in",
"source": "web"
}
Response:
{
"success": true,
"data": {
"waId": "84901234567",
"consent": {
"status": "opted_in",
"timestamp": "2026-01-18T10:20:00Z",
"source": "web"
}
}
}
Automation Flows
List Flows
GET /flows
Get automation flows.
Query Parameters:
shopId(required)isActive(optional) - Filter by status
Response:
{
"success": true,
"data": {
"flows": [
{
"id": "flow-001",
"flowName": "Welcome New Customer",
"triggerType": "keyword",
"isActive": true,
"executionCount": 523,
"createdAt": "2026-01-10T00:00:00Z"
}
]
}
}
Create Flow
POST /flows
Create automation flow.
Request: See Automation Guide
Response:
{
"success": true,
"data": {
"flowId": "flow-002",
"flowName": "FAQ Bot",
"isActive": false
}
}
Update Flow
PUT /flows/{flowId}
Update flow configuration.
Activate Flow
POST /flows/{flowId}/activate
Enable automation flow.
Deactivate Flow
POST /flows/{flowId}/deactivate
Disable automation flow.
AI Agents
Create AI Agent
POST /ai-agents
Configure AI chatbot.
Request: See AI Chatbot Guide
Update AI Agent
PUT /ai-agents/{agentId}
Update personality/prompts.
Activate AI Agent
POST /ai-agents/{agentId}/activate
Enable AI responses.
Test AI Agent
POST /ai-agents/{agentId}/test
Simulate AI response.
Request:
{
"conversationHistory": [
{"role": "user", "content": "Bạn có laptop nào tốt?"}
],
"customerContext": {
"name": "Nguyễn Văn A",
"tags": ["vip"]
}
}
Response:
{
"success": true,
"data": {
"generatedResponse": "Chúng tôi có nhiều laptop tuyệt vời! Bạn đang tìm laptop cho mục đích gì ạ? Gaming hay làm việc văn phòng?",
"tokensUsed": {"prompt": 450, "completion": 120, "total": 570},
"estimatedCost": 0.0154,
"latencyMs": 1850
}
}
Analytics
Message Statistics
GET /analytics/messages
Get message volume metrics.
Query Parameters:
shopId(required)startDate/endDate(ISO 8601)groupBy-hour,day,week
Response:
{
"success": true,
"data": {
"metrics": [
{
"date": "2026-01-18",
"inboundCount": 245,
"outboundCount": 298,
"totalCount": 543
}
],
"summary": {
"totalInbound": 2450,
"totalOutbound": 2980,
"averagePerDay": 543
}
}
}
Conversation Metrics
GET /analytics/conversations
Get conversation performance metrics.
Response:
{
"success": true,
"data": {
"averageResponseTime": "2m 30s",
"averageResolutionTime": "15m 45s",
"automationResolutionRate": 0.65,
"aiResolutionRate": 0.78,
"humanHandoffRate": 0.22
}
}
Automation Performance
GET /analytics/automations
Get automation flow execution stats.
Response:
{
"success": true,
"data": {
"flows": [
{
"flowId": "flow-001",
"flowName": "Welcome Bot",
"executionCount": 523,
"completionRate": 0.89,
"averageSteps": 3.2,
"fallbackRate": 0.11
}
]
}
}
Error Codes
| Code | Message | Description |
|---|---|---|
| 400 | Bad Request | Invalid request format |
| 401 | Unauthorized | Missing or invalid auth token |
| 404 | Not Found | Resource doesn't exist |
| 409 | Conflict | Duplicate resource |
| 422 | Validation Error | Business rule violation |
| 429 | Rate Limit Exceeded | Too many requests |
| 500 | Internal Server Error | Server error |
Error Response Format:
{
"success": false,
"error": "Validation failed: Phone number is required",
"details": {
"field": "phoneNumberId",
"code": "REQUIRED_FIELD"
}
}
Rate Limits
- Public APIs: 60 requests/minute per shop
- Webhooks: No limit (but must respond < 5s)
- Analytics: 10 requests/minute per shop
Webhooks Signature Verification
Verify X-Hub-Signature-256 header:
const crypto = require('crypto');
const signature = req.headers['x-hub-signature-256'];
const payload = JSON.stringify(req.body);
const expectedSignature = 'sha256=' +
crypto.createHmac('sha256', APP_SECRET)
.update(payload)
.digest('hex');
if (signature !== expectedSignature) {
throw new Error('Invalid signature');
}
Pagination
All list endpoints support pagination:
Request:
GET /conversations?skip=20&take=20
Response:
{
"pagination": {
"page": 2,
"limit": 20,
"total": 150,
"totalPages": 8
}
}
Changelog
v1.0 (2026-01-18)
- Initial release
- WhatsApp Cloud API integration
- Automation flows
- AI chatbot
- Customer management