curl --request POST \
--url https://api.zapfy.io/v1/messages/send-list \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"to": "5511999998888",
"title": "Our plans",
"description": "Choose the ideal plan",
"buttonText": "Open menu",
"footerText": "Zapfy",
"sections": [
{
"rows": [
{
"title": "Basic plan",
"description": "$29.90/mo",
"rowId": "plan_basic"
}
],
"title": "Plans"
}
],
"mentionedPhones": [
"5511999998888"
],
"mentionAll": true,
"delay": 123
}
'import requests
url = "https://api.zapfy.io/v1/messages/send-list"
payload = {
"to": "5511999998888",
"title": "Our plans",
"description": "Choose the ideal plan",
"buttonText": "Open menu",
"footerText": "Zapfy",
"sections": [
{
"rows": [
{
"title": "Basic plan",
"description": "$29.90/mo",
"rowId": "plan_basic"
}
],
"title": "Plans"
}
],
"mentionedPhones": ["5511999998888"],
"mentionAll": True,
"delay": 123
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
to: '5511999998888',
title: 'Our plans',
description: 'Choose the ideal plan',
buttonText: 'Open menu',
footerText: 'Zapfy',
sections: [
{
rows: [{title: 'Basic plan', description: '$29.90/mo', rowId: 'plan_basic'}],
title: 'Plans'
}
],
mentionedPhones: ['5511999998888'],
mentionAll: true,
delay: 123
})
};
fetch('https://api.zapfy.io/v1/messages/send-list', 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.zapfy.io/v1/messages/send-list",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'to' => '5511999998888',
'title' => 'Our plans',
'description' => 'Choose the ideal plan',
'buttonText' => 'Open menu',
'footerText' => 'Zapfy',
'sections' => [
[
'rows' => [
[
'title' => 'Basic plan',
'description' => '$29.90/mo',
'rowId' => 'plan_basic'
]
],
'title' => 'Plans'
]
],
'mentionedPhones' => [
'5511999998888'
],
'mentionAll' => true,
'delay' => 123
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.zapfy.io/v1/messages/send-list"
payload := strings.NewReader("{\n \"to\": \"5511999998888\",\n \"title\": \"Our plans\",\n \"description\": \"Choose the ideal plan\",\n \"buttonText\": \"Open menu\",\n \"footerText\": \"Zapfy\",\n \"sections\": [\n {\n \"rows\": [\n {\n \"title\": \"Basic plan\",\n \"description\": \"$29.90/mo\",\n \"rowId\": \"plan_basic\"\n }\n ],\n \"title\": \"Plans\"\n }\n ],\n \"mentionedPhones\": [\n \"5511999998888\"\n ],\n \"mentionAll\": true,\n \"delay\": 123\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.zapfy.io/v1/messages/send-list")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"to\": \"5511999998888\",\n \"title\": \"Our plans\",\n \"description\": \"Choose the ideal plan\",\n \"buttonText\": \"Open menu\",\n \"footerText\": \"Zapfy\",\n \"sections\": [\n {\n \"rows\": [\n {\n \"title\": \"Basic plan\",\n \"description\": \"$29.90/mo\",\n \"rowId\": \"plan_basic\"\n }\n ],\n \"title\": \"Plans\"\n }\n ],\n \"mentionedPhones\": [\n \"5511999998888\"\n ],\n \"mentionAll\": true,\n \"delay\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.zapfy.io/v1/messages/send-list")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"to\": \"5511999998888\",\n \"title\": \"Our plans\",\n \"description\": \"Choose the ideal plan\",\n \"buttonText\": \"Open menu\",\n \"footerText\": \"Zapfy\",\n \"sections\": [\n {\n \"rows\": [\n {\n \"title\": \"Basic plan\",\n \"description\": \"$29.90/mo\",\n \"rowId\": \"plan_basic\"\n }\n ],\n \"title\": \"Plans\"\n }\n ],\n \"mentionedPhones\": [\n \"5511999998888\"\n ],\n \"mentionAll\": true,\n \"delay\": 123\n}"
response = http.request(request)
puts response.read_body{
"data": {
"messageId": "3EB0C767D4..."
}
}{
"error": "Instance not found"
}{
"error": "Instance not found"
}{
"error": "Instance not found"
}{
"error": "Instance not found"
}Send list
Sends an interactive message with a list of options for the user to select from. Ideal for menus, catalogs, and simple forms. Options are grouped into sections and the user picks one. Returns { messageId }.
curl --request POST \
--url https://api.zapfy.io/v1/messages/send-list \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"to": "5511999998888",
"title": "Our plans",
"description": "Choose the ideal plan",
"buttonText": "Open menu",
"footerText": "Zapfy",
"sections": [
{
"rows": [
{
"title": "Basic plan",
"description": "$29.90/mo",
"rowId": "plan_basic"
}
],
"title": "Plans"
}
],
"mentionedPhones": [
"5511999998888"
],
"mentionAll": true,
"delay": 123
}
'import requests
url = "https://api.zapfy.io/v1/messages/send-list"
payload = {
"to": "5511999998888",
"title": "Our plans",
"description": "Choose the ideal plan",
"buttonText": "Open menu",
"footerText": "Zapfy",
"sections": [
{
"rows": [
{
"title": "Basic plan",
"description": "$29.90/mo",
"rowId": "plan_basic"
}
],
"title": "Plans"
}
],
"mentionedPhones": ["5511999998888"],
"mentionAll": True,
"delay": 123
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
to: '5511999998888',
title: 'Our plans',
description: 'Choose the ideal plan',
buttonText: 'Open menu',
footerText: 'Zapfy',
sections: [
{
rows: [{title: 'Basic plan', description: '$29.90/mo', rowId: 'plan_basic'}],
title: 'Plans'
}
],
mentionedPhones: ['5511999998888'],
mentionAll: true,
delay: 123
})
};
fetch('https://api.zapfy.io/v1/messages/send-list', 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.zapfy.io/v1/messages/send-list",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'to' => '5511999998888',
'title' => 'Our plans',
'description' => 'Choose the ideal plan',
'buttonText' => 'Open menu',
'footerText' => 'Zapfy',
'sections' => [
[
'rows' => [
[
'title' => 'Basic plan',
'description' => '$29.90/mo',
'rowId' => 'plan_basic'
]
],
'title' => 'Plans'
]
],
'mentionedPhones' => [
'5511999998888'
],
'mentionAll' => true,
'delay' => 123
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.zapfy.io/v1/messages/send-list"
payload := strings.NewReader("{\n \"to\": \"5511999998888\",\n \"title\": \"Our plans\",\n \"description\": \"Choose the ideal plan\",\n \"buttonText\": \"Open menu\",\n \"footerText\": \"Zapfy\",\n \"sections\": [\n {\n \"rows\": [\n {\n \"title\": \"Basic plan\",\n \"description\": \"$29.90/mo\",\n \"rowId\": \"plan_basic\"\n }\n ],\n \"title\": \"Plans\"\n }\n ],\n \"mentionedPhones\": [\n \"5511999998888\"\n ],\n \"mentionAll\": true,\n \"delay\": 123\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.zapfy.io/v1/messages/send-list")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"to\": \"5511999998888\",\n \"title\": \"Our plans\",\n \"description\": \"Choose the ideal plan\",\n \"buttonText\": \"Open menu\",\n \"footerText\": \"Zapfy\",\n \"sections\": [\n {\n \"rows\": [\n {\n \"title\": \"Basic plan\",\n \"description\": \"$29.90/mo\",\n \"rowId\": \"plan_basic\"\n }\n ],\n \"title\": \"Plans\"\n }\n ],\n \"mentionedPhones\": [\n \"5511999998888\"\n ],\n \"mentionAll\": true,\n \"delay\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.zapfy.io/v1/messages/send-list")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"to\": \"5511999998888\",\n \"title\": \"Our plans\",\n \"description\": \"Choose the ideal plan\",\n \"buttonText\": \"Open menu\",\n \"footerText\": \"Zapfy\",\n \"sections\": [\n {\n \"rows\": [\n {\n \"title\": \"Basic plan\",\n \"description\": \"$29.90/mo\",\n \"rowId\": \"plan_basic\"\n }\n ],\n \"title\": \"Plans\"\n }\n ],\n \"mentionedPhones\": [\n \"5511999998888\"\n ],\n \"mentionAll\": true,\n \"delay\": 123\n}"
response = http.request(request)
puts response.read_body{
"data": {
"messageId": "3EB0C767D4..."
}
}{
"error": "Instance not found"
}{
"error": "Instance not found"
}{
"error": "Instance not found"
}{
"error": "Instance not found"
}Authorizations
Instance token (zpfy_inst_...) — sends messages.
Body
Message recipient: phone in E.164 (e.g. 5511999998888) or a group id.
"5511999998888"
Header title.
"Our plans"
Body text.
"Choose the ideal plan"
Label of the button that opens the list.
"Open menu"
Footer text.
"Zapfy"
Sections, each with one or more rows. At least one section with one row is required.
1Show child attributes
Show child attributes
Phones to mention inside the body text.
Mention every participant (groups only).
Optional delay in milliseconds before sending; WhatsApp shows "typing…" during this interval.
Quotes (replies to) a previous message.
Show child attributes
Show child attributes
Response
Message accepted by WhatsApp.
Identifier of the sent message. Store the messageId: together with the same to you sent to, it is what /messages/delete and /messages/edit need.
Show child attributes
Show child attributes