WhatsApp API Tutorial: How to Send Messages and Templates

Learn how to send WhatsApp messages and templates using the Meta Cloud API and Zernio. This tutorial covers text, media, and template messages, as well as creating and scheduling broadcasts.

Miki Palet

by

·12 min read·

A customer places an order and expects an instant confirmation. Another signs up and needs a one-time password within seconds. A support team wants to send timely updates without delays. In each of these scenarios, speed and reliability are not optional; they are expected and important.

Many businesses begin with email or SMS, only to encounter limitations such as delayed delivery, low engagement, or fragmented systems that are difficult to scale. As user expectations grow, so does the need for a more direct and reliable way to communicate with users.

This is where WhatsApp comes in. With its global reach and high engagement rates, it enables businesses to send messages directly to users in real-time. However, sending messages programmatically, especially template messages, can quickly become complicated when dealing with multiple API endpoints. That is why we built Zernio (formerly Zernio).

In this tutorial, you will learn how to:

  • Send WhatsApp messages and templates using the Meta Cloud API.
  • Integrate the API with Node.js to send messages from your applications.
  • Send messages and templates using the Zernio API and SDKs.
  • Understand why Zernio is a reliable choice for sending bulk messages and templates.

Prerequisites

To follow along with this tutorial, ensure you have the following:

  • WhatsApp Account: An active WhatsApp account to receive and test messages sent via the API.
  • WhatsApp Business Account (WABA): Required to send messages and templates. You can create one via WhatsApp Business.
  • Node.js: A JavaScript runtime that allows you to run JavaScript code outside the browser. Download it from nodejs.org.
  • Code Editor: A software application used for writing and editing code. For example, Visual Studio Code is widely used for JavaScript development.

How to Set Up WhatsApp Messaging with Meta Cloud API

Before sending messages programmatically, you need to set up the WhatsApp API on Meta. In this section, you will create an app, generate an access token, and send your first message.

To get started, visit Meta for Developers, sign in, and click the My Apps button at the top of the page.

my_apps.png

Next, enter your app details and select "Connect with customers through WhatsApp" as the use case.

connect_via_whatsapp.png

Verify the app details and create a new app.

verify_submit.png

After creating the app, configure it based on your use case.

customize_usecase.png

Select API Setup from the sidebar menu and click Generate access token to create your authentication token.

api_setup.png

Add a phone number to the recipients list.

select_recipient.png

Click Send message to test the API. You should receive a message on your test phone number.

send_message.png

Next, select Quickstart from the sidebar menu and click Message Templates.

create_temp.png

WhatsApp sends messages using templates. Templates allow you to create structured messages with placeholders (variables) that can be dynamically filled with user-specific data.

select_template-ezgif.com-video-to-gif-converter.gif

Finally, create a new template by adding content, buttons, and variables. This allows you to build reusable and customisable message templates.

edit_template-ezgif.com-video-to-gif-converter.gif

Send WhatsApp Messages and Templates in Node.js

In this section, you will learn how to integrate the WhatsApp API with Node.js to send text, media, interactive, and template messages directly from your application.

First, create a folder to hold your project files.

mkdir whatsapp-api
cd whatsapp-api

Run the following code snippet to create a package.json file within the project folder.

npm init -y

Next, install the project dependencies. We will use Axios for making HTTP requests to the WhatsApp API, Dotenv for managing environment variables securely, and Form-data to handle multipart form data when sending media or template messages.

npm install axios dotenv form-data

Create an index.js file within the project folder and import the newly installed packages into the file.

require("dotenv").config();
const FormData = require("form-data");
const axios = require("axios");
const fs = require("fs");

Add a .env file inside your project folder and add your credentials as environment variables.

WHATSAPP_TOKEN=<your_access_token>
WHATSAPP_PHONE_NUMBER_ID=<your_phone_number_ID>
WHATSAPP_RECIPIENT_PHONE_NUMBER=<recipient_whatsapp_number>

You can run your application at any time using the following command:

node index.js

Congratulations, your setup is complete!

Code Integration Examples

Add the following code snippet to the index.js file to send message templates directly from the application.

