Skip to content
New to this? Read the Batches guide.

Preview a batch of SMS messages

POST
/v2/sms/batches/preview
curl --request POST \
--url https://api.connect.ms/v2/sms/batches/preview \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "messages": [ { "sender": "example", "recipient": "example", "content": "example", "kind": "transactional", "unicode": "allow", "clientReference": "example", "clientTag": "example" } ], "defaults": { "sender": "example", "kind": "transactional", "clientTag": "example", "scheduledAt": "2026-04-15T12:00:00Z", "validitySeconds": 1, "shortenLinks": true, "trackClicks": true, "bypassSuppressions": true, "link": { "include": true, "mode": "unsubscribe", "preText": "example" } }, "list": { "ids": [ "example" ], "excludeIds": [ "example" ] }, "sender": "example", "content": "example", "template": { "name": "example", "data": { "additionalProperty": "example" } }, "kind": "transactional", "clientReference": "example", "clientTag": "example", "scheduledAt": "2026-04-15T12:00:00Z", "validitySeconds": 1, "pacing": { "ratePerPeriod": 1, "period": "hour" }, "skipMessagedWithinHours": 1, "shortenLinks": true, "trackClicks": true, "link": { "include": true, "mode": "unsubscribe", "preText": "example" } }'

Takes the same body as sending a batch and estimates what would happen: how many messages and parts, the estimated cost, and which rows would be skipped or rejected. Nothing is sent, and a list send’s template is measured as written rather than rendered.

Connect-Version
string

The API version to use, for example 2026-10-01. Defaults to the version set on your API key.

Idempotency-Key
string

A unique value of up to 255 characters, so a retried request is not acted on twice. Required for keys in Strict API Mode.

A batch to send. Provide exactly one of messages (with defaults) and list (with the remaining fields, which apply to every contact).

Media typeapplication/json

A batch to send. Provide exactly one of messages (with defaults) and list (with the remaining fields, which apply to every contact).

object
messages

The messages to send, between 1 and 1000. Cannot be combined with list.

Array<object>

One message in a batch. Fields left out fall back to the batch defaults.

object
sender

Sender Name for the SMS. Falls back to defaults.sender.

string
nullable
recipient

Recipient Number (E.164 format) for the SMS.

string
nullable
content

The message text, up to 5,000 characters.

string
nullable
kind
One of:

The kind of message: transactional (service messages, the default), marketing (promotional, subject to opt-outs and the unsubscribe link) or authentication (one-time codes).

string
Allowed values: transactional marketing authentication
unicode
One of:

How characters outside the GSM alphabet are handled: allow (send as written, using UCS-2 when needed), deny (reject the request if the content you send has any; a stored template is not checked), smart (replace curly quotes, dashes, ellipses and unusual spaces with GSM equivalents and remove emoji, leaving letters untouched) or strip (as smart, then fold accented letters that GSM lacks to their base letter and remove anything else outside the GSM alphabet, so the message always sends as GSM-7).

string
Allowed values: allow deny strip smart
clientReference

Your own reference for this individual message, up to 64 characters.

string
nullable
clientTag

A grouping tag for this message, up to 64 characters. Stored in lower case with anything other than letters and digits replaced by hyphens.

string
nullable
defaults
One of:

Values applied to every message in the batch. A message’s own sender, kind or clientTag takes precedence.

object
sender

Sender for messages that do not name their own: an approved sender name, a verified UK mobile number in 07 format, or one of your inbound numbers in E.164 format.

string
nullable
kind
One of:

The kind of message: transactional (service messages, the default), marketing (promotional, subject to opt-outs and the unsubscribe link) or authentication (one-time codes).

string
Allowed values: transactional marketing authentication
clientTag

A grouping tag applied to the batch for usage reporting, up to 64 characters. Stored in lower case with anything other than letters and digits replaced by hyphens.

string
nullable 0 <= 64 characters
scheduledAt

When (UTC, ISO 8601) to send the batch: at least 5 minutes and at most 12 months ahead. If not specified, the batch is sent immediately.

string format: date-time
nullable
validitySeconds

How long each message stays eligible to send, between 60 and 172800 seconds. If omitted or 0 there is no window and messages the workspace cannot pay for fail immediately.

