Skip to content

Send list

Send interactive list messages on WhatsApp.

Updated View as Markdown

Show a scrollable menu when you have more options than buttons allow — support menus, product picks, or any flow with several choices.

At a glance

Item Detail
type list
Channel support Official and unofficial
Unofficial May be delivered as formatted fallback text
Structure sections[] with rows[] (id, title, optional description)

Request body

Field Required Description
channel_id Yes Sender channel ID
to Yes Recipient phone number
type Yes list
content.body Yes Message text
content.button_text Yes Label on the list open button
content.sections Yes Array of sections with title and rows

Example

curl -X POST "https://api.wazapin.com/v1/messages" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel_id": "wzp_abc123",
    "to": "6281234567890",
    "type": "list",
    "content": {
      "body": "Pilih menu yang kamu mau",
      "button_text": "Lihat menu",
      "sections": [
        {
          "title": "Menu utama",
          "rows": [
            {"id": "menu_1", "title": "Cek pesanan", "description": "Lihat status order"},
            {"id": "menu_2", "title": "Hubungi CS", "description": "Butuh bantuan"}
          ]
        }
      ]
    }
  }'
import { WazapinClient, listMessage } from "@wazapin/sdk";

const wazapin = new WazapinClient({ apiKey: process.env.WAZAPIN_API_KEY! });

await wazapin.messages.send(
  listMessage({
    channel_id: "wzp_abc123",
    to: "6281234567890",
    body: "Pilih menu yang kamu mau",
    button: "Lihat menu",
    sections: [
      {
        title: "Menu utama",
        rows: [
          { id: "menu_1", title: "Cek pesanan", description: "Lihat status order" },
          { id: "menu_2", title: "Hubungi CS", description: "Butuh bantuan" },
        ],
      },
    ],
  }),
);
import requests

requests.post(
    "https://api.wazapin.com/v1/messages",
    headers={"X-Api-Key": "YOUR_API_KEY", "Content-Type": "application/json"},
    json={
        "channel_id": "wzp_abc123",
        "to": "6281234567890",
        "type": "list",
        "content": {
            "body": "Pilih menu yang kamu mau",
            "button_text": "Lihat menu",
            "sections": [
                {
                    "title": "Menu utama",
                    "rows": [
                        {"id": "menu_1", "title": "Cek pesanan", "description": "Lihat status order"},
                        {"id": "menu_2", "title": "Hubungi CS", "description": "Butuh bantuan"},
                    ],
                }
            ],
        },
    },
    timeout=30,
).raise_for_status()
package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	body := []byte(`{
  "channel_id": "wzp_abc123",
  "to": "6281234567890",
  "type": "list",
  "content": {
    "body": "Pilih menu yang kamu mau",
    "button_text": "Lihat menu",
    "sections": [
      {
        "title": "Menu utama",
        "rows": [
          {
            "id": "menu_1",
            "title": "Cek pesanan",
            "description": "Lihat status order"
          },
          {
            "id": "menu_2",
            "title": "Hubungi CS",
            "description": "Butuh bantuan"
          }
        ]
      }
    ]
  }
}`)

	req, err := http.NewRequest(http.MethodPost, "https://api.wazapin.com/v1/messages", bytes.NewReader(body))
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-Api-Key", os.Getenv("WAZAPIN_API_KEY"))
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	// 201 = message accepted; delivery status via webhooks / GET /v1/messages/{id}
	out, _ := io.ReadAll(resp.Body)
	fmt.Println(resp.StatusCode, string(out))
}
<?php

$payload = '{
  "channel_id": "wzp_abc123",
  "to": "6281234567890",
  "type": "list",
  "content": {
    "body": "Pilih menu yang kamu mau",
    "button_text": "Lihat menu",
    "sections": [
      {
        "title": "Menu utama",
        "rows": [
          {
            "id": "menu_1",
            "title": "Cek pesanan",
            "description": "Lihat status order"
          },
          {
            "id": "menu_2",
            "title": "Hubungi CS",
            "description": "Butuh bantuan"
          }
        ]
      }
    ]
  }
}';

