Sending PDF Lab Reports on WhatsApp: API Setup and Implementation Guide

Diagnostic labs across Pakistan and India waste thousands of rupees every month printing reports that patients never pick up. SMS links with download URLs perform poorly because mobile carriers filter them or patients treat unknown links as spam. Sending a PDF report directly into a patient's WhatsApp inbox solves both problems.
This guide explains how to connect your Laboratory Information Management System (LIMS) to WhatsApp using the official WhatsApp Business Cloud API. You will learn how to register templates, upload PDF files, handle message delivery, and write code that triggers reports automatically when test results are ready.
What You Need Before Starting
Do not attempt to write code until you have these components ready:
- A Meta Business Manager Account: Created at business.facebook.com. You will need business verification documents (like your NTN certificate in Pakistan or GST registration in India) if you plan to send more than 250 messages per day.
- A Dedicated Phone Number: A number that is not currently logged into WhatsApp on any phone. If it is active on a personal or business app, you must delete the account inside the app settings first.
- A Meta Developer Account: Registered at developers.facebook.com with an active App set to the "Business" type.
- Patient Opt-In Data: Meta strictly enforces opt-in rules. Your registration desk or online booking portal must explicitly inform patients that reports will arrive via WhatsApp.
Step 1: Set Up Meta Cloud API Credentials
Log in to the Meta Developer Portal, select your app, and navigate to WhatsApp > API Setup. Meta gives you a temporary access token and a test phone number immediately.
For production, a temporary token fails after 24 hours. You must create a permanent System User token:
- Go to Meta Business Settings > System Users.
- Add a System User with the role of Admin.
- Click Generate New Token, select your WhatsApp App, and assign the
whatsapp_business_messagingandwhatsapp_business_managementpermissions. - Copy the generated token. Store it securely in your server environment variables.
You also need your Phone Number ID and WhatsApp Business Account ID (WABA ID) from the API Setup screen. These are numeric strings, not phone numbers.
How to test: Send a sample template message from Meta's API setup console to your personal phone number. If your phone receives the message, your credentials are valid.
Common failure: Error code 190 (Invalid OAuth Access Token). This happens when you use the temporary token past its 24-hour lifespan or forget to assign the system user token to your WABA account.
Step 2: Submit a Document Message Template
Meta does not allow businesses to send arbitrary messages to patients who have not messaged them within the last 24 hours. Because labs usually take several hours or days to process tests, you must use a pre-approved Document Template.
Go to your WhatsApp Manager, select Account Tools > Message Templates, and click Create Template.
- Category: UTILITY
- Name:
lab_report_delivery(lowercase, underscores only) - Language: English (US) or your target language
- Header: Select Document. Upload a sample single-page PDF report for review.
Set the body text to something like this:
Dear {{1}}, your lab test report for {{2}} (Bill No: {{3}}) is ready. The report file is attached to this message. Thank you for choosing {{4}}.
Meta automatically reviews utility templates. Approval usually takes between two minutes and two hours.
How to confirm: Check the template list in WhatsApp Manager. The status badge next to lab_report_delivery must display green as Approved.
Why it fails: Meta rejects templates if you put promotional content inside a UTILITY template or if your variable parameters (like {{1}}) sit at the very beginning or end of a sentence without surrounding context.
Step 3: Format Patient Phone Numbers Correctly
This is where most LIMS integrations fail. Meta requires phone numbers in full E.164 format without any plus signs, zeros, hyphens, or spaces.
In Pakistan, front desk staff often type numbers as 03001234567. In India, they type 09876543210 or 9876543210.
Your backend must sanitize these numbers before firing the API request:
- Pakistani numbers must convert from
03001234567to923001234567. - Indian numbers must convert from
09876543210or9876543210to919876543210.
Strip all non-numeric characters using a regular expression in your code before calling Meta's endpoints.
Step 4: Upload the PDF or Use a Hosted URL
You have two ways to send the PDF file to Meta: uploading the media file directly to Meta's servers to get a media ID, or passing a public HTTPS link to the file in the API payload.
Uploading directly via the Media API is safer for medical privacy because it avoids leaving public links active on Amazon S3 or your web server.
To upload the PDF, make a POST request to Meta's media endpoint:
POST https://graph.facebook.com/v19.0/{PHONE_NUMBER_ID}/media
Include headers for Authorization: Bearer {YOUR_SYSTEM_USER_TOKEN} and form data containing:
file: The local PDF binary file (maximum size 100 MB, though lab PDFs should stay under 5 MB for fast mobile downloading).type:application/pdfmessaging_product:whatsapp
Meta returns a JSON response containing an id field (e.g., "id": "1092837465").
How to confirm: You receive a 200 OK HTTP response code containing a numeric id string.
What fails: Attempting to upload files over local network paths (like C:\Reports\123.pdf) instead of sending multi-part form data bytes. The upload will fail instantly.
Step 5: Send the WhatsApp Template Payload
Now, construct the JSON payload to send the actual message. Send a POST request to:
POST https://graph.facebook.com/v19.0/{PHONE_NUMBER_ID}/messages
Here is a working JSON payload structure:
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "923001234567",
"type": "template",
"template": {
"name": "lab_report_delivery",
"language": {
"code": "en_US"
},
"components": [
{
"type": "header",
"parameters": [
{
"type": "document",
"document": {
"id": "1092837465",
"filename": "Lab_Report_10948.pdf"
}
}
]
},
{
"type": "body",
"parameters": [
{ "type": "text", "text": "Ali Khan" },
{ "type": "text", "text": "Complete Blood Count" },
{ "type": "text", "text": "INV-8839" },
{ "type": "text", "text": "City Lab Lahore" }
]
}
]
}
}
How to confirm: Meta returns a JSON payload containing a messages array with a wamid string (WhatsApp Message ID). This means Meta accepted the queue item.
What Does Not Work and What to Avoid
Do not use web scraping libraries like Puppeteer, Selenium, or unofficial WhatsApp Web wrappers (such as Baileys or WhatsApp-web.js) for medical lab operations. Meta detects these automated scripts within days and issues permanent bans on connected numbers. When your business number gets banned, you lose access to customer service chats and historic patient communication.
Avoid sending direct, unencrypted Amazon S3 URLs containing patient names or medical registration numbers in the filename. Medical data security regulations in India (DISHA standards) and global privacy rules mandate protection of patient records. If you link directly to PDFs, use password-protected PDF files where the password is the patient's date of birth or last four digits of their phone number.
If managing Meta API infrastructure, media uploads, and token lifecycles directly is too complex for your internal IT staff, gateway services like WA Link can manage template syncing and API distribution. However, services like WA Link cannot fix corrupted phone numbers in your LIMS database or bypass Meta's fundamental document size restrictions.
Handling Common Delivery Errors
A successful API call with a 200 OK response code only confirms that Meta received the payload. It does not guarantee the patient received the PDF. You must listen to Webhooks on your server to process real-time status updates.
| Meta Error Code | Meaning | Required Action |
|---|---|---|
131026 | Message undelivered | The patient's phone number is valid, but the message was rejected by Meta (e.g., user opted out, or device unreachable for over 14 days). |
131047 | Re-engagement limit reached | You sent too many unacknowledged messages to a user without a reply. Wait for the user to message you first. |
132001 | Template does not exist | The template name or language code in your JSON payload does not match the approved template in Meta Manager exactly. |
100 | Invalid parameter | You missed a required template variable or passed five variables when your template only defines four. |
What to Do Next
Now that you can dispatch single PDFs manually, connect the process directly into your LIMS backend pipeline:
- Write a database trigger or cron job that runs every 60 seconds looking for test entries marked with status
COMPLETEDand statusNOT_SENT. - Generate the PDF using your reporting engine (like JasperReports, Dompdf, or ReportLab) and save it locally.
- Call Meta's Media API to upload the generated file and retrieve the
media_id. - Fire the WhatsApp Template API call.
- Update your database record to status
SENTalongside the returnedwamidfor audit tracking. - Setup an endpoint to receive incoming webhooks so your system updates to status
DELIVEREDorREADwhen the patient opens the message.
Frequently Asked Questions
Can I send a password-protected PDF file to a patient?
Yes. Meta handles password-protected PDF files the same way as standard PDFs. When the patient opens the document inside WhatsApp, their device prompts them for the password. Setting the password to the patient's year of birth or MRN number is standard industry practice.
What happens if a patient replies to the lab report on WhatsApp?
When a patient replies, Meta triggers a webhook payload containing the message text to your server. This opens a 24-hour customer service window. During this window, you can send free-form text messages back to the patient without using pre-approved templates.
Is there a file size limit for sending PDF test reports?
WhatsApp allows document files up to 100 MB via the Cloud API. However, keep your PDF file sizes under 2 MB to ensure rapid downloading over 3G and 4G mobile networks.