Skip to content

Send SMS

To send a message, give a sender, a recipient and either content or a stored template.

Terminal window
curl https://api.connect.ms/v2/sms \
-H "Authorization: Bearer $CONNECT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-991-shipped" \
-d '{
"sender": "YourBrand",
"recipient": "+447700900123",
"content": "Hi Sam, your order has shipped.",
"clientReference": "order-991"
}'

The response is 201 Created with the message as queued. Keep its id to look it up later, or use events to be told when it is delivered.

API reference: POST /v2/sms

Instead of content, send the name of one of your templates and the values to fill it with:

{
"sender": "YourBrand",
"recipient": "+447700900123",
"template": {
"name": "appointment-reminder",
"data": { "firstName": "Sam", "time": "10am" }
}
}

You can also send content with {{ placeholders }} and fill them from template.data, without storing a template.

kind says what the message is for: transactional (the default), marketing or authentication. Marketing messages follow your opt-out and unsubscribe link rules. See SMS Compliance.

To see who clicks the links in your message, set trackClicks. See Click Tracking.

Set scheduledAt to send later, at least 5 minutes and at most 12 months ahead. A scheduled message stays queued until then and can be cancelled.

A message that only uses the GSM alphabet is sent as gsm7, which fits 160 characters in one part. Anything else, such as an emoji or curly quote, makes the whole message ucs2, which fits only 70. unicode decides what happens to those characters:

ModeWhat it doesExample
allow (default)Sends the content unchanged, as ucs2 if needed.
denyRefuses the message if anything is outside the GSM alphabet.
smartConverts curly quotes, dashes, … and odd spaces to their GSM forms and removes emoji, but never changes letters. Text like Łódź or Greek still needs ucs2.It’s live 🚀 see you… becomes It's live see you... (gsm7)
stripDoes everything smart does, then turns accented letters into their base letter and removes anything else outside GSM. The result is always gsm7.Łódź ąę becomes Lodz ae, Café stays Café (GSM has é), Acme™ becomes Acme

If your workspace can’t pay for a message when it is due to send, what happens depends on validitySeconds:

  • Not set: the message fails straight away, as on v1.
  • Set: the message is held, with hold set on the message and an sms.held event. It sends as soon as your balance is topped up, or fails with reason code payment_required once the validity runs out.

The validity also limits how late a message may go out for any other reason. A message that can’t be sent in time fails with category expired.

POST /v2/sms/preview tells you how many parts a message will use, its encoding and, if you give a recipient, what it will cost. Nothing is sent.

DELETE /v2/sms/{id} cancels a message that hasn’t been sent yet: one that is scheduled, paced, held or still queued. Once it has been sent it can’t be cancelled, and you get a 409.