async function sendTemplateMessage() {
	const response = await axios({
		url: `https://graph.facebook.com/v22.0/${process.env.WHATSAPP_PHONE_NUMBER_ID}/messages`,
		method: "post",
		headers: {
			Authorization: `Bearer ${process.env.WHATSAPP_TOKEN}`,
			"Content-Type": "application/json",
		},
		data: JSON.stringify({
			messaging_product: "whatsapp",
			to: `${process.env.WHATSAPP_RECIPIENT_PHONE_NUMBER}`,
			type: "template",
			template: {
				name: "hello_world",
				language: {
					code: "en_US",
				},
			},
		}),
	});

	console.log(response.data);
}

sendTemplateMessage();

The sendTemplateMessage function sends the default template to the recipient using the credentials stored in the environment variables.

You can also send text messages directly from the API using the function below:

async function sendTextMessage() {
	const response = await axios({
		url: `https://graph.facebook.com/v22.0/${process.env.WHATSAPP_PHONE_NUMBER_ID}/messages`,
		method: "post",
		headers: {
			Authorization: `Bearer ${process.env.WHATSAPP_TOKEN}`,
			"Content-Type": "application/json",
		},
		data: JSON.stringify({
			messaging_product: "whatsapp",
			to: `${process.env.WHATSAPP_RECIPIENT_PHONE_NUMBER}`,
			type: "text",
			text: {
				body: "This is a text message",
			},
		}),
	});

	console.log(response.data);
}

sendTextMessage();

The sendTextMessage has a type attribute set to "text" and includes a text object for sending plain text messages.

To send images with captions, update the type property as follows:

async function sendMediaMessage() {
	const response = await axios({
		url: `https://graph.facebook.com/v22.0/${process.env.WHATSAPP_PHONE_NUMBER_ID}/messages`,
		method: "post",
		headers: {
			Authorization: `Bearer ${process.env.WHATSAPP_TOKEN}`,
			"Content-Type": "application/json",
		},
		data: JSON.stringify({
			messaging_product: "whatsapp",
			to: `${process.env.WHATSAPP_RECIPIENT_PHONE_NUMBER}`,
			type: "image",
			image: {
				link: "https://dummyimage.com/600x400/000/c0a&text=hi",
				caption: "Hi! This is an image message.",
			},
		}),
	});

	console.log(response.data);
}

sendMediaMessage();

The sendMediaMessage function is used to send an image with a caption. It sets the type to "image" and includes an image object containing the link to the image and a caption.

You can also send images stored on your local computer using the WhatsApp API. To do this, you first need to upload the image to the API, retrieve its image ID, and then send the image message using that ID.

Add the image file to your project folder, and then copy the following code snippet into your index.js file:

const fs = require("fs");

async function uploadImage() {
	const data = new FormData();
	data.append("messaging_product", "whatsapp");
	data.append("file", fs.createReadStream(process.cwd() + "/image.png"), {
		contentType: "image/png",
	});
	data.append("type", "image/png");

	const response = await axios({
		url: `https://graph.facebook.com/v22.0/${process.env.WHATSAPP_PHONE_NUMBER_ID}/media`,
		method: "post",
		headers: {
			Authorization: `Bearer ${process.env.WHATSAPP_TOKEN}`,
		},
		data: data,
	});

	console.log(response.data);
}

The uploadImage function uploads a local image to the WhatsApp API and logs the image id attribute to the console.

Finally, send the newly upload image to WhatsApp using the function below:

async function sendMediaMessage() {
	const response = await axios({
		url: `https://graph.facebook.com/v22.0/${process.env.WHATSAPP_PHONE_NUMBER_ID}/messages`,
		method: "post",
		headers: {
			Authorization: `Bearer ${process.env.WHATSAPP_TOKEN}`,
			"Content-Type": "application/json",
		},
		data: JSON.stringify({
			messaging_product: "whatsapp",
			to: `${process.env.WHATSAPP_RECIPIENT_PHONE_NUMBER}`,
			type: "image",
			image: {
				id: "8954**********",
				caption: "Hi! This is an image message.",
			},
		}),
	});

	console.log(response.data);
}

sendMediaMessage();

The sendMediaMessage function replaces the link attribute with the image id when sending images saved on your local computer.

Stop building social integrations from scratch.

One API call to publish, schedule, and manage posts across 15+ platforms.

A Simpler Alternative: Send WhatsApp Messages with Zernio API

Zernio is an all-in-one social media management platform that allows you to schedule and publish multimedia content across multiple platforms, including Twitter (X), Instagram, and LinkedIn, through a single, unified API.

