πΌοΈ Send Image Messages
Send stunning images with captions to WhatsApp contacts using the enhanced Whatspie API with support for various formats and advanced delivery options.
πΈ Rich Media Support
Upload images directly from URLs with automatic optimization, caption support, and typing simulation for a natural conversation experience.
π Endpointβ
POST https://api.whatspie.com/messages
π Authenticationβ
Bearer token required with proper JSON content headers.
π Request Parametersβ
Parameter | Type | Required | Description |
---|---|---|---|
device | string | β | Your registered WhatsApp device number |
receiver | string | β | Recipient's phone number (international format) |
type | string | β | Message type: "image" for image messages |
params | object | β | Message parameters containing image data |
params.image | object | β | Image object with URL |
params.image.url | string | β | Direct URL to the image file |
params.caption | string | β | Image caption text (supports formatting) |
params.viewOnce | boolean | β | Whether image should be viewable only once |
simulate_typing | integer | β | Show typing indicator: 1 (yes) or 0 (no) |
π¨ Supported Image Formatsβ
π· JPEG/JPG
Most compatible format
Most compatible format
πΌοΈ PNG
Transparency support
Transparency support
ποΈ GIF
Animated images
Animated images
π WebP
Modern format
Modern format
π Image Requirementsβ
- Maximum file size: 16MB
- Recommended dimensions: Up to 1600x1600 pixels
- File accessibility: Must be publicly accessible via direct URL
- Upload time: Images are automatically optimized for WhatsApp
π Request Examplesβ
Basic Image Messageβ
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": "image",
"params": {
"image": {
"url": "https://example.com/images/photo.jpg"
},
"caption": "Check out this amazing photo! πΈβ¨"
},
"simulate_typing": 1
}'
Image with Rich Captionβ
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": "image",
"params": {
"image": {
"url": "https://example.com/products/headphones.jpg"
},
"caption": "π *NEW PRODUCT ALERT* π\n\n_Premium Quality Headphones_\n\nβ
Noise Cancellation\nβ
30h Battery Life\nβ
Fast Charging\n\n*Special Price: $199*\n~~Original: $299~~"
},
"simulate_typing": 1
}'
Image Without Captionβ
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": "image",
"params": {
"image": {
"url": "https://example.com/images/screenshot.png"
}
},
"simulate_typing": 1
}'
π Response Formatβ
Success Responseβ
{
"code": 200,
"message": "Image sent successfully",
"data": {
"id": "msg_image_12345",
"status": "pending",
"type": "image",
"device": "6281234567890",
"receiver": "6289876543210",
"file_url": "https://example.com/images/photo.jpg",
"message": "Check out this amazing photo! πΈβ¨",
"simulate_typing": 1,
"timestamp": "2024-12-20T10:30:00Z"
}
}
Response Fieldsβ
Field | Type | Description |
---|---|---|
id | string | Unique message identifier |
status | string | Message status (pending , sent , delivered , failed ) |
type | string | Message type (image ) |
device | string | Sender device number |
receiver | string | Recipient's phone number |
file_url | string | URL of the sent image |
message | string | Image caption (if provided) |
simulate_typing | integer | Typing simulation setting (1 or 0) |
timestamp | string | Message sent timestamp (ISO 8601) |
Error Responsesβ
Invalid Image URLβ
{
"code": 400,
"message": "Invalid image URL",
"error": "The provided image URL is not accessible or invalid"
}
Unsupported Image Formatβ
{
"code": 400,
"message": "Unsupported file format",
"error": "Only JPEG, PNG, GIF, and WebP images are supported"
}
Image Too Largeβ
{
"code": 400,
"message": "File too large",
"error": "Image size exceeds 16MB limit"
}
URL Not Accessibleβ
{
"code": 400,
"message": "Unable to download image",
"error": "The image URL is not publicly accessible"
}
Advanced Examplesβ
Image with Formatting in Captionβ
async function sendProductImage() {
const caption = `π *NEW PRODUCT ALERT* π
_Premium Wireless Headphones_
β
Noise Cancellation
β
30-hour Battery Life
β
Fast Charging
β
Premium Sound Quality
~~$299~~ *$199* (33% OFF)
Use code: *SAVE100*
Valid until: December 31st
Order now: https://shop.example.com`;
await sendImageMessage(
'YOUR_JWT_TOKEN',
'1234567890',
'https://example.com/headphones.jpg',
caption,
'headphones-promo.jpg'
);
}
Batch Image Sendingβ
async function sendImageCatalog(token, phoneNumber, products) {
const results = [];
for (const product of products) {
try {
const caption = `${product.name}\nPrice: $${product.price}\n${product.description}`;
const result = await sendImageMessage(
token,
phoneNumber,
product.imageUrl,
caption,
`${product.id}.jpg`
);
results.push({
product: product.name,
success: true,
messageId: result.data.id
});
// Delay between messages to avoid rate limiting
await new Promise(resolve => setTimeout(resolve, 2000));
} catch (error) {
results.push({
product: product.name,
success: false,
error: error.message
});
}
}
return results;
}
// Usage
const products = [
{
id: 'p001',
name: 'Wireless Headphones',
price: 199,
description: 'Premium quality with noise cancellation',
imageUrl: 'https://example.com/headphones.jpg'
},
{
id: 'p002',
name: 'Smart Watch',
price: 299,
description: 'Track your fitness and stay connected',
imageUrl: 'https://example.com/smartwatch.jpg'
}
];
const results = await sendImageCatalog('YOUR_JWT_TOKEN', '1234567890', products);
console.log('Catalog sent:', results);
Image URL Validationβ
function isValidImageUrl(url) {
try {
const urlObj = new URL(url);
// Check if it's HTTP/HTTPS
if (!['http:', 'https:'].includes(urlObj.protocol)) {
return false;
}
// Check for common image extensions
const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp'];
const hasImageExtension = imageExtensions.some(ext =>
urlObj.pathname.toLowerCase().includes(ext)
);
return hasImageExtension;
} catch {
return false;
}
}
async function sendValidatedImage(token, phoneNumber, imageUrl, caption) {
if (!isValidImageUrl(imageUrl)) {
throw new Error('Invalid image URL format');
}
return await sendImageMessage(token, phoneNumber, imageUrl, caption);
}
Download and Upload Helperβ
If you need to upload images from your local server:
const fs = require('fs');
const FormData = require('form-data');
// Example function to upload image to your CDN/storage
async function uploadImageToCDN(filePath) {
// This is pseudo-code - implement according to your storage solution
const formData = new FormData();
formData.append('file', fs.createReadStream(filePath));
const response = await axios.post('https://your-cdn.com/upload', formData, {
headers: formData.getHeaders()
});
return response.data.url; // Returns public URL
}
// Send local image
async function sendLocalImage(token, phoneNumber, localFilePath, caption) {
try {
// Upload to CDN first
const publicUrl = await uploadImageToCDN(localFilePath);
// Send via WhatsApp
return await sendImageMessage(token, phoneNumber, publicUrl, caption);
} catch (error) {
console.error('Error sending local image:', error);
throw error;
}
}
Best Practicesβ
1. Image Optimizationβ
// Check image size before sending
async function getImageSize(url) {
try {
const response = await fetch(url, { method: 'HEAD' });
const contentLength = response.headers.get('content-length');
return contentLength ? parseInt(contentLength) : null;
} catch {
return null;
}
}
async function sendOptimizedImage(token, phoneNumber, imageUrl, caption) {
const size = await getImageSize(imageUrl);
const maxSize = 16 * 1024 * 1024; // 16MB
if (size && size > maxSize) {
throw new Error(`Image too large: ${size} bytes. Maximum allowed: ${maxSize} bytes`);
}
return await sendImageMessage(token, phoneNumber, imageUrl, caption);
}
2. CDN Usageβ
Use a reliable CDN for hosting images:
const CDN_BASE_URL = 'https://your-cdn.com/images/';
function getCDNImageUrl(fileName) {
return `${CDN_BASE_URL}${fileName}`;
}
async function sendCDNImage(token, phoneNumber, fileName, caption) {
const imageUrl = getCDNImageUrl(fileName);
return await sendImageMessage(token, phoneNumber, imageUrl, caption);
}
3. Error Handling and Retriesβ
async function sendImageWithRetry(token, phoneNumber, imageUrl, caption, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await sendImageMessage(token, phoneNumber, imageUrl, caption);
} catch (error) {
if (error.response?.status === 400 && error.response?.data?.error?.includes('URL')) {
// Don't retry URL-related errors
throw error;
}
if (attempt === maxRetries) {
throw error;
}
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
Common Use Casesβ
E-commerce Product Imagesβ
async function sendProductUpdate(token, customerPhone, product) {
const caption = `ποΈ *${product.name}*
π° Price: $${product.price}
π¦ Stock: ${product.stock > 0 ? 'Available' : 'Out of Stock'}
β Rating: ${product.rating}/5
${product.description}
π Order: ${product.orderUrl}`;
return await sendImageMessage(
token,
customerPhone,
product.imageUrl,
caption,
`${product.sku}.jpg`
);
}
Event Invitationsβ
async function sendEventInvitation(token, guestPhone, event) {
const caption = `π You're Invited! π
*${event.title}*
π
Date: ${event.date}
β° Time: ${event.time}
π Venue: ${event.venue}
${event.description}
RSVP: ${event.rsvpUrl}`;
return await sendImageMessage(
token,
guestPhone,
event.bannerUrl,
caption,
'event-invitation.jpg'
);
}
Limitationsβ
- File size: Maximum 16MB per image
- Formats: JPEG, PNG, GIF, WebP only
- URL accessibility: Images must be publicly accessible
- Rate limits: Follow WhatsApp's messaging limits
Next Stepsβ
- Learn about sending text messages to contacts
- Explore contact verification before sending
- Check out group management for group messaging