Send an SMS
The minimum required fields areto (the recipient’s phone number in format) and body (the message text). If you’ve configured a default phone number on the account, you don’t need to specify from — otherwise you’ll get a no_phone_number error.
from. (Python and Ruby use from_ to avoid the reserved keyword; the wire field is still from.)
Tracking delivery
Message delivery status isn’t a field on the REST response — it comes through webhook events. Subscribe to these event types:
Not all carriers send delivery receipts, so
message.delivered isn’t guaranteed for every carrier. See Webhook Events for the full payload shapes.
Send an MMS
Include anattachments array to send MMS. Each item needs a url pointing to a publicly accessible file.
GET /attachments/{attachment_id}/file.
MMS gotchas
- Content type: some carriers reject attachment types they don’t support. Common safe types are
image/jpeg,image/png, andimage/gif. PDFs deliver reliably to most handsets but not all. - File size: very large files may be silently truncated or fail delivery on certain networks. Keep attachments under 1 MB where possible.
- Body is optional: you can send an MMS with attachments only, no
bodytext.
Automatic SMS-to-MMS conversion
Surge can automatically upgrade a plain SMS to MMS in two situations:- Message exceeds 10 segments: any message over 10 segments (around 1,530 GSM-7 characters) is automatically sent as MMS regardless of whether you included attachments.
- Message is 3 or more segments and
auto_mms_enabledis on for your project: contact support to enable this project-level setting if you want long messages to convert automatically.
mms_not_supported), Surge falls back to SMS.
You never need to detect this yourself — the message.sent and message.delivered events reflect the actual protocol used.
Schedule a message
Setsend_at to an ISO 8601 timestamp to schedule a message for later delivery. The maximum scheduling window is 65 days from now.
message.delivered, message.failed) fire when the message is actually sent at the scheduled time.
Personalize messages with contact variables
If the recipient has a contact record, Surge substitutes these tokens in the message body at send time:first_name is Jordan, the recipient receives Hi Jordan, your order has shipped!. If the contact has no first_name, the {first_name} token is replaced with an empty string, so the recipient gets Hi , your order has shipped! — set names on your contacts before sending personalized messages to avoid awkward blanks. Tokens are replaced when you pass to (a phone number or contact ID); they are not replaced on blast sends that bypass contact resolution.
Add metadata
metadata is a free-form JSON object you can attach to any message. It’s returned in webhook events and list responses, which makes it useful for correlating Surge messages with records in your own system.
Common errors
Full error reference is in Handle Failures and the Error Reference.