Skip to main content

šŸ’¬ Send Text Messages

Send rich text messages to WhatsApp contacts using the Whatspie API with advanced features like typing simulation, message formatting, and real-time delivery tracking.

✨ V2 Enhanced Features

Support for typing simulation, WhatsApp text formatting, emoji support, and improved delivery tracking with comprehensive error handling.

🌐 Endpoint​

POST https://api.whatspie.com/messages

šŸ” Authentication​

Bearer token required in the Authorization header with proper content headers.

šŸ“‹ Request Parameters​

ParameterTypeRequiredDescription
devicestringāœ…Your registered WhatsApp device number
receiverstringāœ…Recipient's phone number (international format)
typestringāœ…Message type: "chat" for text messages
paramsobjectāœ…Message parameters containing text content
params.textstringāœ…Text message content (supports WhatsApp formatting)
simulate_typingintegerāŒShow typing indicator: 1 (yes) or 0 (no)

Text Message with Formatting​

curl -X POST "https://api.whatspie.com/messages" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"device": "6281234567890",
"receiver": "6289876543210",
"type": "chat",
"params": {
"text": "*Bold Text* _Italic Text_ ~Strikethrough~ `Monospace`\n\nNew paragraph with emojis! šŸŽ‰āœØ"
},
"simulate_typing": 1
}'

šŸ“Š Response Format​

Success Response​

{
"code": 200,
"message": "Message sent successfully",
"data": {
"id": "msg_chat_12345",
"status": "pending",
"type": "chat",
"device": "6281234567890",
"receiver": "6289876543210",
"message": "Hello World!",
"simulate_typing": 1,
"timestamp": "2024-12-20T10:30:00Z"
}
}

Response Fields​

FieldTypeDescription
idstringUnique message identifier
statusstringMessage status (pending, sent, delivered, failed)
typestringMessage type (chat)
devicestringSender device number
receiverstringRecipient's phone number
messagestringSent message content
simulate_typingintegerTyping simulation setting (1 or 0)
timestampstringMessage sent timestamp (ISO 8601)

Error Responses​

Invalid Phone Number​

{
"code": 400,
"message": "Invalid phone number format",
"error": "Receiver phone number must be in international format without +"
}

Message Too Long​

{
"code": 400,
"message": "Message too long",
"error": "Message exceeds maximum length of 4096 characters"
}

Device Not Connected​

{
"code": 400,
"message": "Device not connected",
"error": "WhatsApp device is offline or not connected. Please check device status."
}

Invalid Message Type​

{
"code": 400,
"message": "Invalid message type",
"error": "Message type 'chat' is required for text messages"
}

šŸ“± Phone Number Format​

The device and receiver parameters should be in international format without the plus (+) sign:

CountryFormatExampleValid
šŸ‡ŗšŸ‡ø USA1XXXXXXXXXX11234567890āœ…
šŸ‡¬šŸ‡§ UK44XXXXXXXXXX441234567890āœ…
šŸ‡®šŸ‡³ India91XXXXXXXXXX911234567890āœ…
šŸ‡®šŸ‡© Indonesia62XXXXXXXXXXX6281234567890āœ…
šŸ‡§šŸ‡· Brazil55XXXXXXXXXXX5511987654321āœ…
šŸ‡©šŸ‡Ŗ Germany49XXXXXXXXXX491234567890āœ…

āŒ Invalid Formats​

  • +6281234567890 (contains +)
  • 081234567890 (missing country code)
  • 6281-234-567-890 (contains hyphens)
  • 62 81234567890 (contains spaces)

✨ Message Formatting​

WhatsApp Text Formatting​

Whatspie API supports all WhatsApp text formatting options:

Bold Text

Your text hereWraps text with asterisks

Italic Text

Your text hereWraps text with underscores

Strikethrough

Your text hereWraps text with tildes

Monospace

`Your text here`Wraps text with backticks

Formatting Examples​

# Bold text example
curl -X POST "https://api.whatspie.com/messages" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"device": "6281234567890",
"receiver": "6289876543210",
"type": "chat",
"message": "This is *bold text* in WhatsApp",
"simulate_typing": 1
}'

# Mixed formatting
curl -X POST "https://api.whatspie.com/messages" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"device": "6281234567890",
"receiver": "6289876543210",
"type": "chat",
"message": "*Bold* _italic_ ~strike~ \`code\` text combined!",
"simulate_typing": 1
}'

šŸ˜€ Emojis and Special Characters​