$ch = curl_init("https://api.wazapin.com/v1/messages");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Content-Type: application/json",
    "X-Api-Key: " . getenv("WAZAPIN_API_KEY"),
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

// 201 = message accepted; delivery status via webhooks / GET /v1/messages/{id}
echo $httpCode . "\n" . $response . "\n";
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class SendMessage {
    public static void main(String[] args) throws Exception {
        String body = """
                {"channel_id": "wzp_abc123", "to": "6281234567890", "type": "list", "content": {"body": "Pilih menu yang kamu mau", "button_text": "Lihat menu", "sections": [{"title": "Menu utama", "rows": [{"id": "menu_1", "title": "Cek pesanan", "description": "Lihat status order"}, {"id": "menu_2", "title": "Hubungi CS", "description": "Butuh bantuan"}]}]}}
                """;

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://api.wazapin.com/v1/messages"))
                .header("X-Api-Key", System.getenv("WAZAPIN_API_KEY"))
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(body))
                .build();

        HttpResponse<String> response = HttpClient.newHttpClient()
                .send(request, HttpResponse.BodyHandlers.ofString());

        // 201 = message accepted; delivery status via webhooks / GET /v1/messages/{id}
        System.out.println(response.statusCode());
        System.out.println(response.body());
    }
}
require "net/http"
require "uri"

uri = URI("https://api.wazapin.com/v1/messages")
request = Net::HTTP::Post.new(uri)
request["Content-Type"] = "application/json"
request["X-Api-Key"] = ENV["WAZAPIN_API_KEY"]
request.body = '{"channel_id": "wzp_abc123", "to": "6281234567890", "type": "list", "content": {"body": "Pilih menu yang kamu mau", "button_text": "Lihat menu", "sections": [{"title": "Menu utama", "rows": [{"id": "menu_1", "title": "Cek pesanan", "description": "Lihat status order"}, {"id": "menu_2", "title": "Hubungi CS", "description": "Butuh bantuan"}]}]}}'

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end

# 201 = message accepted; delivery status via webhooks / GET /v1/messages/{id}
puts response.code
puts response.body
using System.Net.Http;
using System.Text;

var body = "{\"channel_id\": \"wzp_abc123\", \"to\": \"6281234567890\", \"type\": \"list\", \"content\": {\"body\": \"Pilih menu yang kamu mau\", \"button_text\": \"Lihat menu\", \"sections\": [{\"title\": \"Menu utama\", \"rows\": [{\"id\": \"menu_1\", \"title\": \"Cek pesanan\", \"description\": \"Lihat status order\"}, {\"id\": \"menu_2\", \"title\": \"Hubungi CS\", \"description\": \"Butuh bantuan\"}]}]}}";

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Api-Key", Environment.GetEnvironmentVariable("WAZAPIN_API_KEY"));

var response = await client.PostAsync(
    "https://api.wazapin.com/v1/messages",
    new StringContent(body, Encoding.UTF8, "application/json"));

// 201 = message accepted; delivery status via webhooks / GET /v1/messages/{id}
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());

Endpoint

POST https://api.wazapin.com/v1/messages

Authenticate with X-Api-Key. See Authentication.

Response

On success, the API returns 201 Created with a lean accept-response (status often starts as queued).

{
  "id": "9f1fd66d-c37a-4b50-a8c2-b4dca523f9c8",
  "status": "queued",
  "channel_id": "wzp_abc123",
  "to": "6281234567890",
  "created_at": "2026-03-04T06:20:10Z"
}

Track delivery with Webhooks or GET /v1/messages/{messageID} (full record, including provider_message_id once the provider acknowledges it).

Navigation

Type to search…

↑↓ navigate↵ selectEsc close