integer format: int32
nullable >= 60 <= 172800
shortenLinks

Whether to shorten links in the content. Omit to follow the workspace setting.

boolean
nullable
trackClicks

Whether to give each shortened link a tracking code for this message, so its clicks can be read per message. Every link is then shortened. Omit to follow the workspace setting; cannot be true when shortenLinks is false.

boolean
nullable
bypassSuppressions

Send even to recipients on the suppression list. Defaults to false; a connected app cannot set it to true.

boolean
nullable
link
One of:

Overrides the workspace’s message link settings for this send.

object
include

Whether to append a link. Omit to follow the workspace setting; the link is never added to authentication messages, and a connected app cannot set this to false.

boolean
nullable
mode
One of:

What the appended link offers the recipient: unsubscribe (opt out of marketing), reply (send a reply from the web) or both.

string
Allowed values: unsubscribe reply both
preText

Text placed before the link, up to 64 characters. Omit to follow the workspace setting.

string
nullable 0 <= 64 characters
list
One of:

The contact lists to send to. Contacts in more than one list receive one message; contacts in an excluded list receive none.

object
ids

Ids of the lists to send to, between 1 and 20.

Array<string>
>= 1 characters
excludeIds

Ids of lists whose members are left out, up to 20. A list cannot be both included and excluded.

Array<string>
nullable
sender

Sender for a list send: an approved sender name, a verified UK mobile number in 07 format, or one of your inbound numbers in E.164 format.

string
>= 1 characters
content

The message text for a list send, up to 5,000 characters. Cannot be combined with template.name; contact fields can be used as merge fields.

string
nullable 0 <= 5000 characters
template
One of:

A stored template to render, or merge data for rendering the content field.

object
name

The name of a stored template, up to 64 characters; its merge fields are rendered with data. Cannot be combined with content.

string
nullable 0 <= 64 characters
data
One of:

A JSON object.

object
key
additional properties
kind
One of:

The kind of message: transactional (service messages, the default), marketing (promotional, subject to opt-outs and the unsubscribe link) or authentication (one-time codes).

string
Allowed values: transactional marketing authentication
clientReference

Your own reference applied to every message in a list send, up to 64 characters.

string
nullable 0 <= 64 characters
clientTag

A grouping tag applied to every message in a list send, up to 64 characters. Stored in lower case with anything other than letters and digits replaced by hyphens.

string
nullable 0 <= 64 characters
scheduledAt

When (UTC, ISO 8601) to send a list send: at least 5 minutes and at most 12 months ahead. If not specified, the batch is sent immediately.

string format: date-time
nullable
validitySeconds

How long each message of a list send stays eligible to send, between 60 and 172800 seconds. If omitted or 0 there is no window.

integer format: int32
nullable >= 60 <= 172800
pacing
One of:

Spreads delivery out at a fixed rate instead of sending everything at once. The send must finish within 60 days.

object
ratePerPeriod

How many messages to send per period. At least 1.

integer format: int32
period
One of:

The period a pacing rate applies to: hour or day.

string
Allowed values: hour day
skipMessagedWithinHours

Skips contacts messaged within this many hours. One of 6, 12, 24, 48, 72 or 168.

integer format: int32
nullable
shortenLinks

Whether to shorten links in the content of a list send. Omit to follow the workspace setting.

boolean
nullable
trackClicks

For a list send: whether to give each shortened link a tracking code for this message, so its clicks can be read per message. Every link is then shortened. Omit to follow the workspace setting; cannot be true when shortenLinks is false.

boolean
nullable
link
One of:

Overrides the workspace’s message link settings for this send.

object
include

Whether to append a link. Omit to follow the workspace setting; the link is never added to authentication messages, and a connected app cannot set this to false.

boolean
nullable
mode
One of:

What the appended link offers the recipient: unsubscribe (opt out of marketing), reply (send a reply from the web) or both.

string
Allowed values: unsubscribe reply both
preText

Text placed before the link, up to 64 characters. Omit to follow the workspace setting.

string
nullable 0 <= 64 characters

What the batch would do.

Media typeapplication/json

