Tutorial

Send Files, PDFs, and Documents via WhatsApp API: Full Guide

A practical guide to sending any file type (PDF invoices, Word documents, spreadsheets, images) via the WhatsApp API. Includes MIME type reference and size limits.

Published: February 15, 2026By Retention Stack

Send Files via WhatsApp API: PDFs, Images, Videos & Documents

Meta Description: Complete guide to sending files via WhatsApp APIβ€”PDFs, images, videos, Excel sheets, and more. MIME types, size limits, compression, and real production examples included.

Introduction

Sending files via WhatsApp beats email by 70%.

Why businesses send files on WhatsApp:
  • Invoices: 98% open rate vs 25% for email
  • Receipts: Instant delivery, no spam folder
  • Contracts: E-signature ready, trackable
  • Reports: Customers actually read them
  • Media: Images, videos, audioβ€”all supported
The numbers:
  • πŸ“± 98% open rate within 5 minutes
  • ⚑ 10x faster than email attachments
  • πŸ’° $0.003 per file vs free (but ignored) email
  • βœ… 70% higher engagement than email
This guide shows you how to send any file type via WhatsApp API:
  • βœ… PDFs (invoices, receipts, contracts)
  • βœ… Images (JPEG, PNG, GIF)
  • βœ… Videos (MP4, MOV)
  • βœ… Audio (MP3, voice notes)
  • βœ… Documents (Word, Excel, PowerPoint)
  • βœ… Archives (ZIP, RAR)
Technical details covered:
  • Supported MIME types
  • File size limits (16MB-100MB depending on type)
  • Compression strategies
  • Security best practices
  • Real-world examples
Time to implement: 15-20 minutes Technical level: Beginner-Intermediate

Let's start sending files.


Supported File Types & Limits

Quick Reference

| File Type | Max Size | MIME Type | Use Cases | |-----------|----------|-----------|----------| | Images | 5 MB | image/jpeg, image/png | Product photos, receipts | | Videos | 16 MB | video/mp4 | Tutorials, demos | | Audio | 16 MB | audio/mpeg, audio/ogg | Voice notes, podcasts | | Documents | 100 MB | application/pdf, .docx, .xlsx | Invoices, contracts, reports | | Archives | 100 MB | application/zip | Multiple files |

Complete MIME Type Reference

javascript
const MIME_TYPES = {
  // Images
  'jpg': 'image/jpeg',
  'jpeg': 'image/jpeg',
  'png': 'image/png',
  'gif': 'image/gif',
  'webp': 'image/webp',
  
  // Videos
  'mp4': 'video/mp4',
  'mov': 'video/quicktime',
  'avi': 'video/x-msvideo',
  
  // Audio
  'mp3': 'audio/mpeg',
  'ogg': 'audio/ogg',
  'wav': 'audio/wav',
  'm4a': 'audio/mp4',
  
  // Documents
  'pdf': 'application/pdf',
  'doc': 'application/msword',
  'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  'xls': 'application/vnd.ms-excel',
  'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  'ppt': 'application/vnd.ms-powerpoint',
  'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
  'txt': 'text/plain',
  'csv': 'text/csv',
  
  // Archives
  'zip': 'application/zip',
  'rar': 'application/x-rar-compressed',
  '7z': 'application/x-7z-compressed'
};

Sending Files: Complete Implementation

WhatsApp File Sender Class

javascript
// whatsapp-file-sender.js
const axios = require('axios');
const fs = require('fs');
const FormData = require('form-data');
const path = require('path');
require('dotenv').config();

