Messages
Overview
A Message object in Sent is the fundamental record of any communication sent to a contact. It represents a single, trackable instance of a message sent through a specific channel (SMS or WhatsApp).
Every time you initiate a communication via the API, a Message object is created. This object allows you to:
- Track Delivery: Monitor the complete lifecycle of a message from queue to delivery.
- Audit Communications: Maintain a verifiable history of all messages sent to your contacts.
- Debug Issues: Access detailed status history and provider responses to troubleshoot delivery problems.
- Manage Costs: See the precise cost associated with each message sent.
The Message Lifecycle
When you send a message, it progresses through several statuses. Understanding this lifecycle is key to building a robust integration.
Successful Message Flow
Failed Message Flow
Status Descriptions
- Queued: Your API request was successful, and the message is in Sent's queue awaiting processing. This is the initial status you receive in the API response.
- Sent: The message has been successfully dispatched from Sent to the channel provider (e.g., SMS provider, Meta for WhatsApp).
- Delivered: The channel provider has confirmed the message was successfully delivered to the recipient's device.
- Read: (WhatsApp Only) The recipient has opened and read the message.
- Failed: The message could not be delivered. The Message object will contain an error object with details.
You will receive real-time updates for these status changes via webhooks.
📚 Want to learn more about webhooks? Check out our Webhooks guide.
Automatic Channel Selection
One of the most powerful features of Sent is its ability to choose the best communication channel for you. If you omit the channel field when sending a message, Sent will:
- Check the Contact's channel availability.
- Prioritize WhatsApp if it is available (as it offers a richer experience and is often more cost-effective).
- Fall back to SMS if WhatsApp is not available.
- The selected channel can be retrieved in the Message Object using webhooks.
This allows you to maintain a simple integration while Sent handles the channel complexity.
Sending Messages
Messages can be sent either through the Sent Dashboard playground or programmatically via the API.
Dashboard Playground
You can send messages through the integrated Playground in your Sent Dashboard. The playground provides:
- Visual message composer with template selection and template variable testing
- Message history and delivery tracking
- One-click sending to contacts or phone numbers
API Endpoints
For programmatic message sending, use the following API endpoints:
Every outbound message incurs a cost, which is automatically deducted from your customer account balance.
- Pricing is determined by the
channeland the recipient's country. - If your balance is insufficient to cover the cost of a message, the API call to send it will fail with a
402 Payment Requirederror. - The final cost is confirmed in the Message object, accessible via API or webhooks.
Message Status Tracking
The journey of a message after the initial API call is asynchronous. Polling the API for status updates is not supported and is highly discouraged.
The correct way to track message delivery is to use webhooks. When a message's status changes (e.g., from sent to delivered), Sent will immediately send a message.status.updated event to your configured webhook URL. This provides real-time, push-based updates without requiring you to make constant API calls.
📚 Want to learn more about webhooks? Check out our Webhooks guide.
The Message Object: Schema
This is the schema of a Message object you will receive in a webhook payload.
| Field | Type | Description |
|---|---|---|
id | GUID | The unique identifier for the Message. Store this ID to track the message. |
customerId | GUID | The ID of the customer account that sent the message. |
contact | object | A summary object of the recipient contact. |
template | object | A summary object of the template used for the message. |
channel | string | The channel used for delivery ("sms" or "whatsapp"). |
messageBody | string | The final, rendered text content of the message after variable substitution. |
status | string | The current delivery status of the message. See The Message Lifecycle. |
statusHistory | array | An array of objects, providing a complete chronological history of status changes. |
channelResponse | object | The raw response or status object from the channel provider. Useful for advanced debugging. |
pricing | object | An object detailing the cost of the message. |
createdAt | string | The ISO 8601 timestamp when the message was created. |
updatedAt | string | The ISO 8601 timestamp when the message's status was last updated. |
Example statusHistory Object:
"statusHistory": [
{ "status": "sent", "timestamp": "2025-01-15T08:30:01Z" },
{ "status": "delivered", "timestamp": "2025-01-15T08:30:15Z" }
]Example pricing Object:
"pricing": {
"originalPrice": 0.0125,
"correctedPrice": 0.0125,
"currency": "USD"
}Best Practices
- Store the
messageId: This is your primary key for tracking a message's lifecycle. Log it in your local database against the relevant user or event. It is essential for correlating webhook events and for any communication with Sent support. - Implement Webhooks: A robust webhook handler is critical for a reliable messaging integration. It is the only way to get real-time delivery confirmations and failure notifications.
- Handle Failures Gracefully: When you receive a webhook for a
failedmessage, use the error code to decide on a course of action. For certain transient errors, you might retry the message. For permanent failures (like an invalid number), you should flag the contact in your system. - Leverage Automatic Channel Selection: Unless you have a specific business reason to force a channel (e.g., sending a time-sensitive OTP where SMS is preferred), let Sent choose the optimal channel for you.
- Use
contactId: Always send messages using thecontactIdrather than a raw phone number. This is more efficient as it bypasses the need for Sent to perform a contact lookup and validation on every send.