# Segments, scheduling and campaigns

Send one template to many contacts - at a time, on a schedule, or every week - safely and at a steady pace.

> **In a nutshell:** Save an audience as a segment, create a campaign with an APPROVED template and where each variable comes from, preview it (audience, skips, estimated Meta cost), then launch it now, at send_at, or repeating. Every person goes through suppression, consent, preferences, limits and quiet hours; results come back with clear definitions.

## Segments

A segment is an audience saved as conditions over the business's contacts:

```json
{"name": "SHS 2 owing fees",
 "conditions": {"all": [
   {"field": "custom.class", "op": "eq", "value": "SHS 2"},
   {"field": "custom.fee_balance", "op": "gt", "value": 0},
   {"any": [{"field": "tag", "op": "has", "value": "boarders"},
            {"field": "consent.notifications", "op": "eq", "value": "granted"}]}
 ]}}
```

| Field | Operators |
|---|---|
| `name`, `phone`, `email`, `locale`, `timezone`, `external_id` | `eq`, `neq`, `contains`, `starts_with`, `in`, `exists`, `not_exists` |
| `created_at` | `eq`, `gt`, `gte`, `lt`, `lte`, `within_days`, `older_than_days` |
| `custom.<key>` | by the field's type - numbers and dates also `gt`, `gte`, `lt`, `lte` |
| `tag` | `has`, `not_has` |
| `consent.<marketing\|notifications\|transactional>` | `eq` `granted`, `revoked` or `none` |
| `last_incoming_at` | `within_days`, `older_than_days` - when they last wrote |

Groups nest up to three levels and hold up to 30 conditions. Erased and inactive contacts are
never included. [Preview segment](/docs/api/preview-segment) shows the count and a sample.

## Scheduling one message

Add `send_at` to a template send ([Send message](/docs/api/send-message)): it is accepted
(`202`, `scheduled_for` set) and sent at that time - quiet hours still apply then. Until it
goes, [Cancel scheduled message](/docs/api/cancel-message) withdraws it (`cancelled`).

## Campaigns

1. [Create campaign](/docs/api/create-campaign) - an APPROVED template, a segment (or
   `contact_ids`) and where each variable comes from:

   ```json
   {"name": "October fee reminders",
    "template": {"name": "school_fee_reminder", "language": "en_US"},
    "parameters": {"parent": "field:name", "amount": "custom:fee_balance",
                   "student": "custom:ward_name", "due_date": "text:30 October"},
    "segment_id": 4, "topic": "fees"}
   ```

   Sources: `field:name` (also `phone`, `email`, `external_id`), `custom:<key>`, `text:<fixed>`.
2. [Preview campaign](/docs/api/preview-campaign) - who it reaches, who is skipped and why,
   the **estimated Meta cost** ("Meta bills your WhatsApp Business Account directly. PaalChat
   cost: included in your plan.") and the number's Meta messaging tier.
3. [Launch campaign](/docs/api/launch-campaign) - now, at `send_at`, or every `week` or
   `month` (`repeat`). Each repeat is a run with the audience as it is then.

Campaigns send at `per_minute` messages a minute (default 60). Every person goes through the
same checks as a single send; anyone who cannot be sent is **skipped** with a reason
(`no_whatsapp`, `missing_parameter`, `recipient_suppressed`, `recipient_opted_out`,
`recipient_preference_off`) - never sent a broken template. Pause, resume or cancel with
[Pause, resume or cancel campaign](/docs/api/change-campaign). Status changes arrive as
[`campaign.updated`](/docs/api/callbacks/campaign-updated).

## Results

[Get campaign](/docs/api/get-campaign) returns `stats`:

| Figure | Means |
|---|---|
| `audience` | People fixed when the run started |
| `queued` / `skipped` / `cancelled` | What PaalChat did with each (`skip_reasons` per reason) |
| `sent`, `delivered`, `read`, `failed` | The messages' statuses now - delivered includes read |
| `replied` | People who wrote back on the same conversation within 72 hours of the send |
| `rates` | delivery, read and reply are shares of sent; failure is failed of sent + failed |
| `estimated_meta_cost` | From Meta's pricing reports - an estimate; Meta bills the business |

Before a big campaign, keep Meta's messaging tier in mind: it limits how many people a number
may start conversations with in 24 hours.
