📊 Web Dashboard: Manage Your SMS Gateway from a Browser
We're excited to announce the SMSGate Web Dashboard — a standalone web application that provides a graphical interface for managing your SMS gateway at https://dashboard.sms-gate.app.
Welcome to the SMSGate blog! Here you'll find the latest news, updates, and technical articles about our platform.
Subscribe to our RSS for updates on new posts.
We're excited to announce the SMSGate Web Dashboard — a standalone web application that provides a graphical interface for managing your SMS gateway at https://dashboard.sms-gate.app.
We're excited to announce the Email to SMS Bridge — a new standalone service that acts as an SMTP server, receiving emails and forwarding their content as SMS messages via the SMSGate API. If your system can send email, it can now send SMS.
Following last week's introduction of the SMPP Server, we're happy to announce that a public SMPP server is now available at smpp.sms-gate.app.
We're excited to announce the SMPP Server — a new standalone service that brings SMPP v3.4 protocol support to the SMSGate ecosystem. This enables SMS aggregators, messaging platforms, and any SMPP-compatible client to send and receive SMS messages through Android devices running the SMS Gateway app.
We're announcing a new Message Queue Limits feature that adds configurable rate limiting and queue management capabilities to the SMS Gateway server. This feature helps prevent devices from being overwhelmed with message processing tasks and ensures reliable SMS delivery across your infrastructure.
We're excited to announce a significant enhancement to our JWT authentication system: refresh token support. This new feature enables seamless token rotation, improved security, and a better experience for long-running services that need to maintain access without storing credentials.
sender and recipientWe're excited to announce a significant improvement to our webhook payload structure. Based on user feedback and real-world usage, we've added new fields to make webhook data more explicit, especially for multi-SIM devices and complex messaging scenarios.
TL;DR: Your webhooks now include sender and recipient fields for crystal-clear phone number semantics, while maintaining full backward compatibility with the existing phoneNumber field.
{
"payload": {
"messageId": "abc123",
"phoneNumber": "+1234567890",
"simNumber": 1,
"message": "Hello World"
}
}
The Confusion: What does phoneNumber represent?
This ambiguity forced developers to: - Reverse-engineer semantics based on event type - Maintain separate logic for inbound vs outbound - Guess which phone number they're actually working with
Consider a dual-SIM device with numbers +1112223333 (SIM 1) and +4445556666 (SIM 2):
Scenario 1: Incoming SMS to SIM 1
Scenario 2: Outgoing SMS from SIM 2
In both cases, phoneNumber means something different! 😕
{
"payload": {
"messageId": "abc123",
"sender": "+9998887777",
"recipient": "+1112223333",
"phoneNumber": "+9998887777",
"simNumber": 1,
"message": "Hello World"
}
}
Now it's crystal clear: - sender: The phone number that sent the message - recipient: The phone number that received the message (or null if unavailable) - phoneNumber: Deprecated but kept for backward compatibility
| Event Type | sender | recipient |
|---|---|---|
sms:received (inbound) | External sender | Device's number |
sms:data-received (inbound) | External sender | Device's number |
mms:received (inbound) | External sender | Device's number |
sms:sent (outbound) | Device's number | Recipient |
sms:delivered (outbound) | Device's number | Recipient |
sms:failed (outbound) | Device's number | Recipient |
Key Insight: sender always originates, recipient always receives. No more guessing! 🎯
We understand that changing payload structures can be disruptive. That's why we've designed this enhancement to be 100% backward compatible.
phoneNumber field remains in all payloadsphoneNumber)sender field: Originating phone number (who sent the message)recipient field: Receiving phone number — device's number for inbound, recipient's for outboundphoneNumber field: Now marked as deprecatedPhase 1 - Today (Backward Compatible):
{
"sender": "+1234567890",
"recipient": "+9876543210",
"phoneNumber": "+1234567890" // Still works!
}
Phase 2 - Future (After Deprecation Period):
{
"sender": "+1234567890",
"recipient": "+9876543210"
// phoneNumber removed in future major version
}
Recommendation: Start using sender and recipient in your code now. They're clearer and will be supported indefinitely. The phoneNumber field will remain available for at least 12 months before removal.
The new recipient field is especially valuable for multi-SIM devices.
Device Configuration: - SIM 1: +1112223333 - SIM 2: +4445556666
Incoming SMS to SIM 1:
{
"event": "sms:received",
"payload": {
"sender": "+9998887777",
"recipient": "+1112223333", // ← Now explicit!
"simNumber": 1
}
}
Incoming SMS to SIM 2:
{
"event": "sms:received",
"payload": {
"sender": "+7776665555",
"recipient": "+4445556666", // ← Clear which SIM!
"simNumber": 2
}
}
Now you can: - Route messages to correct handlers based on recipient number - Track which SIM received each message without inference - Build accurate multi-SIM analytics and dashboards
The recipient field is nullable because:
READ_PHONE_STATE permission may not be grantedWhen recipient is null, webhooks still fire normally with the field set to null. This ensures no loss of functionality.
Always Handle null Values
Your webhook handler should always check if recipient is null before using it. Example in JavaScript:
Use the new fields immediately—they're clearer and future-proof:
app.post('/webhook', (req, res) => {
const { sender, recipient, message } = req.body.payload;
console.log(`Message from ${sender} to ${recipient || 'unknown'}`);
// Your business logic here
res.sendStatus(200);
});
No action required! Your existing code will continue to work:
// Old code still works
app.post('/webhook', (req, res) => {
const { phoneNumber, message } = req.body.payload;
console.log(`Message from ${phoneNumber}`);
res.sendStatus(200);
});
But consider upgrading for better clarity:
// Enhanced code with new fields
app.post('/webhook', (req, res) => {
const { sender, recipient, message } = req.body.payload;
// Use sender (explicit) instead of phoneNumber (ambiguous)
console.log(`Message from ${sender} to ${recipient || 'unknown'}`);
res.sendStatus(200);
});
All documentation has been updated to reflect the new payload structure:
sms:received eventsender and recipient fields{
"deviceId": "device-id",
"event": "sms:received",
"id": "webhook-event-id",
"payload": {
"messageId": "abc123",
"sender": "+9998887777",
"recipient": "+1112223333",
"phoneNumber": "+9998887777",
"simNumber": 1,
"receivedAt": "2026-02-17T12:00:00.000+07:00"
},
"webhookId": "webhook-id"
}
A: No! The phoneNumber field remains with the same value as before. Your existing code will work without any changes.
A: We recommend it! The sender and recipient fields are much clearer, especially for multi-SIM scenarios. The migration depends on event type: - For inbound events (sms:received, sms:data-received, mms:received): replace phoneNumber with sender. - For outbound events (sms:sent, sms:delivered, sms:failed): replace phoneNumber with recipient.
phoneNumber be removed?A: We'll keep phoneNumber for at least 12 months to give everyone time to migrate. We'll announce a deprecation timeline well in advance.
recipient is null?A: This can happen if the app lacks READ_PHONE_STATE permission or the carrier doesn't provide the device number. Your code should handle null gracefully. The webhook will still fire with all other fields populated.
A: No. This enhancement only affects webhook payloads. The message sending API remains unchanged.
A: - Use sender for the originating phone number (who sent the message) - Use recipient for the receiving phone number (which device received it or who was the recipient) - Avoid phoneNumber in new code (it's deprecated)
| ✅ | Benefit | Impact |
|---|---|---|
| 1 | Clear Semantics | No more guessing what phoneNumber means |
| 2 | Multi-SIM Clarity | Explicit recipient per SIM slot |
| 3 | Zero Breaking Changes | Existing integrations keep working |
| 4 | Future-Proof | New fields will be supported indefinitely |
| 5 | Better Developer Experience | Self-documenting code with explicit field names |
| 6 | Consistent Logic | Same semantics across all event types |
We'd love to hear your thoughts on this enhancement!
This enhancement was driven by user feedback from the community. Your real-world experiences with multi-SIM devices and complex integrations helped shape this solution.
We're committed to making SMSGate the most developer-friendly SMS gateway platform. Stay tuned for more improvements!
Happy coding! 🚀
Picture this: Your SMS gateway credentials get accidentally committed to a public GitHub repository. With Basic Authentication, every single API request transmits those credentials, creating countless opportunities for interception. One leaked password means immediate exposure of your entire SMS infrastructure. This scenario isn't hypothetical—it happens regularly in production environments, leading to security breaches, and unauthorized access. Modern API security demands a better approach.
Enter JWT (JSON Web Token) authentication—a token-based authentication mechanism that eliminates the need to transmit credentials with every request while providing fine-grained access control through scopes. In this comprehensive guide, we'll explore why JWT authentication is replacing Basic Auth as the primary authentication method for the SMSGate API, walk through the technical implementation, and provide complete code examples for a smooth migration. Whether you're maintaining existing integrations or building new ones, understanding this transition is essential for securing your SMS infrastructure.
Have you ever faced a situation where a customer insisted they never received your critical SMS notification, but your logs showed it was sent? Message delivery tracking is a common pain point for developers integrating SMS functionality, leading to frustrated users and time-consuming debugging sessions. In today's mobile-first world, reliable message history isn't just a nice-to-have—it's essential for customer trust, and operational efficiency. The GET /messages API provides a robust RESTful solution for programmatically retrieving SMS message histories across both local server deployments and cloud services. In this comprehensive guide, we'll walk through the technical specifications, share real-world code examples in Python and JavaScript, and provide expert tips for optimizing your message retrieval implementation. By the end, you'll have everything needed to master SMS message history management in your applications.
In multi-device deployments, ensuring messages reach active, responsive devices is critical for reliability. The deviceActiveWithin parameter provides granular control over device selection based on recent activity, enabling developers to optimize message delivery success rates while maintaining system efficiency.