In this tutorial, you will configure Zernio for WhatsApp messaging and learn how to create, schedule, and send messages using its API and SDKs.

First, create a Zernio account and log into your dashboard.

dashboard.png

Select Connections from the sidebar menu and connect your WhatsApp account to Zernio.

connect_whatsapp.png

After clicking the WhatsApp Connect button, a pop-up appears where you can choose between getting a US number at a flat rate of $2 per month or connecting an existing WhatsApp Business account.

payment_option.png

Select an option and connect your WhatsApp number to Zernio.

connect_successful.png

From the sidebar menu, select Broadcast > Templates to create a new WhatsApp template based on your messaging needs.

create_whatsapp_template-ezgif.com-video-to-gif-converter.gif

You may need to wait up to 24 hours for Meta to approve your template. Once approved, you can start sending messages to your customers or contacts.

template_approve.png

Configuring Zernio API and Node.js SDK

Before we proceed, copy your Zernio API key and WhatsApp account ID and save them into environment variables in the .env file.

Zernio_API_KEY=<your_api_key>
Zernio_WHATSAPP_ACCOUNT_ID=<WhatsApp_account_ID>

Select API keys from the sidebar menu to create a new API key.

create_zernio_key.png

Click the Copy icon under the WhatsApp connection to copy your account ID.

copy_whatsapp_id.png

Next, install Zernio Node.js SDK.

npm install @zernio/node

Finally, import it into the index.js file as shown below:

const Zernio = require("@zernio/node").default;
const zernio = new Zernio({ apiKey: process.env.Zernio_API_KEY });

Sending WhatsApp Messages with the Zernio SDK

Zernio allows you to group your contacts or customers into broadcast lists, making it easy to send or schedule bulk messages. This is useful for sharing updates such as new arrivals, price changes, or other important information.

In this section, you will learn how to create broadcast lists and send messages using the Zernio Node.js SDK.

Using the existing whatsapp-api Node.js project, add the following code snippet to your index.js file.

async function sendWithZernio() {
	const { data } = await zernio.whatsapp.sendWhatsAppBulk({
		body: {
			accountId: process.env.Zernio_WHATSAPP_ACCOUNT_ID,
			recipients: [
				{
					phone: `${process.env.WHATSAPP_RECIPIENT_PHONE_NUMBER}`,
					variables: { 1: "David", 2: "Bread and Butter" },
				},
			],
			template: {
				name: "order_ready",
				language: "en",
			},
		},
	});
	console.log(`Sent: ${data.summary.sent}, Failed: ${data.summary.failed}`);
}

sendWithZernio();

The sendWithZernio function uses the sendWhatsAppBulk method to send a template message to the phone numbers defined in the recipients array. It references the order_ready template and passes dynamic values through the variables object, which are inserted into the template before sending.

Once executed, the function sends the message to the specified contacts and logs a summary of successful and failed deliveries.

zernio_message_deliver.png

Next, let's create a WhatsApp broadcast to schedule and send messages to your contacts.

Add the following code snippet to create a new broadcast:

async function createBroadcastList() {
	const { data } = await zernio.whatsapp.createWhatsAppBroadcast({
		body: {
			accountId: process.env.Zernio_WHATSAPP_ACCOUNT_ID,
			name: "Monthly Newsletter",
			template: {
				name: "order_ready",
				language: "en",
				components: [
					{
						type: "body",
						parameters: [
							{ type: "text", text: "{{1}}" },
							{ type: "text", text: "{{2}}" },
						],
					},
				],
			},
			recipients: [
				{
					phone: `${process.env.WHATSAPP_RECIPIENT_PHONE_NUMBER}`,
					name: "David",
					variables: { 1: "David", 2: "Mac and Cheese" },
				},
			],
		},
	});
	console.log("Broadcast created:", data.broadcast.id);
}

The createBroadcastList function creates a new broadcast using an existing message template and a list of recipients. It assigns a name to the broadcast, defines the template to be used, and includes dynamic variables for each recipient.

When executed, the function logs the broadcast ID to the console. This ID can then be used to send or schedule messages to all recipients in the broadcast list.

Copy the following code snippet to send an instant message to the contacts in the broadcast list.

