Transactional Messaging

Transactional messages are 1:1, event-driven messages — a single message to a single recipient, triggered by something that happens in your application. An order ships, an appointment approaches, a password reset is requested. Send with POST /v1/messages and a single phone number in toNumbers.

Transactional vs. Campaign: Both use the same /v1/messages endpoint. A single number in toNumbers is transactional. Multiple numbers or any use of groupIds makes it a campaign.

Send an SMS

Two fields are required: toNumbers and message. messageType is optional — EZ Texting auto-detects (SMS vs. MMS) based on whether media is attached. A 201 response means the message is queued for delivery.

curl --request POST \
     --url https://a.eztexting.com/v1/messages \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --user 'your_username:your_password' \
     --data '{
  "toNumbers": [
    "15551234567"
  ],
  "message": "Your appointment is confirmed for tomorrow at 2pm."
}'

Send an MMS

Set messageType to "MMS" (or let auto-detect handle it when you include media) and attach media via mediaUrl — a publicly accessible URL, up to 5 MB — or mediaFileId for a file uploaded through the Media Files API.

For high-volume or time-sensitive sends, pre-upload media via POST /v1/media-files and reference the returned mediaFileId. This avoids latency from fetching the URL at send time.

curl --request POST \
     --url https://a.eztexting.com/v1/messages \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --user 'your_username:your_password' \
     --data '{
  "toNumbers": [
    "15551234567"
  ],
  "message": "Check out our new menu!",
  "mediaUrl": "https://example.com/menu.jpg"
}'

Schedule a message

Include sendAt with an ISO 8601 timestamp to schedule future delivery. Omit it to send immediately. Save the returned message ID so you can cancel with DELETE /v1/messages if plans change.

curl --request POST \
     --url https://a.eztexting.com/v1/messages \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --user 'your_username:your_password' \
     --data '{
  "toNumbers": [
    "15551234567"
  ],
  "message": "Your appointment is in 1 hour.",
  "sendAt": "2026-01-15T14:00:00Z"
}'

Check delivery status

Retrieve a message's delivery status with GET /v1/message-details/{id}. For production systems, use webhooksinstead of polling — you'll get real-time delivery notifications pushed to your server.

curl --request GET \
     --url https://a.eztexting.com/v1/message-details/123456789 \
     --header 'accept: application/json' \
     --user 'your_username:your_password'

All message parameters

ParameterTypeDescription
messagestringThe text content of your message
toNumbersstring[]Recipient phone numbers. One number = transactional; multiple = campaign.
groupIdsstring[]Contact group IDs to send to (always a campaign). Cannot combine with toNumbers.
messageTypestringSMS or MMS. Optional — auto-detected based on whether media is attached.
sendAtstringISO 8601 timestamp for scheduled delivery. Omit to send immediately.
companyNamestringPrefix added to the beginning of your message
mediaUrlstringPublicly accessible media URL for MMS (up to 5 MB)
mediaFileIdstringID of a pre-uploaded media file
messageTemplateIdstringID of a saved message template to use
fromNumberstringNumber to send from. If omitted, sends from your default number. Only needed when you have multiple numbers.
strictValidationbooleantrue: entire send fails if any number is invalid. false (default): invalid numbers are skipped.

Message types

SMS— Standard text. Up to 160 characters (GSM-7) sends as one segment; longer messages split into multiple segments and reassemble on the recipient's device. Emoji/Unicode use UCS-2 (70 chars per segment).

MMS — Rich media messages with images, video, or audio alongside text. Attach via mediaUrl or mediaFileId.

Message templates

Templates let you define reusable message content and reference it by ID when sending. Create with POST /v1/message-templates (requires name and message), then pass messageTemplateId when sending. Keeps your sending code clean and lets non-technical teams manage content separately. See the Message Templates API reference.

Delivery reports

For detailed per-recipient reporting, use the Message Reports endpoints:

  • GET /v1/message-reports/{id} — Overall delivery summary
  • GET /v1/message-reports/{id}/responses/delivery — Per-recipient delivery statuses
  • GET /v1/message-reports/{id}/responses/engagement — Engagement metrics
  • GET /v1/message-reports/{id}/responses/link — Link click tracking

Error handling

StatusMeaningWhat to do
400Bad RequestCheck required fields (message, toNumbers). Verify phone number format.
401UnauthorizedCredentials invalid or token expired. Refresh your token.
404Not FoundThe message ID doesn't exist. Verify the ID.
422UnprocessableRequest is well-formed but can't be processed — e.g., sending to an opted-out number.
429Rate Limited200 req/min exceeded. Wait for the duration in the X-Rate-Limit-Retry-After-Milliseconds header.
500Server ErrorRetry with exponential backoff. Contact support if it persists.

Next steps