API v2 to v3 Migration
Migrate your integration from the legacy v2 API to the current v3 API.
Key Differences
| Feature | v2 | v3 |
|---|---|---|
| Base URL | api.sent.dm/v2 | api.sent.dm/v3 |
| Auth Header | x-sender-id + x-api-key | x-api-key only |
| Request Body | recipients, template_id, template_variables | to, template (object with id/name/parameters), channel |
| Response Format | Flat data | Envelope with success, data, error, meta |
| Rate Limits | Varies | 200 req/min (standard), 10 req/min (sensitive) |
| Sandbox Mode | test_mode: true | sandbox: true |
| Templates | Simple text | Structured components |
| Contacts | Basic | Channel intelligence |
Authentication Changes
v2 (Legacy)
GET /v2/messages
x-sender-id: your-sender-id
x-api-key: your-api-keyv3 (Current)
GET /v3/messages
x-api-key: your-api-keyRequest Format Changes
Sending Messages
v2 (Legacy)
{
"recipients": ["+1234567890"],
"template_id": "tmpl_123",
"template_variables": {
"name": "John",
"order_id": "12345"
},
"channels": ["sms"],
"sandbox": true
}v3 (Current)
{
"to": ["+1234567890"],
"template": {
"id": "tmpl_123",
"name": "order_confirmation",
"parameters": {
"name": "John",
"order_id": "12345"
}
},
"channel": ["sms"],
"sandbox": false
}Key Changes:
recipients→totemplate_id→template.id(inside template object)template_variables→template.parameters- Added
template.name(optional) channels→channeltest_moderenamed tosandbox
Response Format Changes
v2 (Legacy)
{
"data": {
"messages": [
{
"id": "msg_123",
"recipient": "+1234567890",
"status": "queued",
"contact_id": "contact_456"
}
]
}
}v3 (Current)
{
"success": true,
"data": {
"status": "QUEUED",
"template_id": "tmpl_123",
"template_name": "order_confirmation",
"recipients": [
{
"message_id": "msg_123",
"to": "+1234567890",
"channel": "sms"
}
]
},
"error": null,
"meta": {
"request_id": "req_abc123",
"timestamp": "2026-03-04T11:28:25.2096416+00:00",
"version": "v3"
}
}Key Changes:
- Response is now wrapped in an envelope with
success,data,error,meta messages→recipientsarrayid→message_idrecipient→to- Added
meta.request_idfor support tickets
Error Format Changes
v2 (Legacy)
{
"error": {
"code": "insufficient_balance",
"message": "Account balance is insufficient"
}
}v3 (Current)
{
"success": false,
"data": null,
"error": {
"code": "BUSINESS_003",
"message": "Account balance is insufficient to send this message",
"details": null,
"doc_url": "https://docs.sent.dm/errors/BUSINESS_003"
},
"meta": {
"request_id": "req_abc123",
"timestamp": "2026-03-04T11:28:25.2096416+00:00",
"version": "v3"
}
}Key Changes:
- Error codes are now prefixed (e.g.,
BUSINESS_003,AUTH_001,VALIDATION_002) - Added
doc_urlwith link to error documentation - Error is part of the standard envelope format
Webhook Event Changes
v2 (Legacy)
{
"field": "messages",
"id": "msg_123",
"status": "DELIVERED",
"channel": "sms",
"to": "+1234567890",
"from": "+1987654321",
"template_id": "tmpl_123",
"timestamp": "2025-01-15T08:30:15Z"
}v3 (Current)
{
"field": "messages",
"timestamp": "2025-01-15T08:30:15Z",
"payload": {
"account_id": "7ba7b820-9dad-11d1-80b4-00c04fd430c8",
"message_id": "8ba7b830-9dad-11d1-80b4-00c04fd430c8",
"message_status": "DELIVERED",
"channel": "sms",
"inbound_number": "+1234567890",
"outbound_number": "+1987654321",
"template_id": "9ba7b840-9dad-11d1-80b4-00c04fd430c8"
}
}Key Changes:
- Added
payloadwrapper — status fields are now nested underpayload id→payload.message_idstatus→payload.message_statusto→payload.inbound_numberfrom→payload.outbound_number- Added
payload.account_idfor multi-account setups - Top-level
template_idmoved intopayload.template_id
Endpoint Mapping
| v2 Endpoint | v3 Endpoint | Changes |
|---|---|---|
POST /v2/messages | POST /v3/messages | New request/response format |
GET /v2/messages/{id} | GET /v3/messages/{id} | Response uses envelope format |
POST /v2/contacts | POST /v3/contacts | New response envelope |
GET /v2/contacts | GET /v3/contacts | Response uses envelope format |
POST /v2/templates | POST /v3/templates | New template structure |
Idempotency Changes
v2 (Legacy)
{
"recipients": ["+1234567890"],
"template_id": "tmpl_123",
"idempotency_key": "order_123_456"
}v3 (Current)
curl -X POST "https://api.sent.dm/v3/messages" \
-H "x-api-key: $SENT_API_KEY" \
-H "Idempotency-Key: order_123_456" \
-d '{
"to": ["+1234567890"],
"template": {"id": "tmpl_123"}
}'Key Changes:
- Idempotency key is now sent as
Idempotency-Keyheader, not request body - Keys are cached for 24 hours
Migration Process
Migration Steps
- Update Base URL - Change from
/v2to/v3 - Update Authentication - Remove
x-sender-idheader, keep onlyx-api-key - Update Request Format - Change
recipientstoto,template_idtotemplate.id, etc. - Update Response Handling - Handle the new envelope format with
success,data,error,meta - Update Error Handling - Use new error codes (e.g.,
BUSINESS_003instead ofinsufficient_balance) - Update Webhook Handlers - Adjust for new nested event structure (
payloadwrapper added; usepayload.message_idandpayload.message_status) - Update Idempotency - Move key from body to
Idempotency-Keyheader - Test in Sandbox Mode - Validate all functionality with
sandbox: true - Deploy Gradually - Use feature flags for rollout
The v2 API is deprecated and will be sunset. Migrate to v3 as soon as possible.