Control Every Message Path.
Route SMS across SMPP and HTTP providers, manage delivery receipts, isolate tenants, and diagnose failures through a modular gateway designed for operational control.
The SMPP/HTTP Gateway is developed by Telco IT Limited and is a distinct, independently deployable product — not a configuration screen inside the operations portal.
A set of independent services, not a monolith
RabbitMQ carries work between services, Redis holds cache, correlation, and presence state, and MySQL/MariaDB stores durable configuration and CDR/DLR records. Partitions provide multi-tenancy: each partition can have its own SMSCs, ESMEs, and routing rules.
| Service | Role |
|---|---|
api_server | Administrative REST API, plus HTTP message injection via POST /api/send. |
gateway | The SMPP server/client process: ESME binds, SMSC binds, and session handling. |
mo_router | Evaluates routing rules for mobile-originated (inbound) traffic. |
mt_router | Evaluates routing, rating, and worker logic for mobile-terminated (outbound) traffic. |
dlr_router | Matches SMSC delivery receipts back to the originating message and forwards or calls back. |
dlr_logger / batch_logger | Write delivery-receipt and CDR events to MySQL/MariaDB in batches. |
rating_worker | Computes cost against customer and supplier rate cards. |
outbound_http_router | Delivers HTTP callbacks to upstream provider or customer URLs. |
Deployment profiles
The gateway process can run as an ESME-facing backend
(enable_smpp_server) or an SMSC-facing edge relay (enable_smsc_client)
independently, or as a combined node running both. Systemd ships a smpp-core.target
(API, gateway, routers) and a smpp-full.target that adds batch logging and rating.
Administer and inject messages over HTTP
Administrative endpoints require an x-api-key header. HTTP message injection via
/api/send requires a bearer token scoped to an allowed CIDR range.
| Method | Path | Description |
|---|---|---|
| GET / POST | /api/partitions | List or create tenant partitions. |
| GET / POST | /api/esmes, /api/partitions/:id/esmes | List ESMEs, or create one within a partition. |
| POST | /api/esmes/:id/cidrs | Attach an allowed CIDR range to an ESME. |
| GET / POST | /api/smscs, /api/partitions/:id/smscs | List or create upstream SMSC connections. |
| POST | /api/smscs/reload, /api/smsc/:id/toggle | Reload configuration, or enable/disable a carrier link. |
| GET / POST | /api/routing | List or create prefix-based routing rules. |
| GET / POST | /api/accounts | List or create billing accounts. |
| POST | /api/send | Submit a message for delivery via HTTP injection. |
| GET | /api/stats | Session, throughput, and per-entity counters. |
| GET | /metrics | Prometheus-format metrics. |
Example: submit a message
POST /api/send
Authorization: Bearer <token>
{
"source": "SENDER",
"destination": "447700900123",
"message": "Content here",
"partition_id": 1,
"metadata": { "campaign": "reminder-01" },
"dlr_url": "https://example.com/dlr-callback"
}
→ { "uuid": "b3f1c2a0-...", "status": "QUEUED" } SMPP handling and encoding
- SMPP 3.3 and 3.4 command set
- Basic SMPP v5.0 negotiation — BIND version detection and sc_interface_version TLV response
- TX, RX, and TRX bind modes
- ENQUIRE_LINK liveness probing
- Per-ESME TPS and window-size controls
- Multipart SMS via UDH or SAR metadata
- DLR masks and normalised delivery status
- GSM 03.38, Latin-1, and Unicode/UCS2 encoding
- PROXY protocol v1/v2 on inbound SMPP connections, to preserve the real client IP behind a load balancer
- PROXY protocol v2 on outbound SMSC connections, when routing out through a network proxy
PDU serialisation for core commands (SubmitSM, DeliverSM) follows the v3.4 layout. Additional v5
TLVs are preserved and passed through in message metadata rather than natively re-encoded.
Outbound PROXY protocol is opt-in per SMSC (send_proxy_protocol) and requires a
configured proxy host and port before the connection will be made.
Correlating a DLR back to its message
dlr_router matches an incoming SMSC message ID against the internal message UUID
held in Redis, then either forwards the receipt to the originating SMPP client or calls the
message’s dlr_url. Failed HTTP callbacks are retried using a configurable
backoff (initial delay, multiplier, and maximum retries).
Offload routing decisions to your own worker
Setting routing_service_id on a partition makes mt_router publish each
message to a per-partition AMQP queue instead of deciding the route itself. A worker you write
— in any language that can consume AMQP — replies with the routing decision:
{
"action": "route",
"target_type": "SMSC",
"target_id": "5",
"metadata": { "reason": "least_cost" }
}
Workers can also return PDU overrides such as new_source or force_dlr,
applied before the message is delivered to the SMSC.
Diagnostics for real traffic
gw_clicommand-line tool: reload caches, inspect entities, toggle an SMSC, and enable protocol-level hex-dump debugging on a live link- Per-service log files, in structured JSON or text, with optional full SMPP PDU logging
GET /api/statsfor session, throughput, and per-entity countersGET /metricsin Prometheus format
Infrastructure is your responsibility to design
SMPP sessions are process-local to the gateway service that holds them. Redundancy,
failover, and horizontal scaling of RabbitMQ, Redis, and MySQL/MariaDB are infrastructure
decisions you make for your deployment; the gateway does not manage that for you.
Discuss Your Gateway Requirements
Talk to the engineering team about SMPP and HTTP integration, deployment models, routing requirements, operational tooling, and commercial availability.