An estimate of what a batch would do if sent: how many messages, how many parts, the estimated cost and what would be skipped. Checks made only at send time, such as sender approval, are not included.

object
recipients
required

How many messages would be queued.

integer format: int32
parts
required

The total SMS parts across those messages. For a list send, merge fields are counted as written, not rendered.

integer format: int32
cost
One of:

An amount in each currency it can be priced in, as decimal strings with four decimal places. A currency with no price is null.

object
gbp

The amount in pounds sterling, e.g. “0.0350”.

string
nullable
eur

The amount in euros, e.g. “0.0410”.

string
nullable
skipped
required
One of:

Why rows were skipped rather than queued.

object
suppressed
required

Recipients on the suppression list.

integer format: int32
recentlyMessaged
required

Recipients messaged within the skipMessagedWithinHours window.

integer format: int32
invalid
required

Rows that failed validation.

integer format: int32
errors
required

Rows that would be rejected, by position. Always empty for a list send.

Array<object>

A row of the request that was not accepted.

object
index
required

The zero-based position of the row in the submitted messages.

integer format: int32
detail
required

What was wrong with the row.

string
paymentRequired
required

True when the workspace would need to top up before this batch could send. Only checked for a list send; always false for individual messages.

boolean
estimatedCompletionAt

When (UTC) a paced batch would finish sending, or null when it is not paced.

string format: date-time
nullable

Example generated

{
"recipients": 1,
"parts": 1,
"cost": {
"gbp": "example",
"eur": "example"
},
"skipped": {
"suppressed": 1,
"recentlyMessaged": 1,
"invalid": 1
},
"errors": [
{
"index": 1,
"detail": "example"
}
],
"paymentRequired": true,
"estimatedCompletionAt": "2026-04-15T12:00:00Z"
}

The request is not valid. The detail field says why, and errors lists any problems by field name.

Media typeapplication/problem+json

Why a request failed, in the RFC 9457 problem details format.

object
type
required

A URI identifying the kind of problem, ending in a code such as validation_failed, not_found, sending_blocked or rate_limited.

string
title
required

A short, fixed summary of the kind of problem.

string
status
required

The HTTP status code of the response.

integer format: int32
detail

What went wrong with this particular request, when there is more to say than the title.

string
nullable
errors

For validation failures, the problems found, keyed by field name (nested fields as template.name, list items as messages[3]).

object
key
additional properties
Array<string>
requestId
required

The id recorded for this error, matching the Request-Id header when one is sent. Quote it when contacting support.

string

Example generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"errors": {
"additionalProperty": [
"example"
]
},
"requestId": "example"
}

The API key or bearer token is missing or not valid, or the request signature could not be verified.

Media typeapplication/problem+json

Why a request failed, in the RFC 9457 problem details format.

object
type
required

A URI identifying the kind of problem, ending in a code such as validation_failed, not_found, sending_blocked or rate_limited.

string
title
required

A short, fixed summary of the kind of problem.

string
status
required

The HTTP status code of the response.

integer format: int32
detail

What went wrong with this particular request, when there is more to say than the title.

string
nullable
errors

For validation failures, the problems found, keyed by field name (nested fields as template.name, list items as messages[3]).

object
key
additional properties
Array<string>
requestId
required

The id recorded for this error, matching the Request-Id header when one is sent. Quote it when contacting support.

string

Example generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"errors": {
"additionalProperty": [
"example"
]
},
"requestId": "example"
}

The caller is not allowed to do this.

Media typeapplication/problem+json

Why a request failed, in the RFC 9457 problem details format.

object
type
required

A URI identifying the kind of problem, ending in a code such as validation_failed, not_found, sending_blocked or rate_limited.

string
title
required

A short, fixed summary of the kind of problem.

string
status
required

The HTTP status code of the response.

integer format: int32
detail

What went wrong with this particular request, when there is more to say than the title.

string
nullable
errors

For validation failures, the problems found, keyed by field name (nested fields as template.name, list items as messages[3]).

object
key
additional properties
Array<string>
requestId
required

The id recorded for this error, matching the Request-Id header when one is sent. Quote it when contacting support.

string

