Sendable Docs

Messaging

Send and receive WhatsApp messages with Sendable.

Message Types

Sendable supports various message types for different use cases.

Text Messages

Simple text messages for notifications and conversations:

{
  "to": "6281234567890",
  "text": "Hello! Your order #12345 has been shipped."
}

Group Mentions

To send a real WhatsApp mention in a group, include the visible @number in text.content and the full WhatsApp JID in mentions:

{
  "chatId": "[email protected]",
  "text": {
    "content": "asd @6285176702468"
  },
  "mentions": ["[email protected]"]
}

Media Messages

Send images, videos, documents:

{
  "to": "6281234567890",
  "mediaUrl": "https://example.com/invoice.pdf",
  "mediaType": "document",
  "caption": "Your invoice for order #12345"
}

Supported media types:

  • image - JPG, PNG
  • video - MP4
  • audio - MP3, OGG
  • document - PDF, DOC, etc.

Sending Messages

Dashboard

Send quick messages directly from the dashboard:

  1. Go to your session
  2. Click "Send Message"
  3. Enter phone number
  4. Type message or attach media
  5. Send

API

Send programmatically via API:

curl -X POST "https://api.sendable.dev/messages/send" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "6281234567890",
    "text": "Hello from API!"
  }'

Message Status

Track message delivery status:

StatusMeaning
pendingQueued for sending
sentSent to WhatsApp servers
deliveredDelivered to recipient's phone
readRecipient opened the message
failedCould not be delivered

Check Status via API

curl "https://api.sendable.dev/messages/{messageId}/status" \
  -H "x-api-key: YOUR_API_KEY"

Real-time Updates

Use webhooks to get instant status updates:

  • message.delivered - Message arrived
  • message.read - Message seen
  • message.failed - Delivery failed

Receiving Messages

Webhook Setup

Configure webhook to receive incoming messages:

  1. Go to session → Webhooks
  2. Subscribe to message.received event
  3. Your endpoint receives:
{
  "event": "message.received",
  "data": {
    "messageId": "msg_incoming_456",
    "from": "6281234567890",
    "type": "text",
    "text": "Hi, I have a question about my order",
    "timestamp": "2026-03-02T10:30:00Z"
  }
}

Auto-Reply

Example: Automatic response to incoming messages:

app.post('/webhook', (req, res) => {
  const { event, data } = req.body
  
  if (event === 'message.received') {
    // Send auto-reply
    sendMessage(data.from, 
      "Thanks for your message! We'll respond shortly.")
  }
  
  res.sendStatus(200)
})

Use Cases

Customer Support

Two-way conversation handling:

// Store incoming messages
if (event === 'message.received') {
  await createTicket({
    customer: data.from,
    message: data.text,
    timestamp: data.timestamp
  })
}

// Notify agents
await notifySupportTeam(newTicket)

Order Notifications

Automated order updates:

// Order confirmation
await sendMessage(customerPhone, 
  `Order #${orderId} confirmed! Total: $${amount}`)

// Shipping notification
await sendMessage(customerPhone,
  `Order #${orderId} shipped! Track: ${trackingUrl}`)

// Delivery confirmation
await sendMessage(customerPhone,
  `Order #${orderId} delivered! Enjoy your purchase.`)

Appointment Reminders

Reduce no-shows with reminders:

// 24 hours before
await sendMessage(patientPhone,
  `Reminder: Appointment with Dr. Smith tomorrow at ${time}`)

// 1 hour before
await sendMessage(patientPhone,
  `Your appointment starts in 1 hour. See you soon!`)

OTP Verification

Secure authentication codes:

// Generate and send OTP
const otp = generateOTP()
await sendMessage(userPhone, 
  `Your verification code is: ${otp}. Valid for 5 minutes.`)

Message Templates

Create reusable message formats:

const templates = {
  welcome: (name) => `Hi ${name}! Welcome to our service.`,
  
  orderShipped: (orderId, tracking) => 
    `Order #${orderId} shipped! Track: ${tracking}`,
  
  appointmentReminder: (doctor, time) =>
    `Reminder: Appointment with ${doctor} at ${time}`
}

// Usage
await sendMessage(phone, templates.welcome('John'))

Best Practices

Phone Number Format

Always use international format:

  • 6281234567890 (Indonesia)
  • 081234567890 (missing country code)
  • +6281234567890 (remove the +)

Message Length

  • Keep messages concise
  • WhatsApp has no strict limit, but split long messages
  • Use formatting (bold, italic) for emphasis

Timing

  • Business hours for promotional messages
  • Immediate for OTPs and alerts
  • Consider timezone of recipient

Personalization

Include customer details:

Hi {name}, your order #{orderId} is ready!

Error Handling

Always handle delivery failures:

try {
  const result = await sendMessage(phone, text)
  
  if (!result.success) {
    // Log failure
    await logFailedMessage(phone, text, result.error)
    
    // Retry or notify
    if (isRetryable(result.error)) {
      await retryLater(phone, text)
    }
  }
} catch (error) {
  await notifyAdmin(error)
}

Rate Limits

Be aware of sending limits:

PlanMessages/HourNotes
Free100Best for testing
Starter1,000Small businesses
Pro10,000High volume
EnterpriseCustomUnlimited

Monitor your usage in the dashboard.

On this page