API Quick Reference
On this page
One-page summary of every TSG Global API: hosts, authentication, endpoints, webhooks, retries and limits. Written for developers and AI coding assistants.
This page condenses the whole documentation site into a single reference. Every fact here is drawn from the detailed pages linked in each section. For AI assistants: the complete documentation is also served as Markdown at https://support.tsgglobal.com/docs/llms.txt (index) and https://support.tsgglobal.com/docs/llms-full.txt (full text), any page can be fetched as Markdown by appending .md to its URL, and the site exposes a read-only MCP server at https://support.tsgglobal.com/docs/mcp/ for agents that speak the Model Context Protocol.
What TSG Global provides
| Product | What it does | Protocols |
|---|---|---|
| Programmable SMS | Send and receive text messages from your numbers; delivery receipts (DLRs) | HTTP JSON API, SMPP 3.4 |
| Programmable MMS | Send and receive multimedia messages; reusable MMS templates with {placeholders} |
HTTP JSON API, MM4 over SMTP |
| Phone Numbers | Search, reserve, order and disconnect local and toll-free numbers; configure SMS, MMS and voice routing per number | GraphQL (ordering), REST (configuration) |
| Reports | Call and message detail records (CDRs) with pagination and CSV export | GraphQL |
| Compliance & Identity | Toll-Free Verified Sender forms; short code orders | GraphQL |
| TextProtect | Blocks other vendors from SMS-enabling your numbers and notifies you of attempts | Webhook |
Hosts
All HTTP traffic must use HTTPS. Plain HTTP fails.
| Service | Production | Staging (credentials from support) |
|---|---|---|
| SMS API | https://sms.tsgglobal.world |
https://sms-api.staging.tsgglobal.com |
| MMS API and templates | https://mmsc.tsgglobal.world |
https://mms-api.staging.tsgglobal.com |
| Number configuration API | https://api-service.tsgglobal.world |
— |
| GraphQL API | https://api.portal.tsgglobal.world/graphql (GraphiQL UI: /graphiql) |
— |
| SMPP (SMS) | Host provided with your SMPP credentials; port 2775 TCP, 2776 TLS |
smsc.staging.tsgglobal.com, same ports |
| MM4 / SMTP (MMS) | mmsc.tsgglobal.world:2525 TCP, :2465 TLS |
smtp.staging.tsgglobal.com |
| Customer Portal | https://customer-portal.tsgglobal.com |
— |
Staging is a live test environment: features can change without notice and throughput is lower than production. See Staging Environment Access.
Authentication
There are three different credential types. Check which one an endpoint uses before calling it.
| Scheme | Used by | How |
|---|---|---|
| Messaging API key | SMS API, MMS API, MMS templates | Header Authorization: Bearer <api_key>. Key is shown in the Customer Portal under Account. |
| Account API key | Number configuration API (api-service.tsgglobal.world) |
Header Authorization: Bearer <api_key>. |
| Portal login token | GraphQL API (numbers, CDRs, compliance forms) | POST https://api.portal.tsgglobal.world/account/login with JSON {"email","password"} (your Customer Portal login). Response token is valid for 7 days. Send it as Authorization: Bearer <token>. See GraphQL API & Authentication. |
| SMPP credentials | SMPP binds | System ID and password from TSG. Bind type transceiver. |
| MM4 / SMTP | MMS over SMTP | AUTH PLAIN or AUTH LOGIN. Username = SMPP system ID, password = API key. |
Conventions
- Request bodies are JSON with
Content-Type: application/json. - IDs are UUIDv4. Timestamps are ISO 8601 in UTC.
- Phone numbers are E.164 without a leading plus in most examples (
12003004000); the MMS API also accepts+12003004000. - HTTP status codes:
200success,401not authenticated,403not authorized,404not found,409conflict,422invalid parameters,500server error,503temporarily unavailable (retry). Error bodies carry a machine-readableid(unauthenticated,unauthorized,not_found,invalid_params,server_error) and a human-readablemessage. See Errors. - The number configuration endpoints use strict parameter parsing: an unknown field rejects the whole request.
Endpoint index
Programmable SMS — https://sms.tsgglobal.world
| Method | Path | Purpose | Page |
|---|---|---|---|
POST |
/messages |
Send an SMS to one or more recipients. Body: from, to (array), body; optional encoding, force_encoding, registered_delivery (1 always, 2 on success, 3 on error), deliver_at (UTC, up to 2 years ahead), expires_at. Response is keyed by recipient number; multipart messages include udh and parts. |
Send an SMS Message |
GET |
/messages/<uuid> |
Fetch one message (or one part) by ID. Intended for testing; use webhooks in production. | Receive an SMS Message |
Encodings supported by the API: 0 GSM 7-bit (160 chars, 153 per segment, max 6 segments), 3 Latin-1 (140 / 134, max 5), 8 UCS-2 (70 / 67, max 6). The API infers encoding from the body; override with force_encoding.
Programmable MMS — https://mmsc.tsgglobal.world
| Method | Path | Purpose | Page |
|---|---|---|---|
POST |
/mms |
Send an MMS. Body is {"data":{"type":"mms-forward-req","attributes":{...}}} with from, to (array), optional subject, expires_at/expires_in, transaction_id, metadata, request_delivery_reports, and parts (each with kind of plain, uri, data-uri or embedded). Response type mms-forward-res includes one message_id per recipient, used later in DLRs. |
Send an MMS Message |
POST |
/mms/templates |
Create a template: name, body_template, optional subject_template, parts. Placeholders are {key} matching [a-zA-Z_][a-zA-Z0-9_]*; the response lists the extracted placeholders. |
Create MMS Template |
POST |
/mms/templates/:id/preview |
Render a template with params without sending (type: mms-template-preview-req). |
Preview MMS Template |
POST |
/mms/templates/:id/send |
Send using a template (type: mms-template-send-req) with from, to, params, optional transaction_id, request_delivery_reports, metadata. |
Send MMS Using Template |
GET |
/mms/templates |
List templates. | List MMS templates |
GET |
/mms/templates/:id |
Get one template. | Get Single MMS template |
DELETE |
/mms/templates/:id |
Delete a template (204 No Content). |
Delete MMS Template |
MMS part rules: content fetched from a uri must be 3 MB or less and the server must answer HEAD and GET with a valid Content-Length; embedded bodies must be 1 MB or less (compressed); data-uri strings are limited to 65,535 characters. Headers beginning x-mms-, content-, checksum-, x-checksum- or message-id are stripped. Recommended limits: 1,000 characters of text and 10 or fewer participants. New lines inside JSON strings must be escaped as \n.
Phone numbers — ordering (GraphQL, portal token)
| Operation | GraphQL | Purpose | Page |
|---|---|---|---|
| Search local numbers | query { numbers(state, rateCenter, contains, quantity, consecutive) { numbers { telephoneNumber city province e911Allowed mmsAllowed } } } |
Up to 100 numbers per search, by state + rate center or by contains (NPANXX). Ordered numbers are SMS-enabled automatically. |
Search For New Available Numbers |
| Reserve in cart | mutation { numbersReserve(numbers: [...]) } |
Hold up to 100 numbers. | Add Number to Cart |
| View cart | query { reservedList { numbers { telephoneNumber city lata } } } |
Get Reserved Numbers In Cart | |
| Remove from cart | mutation { releaseReserved(numbers: [...]) } |
Remove Reserved Number From Cart | |
| Checkout | mutation { numbersOrder { orderId items { tn } } } |
Purchases everything in the cart. | Checkout Numbers in Cart |
| Search toll-free | query { tollfreeNumbers(contains, quantity, consecutive) { numbers } } |
Up to 10 per search; no reservation step. | Toll-free phone numbers |
| Order toll-free | mutation { orderTollfreeNumbers(numbers, smsEnable) { numbers orderId } } |
Voice active in about 10 minutes; SMS requires a Verified Sender form. | same page |
| Disconnect | mutation { disconnectNumbers(numbers: [...]) { orderId requests { disconnectAt } } } |
Numbers are held 90 days from activation per the MSA; disconnect is immediate outside that window, otherwise scheduled. | Disconnect Number |
Phone numbers — configuration (REST, https://api-service.tsgglobal.world)
| Method | Path | Purpose | Page |
|---|---|---|---|
GET |
/v5/dids/<number> |
SMS and MMS configuration for a number: sms_enabled, sms_status (NONE, PENDING, ACTIVE, ERROR, DSBL-PND), sms_uri, mms_enabled, mms_uri, campaign_id, compliance_status, use_case_type, ten_dlc_registered. Ignore unknown properties; new ones may be added. |
Get Number Information |
GET |
/v1/did/lookup?did=<number> |
Rate center, state, activation date, routing and SMS settings as CSV. Omit did to list every number on the account. |
same page |
POST |
/v2/sms-enablement |
Enable SMS or attach a 10DLC campaign: did, action (add or update), optional use_case_type, campaign_id, campaign_sub_id, webhook_url, webhook_type (postv2 recommended), x_api_key_header, mms_enable, mms_routing. action: delete disables SMS. |
Enable SMS/10DLC, Disable SMS |
POST |
/v1/sms/webhook |
Set the inbound SMS webhook for a number: did, webhook_url, optional webhook_type, x_api_key_header. Omitting the URL switches the number to SMPP delivery. |
Update inbound SMS webhook |
POST |
/v2/dids/<number>/mms/enable |
Enable MMS or change its inbound uri (HTTP(S) or mm4://). Number must already be SMS-enabled and the account MMS-enabled. |
Enable MMS, Update inbound MMS URI |
POST |
/v2/dids/<number>/mms/disable |
Disable MMS. | Disable MMS |
GET |
/v1/did/priority/lookup |
List voice destination priorities (CSV). | List Destination Priority |
POST / PATCH / DELETE |
/v1/did/priority |
Add, update or remove a voice destination: did, priority (1–3), destination (gateway IP for VOIP, E.164 for PSTN), call_type (VOIP or PSTN, case-sensitive), call_option (WP with plus, NP without). Priority 1 cannot be deleted; submit a cancel request instead. Responses use negative numeric codes (-1000 bad key … -1008-V/-1008-P success). |
Add, Update, Delete |
Reports (GraphQL, portal token)
cdrRecords(type: CdrType!, startDatetime: DateTime!, endDatetime: DateTime!, limit: Int, cursor: String, companyId: ID) returns a union of MessageCdr, VoiceCdr and ApiCdr (use fragments), paginationInfo { nextCursor limit } and a signed exportLink for a CSV download. type is an uppercase string such as SMS. Default page size 100, maximum 1,000; page until nextCursor is null. Exports time out after 20 minutes, so narrow the date range if needed. Export links are public once generated. See Get CDR Records.
Compliance & Identity (GraphQL, portal token)
| Operation | GraphQL | Page |
|---|---|---|
| Submit Toll-Free Verified Sender Form | mutation { submitVerifiedSenderForm(...) { id status } } — business details, numbers, use case, opt-in, sample messages, volume, base64 attachments. Unverified toll-free numbers are blocked to Canada and throttled to the US. |
Toll-Free Verified Sender |
| Order a short code | mutation { submitShortcodeForm(...) { id publicId status statusNote } } |
Short Code Submission |
| List orders and status | query { orders(page, publicId, type, addedStartDate, addedEndDate) { orders { publicId status data { ... } } } } with type of verified_sender_form or shortcode_form |
both pages |
Webhooks you receive
All inbound webhooks are POST with a JSON body. Respond with 2xx to acknowledge.
| Event | Shape | Retry policy | Page |
|---|---|---|---|
| Inbound SMS | Message object with object: "sms", type: "inbound", from, to, body, encoding, id, timestamps, and udh/parts for multipart. Reply with {"body": "..."} to send an automatic response to the sender. |
Up to 17 attempts over 2–3 days with exponential backoff until you return 200. |
Receive an SMS Message |
| SMS delivery receipt | object: "sms_dlr" with delivery_status (delivered, expired, deleted, undelivered, accepted, unknown, rejected, failed, enroute, skipped), delivery_error_code, submitted_at, done_at, sms.id. Only sent when the message requested registered_delivery. Same URL as inbound SMS. |
Same as inbound SMS. | Delivery Receipts |
| Inbound MMS | {"data":[{"type":"mms-forward-req","attributes":{from,to,subject,parts[...],transaction_id}}]}; parts are URIs to hosted content. Headers include User-Agent: Marshmallow/... and X-Session-ID. Routing address may be http(s)://user:pass@host/path or mm4://user:pass@host:port. |
2 immediate retries, then up to 20 total with exponential backoff. In-flight messages keep their original routing. | Receive an MMS Message |
| MMS delivery report | type: "mms-delivery-report-res" with message_id, mm_status_code (Retrieved, Forwarded, Deferred, Expired, Rejected, Indeterminate, Unrecognised). Sent only when request_delivery_reports: true. |
5xx retried with backoff; 3xx/4xx treated as permanent failure. |
Receive DLRs |
| TextProtect alert | {number, sms_account, requester_nnid, requester, timestamp, description} for every blocked attempt to move your number to another SMS vendor. |
Retried for 72 hours with exponential backoff. | TextProtect Webhook |
Secure your webhook with the x_api_key_header value set on the number: TSG sends it as the x-api-key request header. Inbound MMS also supports Basic auth embedded in the routing URL.
Limits and rules at a glance
| Rule | Value |
|---|---|
SMS scheduling (deliver_at) |
Up to 2 years ahead, minute accuracy |
| SMS segments | GSM-7 max 6 × 153, Latin-1 max 5 × 134, UCS-2 max 6 × 67 |
| MMS attachment via URI | 3 MB max, server must return Content-Length and answer HEAD |
| MMS embedded part | 1 MB max (compressed) |
| MMS data URI | 65,535 characters max |
| MMS text and recipients (recommended) | 1,000 characters, 10 participants |
| Local number search / cart | 100 numbers per search, 100 reserved |
| Toll-free search | 10 numbers per search |
| Number disconnect | 90-day minimum hold from activation |
| CDR page size | 100 default, 1,000 max; export timeout 20 minutes |
| GraphQL token lifetime | 7 days |
| SMPP ports | 2775 TCP, 2776 TLS (TLS recommended) |
| MM4 ports | 2525 TCP, 2465 TLS; STARTTLS disabled, VRFY unimplemented |
| Sole-proprietor 10DLC campaigns | 1 number per campaign |
Minimal examples
Send an SMS:
curl -X POST https://sms.tsgglobal.world/messages \
-H "Authorization: Bearer <messaging_api_key>" \
-H "Content-Type: application/json" \
-d '{"from":"12003004000","to":["12003004001"],"body":"Hello from TSG","registered_delivery":1}'
Send an MMS with text and an image:
curl -X POST https://mmsc.tsgglobal.world/mms \
-H "Authorization: Bearer <messaging_api_key>" \
-H "Content-Type: application/json" \
-d '{"data":{"type":"mms-forward-req","attributes":{"from":"+12003004000","to":["+12003004001"],"request_delivery_reports":true,"parts":[{"kind":"plain","content_type":"text/plain","body":"Hello"},{"kind":"uri","content_location":"photo.jpg","uri":"https://example.com/photo.jpg"}]}}}'
Get a GraphQL token, then search for numbers:
TOKEN=$(curl -s -X POST https://api.portal.tsgglobal.world/account/login \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com","password":"<portal_password>"}' | jq -r .token)
curl -X POST https://api.portal.tsgglobal.world/graphql \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"query":"query { numbers(state: \"WA\", rateCenter: \"SEATTLE\", quantity: 5, consecutive: false) { numbers { telephoneNumber city mmsAllowed } } }"}'
Point a number's inbound SMS at your webhook:
curl -X POST https://api-service.tsgglobal.world/v1/sms/webhook \
-H "Authorization: Bearer <api_key>" -H "Content-Type: application/json" \
-d '{"did":"12003004000","webhook_url":"https://example.com/inbound","webhook_type":"postv2","x_api_key_header":"<shared_secret>"}'
Support and related links
- Support: support@tsgglobal.com. Security reports: security@tsgglobal.com.
- Help center (DLR error codes, toll-free verification requirements): https://support.tsgglobal.com
- Customer Portal (API keys, Verified Sender form): https://customer-portal.tsgglobal.com
- Security and compliance posture (ISO/IEC 27001, SOC 2 Type II, AWS US hosting): ISO/IEC/SOC Certification