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

# Sending SMS

> Create, schedule, and track SMS campaigns with the Phonovation API.

Campaigns let you send one message to one or more recipients. Phonovation validates the request, queues accepted recipients, and returns a campaign ID for delivery tracking.

<Warning>
  A successful campaign request can send SMS and consume message credits.
</Warning>

```mermaid title="Campaign processing flow" theme={"dark"}
%%{init: {"theme": "base", "themeVariables": {"fontFamily": "Outfit", "fontSize": "16px", "primaryColor": "#fff1ef", "primaryTextColor": "#0f1926", "primaryBorderColor": "#d23a25", "lineColor": "#4b69a0", "secondaryColor": "#eaf0fa", "tertiaryColor": "#edf8f0"}}}%%
flowchart LR
  Request["POST campaign"] --> Validate["Validate message, sender, and recipients"]
  Validate --> Skip["Skip invalid, duplicate, or unpermitted recipients"]
  Validate --> Queue["Queue valid recipients"]
  Queue --> Accepted["202 + campaign ID"]
  Accepted --> Summary["GET campaign summary"]
  Queue --> Network["Mobile network"]
  Network --> DLR["Signed DLR webhook"]

  classDef app fill:#eaf0fa,stroke:#4b69a0,color:#0f1926,stroke-width:2px
  classDef phono fill:#fff1ef,stroke:#d23a25,color:#0f1926,stroke-width:2px
  classDef result fill:#edf8f0,stroke:#247a4b,color:#0f1926,stroke-width:2px
  class Request app
  class Validate,Skip,Queue phono
  class Accepted,Summary,Network,DLR result
```

## How sending works

1. Phonovation validates the message, Sender ID, and recipients.
2. Valid recipients are normalized and queued.
3. Invalid, duplicate, or unpermitted recipients can be skipped while the rest continue.
4. The API returns `202 Accepted` with a campaign ID.
5. Campaign totals and delivery receipts report what happens next.

<Note>
  `202 Accepted` means the campaign was queued. It does not confirm handset delivery.
</Note>

## Core request concepts

| Field           | Required | Rules                                                                                   |
| --------------- | -------: | --------------------------------------------------------------------------------------- |
| `text`          |      Yes | 1–2,000 characters and at least one visible character                                   |
| `from`          |      Yes | Numbers-only: up to 20 digits. Other Sender IDs: up to 11 characters                    |
| `recipientInfo` |      Yes | At least one recipient in digits-only international format without `+`                  |
| `campaignName`  |       No | 1–30 characters; defaults to `API Broadcast`                                            |
| `sendAt`        |       No | Irish local time (`Europe/Dublin`); prefer `yyyy-MM-ddTHH:mm` without a timezone suffix |

## Recipients

Every recipient `msisdn` must use the full international format: country code followed by the subscriber number, using digits only and no leading `+`.

For example, use `353871234567` instead of `0871234567` or `+353871234567`. Do not include spaces, brackets, or hyphens.

Duplicate detection runs after normalization. The first occurrence and its [Client Reference](/phonovation-api/client-reference) are kept.

## Message encoding and parts

Phonovation detects the encoding and calculates the SMS parts that are sent and billed.

| Encoding |                  One part |     Concatenated parts |
| -------- | ------------------------: | ---------------------: |
| GSM-7    | Up to 160 character units |     153 units per part |
| UTF-16   |       Up to 70 characters | 67 characters per part |

GSM-7 extended characters count as two units. Before sending, the API replaces typographic quotes, en/em dashes, ellipses, and bullets with handset-compatible equivalents.

<Note>
  The API does not add opt-out or footer text. Include any wording required for your use case before you calculate the final message length.
</Note>

<Card title="SMS Message Lab" icon="flask" color="#247A4B" href="/phonovation-api/tools/message-lab" cta="Inspect a message" arrow="true">
  Preview GSM-7 or UTF-16 encoding, character units, compatibility replacements, and SMS parts without sending anything.
</Card>

## Send now or schedule

<Warning>
  `sendAt` always means Irish local time, regardless of where your request, server, account, or recipient is located. Do not include `Z`, another timezone designator, or a numeric UTC offset.
</Warning>

Phonovation reads the date and clock time as a wall-clock time in the IANA timezone `Europe/Dublin`. For example, `2030-07-08T15:00` sends at 15:00 in Ireland. If a system in China submits that value, the campaign still sends at 15:00 Irish time, not 15:00 China time.

For international scheduling:

1. Start with the date and time when the recipient should receive the message.
2. Convert that instant to `Europe/Dublin` with a timezone-aware date-time library.
3. Format the resulting Irish date and clock time as `yyyy-MM-ddTHH:mm`.

The API also accepts a space instead of `T` and optional seconds. If you supply seconds, Phonovation ignores them and schedules the campaign at the start of the minute.

| Desired local delivery time                         | Irish time to submit | `sendAt`           |
| --------------------------------------------------- | -------------------- | ------------------ |
| UK: 8 July 2030 at 15:00 (`Europe/London`)          | 8 July at 15:00      | `2030-07-08T15:00` |
| China: 8 July 2030 at 15:00 (`Asia/Shanghai`)       | 8 July at 08:00      | `2030-07-08T08:00` |
| China: 15 January 2030 at 15:00 (`Asia/Shanghai`)   | 15 January at 07:00  | `2030-01-15T07:00` |
| New York: 8 July 2030 at 15:00 (`America/New_York`) | 8 July at 20:00      | `2030-07-08T20:00` |

Ireland changes between GMT (UTC+0) and Irish Standard Time (UTC+1). Other countries may change clocks on different dates. Always perform a date-specific conversion with named timezones rather than hard-coding an offset.

Omit `sendAt` or send `null` to send immediately. Empty and whitespace-only strings are invalid. Past dates are accepted, and the API does not publish a maximum scheduling horizon.

## Delivery and retries

Use the returned campaign ID to retrieve aggregate sent, delivered, undelivered, and pending totals. Use delivery receipt webhooks with a Client Reference when you need recipient-level status.

A `404` immediately after submission can mean the campaign is still processing or does not yet have a summary. Retry later with backoff.

The current OpenAPI contract does not publish a fixed rate limit or a throttling response. Control concurrency in your client and follow any account-specific limits supplied by Phonovation.

Do not blindly retry after an unknown network outcome: the original request might already be queued. Store every campaign ID returned with a `202` response.

## Errors

| Response | Meaning                                                                                                     |
| -------- | ----------------------------------------------------------------------------------------------------------- |
| `400`    | Request validation or immediate campaign creation failed; inspect the dynamic problem `detail`              |
| `401`    | Authentication is missing or unsuccessful; the response has no body and includes `WWW-Authenticate: Bearer` |
| `403`    | Authentication succeeded, but the identity is not a recognized client administrator                         |

<CardGroup cols={2}>
  <Card title="Campaign API Reference" icon="paper-plane" color="#D23A25" href="/phonovation-api/api-reference/campaigns/create-campaign" cta="Inspect the request schema" arrow="true">
    Review the complete request and response schema.
  </Card>

  <Card title="Campaign summary reference" icon="chart-line" color="#4B69A0" href="/phonovation-api/api-reference/campaigns/get-campaign-summary" cta="Inspect delivery totals" arrow="true">
    Review delivery-total fields and errors.
  </Card>
</CardGroup>