class WhatsAppFileSender { constructor() { this.baseURL = https://${process.env.RAPIDAPI_HOST}; this.session = process.env.WHATSAPP_SESSION; this.headers = { 'X-RapidAPI-Key': process.env.RAPIDAPI_KEY, 'X-RapidAPI-Host': process.env.RAPIDAPI_HOST }; }

// Send file from URL async sendFile(phoneNumber, fileUrl, filename, caption = '') { const fileType = this.detectFileType(fileUrl); switch(fileType) { case 'image': return await this.sendImage(phoneNumber, fileUrl, caption); case 'video': return await this.sendVideo(phoneNumber, fileUrl, caption); case 'audio': return await this.sendAudio(phoneNumber, fileUrl); case 'document': return await this.sendDocument(phoneNumber, fileUrl, filename, caption); default: throw new Error(Unsupported file type: ${fileType}); } }

async sendImage(phoneNumber, imageUrl, caption = '') { try { const response = await axios.post( ${this.baseURL}/v1/sendImage, { chatId: phoneNumber.replace(/\D/g, ''), url: imageUrl, caption: caption }, { headers: { ...this.headers, 'Content-Type': 'application/json' } } ); console.log(βœ… Image sent to ${phoneNumber}); return response.data; } catch (error) { console.error('Error sending image:', error.response?.data || error.message); throw error; } }

async sendVideo(phoneNumber, videoUrl, caption = '') { try { const response = await axios.post( ${this.baseURL}/v1/sendVideo, { chatId: phoneNumber.replace(/\D/g, ''), url: videoUrl, caption: caption }, { headers: { ...this.headers, 'Content-Type': 'application/json' } } ); console.log(βœ… Video sent to ${phoneNumber}); return response.data; } catch (error) { console.error('Error sending video:', error.response?.data || error.message); throw error; } }

async sendDocument(phoneNumber, documentUrl, filename, caption = '') { try { const response = await axios.post( ${this.baseURL}/v1/sendFile, { chatId: phoneNumber.replace(/\D/g, ''), url: documentUrl, filename: filename, caption: caption }, { headers: { ...this.headers, 'Content-Type': 'application/json' } } ); console.log(βœ… Document sent to ${phoneNumber}); return response.data; } catch (error) { console.error('Error sending document:', error.response?.data || error.message); throw error; } }

async sendAudio(phoneNumber, audioUrl) { try { const response = await axios.post( ${this.baseURL}/v1/sendVoice, { chatId: phoneNumber.replace(/\D/g, ''), url: audioUrl }, { headers: { ...this.headers, 'Content-Type': 'application/json' } } ); console.log(βœ… Audio sent to ${phoneNumber}); return response.data; } catch (error) { console.error('Error sending audio:', error.response?.data || error.message); throw error; } }

// Send local file (uploads then sends) async sendLocalFile(phoneNumber, filePath, caption = '') { // First upload file to your CDN/S3 const fileUrl = await this.uploadFile(filePath); const filename = path.basename(filePath); // Then send via WhatsApp return await this.sendFile(phoneNumber, fileUrl, filename, caption); }

async uploadFile(filePath) { // Example: Upload to your server/CDN // Replace with your actual upload logic (S3, Cloudinary, etc.) 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; }

detectFileType(fileUrl) { const extension = path.extname(fileUrl).toLowerCase().replace('.', ''); if (['jpg', 'jpeg', 'png', 'gif', 'webp'].includes(extension)) { return 'image'; } else if (['mp4', 'mov', 'avi'].includes(extension)) { return 'video'; } else if (['mp3', 'ogg', 'wav', 'm4a'].includes(extension)) { return 'audio'; } else { return 'document'; } } }

module.exports = WhatsAppFileSender;

Usage Examples

javascript
const WhatsAppFileSender = require('./whatsapp-file-sender');

const fileSender = new WhatsAppFileSender();

// Send PDF invoice await fileSender.sendDocument( '1234567890', 'https://yourcdn.com/invoices/INV-001.pdf', 'Invoice_March_2026.pdf', 'πŸ“„ Your invoice for March 2026. Thank you for your business!' );

// Send receipt image await fileSender.sendImage( '1234567890', 'https://yourcdn.com/receipts/receipt-123.jpg', '🧾 Receipt for Order #123. Thank you!' );

// Send tutorial video await fileSender.sendVideo( '1234567890', 'https://yourcdn.com/tutorials/how-to-setup.mp4', 'πŸŽ₯ Here's a quick tutorial on how to get started!' );

// Send voice note await fileSender.sendAudio( '1234567890', 'https://yourcdn.com/voice-notes/welcome.mp3' );

// Send Excel report await fileSender.sendDocument( '1234567890', 'https://yourcdn.com/reports/Q1-2026.xlsx', 'Q1_2026_Report.xlsx', 'πŸ“Š Q1 2026 financial report attached.' );


Real-World Use Cases

Use Case 1: E-Commerce Order Invoices

javascript
// Send invoice after order completion
async function sendOrderInvoice(order) {
  const fileSender = new WhatsAppFileSender();
  
  // Generate PDF invoice (using jsPDF, PDFKit, etc.)
  const invoicePath = await generateInvoicePDF(order);
  
  // Upload to CDN
  const invoiceUrl = await uploadToS3(invoicePath);
  
  // Send via WhatsApp
  const message = 
πŸ“„ *Invoice for Order #${order.number}*

*Order Total:* $${order.total} *Date:* ${new Date().toLocaleDateString()}

Thank you for your purchase! πŸ™

Questions? Reply to this message. .trim(); await fileSender.sendDocument( order.customerPhone, invoiceUrl, Invoice_${order.number}.pdf, message ); console.log(βœ… Invoice sent for order #${order.number}); }

// Usage const order = { number: '12345', total: 149.99, customerPhone: '1234567890', items: [ { name: 'Product A', quantity: 2, price: 49.99 }, { name: 'Product B', quantity: 1, price: 50.01 } ] };

await sendOrderInvoice(order);


Use Case 2: Digital Product Delivery

javascript
// Deliver digital products (eBooks, courses, templates)
async function deliverDigitalProduct(purchase) {
  const fileSender = new WhatsAppFileSender();
  
  const message = 
πŸŽ‰ *Thank you for your purchase!*

*Product:* ${purchase.productName}

Your digital product is attached below.

πŸ’‘ *Pro Tip:* Save this message for future reference.

Need help? Just reply to this message! 😊 .trim(); // Send product file await fileSender.sendDocument( purchase.customerPhone, purchase.downloadUrl, purchase.filename, message ); // If product includes bonus files if (purchase.bonusFiles) { for (const bonus of purchase.bonusFiles) { await fileSender.sendDocument( purchase.customerPhone, bonus.url, bonus.filename, 🎁 Bonus: ${bonus.name} ); // Rate limiting await new Promise(resolve => setTimeout(resolve, 2000)); } } }

// Usage const purchase = { productName: 'The Complete WhatsApp API Guide', downloadUrl: 'https://yourcdn.com/products/whatsapp-guide.pdf', filename: 'WhatsApp_API_Guide.pdf', customerPhone: '1234567890', bonusFiles: [ { name: 'Code Examples', url: 'https://yourcdn.com/bonuses/examples.zip', filename: 'Code_Examples.zip' }, { name: 'Bonus Checklist', url: 'https://yourcdn.com/bonuses/checklist.pdf', filename: 'Checklist.pdf' } ] };

await deliverDigitalProduct(purchase);


Use Case 3: Real Estate Property Tours

javascript
// Send property photos and documents
async function sendPropertyDetails(property, clientPhone) {
  const fileSender = new WhatsAppFileSender();
  
  // Send property intro message
  const intro = 
🏑 *Property Details*

*Address:* ${property.address} *Price:* $${property.price.toLocaleString()} *Beds:* ${property.bedrooms} | *Baths:* ${property.bathrooms}

Here are the photos and floor plans: .trim(); await fileSender.sendImage(clientPhone, property.photos[0], intro); // Send remaining photos for (let i = 1; i < property.photos.length; i++) { await fileSender.sendImage(clientPhone, property.photos[i]); await new Promise(resolve => setTimeout(resolve, 1000)); } // Send floor plan PDF await fileSender.sendDocument( clientPhone, property.floorPlanUrl, 'Floor_Plan.pdf', 'πŸ“ Floor plan attached' ); // Send virtual tour video if (property.virtualTourUrl) { await fileSender.sendVideo( clientPhone, property.virtualTourUrl, 'πŸŽ₯ Virtual property tour' ); } console.log(βœ… Property details sent for ${property.address}); }


Use Case 4: Restaurant Menu & Specials

javascript
// Send daily menu and specials
async function sendDailyMenu(customerPhone) {
  const fileSender = new WhatsAppFileSender();
  
  const menuImageUrl = await generateMenuImage(getTodaysMenu());
  
  const message = 
🍽️ *Today's Specials*

Good morning! Here's our menu for today:

*Chef's Special:* Grilled Salmon with Lemon Butter *Soup of the Day:* Butternut Squash *Dessert Special:* Tiramisu

πŸ“± Order now: [Order Link]

*10% OFF for orders before 12 PM!* ⏰ .trim(); await fileSender.sendImage(customerPhone, menuImageUrl, message); }

// Send weekly newsletter with recipes async function sendWeeklyNewsletter(subscribers) { const fileSender = new WhatsAppFileSender(); const newsletterPDF = 'https://yourcdn.com/newsletters/week-14.pdf'; for (const subscriber of subscribers) { await fileSender.sendDocument( subscriber.phone, newsletterPDF, 'Weekly_Recipes.pdf', 'πŸ“° This week's recipes! Enjoy! πŸ‘¨β€πŸ³' ); await new Promise(resolve => setTimeout(resolve, 500)); } }


File Optimization & Best Practices

Compress Large Files

javascript
const sharp = require('sharp');
const ffmpeg = require('fluent-ffmpeg');

// Compress images with Sharp async function compressImage(inputPath, outputPath, quality = 80) { await sharp(inputPath) .jpeg({ quality, progressive: true }) .toFile(outputPath); const originalSize = fs.statSync(inputPath).size; const newSize = fs.statSync(outputPath).size; const savings = ((originalSize - newSize) / originalSize * 100).toFixed(1); console.log(βœ… Compressed image: ${savings}% smaller); return outputPath; }

// Compress videos with FFmpeg async function compressVideo(inputPath, outputPath) { return new Promise((resolve, reject) => { ffmpeg(inputPath) .outputOptions([ '-c:v libx264', '-crf 28', '-preset fast', '-c:a aac', '-b:a 128k' ]) .on('end', () => { console.log('βœ… Video compressed'); resolve(outputPath); }) .on('error', reject) .save(outputPath); }); }

// Compress PDFs const { PDFDocument } = require('pdf-lib');

async function compressPDF(inputPath, outputPath) { const pdfBytes = fs.readFileSync(inputPath); const pdfDoc = await PDFDocument.load(pdfBytes); // Remove metadata to reduce size pdfDoc.setTitle(''); pdfDoc.setAuthor(''); pdfDoc.setSubject(''); pdfDoc.setKeywords([]); pdfDoc.setProducer(''); pdfDoc.setCreator(''); const compressedPdfBytes = await pdfDoc.save(); fs.writeFileSync(outputPath, compressedPdfBytes); const originalSize = fs.statSync(inputPath).size; const newSize = fs.statSync(outputPath).size; const savings = ((originalSize - newSize) / originalSize * 100).toFixed(1); console.log(βœ… Compressed PDF: ${savings}% smaller); return outputPath; }


Security Best Practices

javascript
// Secure file handling
class SecureFileSender extends WhatsAppFileSender {
  async sendFile(phoneNumber, fileUrl, filename, caption = '') {
    // 1. Validate phone number
    if (!this.isValidPhoneNumber(phoneNumber)) {
      throw new Error('Invalid phone number');
    }
    
    // 2. Check file size
    const fileSize = await this.getFileSize(fileUrl);
    if (fileSize > 100 * 1024 * 1024) { // 100 MB
      throw new Error('File too large (max 100MB)');
    }
    
    // 3. Scan for malware (if using uploads)
    if (this.isUserUploadedFile(fileUrl)) {
      await this.scanForMalware(fileUrl);
    }
    
    // 4. Generate expiring URL (24 hours)
    const expiringUrl = await this.generateExpiringUrl(fileUrl, 24);
    
    // 5. Send file
    return await super.sendFile(phoneNumber, expiringUrl, filename, caption);
  }
  
  async getFileSize(url) {
    const response = await axios.head(url);
    return parseInt(response.headers['content-length']);
  }
  
  isValidPhoneNumber(phone) {
    return /^[1-9]\d{9,14}$/.test(phone.replace(/\D/g, ''));
  }
  
  async scanForMalware(fileUrl) {
    // Integrate with VirusTotal, ClamAV, etc.
    // Throw error if malware detected
  }
  
  async generateExpiringUrl(fileUrl, hoursValid) {
    // Generate signed URL with expiration
    // Example: AWS S3 presigned URLs
  }
}

Troubleshooting

Common Issues

1. File too large
javascript
// Solution: Compress before sending
if (fileSize > MAX_SIZE) {
  filePath = await compressFile(filePath);
}
2. Unsupported file type
javascript
// Solution: Convert to supported format
if (!isSupportedType(file)) {
  file = await convertToSupportedType(file);
}
3. Slow uploads
javascript
//Solution: Use CDN with global distribution
const cdnUrl = await uploadToCDN(file); // Cloudflare, Cloudinary
4. WhatsApp compression ruins quality
javascript
// Solution: Send as document instead of image
await sendDocument(phone, imageUrl, 'High_Quality_Image.jpg');

Conclusion

You've learned how to:

  • βœ… Send any file type via WhatsApp API
  • βœ… Handle PDFs, images, videos, audio, documents
  • βœ… Optimize files for fast delivery
  • βœ… Implement security best practices
  • βœ… Build real-world file sharing systems
  • βœ… Compress and optimize large files
Key takeaways:
  • Max file size: 100 MB (documents)
  • 98% open rate vs 25% for email
  • Cost: ~$0.003 per file
  • Instant delivery (<5 seconds)

Start Sending Files Today

Ready to deliver files via WhatsApp?

πŸ‘‰ Get your free RapidAPI key and send your first file in 5 minutes.

What's included:
  • Support for all file types
  • 100 free messages to test
  • Full API documentation
  • 24/7 support
Related guides:
Questions? Leave a comment!

πŸ“„ Never miss a delivery again!

Ready to Get Started?

Try the WhatsApp API free on RapidAPI with no credit card required.

Try Free on RapidAPI