async function sendInstantMessage() {
	const { data } = await zernio.whatsapp.sendWhatsAppBroadcast({
		path: { broadcastId: "YOUR_BROADCAST_ID" },
	});
	console.log(`Sent: ${data.sent}, Failed: ${data.failed}`);
}

sendInstantMessage();

Finally, you can schedule broadcast messages by providing a scheduledAt attribute with an ISO 8601 formatted timestamp.

async function scheduleBroadcast() {
	await zernio.whatsapp.scheduleWhatsAppBroadcast({
		path: { broadcastId: "YOUR_BROADCAST_ID" },
		body: { scheduledAt: "2026-03-22T19:36:00.000Z" },
	});
	console.log("Broadcast scheduled for 2026-03-22T19:36:00.000Z");
}

scheduleBroadcast();

scheduled_whatsapp.png

The scheduleBroadcast function schedules a broadcast using the broadcast ID and the specified time. Once executed, the broadcast will be sent automatically at the scheduled date and time, and the console logs a confirmation.

If you encounter any issues or want to interact with the Zernio API directly, using another programming language such as Python instead of the SDKs, check out the Zernio WhatsApp API documentation. It includes details on pricing, supported file formats and media requirements, and debugging and troubleshooting tips.

Why Choose Zernio (formerly Zernio)?

When working with social media APIs, publishing content across multiple platforms can quickly become complex, as each has its own API, authentication method, request format, and media upload workflow. For developers building automation systems, this means writing and maintaining separate integrations for every platform.

Zernio simplifies this process by providing a unified API for social media publishing. Instead of managing multiple APIs and authentication flows, you can interact with a single interface that handles the platform-specific complexity for you.

Below are some of the key challenges developers face when working with social media platform APIs and how Zernio addresses them.

Platform-Specific Authentication

Most social media platforms require different authentication mechanisms such as OAuth flows, app passwords, or API keys. Each method has its own setup process, token management system, and permission scopes.

Zernio handles the authentication process for you. Once your account is connected to Zernio, you can publish posts through the unified API without managing platform-specific tokens or authorisation flows.

Different API Payload Structures

Every social platform expects requests in a slightly different format. The structure for creating a post on one platform may look completely different on another.

Zernio standardises these differences by allowing you to send a single payload format that works across supported platforms. This makes your automation workflows simpler and easier to maintain.

const response = await fetch("https://zernio.com/api/v1/posts", {
  method: "POST",
  headers: { "Authorization": `Bearer ${Zernio_API_KEY}` },
  body: JSON.stringify({
    text: "New feature drop!",
    platforms: ["twitter", "instagram", "linkedin"],
    mediaUrls: ["https://example.com/demo.mp4"],
    scheduledFor: "2025-01-15T09:00:00Z"
  })
});

Media Upload Complexity

Uploading images or videos is often one of the most complicated parts of social media integrations. Some platforms require multi-step upload processes, while others have strict requirements for file formats, sizes, and metadata.

Zernio abstracts these workflows into a simple interface, allowing you to attach media to posts without handling the platform-specific upload process.

Rate Limits and Platform Restrictions

Social media platforms typically enforce rate limits that restrict how frequently your application can interact with their APIs. These limits vary between platforms and can cause unexpected failures if not managed correctly.

Zernio helps manage these platform-specific constraints, allowing your automation workflows to focus on publishing content rather than handling rate limit logic.

Comparison: Using Meta Cloud API Directly vs Zernio

FeatureMeta Cloud API (Direct)Zernio API / SDK
Meta Business VerificationRequiredZernio handles it
Supports Other PlatformsNo. WhatsApp only14 platforms including Instagram,
TikTok, LinkedIn, and many others
Template ManagementRequires access to Meta Developer's portalZernio API and dashboard
Handle rate limitingManualAutomatic

Conclusion

In this tutorial, you've learnt how to send WhatsApp messages and templates using both the Meta Cloud API and Zernio. You also explored how to send text, media, and template messages, as well as creating and scheduling broadcasts to reach multiple contacts efficiently using Zernio.

It's also important to note that Zernio includes WhatsApp messaging in your plan at no extra cost, while Meta charges per delivered template message directly to your WhatsApp Business Account.

Here are some helpful resources to explore next:

Thank you for reading!

Sign up and get your free API key to enable automated posting, monitoring, and engagement across multiple platforms.

Learn more about this topic with AI