const messages = [
"Hello! šŸ‘‹ How are you today?",
"Thanks for your order! āœ… We'll process it soon.",
"šŸŽ‰ Congratulations on your achievement!",
"ā— Important: Please reply to this message.",
"🚨 *URGENT NOTICE* 🚨\n\nYour account will expire in 3 days.\n\nāœ… Renew now: https://example.com\nšŸ’³ Questions? Reply to this message"
];

// Send each message with proper V2 API
const token = 'YOUR_API_TOKEN';
const device = '6281234567890';
const receiver = '6289876543210';

messages.forEach(async (msg, index) => {
try {
const result = await sendTextMessage(token, device, receiver, msg);
console.log(`Message ${index + 1} sent:`, result.data.id);

// Small delay between messages
await new Promise(resolve => setTimeout(resolve, 1000));
} catch (error) {
console.error(`Failed to send message ${index + 1}:`, error.message);
}
});

Best Practices​

1. Phone Number Validation​

Always validate phone numbers before sending messages:

function isValidPhoneNumber(phoneNumber) {
// Validation for international format (country code + number)
const phoneRegex = /^[1-9]\d{10,14}$/;
return phoneRegex.test(phoneNumber);
}

function validateWhatspieRequest(device, receiver, message) {
// Validate device number
if (!isValidPhoneNumber(device)) {
throw new Error('Invalid device phone number format');
}

// Validate receiver number
if (!isValidPhoneNumber(receiver)) {
throw new Error('Invalid receiver phone number format');
}

// Validate message length
if (message.length > 4096) {
throw new Error('Message exceeds 4096 character limit');
}

return true;
}

// Usage
const device = '6281234567890';
const receiver = '6289876543210';
const message = 'Hello World!';

try {
validateWhatspieRequest(device, receiver, message);
await sendTextMessage(token, device, receiver, message);
} catch (error) {
console.error('Validation failed:', error.message);
}

2. Message Length Limits​

Keep messages under 4096 characters:

function validateMessage(message) {
const maxLength = 4096;

if (message.length > maxLength) {
throw new Error(`Message too long. Maximum ${maxLength} characters allowed.`);
}

return true;
}

3. Rate Limiting​

Implement rate limiting to avoid being blocked:

class MessageSender {
constructor(token, rateLimit = 1000) { // 1 message per second
this.token = token;
this.rateLimit = rateLimit;
this.lastSent = 0;
}

async sendMessage(phoneNumber, message) {
const now = Date.now();
const timeSinceLastSent = now - this.lastSent;

if (timeSinceLastSent < this.rateLimit) {
await new Promise(resolve =>
setTimeout(resolve, this.rateLimit - timeSinceLastSent)
);
}

const result = await sendTextMessage(this.token, phoneNumber, message);
this.lastSent = Date.now();

return result;
}
}

4. Error Handling​

Implement comprehensive error handling with V2 API structure:

async function sendMessageWithRetry(token, device, receiver, message, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const result = await sendTextMessage(token, device, receiver, message);
return result;
} catch (error) {
console.log(`Attempt ${attempt} failed:`, error.message);

// Don't retry on certain errors
if (error.response?.status === 401 || error.response?.status === 403) {
throw new Error('Authentication failed. Please check your API token.');
}

if (error.response?.status === 400 && error.response?.data?.error?.includes('phone')) {
throw new Error('Invalid phone number format. Please check device and receiver numbers.');
}

if (attempt === maxRetries) {
throw error;
}

// Wait before retry (exponential backoff)
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}

// Advanced error handling class
class WhatspieErrorHandler {
static handleError(error) {
if (error.response) {
const { status, data } = error.response;

switch (status) {
case 400:
return `Bad Request: ${data.error || 'Invalid request format'}`;
case 401:
return 'Unauthorized: Please check your API token';
case 403:
return 'Forbidden: Insufficient permissions';
case 429:
return 'Rate Limited: Too many requests, please wait';
case 500:
return 'Server Error: Please try again later';
default:
return `HTTP ${status}: ${data.message || 'Unknown error'}`;
}
} else {
return `Network Error: ${error.message}`;
}
}
}

// Usage with error handling
try {
const result = await sendMessageWithRetry(
'YOUR_API_TOKEN',
'6281234567890',
'6289876543210',
'Hello with error handling!'
);
console.log('Message sent successfully:', result.data.id);
} catch (error) {
const errorMessage = WhatspieErrorHandler.handleError(error);
console.error('Failed to send message:', errorMessage);
}

5. Bulk Messaging​

For sending messages to multiple recipients with V2 API:

async function sendBulkMessages(token, device, recipients, message, options = {}) {
const {
delay = 2000,
simulateTyping = true,
onProgress = null,
onError = null
} = options;

const results = [];
let sent = 0;
let failed = 0;

for (let i = 0; i < recipients.length; i++) {
const receiver = recipients[i];

try {
const result = await sendTextMessage(token, device, receiver, message, simulateTyping);

results.push({
receiver,
success: true,
messageId: result.data.id,
timestamp: result.data.timestamp
});

sent++;
onProgress?.({ sent, failed, total: recipients.length, current: receiver });

// Add delay between messages to avoid rate limiting
if (i < recipients.length - 1) {
await new Promise(resolve => setTimeout(resolve, delay));
}

} catch (error) {
const errorMsg = error.response?.data?.error || error.message;
results.push({
receiver,
success: false,
error: errorMsg
});

failed++;
onError?.(receiver, errorMsg);
}
}

return {
results,
summary: { sent, failed, total: recipients.length }
};
}

// Usage with progress tracking
const recipients = [
'6289876543210',
'6287654321098',
'6285432109876'
];

const bulkResults = await sendBulkMessages(
'YOUR_API_TOKEN',
'6281234567890',
recipients,
'šŸ“¢ *Important Update*\n\nOur services will be updated tonight from 2-4 AM.\n\nSorry for any inconvenience! šŸ™',
{
delay: 3000, // 3 seconds between messages
simulateTyping: true,
onProgress: (progress) => {
console.log(`Progress: ${progress.sent}/${progress.total} sent (${progress.failed} failed)`);
},
onError: (receiver, error) => {
console.warn(`Failed to send to ${receiver}: ${error}`);
}
}
);

console.log('Bulk messaging completed:', bulkResults.summary);

// Send personalized messages
async function sendPersonalizedMessages(token, device, contacts) {
const results = [];

for (const contact of contacts) {
const personalizedMsg = `Hi ${contact.name}! šŸ‘‹\n\nThanks for being a valued customer. Your account status: ${contact.status}\n\nQuestions? Just reply! šŸ’¬`;

try {
const result = await sendTextMessage(token, device, contact.phone, personalizedMsg);
results.push({ ...contact, success: true, messageId: result.data.id });
} catch (error) {
results.push({ ...contact, success: false, error: error.message });
}

// Wait 2 seconds between personalized messages
await new Promise(resolve => setTimeout(resolve, 2000));
}

return results;
}

// Usage
const contacts = [
{ name: 'John Doe', phone: '6289876543210', status: 'Active' },
{ name: 'Jane Smith', phone: '6287654321098', status: 'Premium' }
];

const personalizedResults = await sendPersonalizedMessages(
'YOUR_API_TOKEN',
'6281234567890',
contacts
);
console.log('Personalized messages sent:', personalizedResults);

āš ļø Limitations & Guidelines​

  • Message Length: Maximum 4096 characters per message
  • Rate Limits: Recommended 1-2 messages per second to avoid temporary blocks
  • Contact Verification: Recipients must have WhatsApp installed and active
  • Device Connection: Sender device must be online and connected to WhatsApp Web
  • Business Compliance: Follow WhatsApp's business messaging policies and terms
  • International Messaging: Ensure proper country code formatting for cross-border messages

šŸ’” Use Cases​

Customer Support​

const supportMsg = `šŸ‘‹ Hi! Thanks for contacting support.

šŸ” *Issue*: ${customerIssue}
šŸŽŸļø *Ticket*: #${ticketNumber}
ā±ļø *Response Time*: Within 2 hours

šŸ“ž Urgent? Call: +1-800-SUPPORT
šŸ’¬ Questions? Just reply here!

_We're here to help!_ ✨`;

Marketing Campaigns​

const campaignMsg = `šŸŽ‰ *FLASH SALE ALERT* šŸŽ‰

⚔ *50% OFF* Everything!
ā° Today only: ${new Date().toLocaleDateString()}
šŸ›ļø Shop now: ${shopUrl}

šŸ’° Use code: *FLASH50*
🚚 Free shipping on orders $75+

*Limited time offer!* ā³`;

Appointment Reminders​

const reminderMsg = `šŸ“… *Appointment Reminder*

šŸ‘¤ *Patient*: ${patientName}
šŸ„ *Doctor*: Dr. ${doctorName}
šŸ“… *Date*: ${appointmentDate}
ā° *Time*: ${appointmentTime}
šŸ“ *Location*: ${clinicAddress}

āœ… Reply *CONFIRM* to confirm
āŒ Reply *CANCEL* to reschedule

šŸ“ž Questions? Call: ${clinicPhone}`;