Contacts
A contact in Sent is a validated communication endpoint: a phone number enriched with the channel information the platform needs to reach its owner.
Rather than forcing developers to manage the complexity of different messaging channels, contacts provide a unified abstraction that handles channel validation, metadata, and routing automatically.
Contacts Architecture
The Sent Contacts Architecture is designed to be intelligent and flexible, while allowing you to have full control over the messaging experience.
Channel-Agnostic Abstraction
Traditional messaging platforms require developers to understand and integrate with separate APIs for SMS, WhatsApp, and other channels. This leads to several problems such as integration complexity, validation overhead, routing decisions, and fallback handling, all of which need to be implemented manually.
Sent solves these problems by providing a channel-agnostic abstraction. When you send a message to a contact, the platform handles all channel-specific complexity behind a unified interface.
The Contact as a Validated Communication Endpoint
A contact in Sent is fundamentally different from a simple phone number or user record. It represents:
A validated, intelligent communication endpoint that:
- Knows which messaging channels can successfully reach the recipient
- Understands the optimal channel for delivery based on regional preferences and availability
- Maintains channel-specific formatting and validation rules
- Provides automatic fallback routing when primary channels fail
This abstraction allows developers to focus on their app logic rather than the intricacies of multi-channel messaging infrastructure.
Channel Availability and Routing
A contact records which channels can currently reach its phone number. SMS, WhatsApp, and RCS are all live channels in Sent, and a contact carries a per-channel availability record for each.
When you send without pinning a channel, routing selects among the contact's available channels per recipient at send time. There is no fixed channel preference order: the winning route depends on the routing rules configured for your account and the recipient, and the remaining candidates are kept as fallbacks. The factors the router weighs are summarized in Routing Factors; Unified Messaging Intelligence explains the decision engine, and the channel routing reference specifies the exact matching and ordering rules.
Persistent State
Contacts maintain persistent state that benefits future interactions:
- Channel availability is cached and periodically refreshed
- Routing decisions improve based on delivery history
- Validation status prevents repeated failed delivery attempts
This persistence means that applications naturally become more efficient over time without additional developer effort.
Phone Number Normalization
Contacts handle the complexity of phone number formatting across different contexts:
- E.164 format: International standard for programmatic use
- International format: Human-readable international representation
- National format: Localized formatting for user interfaces
- RFC format: Standardized format for system integration
This multi-format support ensures that contacts work correctly regardless of how phone numbers are provided or displayed in your app.
Customer Scoping and Isolation
Contacts are scoped to individual customers, providing:
- Access control: Customers can only access their own contacts
- Billing isolation: Message costs are attributed correctly
- Data privacy: Contact information remains segregated between customers
This architecture supports multi-tenant applications while maintaining security and billing accuracy.
Channel-Specific Metadata
While contacts abstract channel complexity, they also preserve channel-specific information when needed:
- WhatsApp profile status: Whether a number has an active WhatsApp Business API registration
- SMS carrier information: Network-specific delivery capabilities
- Regional restrictions: Compliance and availability constraints by geography
This metadata enables advanced applications to make informed decisions while still benefiting from the unified API approach.
Contact Intelligence
Automatic Contact Creation
Contacts follow a lazy creation pattern that reduces integration friction. This approach means developers never need to pre-register contacts. The system creates and optimizes them automatically during the first messaging interaction.
Here's how it works:
Real-Time Channel Validation
When a contact is created, and again as messages are sent to it, Sent validates the phone number against the supported channels:
- SMS availability: verified through carrier network validation
- WhatsApp registration: checked against the WhatsApp Business API
- RCS capability: checked against the recipient device's RCS support, with the result cached for reuse
This validation ensures that every contact represents a deliverable endpoint, reducing bounce rates and failed message attempts.
Contact Enrichment Over Time
Contacts become more intelligent through usage:
- Delivery success patterns inform future routing decisions
- Channel preferences are learned from recipient engagement
- Validation status is periodically refreshed to maintain accuracy
This creates a feedback loop where messaging performance improves automatically as the system learns more about each contact.
Contacts for Developers
Sent supports two primary patterns for working with contacts. Both patterns use the same underlying intelligence but offer different levels of control and visibility.
Direct phone messaging (automatic contact creation):
- Send immediately to any phone number
- Contact created and optimized transparently
- Ideal for one-off or ad-hoc messaging
Explicit contact management:
- Retrieve and work with contact objects
- Access channel availability metadata
- Suitable for applications that need contact state awareness
Managing Contacts covers both patterns in practice.
When building with Sent's contact system, developers should shift their mental model to a contact-based approach
Avoid the traditional approach of branching on channel in your own code:
if (user.hasWhatsApp) {
sendWhatsApp(message, user.phone);
} else {
sendSMS(message, user.phone);
}Prefer the contact-based approach, where the platform picks the channel:
sendMessage(message, contact);SMS Encoding & Message Length
How SMS character encoding (GSM-7 vs Unicode) and message concatenation determine character limits, segment counts, and cost
Templates
Why Sent messages are defined as templates, and how one channel-agnostic definition adapts its content, variables, and buttons to SMS, WhatsApp, and RCS