Technical Documentation

SMPP Integration Guide

Everything you need to connect your platform to A2P Shield via SMPP. This guide covers connection setup, message encoding, error handling, and best practices.

1Overview

A2P Shield acts as an SMPP proxy between your platform and the operator's SMSC. All A2P SMS traffic is routed through our firewall for real-time security analysis and filtering.

Low Latency

< 50ms processing time per message

Transparent Proxy

Messages forwarded with full integrity

Security Analysis

Every message scanned against threat rules

Your Platform
SMPP Client
Firewall
A2P Shield
Operator
SMSC

2Connection Details

Hostsmpp.a2pshield.telecom-works.com
Port2775(Standard SMPP)
ProtocolSMPP v3.4
Bind Typesbind_transceiver, bind_transmitter, bind_receiver
Credentialssystem_id and password provided during onboarding
TLS Port2776Coming Soon

3Supported Operations

OperationDirectionSupportedNotes
bind_transceiverClient → ServerRecommended
bind_transmitterClient → ServerSend only
bind_receiverClient → ServerReceive DLRs only
submit_smClient → ServerSend SMS
submit_sm_respServer → ClientAcknowledgement with message_id
deliver_smServer → ClientDelivery receipts
enquire_linkBidirectionalKeepalive (30s interval recommended)
unbindBidirectionalClean disconnect

4Message Encoding

data_codingEncodingSingle SMSPer PartDescription
0GSM 7-bit160153Default alphabet. Extended chars (€, {, }, [, ]) count as 2
1ASCII (IA5)1601537-bit ASCII
3Latin-1 (ISO-8859-1)1401348-bit. Western European characters
4Binary1401348-bit binary data
8UCS-2 (UTF-16BE)706716-bit. Arabic, Chinese, Cyrillic, emoji

GSM 7-bit Character Set

The GSM 7-bit default alphabet includes the characters below. Characters marked with 2 chars require the extension table and consume 2 character slots.

Basic: A-Z a-z 0-9 @ £ $ ¥ è é ù ì ò Ç Ø ø Å å Δ _ Φ Γ Λ Ω Π Ψ Σ Θ Ξ ¡ § ¿ ä ö ñ ü Ä Ö Ñ Ü ! " # ¤ % & ' ( ) * + , - . / : ; < = > ? SP CR LF
Extension table 2 chars each
|^{}\[~]

Concatenated SMS (Long Messages)

Messages exceeding single SMS character limits are sent as concatenated SMS using a UDH (User Data Header). Set esm_class bit 6 (0x40) to enable the UDHI flag.

8-bit reference (6 bytes UDH)

05 00 03 XX YY ZZ
XX = reference numberYY = total partsZZ = part number

16-bit reference (7 bytes UDH)

06 08 04 XXXX YY ZZ
XXXX = 16-bit referenceYY = total partsZZ = part number

The UDH reduces available payload per part: 7 bytes for 8-bit reference, 8 bytes for 16-bit reference.

message_payload TLV

For messages longer than 254 bytes, use the message_payload TLV (tag 0x0424) instead of short_message. When using message_payload, set sm_length to 0.

5Sender ID (source_addr)

Alphanumeric

Maximum 11 characters

e.g., BrandName

Numeric

Maximum 15 digits (E.164 recommended)

e.g., +34600123456

Sender IDs must be pre-registered and authorized. Unauthorized sender IDs will be rejected with ESME_RINVSRCADR (0x0000000A).

6Destination Address

All destination addresses must be in E.164 format: +[country_code][number]

Example: +34612345678
TON (Type of Number)
1 (International)
NPI (Numbering Plan)
1 (E.164)

7Rate Limits

100
TPS

Default rate limit: 100 transactions per second per account.

Custom limits available on request. Limits apply per system_id.

Exceeding the rate limit returns ESME_RTHROTTLED (0x00000058). Implement exponential backoff to handle this gracefully.

8Delivery Receipts

Delivery receipts are enabled by default (registered_delivery = 1). They arrive as deliver_sm PDUs.

DLR Body Format

id:XXXXX sub:001 dlvrd:001 submit date:YYMMDDHHMM done date:YYMMDDHHMM stat:DELIVRD err:000 text:...

Status Values

DELIVRDDelivered
UNDELIVUndeliverable
EXPIREDExpired
REJECTDRejected
ACCEPTDAccepted
UNKNOWNUnknown

9Error Codes

CodeHexNameDescription
00x00000000ESME_ROKSuccess
10x00000001ESME_RINVMSGLENInvalid message length
50x00000005ESME_RBINDFAILBind failed (wrong credentials or IP not whitelisted)
80x00000008ESME_RSYSERRSystem error (SMSC unavailable)
100x0000000AESME_RINVSRCADRInvalid/unauthorized source address
130x0000000DESME_RINVBNDSTSInvalid bind status (not bound)
140x0000000EESME_RINVDFTMSGIDMessage rejected by firewall rules
880x00000058ESME_RTHROTTLEDRate limit exceeded

10Connection Best Practices

Persistent Connections

Maintain persistent connections. Avoid frequent bind/unbind cycles.

Keepalive

Send enquire_link every 30 seconds to keep the session alive.

Exponential Backoff

Handle ESME_RTHROTTLED with exponential backoff. Do not retry immediately.

Use Transceiver

Use bind_transceiver for both sending and receiving DLRs on a single connection.

Auto Reconnect

Implement automatic reconnection with incremental backoff on connection loss.

Monitor DLRs

Monitor DLR status to track delivery rates and detect issues early.

11IP Whitelisting

Only whitelisted IPs can establish SMPP connections. Provide your source IP addresses during the onboarding process.

  • Provide your source IPs during onboarding
  • Connections from non-whitelisted IPs are silently dropped
  • Request IP changes through your account manager

12Code Examples

Python (smpplib)

Python
import smpplib.client
import smpplib.consts

client = smpplib.client.Client("smpp.a2pshield.telecom-works.com", 2775)
client.connect()
client.bind_transceiver(system_id="YOUR_SYSTEM_ID", password="YOUR_PASSWORD")

client.send_message(
    source_addr_ton=smpplib.consts.SMPP_TON_ALNUM,
    source_addr="BrandName",
    dest_addr_ton=smpplib.consts.SMPP_TON_INTL,
    destination_addr="+34612345678",
    short_message=b"Your verification code is 123456",
    data_coding=0,  # GSM7
    registered_delivery=True,
)

Node.js (smpp)

JavaScript
const smpp = require("smpp");
const session = smpp.connect({
  url: "smpp://smpp.a2pshield.telecom-works.com:2775",
});

session.on("connect", () => {
  session.bind_transceiver(
    {
      system_id: "YOUR_SYSTEM_ID",
      password: "YOUR_PASSWORD",
    },
    (pdu) => {
      if (pdu.command_status === 0) {
        session.submit_sm(
          {
            source_addr: "BrandName",
            destination_addr: "+34612345678",
            short_message: Buffer.from("Your code is 123456"),
            data_coding: 0,
            registered_delivery: 1,
          },
          (resp) => {
            console.log("Message ID:", resp.message_id);
          }
        );
      }
    }
  );
});

session.on("deliver_sm", (pdu) => {
  console.log("DLR:", pdu.short_message.toString());
  session.send(pdu.response());
});

13Support

Technical Support

support@telecom-works.com

Emergency

24/7 for critical issues

Account Setup

Contact your account manager

© 2026 A2P Shield by Telecom Works. All rights reserved.
Last updated: June 2026
Powered byTelecom Works