---
title: "Campaigns, templates and bulletins"
description: "Call campaigns that reach a list of people, the WhatsApp templates that open conversations, and bulletins that tell every agent what is happening for a while."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.getarbol.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Campaigns, templates and bulletins

Raíz can reach out as well as answer. A campaign has a voice agent call a list of people within the hours you allow, and it can call again those who didn't answer. On WhatsApp, a conversation your organization starts must open with a message template WhatsApp has approved. And when something changes for a while, such as a closed day or a service that isn't available, a bulletin tells your agents, without touching their instructions.

## Call campaigns

[`raiz.campaigns.create`](/api/raiz/campaigns/create/) prepares a campaign for a voice agent, with up to 10,000 `recipients`. Creating it calls nobody: the campaign stays `queued` until it's started. The call isn't idempotent.

```bash
curl https://api.getarbol.com/v1/raiz/campaigns \
  --request POST \
  --header "Authorization: Bearer $ARBOL_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "Appointment reminders, November",
    "agentId": "agt_01jd8xq4r5s6t7v8w9x0y1z2a3",
    "instructions": "Remind {{contact_given_name}} of their appointment on {{appointment_date}} and ask whether they will attend.",
    "contactHours": [{ "days": ["MO", "TU", "WE", "TH", "FR"], "from": "08:00", "to": "18:00" }],
    "timeZone": "America/Bogota",
    "maxAttempts": 3,
    "retryAfterMinutes": 120,
    "recipients": [
      { "address": "+12025550143", "variables": { "appointment_date": "November 12" } }
    ]
  }'
```

| Field | What it does |
| --- | --- |
| `agentId` | The voice agent that calls. One that can't take calls yet answers `409 VOICE_AGENT_NOT_READY`: it must be active, have instructions and be published for calls. |
| `recipients` | Each a phone `address` in E.164, unique in the campaign, with an optional `contactId`, `variables`, and a `firstMessage` and `instructions` for that call. |
| `firstMessage`, `instructions` | What the agent says first on every call, and what these calls are about, added to the agent's instructions. |
| `contactHours`, `timeZone` | When calls may start, in the campaign's time zone, the organization's by default. Empty: any time. |
| `scheduledStartAt`, `scheduledEndAt` | No call starts before or after these instants. |
| `maxAttempts`, `retryAfterMinutes`, `retryOn` | Calls per recipient, retries included (1 to 10, default 1); the wait before a retry (default 60 minutes); and which results earn one: `no_answer` (the default) and `failure`. |
| `channelId` | The voice line calls leave from. By default, the agent's own outbound line. |

The texts of the agent and the campaign can use `{{name}}` variables, filled from each recipient's `variables`. Raíz always provides `contact_name`, `contact_given_name`, `contact_id`, `contact_phone`, `conversation_id` and `bulletins` (the bulletins in force), and a recipient's values never replace them. A recipient's contact is the one it names, or else the contact that owns its number, created when there is none.

### Follow and change a campaign

A campaign's `status` is `queued` (not started, or its start is scheduled), `running` (calling the recipients that are due), `paused` (no new call starts; calls in progress finish), `completed` (nobody is left to call), `cancelled` or `failed`. Its `progress` counts its `recipients` and how many are `pending`, `inProgress`, `completed` or `failed`, and how many `succeeded`: their latest call's analysis judged it successful.

[`raiz.campaigns.get`](/api/raiz/campaigns/get/) with `expand=recipients` adds each recipient's status, attempts, next attempt and latest call, whose `conversationId` leads to its transcript. A recipient that failed says why in `errorCode`: `NO_ANSWER` or `CALL_FAILED` after its last attempt, or `CONTACT_SUPPRESSED` when a [do-not-contact rule](/en/developers/raiz/contacts/#do-not-contact-rules) forbids the number. The campaign's calls are also in [`raiz.conversations.list`](/api/raiz/conversations/list/) with `campaignId`.

[`raiz.campaigns.update`](/api/raiz/campaigns/update/) changes a campaign; fields you leave out stay. `"paused": true` pauses a started campaign and `false` resumes it, with the same checks as starting; on a campaign that never started, it answers `409 INVALID_STATE`. Before the start, `recipients` is the complete list, matched by `address`; once started, it only adds, so you can send a long list in batches. The agent changes only before the start, and a completed campaign accepts only a new `name` and `metadata`. Your organization places at most `settings.channels.maxConcurrentOutboundCalls` campaign calls at once (5 by default).

