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.

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 TypeMax SizeMIME TypeUse Cases
Images5 MBimage/jpeg, image/pngProduct photos, receipts
Videos16 MBvideo/mp4Tutorials, demos
Audio16 MBaudio/mpeg, audio/oggVoice notes, podcasts
Documents100 MBapplication/pdf, .docx, .xlsxInvoices, contracts, reports
Archives100 MBapplication/zipMultiple 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