# Sending rules

> Every rule that decides what a campaign will and will not send — opt-outs, channel opt-outs, frequency caps, quiet hours, templates, plan and credit limits — the workspace settings you can tighten, and every refusal with its fix.

Source: https://docs.amomic.in/campaigns/sending-rules

---

This page is the whole list. Everything here is enforced on the server, applies to campaigns started from the console, from the API and from apps such as Duesly, and none of it can be turned off by a setting or a request field. You can make some rules stricter for your workspace; you can never make them looser.

## Workspace sending rules

Admins set the workspace's own rules under **Campaigns → Sending rules**.

![The Sending rules dialog with Earliest send, Latest send, Messages per minute, Most messages one person gets a week, Time zone and the locked rules note](https://docs.amomic.in/screens/campaigns/sending-rules.light.webp)

*Workspace rules: every campaign and app follows them.*

| Field | Range | What it does |
|---|---|---|
| **Earliest send** | 09:00 to 20:00 | No campaign message goes out before this hour. |
| **Latest send** | 10:00 to 21:00 | No campaign message goes out after this hour. Must be later than **Earliest send**. |
| **Messages per minute** | 1 to 600, default 60 | The default pace for messages. |
| **Most messages one person gets a week** | 1 to 4 | Across every campaign. 4 is the ceiling. |
| **Time zone** | | **Use the workspace time zone** is on by default, so changing the zone under **Settings** moves campaigns with it. Turn it off to pick a different zone. Sending hours are read in this zone, not the recipient's. |

**Save rules** applies them to every campaign from then on. The locked note at the bottom lists what isn't adjustable: opt-outs, approved templates, calling hours of 10:00 to 19:00, and the payment reminder's limit of two follow-ups.

## What you can send

| Channel | Message |
|---|---|
| WhatsApp | An approved template. Free-form text only reaches someone whose [24-hour window](/channels/whatsapp-window) is open, which is almost never true of a broadcast recipient. |
| Voice | An agent conversation, with a stated reason for the call. |

## Opt-outs and suppression

**Always on. No toggle, no override, no exception.**

Anyone on a channel's opt-out list is removed from the audience before launch and checked again immediately before each send. A template is refused just as firmly as free-form text, and an uploaded list gets the same check as your contacts.

This check sits inside the channel's own send path, below every entry point: the API, an agent, an app, the console. No caller can route around it.

## Channel consent

Consent is recorded **per channel** on each contact: allowed, opted out, or not recorded.

Only an explicit opt-out excludes someone. A contact who opted out of WhatsApp is removed from a WhatsApp broadcast, with the reason `channel_consent_missing`, and can still be called in a call batch. A contact with nothing recorded is included.

## Consent and attestation

No consent statement, lawful basis or attestation is needed to launch a campaign, and the console doesn't ask for one. The rules on this page, above all opt-outs, are what protect the people you message.

Over the API you may record a basis anyway. If a campaign is created with a `consent` object, it is pinned at launch with who launched it, when, how many people it covered and a checksum of the exact list, and the campaign page shows it. It isn't copied when you duplicate the campaign. See [Campaigns API](/api/campaigns).

## Frequency caps

| Cap | Value |
|---|---|
| From one campaign, to one person, in one day | 1 message |
| From all campaigns, to one person, in one week | 4 messages, or fewer if you lower it in **Sending rules** |

The week runs Monday to Sunday, not a rolling seven days.

People over a cap are marked **Not sent** with *Already messaged today* or *Over the weekly limit*. They aren't queued for later: the campaign made its attempt, and quietly holding a message for days is worse than not sending it.

## Quiet hours

Messages go out between **09:00 and 21:00** in your campaign time zone; calls between **10:00 and 19:00**. Your workspace rules and each campaign can narrow that window, never widen it, and anything queued outside it waits for the next open hour. See [Scheduling](/campaigns/scheduling#quiet-hours).

## Approved templates only

Outside WhatsApp's 24-hour window, an approved template is the only message Meta will deliver. A broadcast without one is refused at launch, once, with a fix, rather than producing thousands of identical failures.

A template that is submitted but not yet approved is refused with `template_not_approved`. A template with an image or video header also needs that file attached in Amomic-AI, or the launch is refused with `template_media_missing`. Meta approves the layout, not the file. See [Image headers](/channels/whatsapp-templates#image-headers).

## Your WhatsApp number's health

If your WhatsApp number is connected but Meta is refusing to deliver from it, for example because of a payment problem on the WhatsApp Business Account, a new broadcast is refused with `sender_blocked` and the explanation. Fix the cause in Meta Business Manager or under **Channels**; once messages are delivering again, launches are allowed.

## Calls

- **Calling hours 10:00 to 19:00**, narrower than messaging.
- **A daily limit on outbound calls per workspace.** If none are left today, the final check blocks the batch with `voice_daily_cap`. If only some fit, it warns *Only N of these M calls will be placed today*. Don't count on the rest carrying over: calls refused by the daily limit can be marked failed instead of waiting. Keep a batch within what's left today, or use **Retry N failed** the next day.
- **Lines are shared.** A gradual call batch leaves some of the workspace's call lines free for your team. When every line it may use is busy, it waits rather than failing. See [When a campaign is waiting](/campaigns/results#when-a-campaign-is-waiting).

## Your plan and credits

- **Plan.** Campaigns need Growth or Enterprise. Growth allows 5,000 recipients per campaign; every plan is capped at 50,000. See [Limits & plans](/operate/limits#campaign-recipients).
- **Plan allowance first, then credits.** A broadcast uses your plan's included conversations first. If a campaign will run past what's left this month, the rest is paid from prepaid credits, and the launch still goes ahead. The final check doesn't warn you about this; once launched, the campaign page notes it under **Worth knowing about this send** (`allowance_spill`). A call batch works the same way with voice minutes.
- **Nothing left.** If the allowance is used up and the wallet is empty, the launch is refused with `allowance_exhausted` before anything is staged. Nobody is contacted, and the campaign stays a draft. Top up, then launch again. See [Credits](/operate/credits).
- **A channel your plan no longer includes.** After a plan change removes a channel, a campaign on it is refused with `channel_dormant`.

## Payments

Amomic-AI never sees a card number. Payment collection through [Duesly](/apps/duesly) sends a hosted payment link: the payment page belongs to the gateway, and no card details reach Amomic-AI.

## Every refusal, and what it means

Shown in the final check, on a campaign's page, or over the API as `details.reason` with `details.docs` pointing at the explanation.

**Before launch: these stop the campaign**

| Reason | What happened | What to do |
|---|---|---|
| `email_not_available` | Email campaigns aren't available | Use WhatsApp or a call batch |
| `unsupported_channel` | That channel isn't available on this workspace | Pick a live channel |
| `channel_not_connected` | No sender is connected for this channel | Connect one under **Channels**; the draft is saved |
| `sender_blocked` | The WhatsApp number is connected but not delivering | Fix the cause shown, then launch again |
| `channel_dormant` | A plan change took this channel away. Checked when you press **Send it**, not in the final check | Change plan, or use another channel |
| `allowance_exhausted` | Plan allowance used up and no prepaid credits. Checked when you press **Send it**, not in the final check | Top up under **Billing**, then launch again |
| `workspace_suspended` | The workspace is suspended for an unpaid plan invoice. Also refuses **Resume**, and holds a campaign that is already sending | An owner pays the invoice under **Billing**; a held campaign carries on by itself |
| `audience_empty` | Nobody is left after the exclusions | Check the exclusions |
| `audience_too_large` | Over 50,000 recipients | Split the campaign |
| `plan_limit` | Over your plan's recipients per campaign | Narrow the audience or upgrade |
| `template_not_found` | No template chosen, or it no longer exists | Pick or create one |
| `template_not_approved` | Meta hasn't approved it yet | Wait, or pick another |
| `template_media_missing` | The template's header image or video isn't attached | Upload it under **Channels → WhatsApp → Templates** |
| `voice_daily_cap` | No outbound calls left today (a warning when only some fit) | Schedule the batch for tomorrow |
| `version_conflict` | The audience or campaign changed since you looked | Check again and launch |
| `campaign_frozen` | The action doesn't fit the campaign's state, such as editing after launch | Duplicate it instead |
| `campaign_active` | Archiving a campaign that is still sending, scheduled or paused | Cancel it first |

**Informational: these don't stop anything**

| Reason | Meaning |
|---|---|
| `quiet_hours` | Your requested hours were narrowed to the allowed window |
| `suppressed` | N people opted out and were removed |
| `channel_consent_missing` | N contacts opted out of this channel and were removed |
| `duplicate_recipient` | N duplicate rows were collapsed |
| `invalid_destination` | N rows had a number that couldn't be used (a warning) |
| `allowance_spill` | Part of the send will be paid from prepaid credits. Recorded at launch and shown on the campaign page, not in the final check. |

**Per recipient: recorded as Not sent**

| Reason | Shown as | Meaning |
|---|---|---|
| `suppressed` | Opted out | On the channel's opt-out list. Permanent. |
| `channel_consent_missing` | No consent on this channel | The contact opted out of this channel. |
| `daily_contact_cap` | Already messaged today | This campaign already reached them today. |
| `weekly_contact_cap` | Over the weekly limit | Your weekly cap is reached. |
| `missing_variable` | Missing a personalised value | Their row has no value for a placeholder. |
| `invalid_destination` | Unusable phone number | The number couldn't be used. |
| `campaign_cancelled` | Campaign cancelled | Cancelled before they were reached. |

Failures from WhatsApp and from calls have their own labels; they're all in [Why someone wasn't reached](/campaigns/failure-reasons).

## The audit trail

Creating, launching, pausing, resuming, retrying, cancelling, archiving and exporting outcomes each write a record with the person and the time; the platform's own actions, such as stopping or completing, are recorded as *automatically*. Admins see it under **History** on the campaign page. Payments recorded in Duesly keep who recorded them and the reference they gave.