## WhatsApp templates

WhatsApp lets a business start a conversation, or write to someone who hasn't written in the last 24 hours, only with a message template it approved. Templates belong to the WhatsApp Business Account of each number, so both template operations take a WhatsApp `channelId`.

[`raiz.templates.list`](/api/raiz/templates/list/) reads a channel's templates live from WhatsApp, newest first, and filters them by `status`: `approved`, `pending` or `rejected`. `sendable` says whether Raíz can send one: approved, with variables only in the body and, if it has a media header, a document, image or video. `parameterCount` is how many body values a send needs.

[`raiz.templates.create`](/api/raiz/templates/create/) submits a template for WhatsApp's review:

```json
{
  "channelId": "chn_01jd8x6b3c4d5e6f7g8h9j0k1m",
  "name": "appointment_reminder",
  "language": "en_US",
  "category": "utility",
  "body": {
    "text": "Hello {{1}}, this is a reminder of your appointment on {{2}} at Example Clinic.",
    "examples": ["Ana", "November 12"]
  }
}
```

The `name` takes lowercase letters, digits and `_`, and the `language` WhatsApp's code, such as `es`, `es_MX` or `en_US`. `category` is `utility` for messages about something the person asked for, such as appointments, or `marketing` for promotions. The `body` has up to 1,024 characters with variables `{{1}}`, `{{2}}` and so on, and one `examples` value per variable. A `header` (a fixed text, or a document, image or video with a sample file of up to 5 MiB), a `footer` and up to 10 `buttons` are optional. The template stays `pending` until WhatsApp approves or rejects it, usually within minutes; WhatsApp may change its category, and `rejectedReason` says why it was rejected.

You also choose approved templates for a WhatsApp [contact profile](/en/developers/raiz/contacts/#contact-profiles), which opens each conversation with one, and for a number's [outside-hours notice](/en/developers/raiz/channels/#business-hours-on-whatsapp).

## Bulletins

A bulletin tells your agents about something happening for a while: a service that isn't available, no appointments at a site for some days, a closed day, a promotion. Agents apply it on calls, WhatsApp and web chat until it ends. It isn't sent to anyone; agents take it into account when they talk to people. Your team may call bulletins *novedades* or *avisos*.

[`raiz.bulletins.create`](/api/raiz/bulletins/create/) takes the `text`, up to 1,000 characters, written as you would tell your agents, with what they should offer instead. Add an `agentId` for one agent, or leave it out for every agent. `startsAt` is now by default, and without `endsAt` the bulletin lasts until it's deleted. In this example, Example Clinic works in `America/Bogota`, so its days end at 05:00 UTC:

```json
{
  "text": "The North site is closed from 24 to 26 November. Offer appointments at the South site instead.",
  "endsAt": "2026-11-27T05:00:00Z"
}
```

Agents apply a bulletin from their next reply or call once it starts, and no agent reads it before. For agents to know ahead, so they book nothing on a closed day, start it now and write the dates in the text, as above. A bulletin's `status` is `scheduled`, `active` or `ended`. An organization can have 30 bulletins in force or scheduled (`409 BULLETIN_LIMIT_REACHED`), and one that would end before it starts, or would already be over, answers `422 BULLETIN_PERIOD_INVALID`.

[`raiz.bulletins.list`](/api/raiz/bulletins/list/) lists scheduled and active bulletins, or ended ones with `status=ended`, by `agentId` or by text with `q`. [`raiz.bulletins.update`](/api/raiz/bulletins/update/) changes one; to end it now, set `endsAt` to the current instant (a scheduled one is deleted instead). [`raiz.bulletins.delete`](/api/raiz/bulletins/delete/) deletes one that was a mistake, and the [change history](/en/developers/raiz/data/#change-history) keeps who deleted it. Bulletins use the agents scopes: `raiz:agents:write` to post, change or delete one.

Source: https://docs.getarbol.com/en/developers/raiz/campaigns/index.mdx
