Scheduled Broadcasts
Schedule a broadcast to an audience filter — once at a set time, or on a recurring cadence. The audience is evaluated at every send, so contacts who join or leave your groups before then are included or left out accordingly.
Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /api/v1/messaging/broadcast/schedules | Create a schedule |
GET | /api/v1/messaging/broadcast/schedules | List your schedules |
GET | /api/v1/messaging/broadcast/schedules/{scheduleId} | Get one schedule |
PATCH | /api/v1/messaging/broadcast/schedules/{scheduleId} | Change a schedule |
DELETE | /api/v1/messaging/broadcast/schedules/{scheduleId} | Cancel a schedule |
Schedule ids are prefixed sch_.
Timing — schedule
scheduleAll timing lives in one schedule object:
| Field | Required | Description |
|---|---|---|
at | Yes | The date and time to send, as a wall clock with no offset: "2026-10-05T09:00" (seconds optional). With a recurrence, it is the first send and the time of day of every send. |
timezone | Yes | The IANA timezone at is read in, e.g. "America/New_York", "Europe/London", "UTC". Offsets (-04:00) and abbreviations (EST) are not accepted. |
sendByLocalTime | No | true delivers at at's wall-clock time in each recipient's own timezone. Default false. |
recurrence | No | Repeat pattern (below). Absent = a one-time send. |
at may be up to 1 hour in the past — the schedule then sends right away. Further back is rejected (33044).
Daylight saving time is handled for you: a time that does not exist on the change day moves forward by the length of the gap (02:30 on the spring-forward day sends at 03:30), and a time that happens twice (when clocks fall back) sends at the first one.
recurrence
recurrence| Field | Required | Description |
|---|---|---|
frequency | Yes | daily, weekly or monthly |
interval | Yes | Every N days / weeks / months (1–12) |
daysOfWeek | Only when weekly (required) | mon … sun |
dayOfMonth | Only when monthly (required) | 1–31 (past a month's end, its last day) |
endType | Yes | never, onDate or afterOccurrences |
endOnDate | Only when onDate (required) | Wall clock in schedule.timezone, e.g. "2026-12-31T23:59" |
endAfterOccurrences | Only when afterOccurrences (required) | Number of sends |
The time of day and timezone come from schedule.at and schedule.timezone — a recurrence has no time of its own.
Delivery options
schedule.sendByLocalTime: truedelivers atat's wall-clock time in each recipient's own timezone instead of one instant — 9:00 in New York, then 9:00 in Chicago, and so on. Recipients whose timezone is unknown getatinschedule.timezone.waveConfig(recipientsPerWave,waveIntervalMinutes) sends in waves instead of all at once.
The two cannot be combined.
Example — every Monday at 9am New York time, 8 times
curl -X POST https://platform.textingline.com/api/v1/messaging/broadcast/schedules \
-u "your_key_id:your_key_secret" \
-H "Content-Type: application/json" \
-d '{
"audience": {
"filter": { "contact": { "groups": { "ids": { "in": ["grp_7L1uzUXqj3eJvAwHf"] } } } }
},
"from": "+18005559876",
"body": "This week at Acme, {{contact_first_name}}: {{trackingLink \"go.acme.com/weekly\"}}",
"schedule": {
"at": "2026-10-05T09:00",
"timezone": "America/New_York",
"recurrence": {
"frequency": "weekly",
"interval": 1,
"daysOfWeek": ["mon"],
"endType": "afterOccurrences",
"endAfterOccurrences": 8
}
},
"idempotencyKey": "weekly-digest-2026-q4"
}'Response
{
"id": "sch_EfQC8m8rW74FYsVX87fSvr",
"status": "active",
"timing": "recurring",
"schedule": {
"at": "2026-10-05T09:00:00",
"timezone": "America/New_York",
"sendByLocalTime": false,
"recurrence": {
"frequency": "weekly",
"interval": 1,
"daysOfWeek": ["mon"],
"endType": "afterOccurrences",
"endAfterOccurrences": 8
}
},
"nextScheduledFor": "2026-10-05T13:00:00.000Z",
"from": "+18005559876",
"body": "This week at Acme, {{contact_first_name}}: {{trackingLink \"go.acme.com/weekly\"}}",
"audience": {
"filter": { "contact": { "groups": { "ids": { "in": ["grp_7L1uzUXqj3eJvAwHf"] } } } }
},
"audienceReadable": true,
"createdAt": "2026-09-28T10:00:00.000Z",
"updatedAt": "2026-09-28T10:00:00.000Z"
}schedule is returned in the shape you sent it — at with seconds (2026-10-05T09:00:00) and sendByLocalTime always present. status is active, paused or ended. nextScheduledFor is the next send as a UTC instant; it is absent once the schedule has ended. With sendByLocalTime it is at in schedule.timezone — recipients elsewhere get it at their own wall clock.
One-time, in each recipient's local time
"schedule": {
"at": "2026-10-01T09:00",
"timezone": "America/New_York",
"sendByLocalTime": true
}Listing
GET /api/v1/messaging/broadcast/schedules returns all of your account's schedules — including those created in the app — upcoming first, paginated like other lists (page, limit, totalCount, results).
| Query parameter | Description |
|---|---|
status | Comma-separated: active, paused, ended |
timing | Comma-separated: oneTime, recurring |
nextScheduledFrom | Next send at or after this instant (ISO 8601) |
nextScheduledTo | Next send at or before this instant (ISO 8601) |
sort | nextScheduledFor (default), -nextScheduledFor, createdAt, -createdAt |
page, limit | Pagination (limit up to 100) |
Schedules built in the app
A schedule built in the app may target contacts with conditions an audience filter cannot express. Such a schedule is returned with "audience": null and "audienceReadable": false. Everything else — timing, content, status — is shown, and can be changed; sending an audience in an update replaces the app-built one.
Updating and cancelling
PATCHchanges only the fields you send.audienceandscheduleare each replaced as a whole — a newschedulereplaces all of the timing. Changes apply from the next send — a send already in progress is not affected. An ended schedule cannot be changed (33043).DELETEremoves a schedule that never sent. A schedule that already sent is ended instead: nothing further is sent, and it stays in the list asended.
Service levels
- A scheduled send starts within 2 minutes of its scheduled time, never before it. (With
sendByLocalTime, each timezone starts at its own local time.) - A send that cannot start within 1 hour of its scheduled time is not sent late — that send is skipped and reported as failed.
- The schedule endpoints respond within 2 seconds (create, update) and 1 second (list, get, cancel) at the 95th percentile.
See Rate limits for request limits.
Updated about 2 hours ago