Skip to main content
Back to blog

Running SMPP on Orbit — bring your own bind, keep the Inbox quiet, and practice bind hygiene

A practical playbook for tenants who bind their own SMPP client to Orbit's edge — how the bring-your-own-bind model works, when the SMPP Inbox toggle earns its keep, when SMPP beats an HTTP webhook flow (and when it doesn't), and the bind hygiene that keeps high-volume SMS sessions clean.

Orbit Editorial Team

SMS aggregators, platforms migrating off a legacy SMSC, and high-throughput senders often already speak SMPP — the binary protocol carriers and their customers' equipment have exchanged messages with since the 1990s. Rewriting that integration for a REST API is one option; binding straight to Orbit's SMPP edge is the other. Orbit issues a system_id and password per credential, you bind to smpp.orbit.devotel.io:2775, and your submit_sm PDUs ride the same routing, delivery tracking, and compliance gates as a REST-submitted send. This playbook covers where SMPP sits in the SMS stack, how the bring-your-own-bind model works on Orbit, what the SMPP Inbox toggle settles, when a webhook flow wins over a session, and the bind hygiene that keeps high-volume sessions healthy.

1. What SMPP is, and where it sits in the SMS stack

SMPP is the session protocol SMS applications and SMS centers (SMSCs) use to hand messages to each other: a persistent TCP session, an authenticated bind, and binary PDUs in one of three roles — bind_transmitter (send only), bind_receiver (receive receipts and inbound), or bind_transceiver (both, and what almost every integration wants). Messages go over submit_sm with the message id echoed back on submit_sm_resp; delivery receipts arrive as deliver_sm; enquire_link keepalives hold the session open.

In the four-layer architecture from how CPaaS works — API layer, orchestration, network, events — SMPP and the REST API are two different doors into the same house. The API layer just happens to speak binary PDUs instead of HTTP JSON on this door. Everything downstream is shared: the same compliance gates on the way in, the same routing engine choosing a route, the same delivery-receipt pipeline reporting back. Choosing SMPP is a wire decision, not a capability decision.

2. Bring your own bind: how a tenant registers its own connection

