List template library
curl --request GET \
--url https://api.omni.z-api.io/whatsapp/businesses/{wabaId}/template-library \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.omni.z-api.io/whatsapp/businesses/{wabaId}/template-library"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.omni.z-api.io/whatsapp/businesses/{wabaId}/template-library', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.omni.z-api.io/whatsapp/businesses/{wabaId}/template-library",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.omni.z-api.io/whatsapp/businesses/{wabaId}/template-library"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.omni.z-api.io/whatsapp/businesses/{wabaId}/template-library")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.omni.z-api.io/whatsapp/businesses/{wabaId}/template-library")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"name": "order_confirmation_1",
"category": "UTILITY",
"languages": [
"pt_BR",
"en_US",
"es_ES"
],
"body": "Ola {{1}}, seu pedido {{2}} foi confirmado."
}
]
}{
"error": 123,
"message": "<string>"
}Other endpoints
Template library
Use Meta’s ready-made templates without going through review
GET
/
whatsapp
/
businesses
/
{wabaId}
/
template-library
List template library
curl --request GET \
--url https://api.omni.z-api.io/whatsapp/businesses/{wabaId}/template-library \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.omni.z-api.io/whatsapp/businesses/{wabaId}/template-library"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.omni.z-api.io/whatsapp/businesses/{wabaId}/template-library', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.omni.z-api.io/whatsapp/businesses/{wabaId}/template-library",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.omni.z-api.io/whatsapp/businesses/{wabaId}/template-library"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.omni.z-api.io/whatsapp/businesses/{wabaId}/template-library")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.omni.z-api.io/whatsapp/businesses/{wabaId}/template-library")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"name": "order_confirmation_1",
"category": "UTILITY",
"languages": [
"pt_BR",
"en_US",
"es_ES"
],
"body": "Ola {{1}}, seu pedido {{2}} foi confirmado."
}
]
}{
"error": 123,
"message": "<string>"
}Concepts
Meta keeps a library of ready-made templates for common use cases — order confirmation, delivery notice, verification code. Templates created from it skip review: they are approved from the start. This endpoint lists what is available for your WABA.The library is defined by Meta and varies by category and language. You cannot add templates to it.
How to find out which models exist
The list belongs to Meta and changes over time, so you query it instead of memorizing it. The endpoint above returns the models available to your WABA, and each one comes with its topic and use case.On Meta’s Graph API, the search (
GET /message_template_library) accepts the
topic, usecase, industry and language filters, plus search and
name. Our route does not pass those filters through today: it returns
the list, and the filtering is yours to do. The values below are there so you
can recognize the topic and the use case of each model in the response.Topics and use cases
| Filter | Values |
|---|---|
| Topic | ACCOUNT_UPDATE, CUSTOMER_FEEDBACK, ORDER_MANAGEMENT, PAYMENTS |
| Industry | E_COMMERCE, FINANCIAL_SERVICES |
| Topic | Use cases |
|---|---|
ORDER_MANAGEMENT | ORDER_CONFIRMATION, ORDER_ACTION_NEEDED, ORDER_DELAY, ORDER_PICK_UP, ORDER_OR_TRANSACTION_CANCEL, DELIVERY_CONFIRMATION, DELIVERY_UPDATE, DELIVERY_FAILED, SHIPMENT_CONFIRMATION, RETURN_CONFIRMATION |
PAYMENTS | PAYMENT_CONFIRMATION, PAYMENT_DUE_REMINDER, PAYMENT_OVERDUE, PAYMENT_ACTION_REQUIRED, PAYMENT_SCHEDULED, PAYMENT_REJECT_FAIL, AUTO_PAY_REMINDER, LOW_BALANCE_WARNING, RECEIPT_ATTACHMENT, STATEMENT_ATTACHMENT, STATEMENT_AVAILABLE, TRANSACTION_ALERT |
ACCOUNT_UPDATE | ACCOUNT_CREATION_CONFIRMATION, FRAUD_ALERT |
CUSTOMER_FEEDBACK | FEEDBACK_SURVEY |
delivery_update_1 or
low_balance_warning_1: that is what goes in library_template_name.
Creating from a model
Creation uses the same API reference endpoint, but the body is different: instead ofcomponents, you send the
model name and the inputs it accepts.
{
"name": "delivery_notice",
"category": "UTILITY",
"language": "en_US",
"library_template_name": "delivery_update_1",
"library_template_body_inputs": [
{ "add_contact_number": true, "add_track_package_link": true }
],
"library_template_button_inputs": [
{
"type": "URL",
"url": {
"base_url": "https://yourstore.com/order/{{1}}",
"url_suffix_example": "https://yourstore.com/order/1042"
}
},
{ "type": "PHONE_NUMBER", "phone_number": "+5511988881234" }
]
}
add_contact_number,
add_learn_more_link, add_security_recommendation,
add_track_package_link) and provide the data for the buttons it asks for.
A model used as is starts out approved. Meta’s docs say customizing
changes that: “If you choose Customize template, your template will have to
go through review before you are able to send messages.” If you change the
content, it goes back into the normal review queue.