How to send an SMS campaign

Intro

Send promotional text messages — flash sales, limited-time offers, event reminders — to your subscriber audience through the Campaigns API. SMS campaigns target specific segments or all subscribers and can be sent immediately or scheduled for a future time.

See API reference: Campaigns | Images

Prerequisites

  • An API key with campaigns.write scope, or an OAuth token with the same scope
  • SMS channel enabled for your brand (enable in Channel Settings → SMS)
  • Sufficient SMS credits for your audience size (manage credits) — each sent message consumes credits based on the recipient's country

Step 1: Create the campaign

Create a draft SMS campaign with the message body and compliance text. The compliance fields are required — stopKeywordText is appended for US/CA recipients, and unsubscribeLinkText (which must contain [[unsubscribe_link]]) is appended for all other regions.

See endpoint: Create campaign

curl -X POST 'https://api.omnisend.com/api/campaigns' \
  -H 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
  -H 'Omnisend-Version: 2026-03-15' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Summer Flash Sale",
    "type": "regular",
    "channel": "sms",
    "language": "en_US",
    "content": {
      "sms": {
        "message": "Flash sale! 30% off everything today only. Shop now: https://example.com/sale",
        "compliance": {
          "stopKeywordText": "Reply STOP to opt out",
          "unsubscribeLinkText": "Unsubscribe: [[unsubscribe_link]]"
        }
      }
    },
    "audience": {
      "includedSegmentIDs": ["segment-id-1"]
    },
    "sendingSettings": {
      "strategy": "scheduled",
      "scheduledAt": "2026-06-15T14:00:00Z"
    }
  }'

The response returns the campaign in draft status with an id you will use in subsequent steps.

Note: audience and sendingSettings are optional. Omitting audience (or leaving includedSegmentIDs empty) targets all subscribers. Omitting sendingSettings defaults to immediate strategy. Included and excluded segment IDs must not overlap.

Note: The total message length — body + compliance text + unsubscribe link — must not exceed 9 SMS segments. Links in the message body are auto-shortened by default (isLinkShorteningEnabled: true).

Step 2: Send the campaign

Trigger the campaign send. If the sending strategy is immediate (the default), the campaign starts sending right away. If scheduled, it queues for the scheduled time.

See endpoint: Send campaign

curl -X POST 'https://api.omnisend.com/api/campaigns/CAMPAIGN_ID/send' \
  -H 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
  -H 'Omnisend-Version: 2026-03-15'

A 204 response confirms the send was initiated. The campaign status changes to started (immediate) or scheduled (scheduled strategy).

Warning: The send endpoint returns 402 Payment Required when the campaign audience exceeds your current billing tier limits or you have insufficient SMS credits. A plan upgrade or credit purchase is required to proceed.

Verify results

Retrieve the campaign to check its current status.

See endpoint: Get campaign

curl -X GET 'https://api.omnisend.com/api/campaigns/CAMPAIGN_ID' \
  -H 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
  -H 'Omnisend-Version: 2026-03-15'
StatusMeaning
scheduledCampaign is queued to send at the scheduled time
startedCampaign is actively sending
pausedCampaign is undergoing automated verification (~60 min check)
sentCampaign has finished sending
onHoldCampaign did not pass content verification — review required
errorCampaign encountered an error during sending

Optional: Add an image (MMS)

To send MMS (image + text) to US/CA recipients instead of plain SMS, upload an image via the Images API and reference it in the campaign content. Recipients in other regions always receive plain SMS without the image.

Upload the image

Upload from a public URL. The image must be JPEG, PNG, or GIF and must not exceed 500 KB. Images wider than 2000 px are automatically resized.

See endpoint: Upload image by URL

curl -X POST 'https://api.omnisend.com/api/images' \
  -H 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
  -H 'Omnisend-Version: 2026-03-15' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://your-cdn.com/promo-banner.jpg",
    "name": "summer-sale-mms"
  }'

The response returns an id field — use it as imageID when creating the campaign.

Note: The URL must point to a publicly accessible image (JPEG, PNG, or GIF). Your API key needs the additional images.write scope for this call. For all upload options see Images API reference.

Create an MMS campaign

Include imageID in the SMS content object. The rest of the payload is identical to a plain SMS campaign from Step 1.

See endpoint: Create campaign

curl -X POST 'https://api.omnisend.com/api/campaigns' \
  -H 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
  -H 'Omnisend-Version: 2026-03-15' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Summer Flash Sale (MMS)",
    "type": "regular",
    "channel": "sms",
    "language": "en_US",
    "content": {
      "sms": {
        "message": "Flash sale! 30% off everything today only.",
        "imageID": "IMAGE_ID",
        "compliance": {
          "stopKeywordText": "Reply STOP to opt out",
          "unsubscribeLinkText": "Unsubscribe: [[unsubscribe_link]]"
        }
      }
    },
    "audience": {
      "includedSegmentIDs": ["segment-id-1"]
    },
    "sendingSettings": {
      "strategy": "scheduled",
      "scheduledAt": "2026-06-15T14:00:00Z"
    }
  }'

Note: US/CA recipients receive MMS (image + text). When imageID is set, the message limit for US/CA is 1600 characters (body + compliance text) instead of the usual 9 SMS segments.

Troubleshooting

  • 409 Conflict on update or send: Only campaigns in draft status can be edited or sent. If the campaign has already been sent or scheduled, copy it to create a new draft.
  • 402 Payment Required on send: The campaign audience exceeds your plan limits or you have insufficient SMS credits. Upgrade your plan or purchase credits.
  • Validation error on compliance.unsubscribeLinkText: The value must contain the [[unsubscribe_link]] placeholder. Example: "Unsubscribe: [[unsubscribe_link]]".
  • Campaign ends in error status: A campaign can fail during sending due to insufficient SMS credits or internal issues. The API does not always include error details in the campaign response — check your SMS credit balance if the cause is unclear.
  • Message too long: The total message (body + compliance + unsubscribe link) must fit within 9 SMS segments. For MMS to US/CA, the limit is 1600 characters. Shorten your message or compliance text.

Related resources