The model is deliberately flat: Orbit gives you the credentials, you bring the client.

  1. Create a credential in the dashboard (Messaging → SMPP) or over the API. You get a system_id and a password — the plaintext is returned once, at creation, so capture it on the spot. Rotate it later under the same credential; the id your client binds with stays put.
  2. Bind from your side. Your ESME — Gateway's smpp client, a Kannel instance, an aggregator platform, a smpplib script — opens a transceiver bind to smpp.orbit.devotel.io:2775 with those credentials and starts submitting.
  3. Traffic flows as normal platform traffic. A bind-submitted message resolves sender, compliance, and route exactly as a REST-submitted one would, records on the per-channel Messages list with its receipt trail and billing, and (depending on the credential's dlrMode) pushes receipts back over the bind as deliver_sm.

The row lives in your tenant, the password is encrypted at rest and never shown in full again, and only your traffic crosses your credential — bring-your-own-bind is tenant-owned end to end. If you run the mirror-image setup — your own upstream carrier attached to Orbit for outbound preference — that lifecycle (attach, health probe, detach) is documented separately in the BYO carrier lifecycle page; the two compose: inbound bind in, your carrier preferred on the way out.

3. The Inbox-noise problem, and the two-mode toggle

Here is the failure this toggle retired: by default, a submit_sm that arrived on your bind used to open a fresh SMS conversation in the team Inbox on every send. Fine at human volumes; at aggregator volumes it turned the Inbox into a firehose — one synthetic conversation per OTP, one new-conversation notification per destination, an agent queue drowning in machine traffic.

The fix shipped 2026-09-10 as a per-tenant decision with two modes:

  • Record on Messages (the default, `inbox_conversations: false`). Every bind submit gets its full Messages row — status trail, receipt, billing — but no conversation opens and no bell rings. Machine traffic stays machine-side.
  • Open Inbox conversations (`inbox_conversations: true`). Pass-through bind submits upsert a conversation per send and mint the new-conversation notification, so agents can answer. This is the mode for the genuine two-way case: recipients texting your short code, agents replying from the Inbox.

Flip it under Settings → Channels → SMPP Inbox, or over the API with GET / PUT /messages/smpp-bind-inbox. Two properties of the design matter for planning:

  • The record never disappears. The toggle gates conversation creation only. Whichever mode you run, the Messages list shows every bind row; only the Inbox object is conditional.
  • Replies still thread regardless. An inbound reply to a bind-sent message threads on the normal inbound path in both modes — the gate applies to the conversation the bind submit_sm itself would open, not to the thread your recipients reply on.

One refinement: if only some of your bind traffic should skip the Inbox, don't decide it with the global toggle — pin no-inbox on the termination rule for that traffic instead. The per-hop stamp wins over the tenant default when the two disagree. The full decision tree is in the SMPP bind → Inbox opt-in guide.

4. SMPP vs HTTP webhook flows: when each wins

Same destination, same compliance, same routing — so the choice is about your integration's shape, not the platform's.

SMPP wins when:

  • You already operate an SMPP client — a Kannel/Jasmin-style gateway, an aggregator bridge, a platform migration coming off an SMSC. Binding avoids the rewrite.
  • You push sustained throughput. A persistent session with many submit_sm PDUs in flight beats one TLS handshake per message, and receipts stream back in-band as deliver_sm instead of needing an HTTP listener.
  • Your accounting is SMPP-native: sequence numbers, submit_sm_resp ids, and enquire_link health are the operational vocabulary your tooling already speaks.

REST + webhooks win when:

  • The integration is new. One HTTPS POST per send and a webhook endpoint for status is a few lines in any language, with no session state to keep alive.
  • Volume is low or bursty rather than sustained — per-request overhead stops mattering, and a dropped TCP session stops being an operational concern.
  • Your stack already consumes the platform's events as webhooks and you would rather keep one event contract than run two receivers.

The wrong reason to pick either is capability: both doors reach the same routing and the same receipts. Pick by what your sending infrastructure already is.

How to run a clean SMPP bind on Orbit

  1. Prefer a transceiver bind. One session carrying both directions beats juggling a transmitter for sends and a receiver for receipts.
  2. Keep the session honest. Send enquire_link every 30–60 seconds; reconnect with backoff when the bind drops; and treat a silent session as a torn-down one instead of submitting into the void.
  3. Respect the negotiated window and your TPS cap. Pipeline submit_sm in flight — that is how SMPP batches — but let your client's remote window, not optimism, set the depth.
  4. Capture the plaintext once. The credential's password is returned at creation and at rotation, nowhere else. Store it in a secret manager on the spot; the dashboard only ever shows that a password is set.
  5. Set the Inbox mode deliberately. Default off for OTP/notification binds; on for genuinely two-way aggregator traffic; per-hop stamps for the mixed case.
  6. Rotate on a schedule and after staff changes. Rotation keeps the system_id stable, so an unplanned re-credential never becomes an unplanned re-integration.

None of these asks the platform to hold state for you — they are the same discipline any SMPP operator applies to any SMSC, applied to a bind whose upstream you do not have to run.

5. Tenant-owned bind hygiene: keeping your bind out of trouble

Which carrier your send terminates on is never your bind's decision — outbound termination in both directions of Orbit (REST in, SMPP in) goes out over the platform's managed edge, and routes you or your attached BYO carriers prefer are policy, not a new wire. The hygiene to practice on your bind is the session discipline above, plus three tenant-side habits:

  • One credential per system, not per environment variable. If three services share one client deployment, they share one credential; if they are three deployments, give them three credentials. Rotation and abuse-scoping stay cheap when credentials map to systems you can name.
  • Watch the bind state, not just the send count. A credential whose client silently lost its session shows up as empty receipt streams long before it shows up in a dashboard. Alert on enquire_link-silence the way you would on HTTP 5xx.
  • Keep sender policy on the platform, not in your client. Registered sender resolution and compliance checks run on the Orbit side either way — a client that tries to route around them fails at the API boundary, which is the response you want.

Everything on this list is tenant-owned: the credentials, the client, the Inbox mode, and the alerts are all yours to set and to audit.

Frequently asked questions

What is the SMPP host and port on Orbit?

Bind your SMPP 3.4 client to smpp.orbit.devotel.io:2775 with the system id and password issued at credential creation. A transceiver bind covers both directions.

How do I stop SMPP bind traffic flooding the Inbox?

Leave the SMPP Inbox toggle off — it is the default. Every bind submit still records a full Messages row; no conversation opens and no notification fires. Turn the toggle on only where agents genuinely answer bind free-text.

SMPP or REST + webhooks — how do I choose?

Keep SMPP for existing SMPP infrastructure and sustained throughput; choose REST + webhooks for new work and variable volume. Capability is identical either way.

What happens when my bind drops?

The idle session is torn down; your client should reconnect with backoff and keep enquire_link flowing every 30–60 seconds. REST-submitted traffic is unaffected throughout.

The takeaway

Bring-your-own-bind on Orbit is a wire choice with guardrails, not a second platform: credentials you own, a session you keep, traffic that shares the same routing and compliance as the REST API, and an Inbox that only sees your bind when you say so. Run the bind like an SMPP operator would — transceiver, keepalives, sane windows, scheduled rotation — and the only thing left that the protocol can't do for you is deciding, per tenant, whether machine traffic belongs in the agent queue.

Published 13 September 2026.

Running SMPP on Orbit — bring your own bind, keep the Inbox quiet, and practice bind hygiene — Orbit by Devotel