Example generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"errors": {
"additionalProperty": [
"example"
]
},
"requestId": "example"
}

One or more of the contact lists do not exist.

Media typeapplication/problem+json

Why a request failed, in the RFC 9457 problem details format.

object
type
required

A URI identifying the kind of problem, ending in a code such as validation_failed, not_found, sending_blocked or rate_limited.

string
title
required

A short, fixed summary of the kind of problem.

string
status
required

The HTTP status code of the response.

integer format: int32
detail

What went wrong with this particular request, when there is more to say than the title.

string
nullable
errors

For validation failures, the problems found, keyed by field name (nested fields as template.name, list items as messages[3]).

object
key
additional properties
Array<string>
requestId
required

The id recorded for this error, matching the Request-Id header when one is sent. Quote it when contacting support.

string

Example generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"errors": {
"additionalProperty": [
"example"
]
},
"requestId": "example"
}

A request with this Idempotency-Key is still being processed. Retry after the Retry-After header.

Media typeapplication/problem+json

Why a request failed, in the RFC 9457 problem details format.

object
type
required

A URI identifying the kind of problem, ending in a code such as validation_failed, not_found, sending_blocked or rate_limited.

string
title
required

A short, fixed summary of the kind of problem.

string
status
required

The HTTP status code of the response.

integer format: int32
detail

What went wrong with this particular request, when there is more to say than the title.

string
nullable
errors

For validation failures, the problems found, keyed by field name (nested fields as template.name, list items as messages[3]).

object
key
additional properties
Array<string>
requestId
required

The id recorded for this error, matching the Request-Id header when one is sent. Quote it when contacting support.

string

Example generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"errors": {
"additionalProperty": [
"example"
]
},
"requestId": "example"
}

This Idempotency-Key was already used for a different request. Use a new key.

Media typeapplication/problem+json

Why a request failed, in the RFC 9457 problem details format.

object
type
required

A URI identifying the kind of problem, ending in a code such as validation_failed, not_found, sending_blocked or rate_limited.

string
title
required

A short, fixed summary of the kind of problem.

string
status
required

The HTTP status code of the response.

integer format: int32
detail

What went wrong with this particular request, when there is more to say than the title.

string
nullable
errors

For validation failures, the problems found, keyed by field name (nested fields as template.name, list items as messages[3]).

object
key
additional properties
Array<string>
requestId
required

The id recorded for this error, matching the Request-Id header when one is sent. Quote it when contacting support.

string

Example generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"errors": {
"additionalProperty": [
"example"
]
},
"requestId": "example"
}

This API key requires an Idempotency-Key header on every POST and PATCH.

Media typeapplication/problem+json

Why a request failed, in the RFC 9457 problem details format.

object
type
required

A URI identifying the kind of problem, ending in a code such as validation_failed, not_found, sending_blocked or rate_limited.

string
title
required

A short, fixed summary of the kind of problem.

string
status
required

The HTTP status code of the response.

integer format: int32
detail

What went wrong with this particular request, when there is more to say than the title.

string
nullable
errors

For validation failures, the problems found, keyed by field name (nested fields as template.name, list items as messages[3]).

object
key
additional properties
Array<string>
requestId
required

The id recorded for this error, matching the Request-Id header when one is sent. Quote it when contacting support.

string

Example generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"errors": {
"additionalProperty": [
"example"
]
},
"requestId": "example"
}

The service is temporarily unavailable. Retry after the Retry-After header.

Media typeapplication/problem+json

Why a request failed, in the RFC 9457 problem details format.

object
type
required

A URI identifying the kind of problem, ending in a code such as validation_failed, not_found, sending_blocked or rate_limited.

string
title
required

A short, fixed summary of the kind of problem.

string
status
required

The HTTP status code of the response.

integer format: int32
detail

What went wrong with this particular request, when there is more to say than the title.

string
nullable
errors

For validation failures, the problems found, keyed by field name (nested fields as template.name, list items as messages[3]).

object
key
additional properties
Array<string>
requestId
required

The id recorded for this error, matching the Request-Id header when one is sent. Quote it when contacting support.

string

Example generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"errors": {
"additionalProperty": [
"example"
]
},
"requestId": "example"
}