curl --request POST \
--url https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/campaigns/preview-recipients \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'cloudchat-instance: <cloudchat-instance>' \
--data '
{
"channel": "whatsapp",
"audience": [
{
"type": "Label",
"id": 20010
}
]
}
'import requests
url = "https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/campaigns/preview-recipients"
payload = {
"channel": "whatsapp",
"audience": [
{
"type": "Label",
"id": 20010
}
]
}
headers = {
"cloudchat-instance": "<cloudchat-instance>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'cloudchat-instance': '<cloudchat-instance>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({channel: 'whatsapp', audience: [{type: 'Label', id: 20010}]})
};
fetch('https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/campaigns/preview-recipients', 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.cloudhumans.com/cloudchat/v1/accounts/{accountId}/campaigns/preview-recipients",
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([
'channel' => 'whatsapp',
'audience' => [
[
'type' => 'Label',
'id' => 20010
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"cloudchat-instance: <cloudchat-instance>"
],
]);
$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.cloudhumans.com/cloudchat/v1/accounts/{accountId}/campaigns/preview-recipients"
payload := strings.NewReader("{\n \"channel\": \"whatsapp\",\n \"audience\": [\n {\n \"type\": \"Label\",\n \"id\": 20010\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("cloudchat-instance", "<cloudchat-instance>")
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.cloudhumans.com/cloudchat/v1/accounts/{accountId}/campaigns/preview-recipients")
.header("cloudchat-instance", "<cloudchat-instance>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"channel\": \"whatsapp\",\n \"audience\": [\n {\n \"type\": \"Label\",\n \"id\": 20010\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/campaigns/preview-recipients")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["cloudchat-instance"] = '<cloudchat-instance>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"channel\": \"whatsapp\",\n \"audience\": [\n {\n \"type\": \"Label\",\n \"id\": 20010\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"total": 1240,
"reachable": 1187
}{
"error": {
"code": "bad_request",
"message": "The request is malformed."
}
}{
"error": {
"code": "unauthorized",
"message": "Authentication is required. Send a valid Bearer token in the Authorization header."
}
}{
"error": {
"code": "forbidden",
"message": "You do not have permission to perform this action."
}
}{
"error": {
"code": "not_found",
"message": "Resource could not be found."
}
}{
"error": {
"code": "validation_failed",
"message": "The request payload is invalid.",
"details": [
{
"field": "short_code",
"code": "taken",
"message": "has already been taken"
}
]
}
}{
"error": {
"code": "rate_limited",
"message": "Too many requests. Try again in a moment."
}
}{
"error": {
"code": "internal_error",
"message": "An unexpected error occurred. Please try again later."
}
}Preview campaign recipients
Resolve an audience and count it, without creating anything. Run this before creating a campaign: the reachable it returns is what the create endpoint expects in confirm_recipients, and any other value is refused with 409.
Measure the channel the campaign will really use. The create endpoint takes no channel — it follows from the inbox, or from the e-mail sender — so previewing one channel and creating in another gives two different numbers.
On whatsapp only contacts with a phone number count: a contact you can otherwise message through a Meta business-scoped id does not receive campaigns. On email the figure is an estimate rather than a promise, because the dispatcher still drops addresses that fail its format check or sit on your suppression list.
curl --request POST \
--url https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/campaigns/preview-recipients \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'cloudchat-instance: <cloudchat-instance>' \
--data '
{
"channel": "whatsapp",
"audience": [
{
"type": "Label",
"id": 20010
}
]
}
'import requests
url = "https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/campaigns/preview-recipients"
payload = {
"channel": "whatsapp",
"audience": [
{
"type": "Label",
"id": 20010
}
]
}
headers = {
"cloudchat-instance": "<cloudchat-instance>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'cloudchat-instance': '<cloudchat-instance>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({channel: 'whatsapp', audience: [{type: 'Label', id: 20010}]})
};
fetch('https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/campaigns/preview-recipients', 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.cloudhumans.com/cloudchat/v1/accounts/{accountId}/campaigns/preview-recipients",
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([
'channel' => 'whatsapp',
'audience' => [
[
'type' => 'Label',
'id' => 20010
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"cloudchat-instance: <cloudchat-instance>"
],
]);
$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.cloudhumans.com/cloudchat/v1/accounts/{accountId}/campaigns/preview-recipients"
payload := strings.NewReader("{\n \"channel\": \"whatsapp\",\n \"audience\": [\n {\n \"type\": \"Label\",\n \"id\": 20010\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("cloudchat-instance", "<cloudchat-instance>")
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.cloudhumans.com/cloudchat/v1/accounts/{accountId}/campaigns/preview-recipients")
.header("cloudchat-instance", "<cloudchat-instance>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"channel\": \"whatsapp\",\n \"audience\": [\n {\n \"type\": \"Label\",\n \"id\": 20010\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/campaigns/preview-recipients")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["cloudchat-instance"] = '<cloudchat-instance>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"channel\": \"whatsapp\",\n \"audience\": [\n {\n \"type\": \"Label\",\n \"id\": 20010\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"total": 1240,
"reachable": 1187
}{
"error": {
"code": "bad_request",
"message": "The request is malformed."
}
}{
"error": {
"code": "unauthorized",
"message": "Authentication is required. Send a valid Bearer token in the Authorization header."
}
}{
"error": {
"code": "forbidden",
"message": "You do not have permission to perform this action."
}
}{
"error": {
"code": "not_found",
"message": "Resource could not be found."
}
}{
"error": {
"code": "validation_failed",
"message": "The request payload is invalid.",
"details": [
{
"field": "short_code",
"code": "taken",
"message": "has already been taken"
}
]
}
}{
"error": {
"code": "rate_limited",
"message": "Too many requests. Try again in a moment."
}
}{
"error": {
"code": "internal_error",
"message": "An unexpected error occurred. Please try again later."
}
}Authorizations
The id_token from POST /auth/v1/signin, sent as Authorization: Bearer <id_token>. Not the access_token — that one does not carry the identity Cloud Chat authorizes on.
Headers
Your Cloud Chat instance ID — an integer, fixed for your company, told at onboarding. The API overview explains how instances work, how to find yours, and the errors a wrong or missing value produces.
1
Path Parameters
Your Cloud Chat account. It has to be an account your token grants membership on, and it has to live on the instance in the cloudchat-instance header — the two travel together. Account numbers are only unique within an instance, so the same number is a different company on another instance. Usually a mismatched pair fails closed with a 401, because your user does not exist on the other instance — but if your identity happens to exist on both, the call succeeds against the other company's data, silently. Read it and you are looking at the wrong help center; write it and you have stored into the wrong account. Send the two values that were given to you together, and never try a number to see what answers.
1
Body
An audience to resolve, and the channel to measure it in.
What counts as reachable: a phone number for whatsapp, an e-mail address for email, a widget identifier for widget. Measure the channel the campaign will really use, or the number will not match when you create it.
whatsapp, email, widget "whatsapp"
Whose reach to count. At most 50 entries; more is refused rather than silently truncated.
Show child attributes
Show child attributes
Response
The size of the audience, and how much of it this channel reaches.
How big an audience is, before and after the reachability check for a channel.