Skip to main content
POST
Keys requiring send approval cannot create schedules, including drafts (403 confirmation_required). Reads and stop remain available. Use pending sends for approved single or bulk SMS. Create a new schedule to send SMS or MMS messages to one or more audiences. Schedules can be one-time or repeating, and support multiple blast variants for A/B testing. API keys with a daily send cap cannot create schedules, including drafts. Scheduled sends do not enforce the key’s daily allowance, so these requests return 403 schedule_not_allowed_for_capped_key without creating a schedule. Every source list must also be allowed by the key’s send_policy.list_numbers. Keys with list restrictions must supply nonempty source_lists. Omitting this field or sending [] selects all active account lists during execution, so restricted keys cannot use that default. The server validates current key policy and saves the schedule in one transaction; concurrent policy changes cannot retain the earlier permission to create it.

Create a one-time blast

Use POST https://api.tracklysms.com/api/v2/schedules with a live API key that has no daily send cap and does not require send approval. Put the key in the X-Api-Key header. Choose an active audience and allowed sending lists from the same account. Only keys without list restrictions may omit source_lists. This example creates a draft. Replace the example IDs and choose your send date and time:
A successful request returns HTTP 201 with success: true and the new ID in schedule.id. Supply message text directly in blasts[].message; no saved creative or creative ID is required. Plain text without link placeholders needs no offer_links. Each {{linkN}} placeholder requires a mapping with a unique key and either an offer_id from your account or an public HTTPS custom_url, never both. Different placeholders can use different destinations. To reuse a saved creative, copy its message and offer_links into the blast object. This endpoint accepts SMS offer bindings (offer_source omitted or sms) and custom URLs. OMS offer bindings are not supported here; use the app’s blast editor for creatives containing OMS offers. Set status to on in the creation request to activate the blast for its scheduled date and time. If you create a draft first, activate it with PUT /v2/schedules/{schedule_id} and {"status":"on"}. The default draft status and off status do not start sending. Schedule creation and activation do not provide sandbox simulation; use draft to review without sending. With use_local_time: false, send_time uses the account timezone. With true, it uses each recipient’s local timezone. Creation and activation return the schedule; delivery happens through the scheduler and remains subject to the normal sending checks. Use a distinct Idempotency-Key for each intended blast and reuse it with the same request body when retrying that creation request.

Also save a reusable creative

By default, creating a blast saves only the schedule. On any variant you want to keep for later manual sends, set save_as_creative: true. This option works only on POST with send_type: "blast". Set creative_name to choose its name; otherwise the name comes from variant_name, falling back to the schedule’s name. This request creates a draft with a custom link and saves its text and link mapping as a creative:
Relevant fields from the HTTP 201 response are shown below; schedule also contains the full schedule configuration:
Use schedule.id to retrieve or activate the schedule. Use each integer creative_id with GET /v2/creatives/{id} to retrieve the saved asset. In the blast editor, choose Use existing creative to reuse it. Plain-text and custom-link-only assets are listed under Creatives without offers; offer-backed assets appear under their offer. blast_index is the zero-based position in your submitted blasts array. Both result arrays appear only when at least one variant requests saving; either array can be empty. Each saved creative is active with creative_type: "one_time" for manual sends. It snapshots the variant’s message and offer/custom-link mappings. Its list controls use include with the schedule’s source_lists, or all when those lists are omitted or empty. These are independent records: editing or archiving the schedule does not change the creative, and editing the creative does not change the schedule. MMS images stay on the schedule and are not included in the saved creative.

When saving a creative fails

Request validation happens before creation. Invalid save options or link mappings return HTTP 400. A 403 key-policy rejection creates neither the schedule nor its optional creatives. After validation and policy admission, the schedule is saved first. If a creative save then fails, the request still returns HTTP 201, success: true, and schedule.id. Inspect creative_save_errors even on success; each failure includes blast_index, code: "creative_save_failed", and a safe error message. Other requested creatives may have saved. The schedule remains valid and can send when its status is on. Do not submit another schedule with a new idempotency key to retry a failed creative save: that creates another blast. Within the 24-hour cache window, an identical request with the same key replays the original response, including creative-save errors; it does not retry those saves. The idempotency limitations still apply. To recover a failed asset save, create only the creative through POST /v2/creatives. Use the failed variant’s original text and links with creative_type: "one_time". For the custom-link example above:
For text without placeholders, omit offer_links or send []. To match an original schedule with no source_lists, use list_control_mode: "all" and list_control_ids: []. HTTP 201 returns the asset ID in creative.id. This creates no schedule and sends no messages. The dedicated creative endpoint does not support Idempotency-Key; if its response is uncertain, check existing creatives before retrying.

Body Parameters

string
required
A descriptive name for this schedule.
string
required
The type of schedule. Must be blast or automated.
array of strings
required
Array of audience IDs to target. Each audience must exist and be active on your account.
boolean
required
Set to true for a recurring schedule that runs on selected days of the week, or false for a one-time send.
string
required
Time of day to send, in HH:MM format (24-hour clock). For example, "14:30" for 2:30 PM.
array of integers
IDs of source sending lists. Each list must exist on your account. Required and nonempty for keys with list restrictions; unrestricted keys may omit it or use [] to select all active account lists.
string
default:"draft"
Initial status. Allowed values: draft, off, on. Defaults to draft. Use on to activate the scheduled send; draft and off do not send.
datetime
required
The date to send for a one-time schedule. Required when is_repeating is false.
datetime
required
The first date the repeating schedule should run. Required when is_repeating is true.
datetime
required
The last date the repeating schedule should run. Required when is_repeating is true.
object
required
An object specifying which days the schedule should run. Keys: monday, tuesday, wednesday, thursday, friday, saturday, sunday. Values are booleans. At least one day must be true.
float
default:"0"
Skip sending to a contact if they were already sent to within this many hours. Set to 0 to disable.
boolean
default:"false"
When true, send_time is interpreted in each recipient’s local timezone rather than the account timezone.
boolean
default:"false"
Enable bot filtering to display an interstitial page for suspected bots instead of the message.
boolean
default:"false"
Set to true to send MMS messages with image attachments. Every blast variant must then include mms_image_url, including when creating a draft.
boolean
default:"false"
Enable click-to-open mode.
float
default:"0"
Percentage of the audience to allocate to automated (ML-powered) creative selection. Value between 0 and 100.
float
default:"0"
Expected or target revenue from this send. This value is for reporting only — it has no effect on audience selection or send optimization.
array
required
Array of blast variant objects. Required when send_type is blast.

Response Fields

boolean
true if the schedule was created successfully.
object
The full schedule object, including all fields and the generated id. See List Schedules for the complete schedule object schema.
array
Present only when at least one variant requested save_as_creative: true. Each successful save contains blast_index (zero-based integer), creative_id (integer), and name (string). Empty when no requested save succeeded.
array
Present only when at least one variant requested save_as_creative: true. Each failed save contains blast_index (zero-based integer), code: "creative_save_failed", and error (string). Empty when all requested saves succeeded. An entry does not undo the successful schedule creation or change HTTP 201.

Examples

Error Codes

creative_save_failed appears inside creative_save_errors on HTTP 201, not as a request-validation error. The schedule was created successfully; retain its ID and inspect the per-variant results. See When saving a creative fails.

Next Steps

Campaign Scheduling

Learn scheduling best practices

List Audiences

Find audiences for your campaign