# TSG Global API documentation

Canonical documentation: https://support.tsgglobal.com/docs

This export contains all 57 published pages in this collection. Source URLs identify each page; API hosts and code examples are preserved.

## Contents

- [Get Started](https://support.tsgglobal.com/docs)
- [Staging Environment Access](https://support.tsgglobal.com/docs/staging-environment-access)
- [API Quick Reference](https://support.tsgglobal.com/docs/api-quick-reference)
- [AI Assistants & MCP](https://support.tsgglobal.com/docs/ai-assistants-and-mcp)
- [OpenAPI Specification](https://support.tsgglobal.com/docs/openapi-specification)
- [Programmable SMS](https://support.tsgglobal.com/docs/api-reference/programmable-sms)
- [Send an SMS Message](https://support.tsgglobal.com/docs/api-reference/programmable-sms/send-an-sms-message)
- [Receive an SMS Message](https://support.tsgglobal.com/docs/api-reference/programmable-sms/receive-an-sms-message)
- [Delivery Receipts (DLRs)](https://support.tsgglobal.com/docs/api-reference/programmable-sms/delivery-receipts-dlrs)
- [SMPP](https://support.tsgglobal.com/docs/api-reference/programmable-sms/smpp)
- [Headers](https://support.tsgglobal.com/docs/api-reference/programmable-sms/smpp/headers)
- [Errors](https://support.tsgglobal.com/docs/api-reference/programmable-sms/smpp/errors)
- [Programmable MMS](https://support.tsgglobal.com/docs/api-reference/programmable-mms)
- [Send an MMS Message](https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message)
- [Send an MMS Message Using Templates](https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates)
- [Create MMS Template](https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/create-mms-template)
- [Preview MMS Template](https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/preview-mms-template)
- [Send MMS Using Template](https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/send-mms-using-template)
- [List MMS templates](https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/list-mms-templates)
- [Get Single MMS template](https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/get-single-mms-template)
- [Delete MMS Template](https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/delete-mms-template)
- [Receive an MMS Message](https://support.tsgglobal.com/docs/api-reference/programmable-mms/receive-an-mms-message)
- [Receive DLRs](https://support.tsgglobal.com/docs/api-reference/programmable-mms/receive-dlrs)
- [SMTP](https://support.tsgglobal.com/docs/api-reference/programmable-mms/smtp)
- [Phone Numbers](https://support.tsgglobal.com/docs/api-reference/phone-numbers)
- [Search For New Available Numbers](https://support.tsgglobal.com/docs/api-reference/phone-numbers/search-for-new-available-numbers)
- [Add Number to Cart](https://support.tsgglobal.com/docs/api-reference/phone-numbers/add-number-to-cart)
- [Get Reserved Numbers In Cart](https://support.tsgglobal.com/docs/api-reference/phone-numbers/get-reserved-numbers-in-cart)
- [Remove Reserved Number From Cart](https://support.tsgglobal.com/docs/api-reference/phone-numbers/remove-reserved-number-from-cart)
- [Checkout Numbers in Cart](https://support.tsgglobal.com/docs/api-reference/phone-numbers/checkout-numbers-in-cart)
- [Disconnect Number](https://support.tsgglobal.com/docs/api-reference/phone-numbers/disconnect-number)
- [Get Number Information](https://support.tsgglobal.com/docs/api-reference/phone-numbers/get-number-information)
- [Manage Number for SMS & 10DLC](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-sms-and-10dlc)
- [Enable SMS/10DLC on a Number](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-sms-and-10dlc/enable-sms-10dlc-on-a-number)
- [Disable SMS on a Number](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-sms-and-10dlc/disable-sms-on-a-number)
- [Update inbound SMS webhook/URI](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-sms-and-10dlc/update-inbound-sms-webhook-uri)
- [Manage Number for MMS](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-mms)
- [Enable MMS on a Number](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-mms/enable-mms-on-a-number)
- [Disable MMS on a Number](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-mms/disable-mms-on-a-number)
- [Update inbound MMS webhook/URI](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-mms/update-inbound-mms-webhook-uri)
- [Manage Number for Voice](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice)
- [List Destination Priority](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice/list-destination-priority)
- [Add Destination Priority](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice/add-destination-priority)
- [Update Destination Priority](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice/update-destination-priority)
- [Delete Destination Priority](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice/delete-destination-priority)
- [Protect your phone number](https://support.tsgglobal.com/docs/api-reference/phone-numbers/protect-your-phone-number)
- [TextProtect Webhook](https://support.tsgglobal.com/docs/api-reference/phone-numbers/protect-your-phone-number/textprotect-webhook)
- [Toll-free phone numbers - search & ordering](https://support.tsgglobal.com/docs/api-reference/phone-numbers/toll-free-phone-numbers-search-and-ordering)
- [Reports](https://support.tsgglobal.com/docs/api-reference/reports)
- [CDR Records](https://support.tsgglobal.com/docs/api-reference/reports/cdr-records)
- [Get Count of CDR Records](https://support.tsgglobal.com/docs/api-reference/reports/cdr-records/get-count-of-cdr-records)
- [Get CDR Records](https://support.tsgglobal.com/docs/api-reference/reports/cdr-records/get-cdr-records)
- [Compliance & Identity](https://support.tsgglobal.com/docs/api-reference/compliance-and-identity)
- [Toll-Free Verified Sender (Order)](https://support.tsgglobal.com/docs/api-reference/compliance-and-identity/toll-free-verified-sender-order)
- [Short Code Submission (Order)](https://support.tsgglobal.com/docs/api-reference/compliance-and-identity/short-code-submission-order)
- [GraphQL API & Authentication](https://support.tsgglobal.com/docs/graphql-api-and-authentication)
- [Changelog](https://support.tsgglobal.com/docs/changelog)

---

# Get Started

Source: https://support.tsgglobal.com/docs
Markdown: https://support.tsgglobal.com/docs/index.md
Last updated: 2026-03-23T15:54:48.630Z

TSG Global makes sending and receiving messages & calls easy. Find the documentation you need to build exactly what you need. We’ll handle the complexity of mobile carrier and global regulations.

## Document Formatting

We generally format our API documents in the following manner:

1. Overview: the purpose of the end-point
2. Authentication: how to authenticate to the end-point
3. Method: details regarding the API method and examples.

We have several API types. Most are REST-based, but we also have GraphQL APIs. We use common HTTP features such as HTTP verbs and HTTP status codes. Requests must be made via HTTPS (calls over plain HTTP will fail).

For a one-page overview of every host, authentication scheme, endpoint and webhook, see the [API Quick Reference](https://support.tsgglobal.com/docs/api-quick-reference.md). The REST APIs are also described by an [OpenAPI specification](https://support.tsgglobal.com/docs/openapi-specification.md), and changes are recorded in the [Changelog](https://support.tsgglobal.com/docs/changelog.md).

## Get your Credentials

Some of our APIs currently require an API key. For those services, an API key will be generated for you and be available to view via the Customer Portal here: <https://customer-portal.tsgglobal.com/>.

For other services, you will be able to generate a Bearer token using your unique email address and password assigned to your Customer Portal user to access resources. When in doubt, simply check the Authentication section for the resource you are attempting to access.

## SMPP

We also provide a SMPP interface for high-volume users. SMPP is available on the canonical port 2775. An encrypted, secure connection is also provided over TLS (1.1 or 1.2) on port 2776. We highly recommend you connect via TLS in order to securely transport your messages to us.

## Using an AI assistant

These docs are available to AI coding assistants over the Model Context Protocol (MCP) and as plain Markdown (`llms.txt`, `llms-full.txt`, or any page with `.md` appended). Connect Claude, Cursor, VS Code or Codex in a minute: see [AI Assistants & MCP](https://support.tsgglobal.com/docs/ai-assistants-and-mcp.md).

Happy coding!

---

# Staging Environment Access

Source: https://support.tsgglobal.com/docs/staging-environment-access
Markdown: https://support.tsgglobal.com/docs/staging-environment-access.md
Last updated: 2024-02-12T18:21:15.543Z

How to connect to the TSG Global staging environment over SMPP, MM4/SMTP and the HTTP APIs before moving to production.

## Introduction

This document outlines the steps customers should take to onboard onto our staging environment, focusing on connecting using SMPP/SMTP and HTTP API protocols for both SMS and MMS messaging.



> **Warning**



## Disclaimers

Please be advised that you will be connecting to an active staging/testing environment hosted by TSG Global. There will be changes actively pushed to our staging environment that may occasionally break some features without warning. Additionally, to control costs, we do not scale our staging environment to the same degree as our production environment, so throughput may occasionally become an issue. We will work closely with your testing team in a dedicated Slack channel to ensure you have a robust testing experience that you are happy with prior to migrating to production.



## Prerequisites

Before connecting to our staging environment:

1. Ensure that you have valid credentials provided by our support team.
2. Ensure that you have joined the Slack channel set up with your team to assist you with any technical questions you may have during testing.
3. Set up a testing machine or environment on your end.
4. Familiarize yourself with the SMPP protocol and HTTP API concepts if you haven't already.
5. Review the TSG Global API documents located at: <https://support.tsgglobal.com/docs/index.md>, starting with the [API Quick Reference](https://support.tsgglobal.com/docs/api-quick-reference.md).

## SMS via SMPP

### Configuration Details

* SMPP Host: `smsc.staging.tsgglobal.com`
* SMPP Port: `2775` for TCP or `2776` for TLS connections
* Bind type: Transceiver
* System ID: Provided by our support team.
* Password: Provided by our support team.

### Steps to Connect

1. Install an SMPP client or library compatible with your system.
2. Configure the SMPP client using the provided configuration details.
3. Connect to the staging SMPP server.
4. Test by sending and receiving SMS messages.
5. Review the sample delivery reports and error messages (if any) for troubleshooting.
6. For any additional information please refer to [SMPP](https://support.tsgglobal.com/docs/api-reference/programmable-sms/smpp.md).

## Sending SMS via HTTP API

### Endpoint Information

* Base URL: `https://sms-api.staging.tsgglobal.com`
* Endpoint: see [Send an SMS Message](https://support.tsgglobal.com/docs/api-reference/programmable-sms/send-an-sms-message.md)
* Authentication key: provided by our support team.

### Steps to Connect

1. Configure the HTTP client or tool you will use for testing (e.g. Postman, curl).
2. Set the request headers per the API documentation:

```http
Authorization: Bearer <your-authentication-key>
Content-Type: application/json
```

3. For sending, make the necessary POST requests.
4. Review the API response for any errors and to ensure successful delivery.

## Receiving SMS via HTTP webhook

To receive SMS messages via webhook, provide your webhook URL as described in [Receive an SMS Message](https://support.tsgglobal.com/docs/api-reference/programmable-sms/receive-an-sms-message.md).

## MMS via SMTP (MM4)

### Configuration Details

* SMTP Host: `smtp.staging.tsgglobal.com`
* Ports: as documented on the [SMTP](https://support.tsgglobal.com/docs/api-reference/programmable-mms/smtp.md) page (`2525` TCP, `2465` TLS), unless our support team gives you different values for staging
* Authentication: `AUTH LOGIN` or `AUTH PLAIN`; username is your SMPP system ID, password is your API key
* System ID and API key: provided by our support team.

### Steps to Connect

1. Install an SMTP client or library compatible with your system.
2. Configure the SMTP client using the provided configuration details.
3. Connect to the staging SMTP server.
4. Test by sending and receiving MMS messages.
5. Review the sample delivery reports and error messages (if any) for troubleshooting.
6. For any additional information please refer to [SMTP](https://support.tsgglobal.com/docs/api-reference/programmable-mms/smtp.md).

## Sending MMS via HTTP API

### Endpoint Information

* Base URL: `https://mms-api.staging.tsgglobal.com`
* Endpoint: see [Send an MMS Message](https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message.md)
* Authentication key: provided by our support team.

### Steps to Connect

1. Configure the HTTP client or tool you will use for testing (e.g. Postman, curl).
2. Set the request headers per the API documentation:

```http
Authorization: Bearer <your-authentication-key>
Content-Type: application/json
```

3. For sending, make the necessary POST requests.
4. Review the API response for any errors and to ensure successful delivery.

## Receiving MMS via HTTP webhook

To receive MMS messages via webhook, provide your webhook URL as described in [Receive an MMS Message](https://support.tsgglobal.com/docs/api-reference/programmable-mms/receive-an-mms-message.md).

## Troubleshooting

Below are some frequently encountered issues that may assist:

1. Ensure you're using the correct credentials.
2. Check your network/firewall settings to ensure communication isn't being blocked.
3. Review error logs and messages for clues.
4. Reach out to our support team with detailed error messages for assistance.

## Conclusion

After successful testing on the staging environment, inform our support team so that they can assist you with transitioning to the production environment.

---

# API Quick Reference

Source: https://support.tsgglobal.com/docs/api-quick-reference
Markdown: https://support.tsgglobal.com/docs/api-quick-reference.md

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](https://support.tsgglobal.com/docs/staging-environment-access.md).

## 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](https://support.tsgglobal.com/docs/graphql-api-and-authentication.md). |
| 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: `200` success, `401` not authenticated, `403` not authorized, `404` not found, `409` conflict, `422` invalid parameters, `500` server error, `503` temporarily unavailable (retry). Error bodies carry a machine-readable `id` (`unauthenticated`, `unauthorized`, `not_found`, `invalid_params`, `server_error`) and a human-readable `message`. See [Errors](https://support.tsgglobal.com/docs/api-reference/programmable-sms/smpp/errors.md).
* 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](https://support.tsgglobal.com/docs/api-reference/programmable-sms/send-an-sms-message.md)       |
| `GET`  | `/messages/<uuid>` | Fetch one message (or one part) by ID. Intended for testing; use webhooks in production.                                                                                                                                                                                                                                  | [Receive an SMS Message](https://support.tsgglobal.com/docs/api-reference/programmable-sms/receive-an-sms-message.md) |

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](https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message.md)                                             |
| `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](https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/create-mms-template.md)         |
| `POST`   | `/mms/templates/:id/preview` | Render a template with `params` without sending (`type: mms-template-preview-req`).                                                                                                                                                                                                                                                                                                        | [Preview MMS Template](https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/preview-mms-template.md)       |
| `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](https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/send-mms-using-template.md) |
| `GET`    | `/mms/templates`             | List templates.                                                                                                                                                                                                                                                                                                                                                                            | [List MMS templates](https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/list-mms-templates.md)           |
| `GET`    | `/mms/templates/:id`         | Get one template.                                                                                                                                                                                                                                                                                                                                                                          | [Get Single MMS template](https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/get-single-mms-template.md) |
| `DELETE` | `/mms/templates/:id`         | Delete a template (`204 No Content`).                                                                                                                                                                                                                                                                                                                                                      | [Delete MMS Template](https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/delete-mms-template.md)         |

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](https://support.tsgglobal.com/docs/api-reference/phone-numbers/search-for-new-available-numbers.md)   |
| Reserve in cart      | `mutation { numbersReserve(numbers: [...]) }`                                                                                                | Hold up to 100 numbers.                                                                                                        | [Add Number to Cart](https://support.tsgglobal.com/docs/api-reference/phone-numbers/add-number-to-cart.md)                               |
| View cart            | `query { reservedList { numbers { telephoneNumber city lata } } }`                                                                           |                                                                                                                                | [Get Reserved Numbers In Cart](https://support.tsgglobal.com/docs/api-reference/phone-numbers/get-reserved-numbers-in-cart.md)           |
| Remove from cart     | `mutation { releaseReserved(numbers: [...]) }`                                                                                               |                                                                                                                                | [Remove Reserved Number From Cart](https://support.tsgglobal.com/docs/api-reference/phone-numbers/remove-reserved-number-from-cart.md)   |
| Checkout             | `mutation { numbersOrder { orderId items { tn } } }`                                                                                         | Purchases everything in the cart.                                                                                              | [Checkout Numbers in Cart](https://support.tsgglobal.com/docs/api-reference/phone-numbers/checkout-numbers-in-cart.md)                   |
| Search toll-free     | `query { tollfreeNumbers(contains, quantity, consecutive) { numbers } }`                                                                     | Up to 10 per search; no reservation step.                                                                                      | [Toll-free phone numbers](https://support.tsgglobal.com/docs/api-reference/phone-numbers/toll-free-phone-numbers-search-and-ordering.md) |
| 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](https://support.tsgglobal.com/docs/api-reference/phone-numbers/disconnect-number.md)                                 |

### 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](https://support.tsgglobal.com/docs/api-reference/phone-numbers/get-number-information.md)                                                                                                                                                                                                      |
| `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](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-sms-and-10dlc/enable-sms-10dlc-on-a-number.md), [Disable SMS](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-sms-and-10dlc/disable-sms-on-a-number.md)                                                              |
| `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](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-sms-and-10dlc/update-inbound-sms-webhook-uri.md)                                                                                                                                                          |
| `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](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-mms/enable-mms-on-a-number.md), [Update inbound MMS URI](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-mms/update-inbound-mms-webhook-uri.md)                                                                            |
| `POST`                      | `/v2/dids/<number>/mms/disable` | Disable MMS.                                                                                                                                                                                                                                                                                                                                                                    | [Disable MMS](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-mms/disable-mms-on-a-number.md)                                                                                                                                                                                          |
| `GET`                       | `/v1/did/priority/lookup`       | List voice destination priorities (CSV).                                                                                                                                                                                                                                                                                                                                        | [List Destination Priority](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice/list-destination-priority.md)                                                                                                                                                                        |
| `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](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice/add-destination-priority.md), [Update](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice/update-destination-priority.md), [Delete](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice/delete-destination-priority.md) |

### 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](https://support.tsgglobal.com/docs/api-reference/reports/cdr-records/get-cdr-records.md).

### 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](https://support.tsgglobal.com/docs/api-reference/compliance-and-identity/toll-free-verified-sender-order.md) |
| Order a short code                    | `mutation { submitShortcodeForm(...) { id publicId status statusNote } }`                                                                                                                                                          | [Short Code Submission](https://support.tsgglobal.com/docs/api-reference/compliance-and-identity/short-code-submission-order.md)         |
| 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](https://support.tsgglobal.com/docs/api-reference/programmable-sms/receive-an-sms-message.md)                  |
| 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](https://support.tsgglobal.com/docs/api-reference/programmable-sms/delivery-receipts-dlrs.md)                       |
| 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](https://support.tsgglobal.com/docs/api-reference/programmable-mms/receive-an-mms-message.md)                  |
| 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](https://support.tsgglobal.com/docs/api-reference/programmable-mms/receive-dlrs.md)                                      |
| 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](https://support.tsgglobal.com/docs/api-reference/phone-numbers/protect-your-phone-number/textprotect-webhook.md) |

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:

```bash
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:

```bash
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:

```bash
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:

```bash
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

---

# AI Assistants & MCP

Source: https://support.tsgglobal.com/docs/ai-assistants-and-mcp
Markdown: https://support.tsgglobal.com/docs/ai-assistants-and-mcp.md

Connect Claude, Cursor, VS Code, Codex or any MCP client to the TSG Global documentation so your AI assistant answers from the real docs.

TSG Global's documentation is available to AI coding assistants through the Model Context Protocol (MCP), an open standard that lets an assistant call outside tools. Connect the server below and your assistant can search these docs and read any page, instead of guessing from stale training data.

## The documentation MCP server

| Setting        | Value                                             |
| -------------- | ------------------------------------------------- |
| Server URL     | `https://support.tsgglobal.com/docs/mcp/`         |
| Transport      | Streamable HTTP                                   |
| Authentication | None. The server only reads public documentation. |
| Cost           | Free                                              |

The server exposes two read-only tools:

| Tool                  | What it does                                                                                                                                       |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `searchDocumentation` | Full-text search across every page. Returns matching titles, summaries and links.                                                               |
| `getPage`             | Fetches the complete Markdown of one page by its URL, for example `https://support.tsgglobal.com/docs/api-reference/programmable-sms/send-an-sms-message.md`. |



> **Info**


This server covers documentation only. It cannot send messages, order numbers, read your account or call any TSG Global API. Your API keys never pass through it. To act on the platform, your code still calls the APIs described in this documentation.



## Connect your assistant





### Claude Code


Run once in your terminal:

```bash
claude mcp add --transport http tsg-docs https://support.tsgglobal.com/docs/mcp/
```

Then ask, for example, "Using the TSG docs, write a function that sends an SMS and handles the delivery receipt webhook."





### Claude.ai / Desktop


Open **Settings → Connectors → Add custom connector**, name it "TSG Global docs", and paste `https://support.tsgglobal.com/docs/mcp/` as the URL. No authentication is needed. Enable it in a chat from the tools menu.





### Cursor


Add to `.cursor/mcp.json` in your project (or `~/.cursor/mcp.json` for all projects):

```json
{
  "mcpServers": {
    "tsg-docs": {
      "url": "https://support.tsgglobal.com/docs/mcp/"
    }
  }
}
```






### VS Code


Add to `.vscode/mcp.json` in your workspace, then start the server from the MCP view:

```json
{
  "servers": {
    "tsg-docs": {
      "type": "http",
      "url": "https://support.tsgglobal.com/docs/mcp/"
    }
  }
}
```






### Codex



```bash
codex mcp add tsg-docs --url https://support.tsgglobal.com/docs/mcp/
```






### Other clients


Any MCP client that supports streamable HTTP can connect. Point it at `https://support.tsgglobal.com/docs/mcp/` with no bearer token. `stdio` and SSE transports are not offered.





## Other machine-readable formats

If your tool does not speak MCP, the same content is available as plain Markdown:

| Resource                          | URL                                                                       | Use it for                                                             |
| --------------------------------- | ------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| Index of all pages with summaries | `https://support.tsgglobal.com/docs/llms.txt`                                     | Give an assistant a map of the docs                                    |
| Every page in one file            | `https://support.tsgglobal.com/docs/llms-full.txt`                                | Load the whole documentation into context               |
| Any single page                   | Append `.md` to its URL, e.g. `https://support.tsgglobal.com/docs/index.md` | Fetch one page without HTML                                            |
| One-page API summary              | [API Quick Reference](https://support.tsgglobal.com/docs/api-quick-reference.md)                            | Hosts, authentication, endpoints, webhooks and limits in a single read |

## What to expect

* Answers are grounded in the published documentation. If the docs are wrong, the assistant will be wrong too. Report documentation issues to support@tsgglobal.com.
* The assistant still needs your credentials to run code against the API. Keep API keys in environment variables, never in prompts or chat history.
* Prompts that work well: "Search the TSG docs for how DLRs are delivered and write the webhook handler", "Which authentication does the phone-number search API use?", "Compare the SMS and MMS webhook retry policies."

Questions or ideas for the MCP server, including an MCP server for the API itself? Email <support@tsgglobal.com>.

---

# OpenAPI Specification

Source: https://support.tsgglobal.com/docs/openapi-specification
Markdown: https://support.tsgglobal.com/docs/openapi-specification.md

OpenAPI 3.1 description of the TSG Global REST APIs (SMS, MMS, MMS templates, number configuration) with interactive operation blocks and a downloadable spec.

The REST APIs are described in an OpenAPI 3.1 document. Use it to generate clients, import into Postman or Insomnia, or feed to an AI assistant. The GraphQL APIs (number ordering, CDR reports, compliance forms) are not covered; see [GraphQL API & Authentication](https://support.tsgglobal.com/docs/graphql-api-and-authentication.md).

**Download:** [tsg-global-rest.json](https://support.tsgglobal.com/docs/openapi.json)

The blocks below render straight from the spec, so they stay in step with it.

## SMS

## Send an SMS message

> Sends an SMS to one or more recipients. Recipients are de-duplicated. Long messages are split into\
> GSM-standard segments (max 6 for GSM-7 and UCS-2, 5 for Latin-1). Scheduling with \`deliver\_at\` is\
> supported up to 2 years ahead. The response is keyed by recipient number.<br>

```json
{"openapi":"3.1.0","info":{"title":"TSG Global REST APIs","version":"2026-09-11"},"tags":[{"name":"SMS","description":"Send SMS and fetch messages. Host sms.tsgglobal.world."}],"servers":[{"url":"https://sms.tsgglobal.world","description":"Programmable SMS (production)"},{"url":"https://mmsc.tsgglobal.world","description":"Programmable MMS and MMS templates (production)"},{"url":"https://api-service.tsgglobal.world","description":"Phone-number configuration (production)"},{"url":"https://sms-api.staging.tsgglobal.com","description":"Programmable SMS (staging)"},{"url":"https://mms-api.staging.tsgglobal.com","description":"Programmable MMS (staging)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key from the Customer Portal, sent as `Authorization: Bearer <api_key>`."}},"schemas":{"SendSmsRequest":{"type":"object","required":["from","to","body"],"properties":{"from":{"type":"string","description":"E.164 number or alphanumeric sender ID."},"to":{"type":"array","items":{"type":"string"},"description":"E.164 recipients; de-duplicated."},"body":{"type":"string","description":"UTF-8 text, or base64 when a custom encoding is set."},"encoding":{"type":"integer","enum":[0,3,8],"description":"0 GSM-7, 3 Latin-1, 8 UCS-2."},"force_encoding":{"type":"integer","enum":[0,3,8]},"registered_delivery":{"type":"integer","enum":[1,2,3],"description":"1 always, 2 on success, 3 on error."},"deliver_at":{"type":"string","format":"date-time","description":"UTC, up to 2 years ahead."},"expires_at":{"type":"string","format":"date-time"}}},"SmsMessage":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"object":{"type":"string","enum":["sms"]},"type":{"type":"string","enum":["inbound","outbound"]},"from":{"type":"string"},"to":{"type":"string"},"body":{"type":"string"},"encoding":{"type":"integer"},"status":{"type":"string"},"delivery_receipt":{},"udh":{"type":["object","null"],"properties":{"ref_num":{"type":["integer","null"]},"count":{"type":["integer","null"]},"seq_num":{"type":["integer","null"]}}},"parts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}}}},"location":{"type":["string","null"]},"inserted_at":{"type":"string"},"updated_at":{"type":"string"},"scheduled_at":{"type":["string","null"]},"processed_at":{"type":["string","null"]},"delivered_at":{"type":["string","null"]},"expires_at":{"type":["string","null"]}}},"Error":{"type":"object","properties":{"id":{"type":"string","enum":["unauthenticated","unauthorized","not_found","server_error","invalid_params"]},"message":{"type":"string"}}}},"responses":{"Unauthenticated":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InvalidParams":{"description":"Request understood but parameters invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/messages":{"post":{"tags":["SMS"],"operationId":"sendSms","summary":"Send an SMS message","description":"Sends an SMS to one or more recipients. Recipients are de-duplicated. Long messages are split into\nGSM-standard segments (max 6 for GSM-7 and UCS-2, 5 for Latin-1). Scheduling with `deliver_at` is\nsupported up to 2 years ahead. The response is keyed by recipient number.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendSmsRequest"}}}},"responses":{"200":{"description":"Message accepted. One Message object per recipient.","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/SmsMessage"}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"422":{"$ref":"#/components/responses/InvalidParams"}}}}}}
```

## Fetch a message or message part

> Returns a single message by message id or part id. Intended for testing; register a webhook for production\
> traffic (see <https://support.tsgglobal.com/docs/api-reference/programmable-sms/receive-an-sms-message.md>).<br>

```json
{"openapi":"3.1.0","info":{"title":"TSG Global REST APIs","version":"2026-09-11"},"tags":[{"name":"SMS","description":"Send SMS and fetch messages. Host sms.tsgglobal.world."}],"servers":[{"url":"https://sms.tsgglobal.world","description":"Programmable SMS (production)"},{"url":"https://mmsc.tsgglobal.world","description":"Programmable MMS and MMS templates (production)"},{"url":"https://api-service.tsgglobal.world","description":"Phone-number configuration (production)"},{"url":"https://sms-api.staging.tsgglobal.com","description":"Programmable SMS (staging)"},{"url":"https://mms-api.staging.tsgglobal.com","description":"Programmable MMS (staging)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key from the Customer Portal, sent as `Authorization: Bearer <api_key>`."}},"schemas":{"SmsMessage":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"object":{"type":"string","enum":["sms"]},"type":{"type":"string","enum":["inbound","outbound"]},"from":{"type":"string"},"to":{"type":"string"},"body":{"type":"string"},"encoding":{"type":"integer"},"status":{"type":"string"},"delivery_receipt":{},"udh":{"type":["object","null"],"properties":{"ref_num":{"type":["integer","null"]},"count":{"type":["integer","null"]},"seq_num":{"type":["integer","null"]}}},"parts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}}}},"location":{"type":["string","null"]},"inserted_at":{"type":"string"},"updated_at":{"type":"string"},"scheduled_at":{"type":["string","null"]},"processed_at":{"type":["string","null"]},"delivered_at":{"type":["string","null"]},"expires_at":{"type":["string","null"]}}},"Error":{"type":"object","properties":{"id":{"type":"string","enum":["unauthenticated","unauthorized","not_found","server_error","invalid_params"]},"message":{"type":"string"}}}},"responses":{"Unauthenticated":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/messages/{uuid}":{"get":{"tags":["SMS"],"operationId":"getSms","summary":"Fetch a message or message part","description":"Returns a single message by message id or part id. Intended for testing; register a webhook for production\ntraffic (see https://support.tsgglobal.com/docs/api-reference/programmable-sms/receive-an-sms-message.md).\n","parameters":[{"name":"uuid","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The message.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmsMessage"}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"}}}}}}
```

## MMS

## Send an MMS message

> Sends an MMS. The body mirrors an MM4 forward request. Parts may be \`plain\` text, a public \`uri\`\
> (3 MB max, server must answer HEAD and GET with Content-Length), an RFC 2397 \`data-uri\` (65,535 chars max)\
> or an \`embedded\` body (1 MB max). A 200 means the message was accepted for processing, not delivered.\
> Set \`request\_delivery\_reports\` to receive DLRs on your inbound webhook.<br>

```json
{"openapi":"3.1.0","info":{"title":"TSG Global REST APIs","version":"2026-09-11"},"tags":[{"name":"MMS","description":"Send MMS. Host mmsc.tsgglobal.world."}],"servers":[{"url":"https://sms.tsgglobal.world","description":"Programmable SMS (production)"},{"url":"https://mmsc.tsgglobal.world","description":"Programmable MMS and MMS templates (production)"},{"url":"https://api-service.tsgglobal.world","description":"Phone-number configuration (production)"},{"url":"https://sms-api.staging.tsgglobal.com","description":"Programmable SMS (staging)"},{"url":"https://mms-api.staging.tsgglobal.com","description":"Programmable MMS (staging)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key from the Customer Portal, sent as `Authorization: Bearer <api_key>`."}},"schemas":{"MmsForwardRequest":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["type","attributes"],"properties":{"id":{"type":"string"},"type":{"type":"string","enum":["mms-forward-req"]},"attributes":{"type":"object","required":["from","to","parts"],"properties":{"from":{"type":"string"},"to":{"type":"array","items":{"type":"string"}},"subject":{"type":"string"},"expires_at":{"type":"string","format":"date-time"},"expires_in":{"type":"integer","description":"Seconds after receipt."},"transaction_id":{"type":"string"},"headers":{"type":"object"},"metadata":{"type":"object"},"request_delivery_reports":{"type":"boolean","default":false},"parts":{"type":"array","items":{"$ref":"#/components/schemas/MmsPart"}}}}}}}},"MmsPart":{"type":"object","properties":{"kind":{"type":"string","enum":["plain","uri","data-uri","embedded"],"default":"plain"},"content_type":{"type":"string"},"content_location":{"type":"string"},"content_encoding":{"type":"string"},"transfer_encoding":{"type":"string"},"body":{"type":"string"},"uri":{"type":"string"},"headers":{"type":"object","additionalProperties":{"type":"string"}},"metadata":{"type":"object"}}},"MmsForwardResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["mms-forward-res"]},"attributes":{"type":"object","properties":{"inserted_at":{"type":"string"},"transaction_id":{"type":"string"},"from":{"type":"string"},"to":{"type":"array","items":{"type":"string"}},"subject":{"type":"string"},"headers":{"type":"object"},"messages":{"type":"array","items":{"type":"object","properties":{"message_id":{"type":"string","format":"uuid"},"to":{"type":"string"}}}},"parts":{"type":"array","items":{"$ref":"#/components/schemas/MmsPart"}}}}}}}},"Error":{"type":"object","properties":{"id":{"type":"string","enum":["unauthenticated","unauthorized","not_found","server_error","invalid_params"]},"message":{"type":"string"}}}},"responses":{"Unauthenticated":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/mms":{"post":{"tags":["MMS"],"operationId":"sendMms","summary":"Send an MMS message","description":"Sends an MMS. The body mirrors an MM4 forward request. Parts may be `plain` text, a public `uri`\n(3 MB max, server must answer HEAD and GET with Content-Length), an RFC 2397 `data-uri` (65,535 chars max)\nor an `embedded` body (1 MB max). A 200 means the message was accepted for processing, not delivered.\nSet `request_delivery_reports` to receive DLRs on your inbound webhook.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MmsForwardRequest"}}}},"responses":{"200":{"description":"Accepted. `data.attributes.messages` carries one `message_id` per recipient, used in DLRs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MmsForwardResponse"}}}},"400":{"description":"Malformed JSON (for example unescaped new lines inside strings)."},"401":{"$ref":"#/components/responses/Unauthenticated"}}}}}}
```

## Create an MMS template

> Placeholders use \`{key}\` where key matches \`\[a-zA-Z\_]\[a-zA-Z0-9\_]\*\`. The response lists the extracted placeholders.

```json
{"openapi":"3.1.0","info":{"title":"TSG Global REST APIs","version":"2026-09-11"},"tags":[{"name":"MMS templates","description":"Reusable MMS templates with {placeholder} substitution. Host mmsc.tsgglobal.world."}],"servers":[{"url":"https://sms.tsgglobal.world","description":"Programmable SMS (production)"},{"url":"https://mmsc.tsgglobal.world","description":"Programmable MMS and MMS templates (production)"},{"url":"https://api-service.tsgglobal.world","description":"Phone-number configuration (production)"},{"url":"https://sms-api.staging.tsgglobal.com","description":"Programmable SMS (staging)"},{"url":"https://mms-api.staging.tsgglobal.com","description":"Programmable MMS (staging)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key from the Customer Portal, sent as `Authorization: Bearer <api_key>`."}},"schemas":{"MmsTemplateRequest":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["type","attributes"],"properties":{"type":{"type":"string","enum":["mms-template"]},"attributes":{"type":"object","required":["name","body_template"],"properties":{"name":{"type":"string"},"body_template":{"type":"string"},"subject_template":{"type":"string"},"parts":{"type":"array","items":{"$ref":"#/components/schemas/MmsPart"}}}}}}}},"MmsPart":{"type":"object","properties":{"kind":{"type":"string","enum":["plain","uri","data-uri","embedded"],"default":"plain"},"content_type":{"type":"string"},"content_location":{"type":"string"},"content_encoding":{"type":"string"},"transfer_encoding":{"type":"string"},"body":{"type":"string"},"uri":{"type":"string"},"headers":{"type":"object","additionalProperties":{"type":"string"}},"metadata":{"type":"object"}}},"MmsTemplateResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MmsTemplate"}}},"MmsTemplate":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["mms-template"]},"attributes":{"type":"object","properties":{"name":{"type":"string"},"body_template":{"type":"string"},"subject_template":{"type":"string"},"placeholders":{"type":"array","items":{"type":"string"}},"parts":{"type":"array","items":{"$ref":"#/components/schemas/MmsPart"}},"inserted_at":{"type":"string"},"updated_at":{"type":"string"}}}}},"Error":{"type":"object","properties":{"id":{"type":"string","enum":["unauthenticated","unauthorized","not_found","server_error","invalid_params"]},"message":{"type":"string"}}}},"responses":{"Unauthenticated":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/mms/templates":{"post":{"tags":["MMS templates"],"operationId":"createMmsTemplate","summary":"Create an MMS template","description":"Placeholders use `{key}` where key matches `[a-zA-Z_][a-zA-Z0-9_]*`. The response lists the extracted placeholders.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MmsTemplateRequest"}}}},"responses":{"200":{"description":"The created template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MmsTemplateResponse"}}}},"401":{"$ref":"#/components/responses/Unauthenticated"}}}}}}
```

## POST /mms/templates/{id}/send

> Send an MMS from a template

```json
{"openapi":"3.1.0","info":{"title":"TSG Global REST APIs","version":"2026-09-11"},"tags":[{"name":"MMS templates","description":"Reusable MMS templates with {placeholder} substitution. Host mmsc.tsgglobal.world."}],"servers":[{"url":"https://sms.tsgglobal.world","description":"Programmable SMS (production)"},{"url":"https://mmsc.tsgglobal.world","description":"Programmable MMS and MMS templates (production)"},{"url":"https://api-service.tsgglobal.world","description":"Phone-number configuration (production)"},{"url":"https://sms-api.staging.tsgglobal.com","description":"Programmable SMS (staging)"},{"url":"https://mms-api.staging.tsgglobal.com","description":"Programmable MMS (staging)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key from the Customer Portal, sent as `Authorization: Bearer <api_key>`."}},"schemas":{"MmsTemplateSendRequest":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["type","attributes"],"properties":{"type":{"type":"string","enum":["mms-template-send-req"]},"attributes":{"type":"object","required":["from","to","params"],"properties":{"from":{"type":"string"},"to":{"type":"array","items":{"type":"string"}},"params":{"type":"object","additionalProperties":{"type":"string"}},"transaction_id":{"type":"string"},"request_delivery_reports":{"type":"boolean","default":false},"metadata":{"type":"object"}}}}}}},"MmsForwardResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["mms-forward-res"]},"attributes":{"type":"object","properties":{"inserted_at":{"type":"string"},"transaction_id":{"type":"string"},"from":{"type":"string"},"to":{"type":"array","items":{"type":"string"}},"subject":{"type":"string"},"headers":{"type":"object"},"messages":{"type":"array","items":{"type":"object","properties":{"message_id":{"type":"string","format":"uuid"},"to":{"type":"string"}}}},"parts":{"type":"array","items":{"$ref":"#/components/schemas/MmsPart"}}}}}}}},"MmsPart":{"type":"object","properties":{"kind":{"type":"string","enum":["plain","uri","data-uri","embedded"],"default":"plain"},"content_type":{"type":"string"},"content_location":{"type":"string"},"content_encoding":{"type":"string"},"transfer_encoding":{"type":"string"},"body":{"type":"string"},"uri":{"type":"string"},"headers":{"type":"object","additionalProperties":{"type":"string"}},"metadata":{"type":"object"}}},"Error":{"type":"object","properties":{"id":{"type":"string","enum":["unauthenticated","unauthorized","not_found","server_error","invalid_params"]},"message":{"type":"string"}}}},"responses":{"NotFound":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/mms/templates/{id}/send":{"post":{"tags":["MMS templates"],"operationId":"sendMmsFromTemplate","summary":"Send an MMS from a template","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MmsTemplateSendRequest"}}}},"responses":{"200":{"description":"Accepted. Same shape as sending an MMS directly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MmsForwardResponse"}}}},"404":{"$ref":"#/components/responses/NotFound"}}}}}}
```

## Number configuration

## Get a number's SMS and MMS configuration

> Clients must ignore unknown properties; new ones may be added without notice.

```json
{"openapi":"3.1.0","info":{"title":"TSG Global REST APIs","version":"2026-09-11"},"tags":[{"name":"Number configuration","description":"Per-number SMS, MMS and voice settings. Host api-service.tsgglobal.world."}],"servers":[{"url":"https://sms.tsgglobal.world","description":"Programmable SMS (production)"},{"url":"https://mmsc.tsgglobal.world","description":"Programmable MMS and MMS templates (production)"},{"url":"https://api-service.tsgglobal.world","description":"Phone-number configuration (production)"},{"url":"https://sms-api.staging.tsgglobal.com","description":"Programmable SMS (staging)"},{"url":"https://mms-api.staging.tsgglobal.com","description":"Programmable MMS (staging)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key from the Customer Portal, sent as `Authorization: Bearer <api_key>`."}},"schemas":{"NumberConfiguration":{"type":"object","properties":{"number":{"type":"string"},"number_type":{"type":"string","enum":["long-code","short-code","toll-free"]},"mms_enabled":{"type":"boolean"},"mms_uri":{"type":["string","null"]},"sms_enabled":{"type":"boolean"},"campaign_id":{"type":["string","null"]},"compliance_status":{"type":"string","enum":["non_compliant","pending","compliant"]},"sms_status":{"type":"string","enum":["NONE","PENDING","ACTIVE","ERROR","DSBL-PND"]},"use_case_type":{"type":"string","enum":["","p2p","a2p"]},"nnid":{"type":["string","null"]},"sms_post_ver":{"type":"string","enum":["smpp","postv1","postv2","post3jam"]},"sms_uri":{"type":["string","null"],"description":"null means SMPP delivery."},"x_api_key_header":{"type":["string","null"]},"ten_dlc_registered":{"type":"boolean"},"tmobile_ten_dlc_registered":{"type":"boolean"}}},"Error":{"type":"object","properties":{"id":{"type":"string","enum":["unauthenticated","unauthorized","not_found","server_error","invalid_params"]},"message":{"type":"string"}}}},"responses":{"Unauthenticated":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v5/dids/{number}":{"get":{"tags":["Number configuration"],"operationId":"getNumberConfiguration","summary":"Get a number's SMS and MMS configuration","description":"Clients must ignore unknown properties; new ones may be added without notice.","parameters":[{"name":"number","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Configuration.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NumberConfiguration"}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"}}}}}}
```

## Enable, update or disable SMS (and 10DLC assignment) on a number

> Strict parameter parsing: unknown fields reject the request. Use \`action: add\` to enable, \`update\` to change\
> settings or attach a campaign, \`delete\` to disable SMS.<br>

```json
{"openapi":"3.1.0","info":{"title":"TSG Global REST APIs","version":"2026-09-11"},"tags":[{"name":"Number configuration","description":"Per-number SMS, MMS and voice settings. Host api-service.tsgglobal.world."}],"servers":[{"url":"https://sms.tsgglobal.world","description":"Programmable SMS (production)"},{"url":"https://mmsc.tsgglobal.world","description":"Programmable MMS and MMS templates (production)"},{"url":"https://api-service.tsgglobal.world","description":"Phone-number configuration (production)"},{"url":"https://sms-api.staging.tsgglobal.com","description":"Programmable SMS (staging)"},{"url":"https://mms-api.staging.tsgglobal.com","description":"Programmable MMS (staging)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key from the Customer Portal, sent as `Authorization: Bearer <api_key>`."}},"schemas":{"SmsEnablementRequest":{"type":"object","required":["did","action"],"properties":{"did":{"type":"string"},"action":{"type":"string","enum":["add","update","delete"]},"use_case_type":{"type":"string","enum":["a2p","p2p","account_default"]},"p2p_nnid":{"type":"string"},"mms_enable":{"type":"string","enum":["true","false"]},"mms_routing":{"type":"string","description":"http, https, mm4 or mm4s URL for inbound MMS."},"webhook_url":{"type":"string","format":"uri"},"webhook_type":{"type":"string","enum":["smpp","postv1","postv2","post3jam"]},"x_api_key_header":{"type":"string"},"campaign_id":{"type":"string","description":"10DLC campaign to assign. Sole-proprietor campaigns allow one number."},"campaign_sub_id":{"type":"string"},"skip_number_validation":{"type":"string","enum":["true"],"description":"Only after TSG has accepted your LOA for the number."}}},"Error":{"type":"object","properties":{"id":{"type":"string","enum":["unauthenticated","unauthorized","not_found","server_error","invalid_params"]},"message":{"type":"string"}}}},"responses":{"Unauthenticated":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InvalidParams":{"description":"Request understood but parameters invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v2/sms-enablement":{"post":{"tags":["Number configuration"],"operationId":"smsEnablement","summary":"Enable, update or disable SMS (and 10DLC assignment) on a number","description":"Strict parameter parsing: unknown fields reject the request. Use `action: add` to enable, `update` to change\nsettings or attach a campaign, `delete` to disable SMS.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmsEnablementRequest"}}}},"responses":{"200":{"description":"`Success`","content":{"text/plain":{"schema":{"type":"string"}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"422":{"$ref":"#/components/responses/InvalidParams"}}}}}}
```

## Set the inbound SMS webhook for a number

> Omitting \`webhook\_url\` switches the number to SMPP delivery. Have SMPP credentials tested first.

```json
{"openapi":"3.1.0","info":{"title":"TSG Global REST APIs","version":"2026-09-11"},"tags":[{"name":"Number configuration","description":"Per-number SMS, MMS and voice settings. Host api-service.tsgglobal.world."}],"servers":[{"url":"https://sms.tsgglobal.world","description":"Programmable SMS (production)"},{"url":"https://mmsc.tsgglobal.world","description":"Programmable MMS and MMS templates (production)"},{"url":"https://api-service.tsgglobal.world","description":"Phone-number configuration (production)"},{"url":"https://sms-api.staging.tsgglobal.com","description":"Programmable SMS (staging)"},{"url":"https://mms-api.staging.tsgglobal.com","description":"Programmable MMS (staging)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key from the Customer Portal, sent as `Authorization: Bearer <api_key>`."}},"responses":{"Unauthenticated":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","properties":{"id":{"type":"string","enum":["unauthenticated","unauthorized","not_found","server_error","invalid_params"]},"message":{"type":"string"}}}}},"paths":{"/v1/sms/webhook":{"post":{"tags":["Number configuration"],"operationId":"setSmsWebhook","summary":"Set the inbound SMS webhook for a number","description":"Omitting `webhook_url` switches the number to SMPP delivery. Have SMPP credentials tested first.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["did"],"properties":{"did":{"type":"string"},"webhook_url":{"type":"string","format":"uri"},"webhook_type":{"type":"string","enum":["postv2","postv1","post3jam","smpp"],"default":"postv2"},"x_api_key_header":{"type":"string","description":"Sent back to you as the x-api-key header on every webhook call."}}}}}},"responses":{"200":{"description":"`Success`","content":{"text/plain":{"schema":{"type":"string"}}}},"401":{"$ref":"#/components/responses/Unauthenticated"}}}}}}
```

## Enable MMS on a number or change its inbound MMS URI

> The number must already be SMS-enabled and the account MMS-enabled.

```json
{"openapi":"3.1.0","info":{"title":"TSG Global REST APIs","version":"2026-09-11"},"tags":[{"name":"Number configuration","description":"Per-number SMS, MMS and voice settings. Host api-service.tsgglobal.world."}],"servers":[{"url":"https://sms.tsgglobal.world","description":"Programmable SMS (production)"},{"url":"https://mmsc.tsgglobal.world","description":"Programmable MMS and MMS templates (production)"},{"url":"https://api-service.tsgglobal.world","description":"Phone-number configuration (production)"},{"url":"https://sms-api.staging.tsgglobal.com","description":"Programmable SMS (staging)"},{"url":"https://mms-api.staging.tsgglobal.com","description":"Programmable MMS (staging)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key from the Customer Portal, sent as `Authorization: Bearer <api_key>`."}},"schemas":{"MmsConfiguration":{"type":"object","properties":{"number":{"type":"string"},"mms_enabled":{"type":"boolean"},"mms_uri":{"type":["string","null"]},"sms_enabled":{"type":"boolean"},"sms_uri":{"type":["string","null"]}}},"Error":{"type":"object","properties":{"id":{"type":"string","enum":["unauthenticated","unauthorized","not_found","server_error","invalid_params"]},"message":{"type":"string"}}}},"responses":{"Unauthenticated":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v2/dids/{number}/mms/enable":{"post":{"tags":["Number configuration"],"operationId":"enableMms","summary":"Enable MMS on a number or change its inbound MMS URI","description":"The number must already be SMS-enabled and the account MMS-enabled.","parameters":[{"name":"number","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["uri"],"properties":{"uri":{"type":"string","description":"HTTP(S) URL or `mm4://user:pass@host:port` that receives inbound MMS."}}}}}},"responses":{"200":{"description":"Updated configuration.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MmsConfiguration"}}}},"401":{"$ref":"#/components/responses/Unauthenticated"}}}}}}
```

## POST /v1/did/priority

> Add a voice destination priority

```json
{"openapi":"3.1.0","info":{"title":"TSG Global REST APIs","version":"2026-09-11"},"tags":[{"name":"Number configuration","description":"Per-number SMS, MMS and voice settings. Host api-service.tsgglobal.world."}],"servers":[{"url":"https://sms.tsgglobal.world","description":"Programmable SMS (production)"},{"url":"https://mmsc.tsgglobal.world","description":"Programmable MMS and MMS templates (production)"},{"url":"https://api-service.tsgglobal.world","description":"Phone-number configuration (production)"},{"url":"https://sms-api.staging.tsgglobal.com","description":"Programmable SMS (staging)"},{"url":"https://mms-api.staging.tsgglobal.com","description":"Programmable MMS (staging)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key from the Customer Portal, sent as `Authorization: Bearer <api_key>`."}},"schemas":{"DestinationPriority":{"type":"object","required":["did","priority","destination","call_type"],"properties":{"did":{"type":"string"},"priority":{"type":"integer","minimum":1,"maximum":3},"destination":{"type":"string","description":"Gateway IP for VOIP, E.164 for PSTN."},"call_type":{"type":"string","enum":["VOIP","PSTN"],"description":"Case sensitive."},"call_option":{"type":"string","enum":["WP","NP"],"description":"WP sends the DID with a plus, NP without. Case sensitive."}}}}},"paths":{"/v1/did/priority":{"post":{"tags":["Number configuration"],"operationId":"addDestinationPriority","summary":"Add a voice destination priority","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DestinationPriority"}}}},"responses":{"200":{"description":"Result code. `-1008-V` or `-1008-P` means added; negative codes below -1000 are errors (see docs).","content":{"text/plain":{"schema":{"type":"string"}}}}}}}}}
```

## Every operation in the spec

| Method | Path                            | Operation                   |
| ------ | ------------------------------- | --------------------------- |
| POST   | `/messages`                     | `sendSms`                   |
| GET    | `/messages/{uuid}`              | `getSms`                    |
| POST   | `/mms`                          | `sendMms`                   |
| POST   | `/mms/templates`                | `createMmsTemplate`         |
| GET    | `/mms/templates`                | `listMmsTemplates`          |
| GET    | `/mms/templates/{id}`           | `getMmsTemplate`            |
| DELETE | `/mms/templates/{id}`           | `deleteMmsTemplate`         |
| POST   | `/mms/templates/{id}/preview`   | `previewMmsTemplate`        |
| POST   | `/mms/templates/{id}/send`      | `sendMmsFromTemplate`       |
| GET    | `/v5/dids/{number}`             | `getNumberConfiguration`    |
| GET    | `/v1/did/lookup`                | `lookupNumber`              |
| POST   | `/v2/sms-enablement`            | `smsEnablement`             |
| POST   | `/v1/sms/webhook`               | `setSmsWebhook`             |
| POST   | `/v2/dids/{number}/mms/enable`  | `enableMms`                 |
| POST   | `/v2/dids/{number}/mms/disable` | `disableMms`                |
| GET    | `/v1/did/priority/lookup`       | `listDestinationPriorities` |
| POST   | `/v1/did/priority`              | `addDestinationPriority`    |
| PATCH  | `/v1/did/priority`              | `updateDestinationPriority` |
| DELETE | `/v1/did/priority`              | `deleteDestinationPriority` |

The hand-written pages under API Reference remain the place for narrative, encoding rules, webhook payloads and worked examples; the spec is the machine-readable contract.

---

# Programmable SMS

Source: https://support.tsgglobal.com/docs/api-reference/programmable-sms
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-sms.md
Last updated: 2026-01-27T20:37:12.076Z

TSG Global makes sending and receiving SMS easy. Find the documentation and tools you need to build exactly what you want, fast. We’ll handle the complexity of mobile carrier and global regulations.

---

# Send an SMS Message

Source: https://support.tsgglobal.com/docs/api-reference/programmable-sms/send-an-sms-message
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-sms/send-an-sms-message.md
Last updated: 2024-10-18T19:41:07.557Z

POST /messages: send an SMS to one or more E.164 recipients with optional encoding, scheduling, expiry and delivery-receipt flags.

## Overview

This method allows you to send an SMS message. Using TSG Global APIs, you can send outgoing SMS messages from your enabled phone numbers to mobile phones around the globe.

## Authentication



> **Info**


Authentication is done by passing your TSG Global API key via the Authorization header in the format "Authorization: Bearer \<api\_key>" (using the messaging API key specifically). API credentials can be found here: <https://customer-portal.tsgglobal.com/account>



## Method

## Send an SMS message.

<mark style="color:green;">`POST`</mark> `https://sms.tsgglobal.world/messages`

Sends a new SMS message.

#### Request Body

| Name                                   | Type          | Description                                                                                                                                    |
| -------------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| from<mark style="color:red;">\*</mark> | string        | Alphanumeric string representing the sender. Either an E.164 format number or Sender ID.                                                       |
| to<mark style="color:red;">\*</mark>   | array(string) | One or more recipient numbers in E.164 format. Recipients will be de-duplicated (the same number will only be sent once).                      |
| body<mark style="color:red;">\*</mark> | string        | Message contents. UTF8-encoded. If a custom encoding is specified, this should be a base64 encoded representation of the raw data.             |
| encoding                               | int           | Specifies message encoding.                                                                                                                    |
| force\_encoding                        | int           | Normally the system will try to infer what encoding type is best suited for your message, however you can override it using this field instead |
| registered\_delivery                   | int           | Defaults to off. Set to request a delivery receipt from the carrier. `1-3` (always, on success, on error)                                      |
| deliver\_at                            | datetime      | Specifies a future datetime at which to schedule message delivery. Has to be UTC, e.g. "2017-08-04T08:00:00"                                   |
| expires\_at                            | datetime      | Specifies a future datetime when the message should be expired                                                                                 |

The response is a JSON object keyed by recipient number. Each value is a Message object (see [Receive an SMS Message](https://support.tsgglobal.com/docs/api-reference/programmable-sms/receive-an-sms-message.md) for the field reference).





### 200: single message


A single-segment message sent to 9999999 and 12342341234.

```json
{
  "9999999": {
    "updated_at": "2017-09-28T08:28:39.132046",
    "type": "outbound",
    "to": "9999999",
    "status": "new",
    "scheduled_at": null,
    "expires_at": null,
    "processed_at": null,
    "object": "sms",
    "location": null,
    "inserted_at": "2017-09-28T08:28:39.132037",
    "id": "1e7bd5e9-d9ba-41de-814e-3fe755e60e83",
    "from": "15550555055",
    "encoding": 3,
    "delivery_receipt": 0,
    "delivered_at": null,
    "body": "hello world"
  },
  "12342341234": {
    "updated_at": "2017-09-28T08:28:39.132046",
    "type": "outbound",
    "to": "12342341234",
    "status": "new",
    "scheduled_at": null,
    "expires_at": null,
    "processed_at": null,
    "object": "sms",
    "location": null,
    "inserted_at": "2017-09-28T08:28:39.132038",
    "id": "2e6ed7eb-a16f-4e56-b9f2-f66000921da3",
    "from": "15550555055",
    "encoding": 3,
    "delivery_receipt": 0,
    "delivered_at": null,
    "body": "hello world"
  }
}
```






### 200: multipart message


A 3-part multipart message sent to 9999999 and 12342341234. The top-level `id` always equals the first part's `id`.

```json
{
  "9999999": {
    "updated_at": "2017-09-28T08:28:39.132046",
    "udh": {
      "ref_num": 234,
      "count": 3
    },
    "parts": [
      {"id": "3203283d-7a98-49ad-a8d4-17b45a8373b8"},
      {"id": "2a87beb4-791c-480d-9b77-1780d785847c"},
      {"id": "98c8ec04-54e3-40bb-b256-35ebb5c15280"}
    ],
    "type": "outbound",
    "to": "9999999",
    "status": "new",
    "scheduled_at": null,
    "expires_at": null,
    "processed_at": null,
    "object": "sms",
    "location": null,
    "inserted_at": "2017-09-28T08:28:39.132037",
    "id": "3203283d-7a98-49ad-a8d4-17b45a8373b8",
    "from": "15550555055",
    "encoding": 3,
    "delivery_receipt": 0,
    "delivered_at": null,
    "body": "hello world [..]"
  },
  "12342341234": {
    "updated_at": "2017-09-28T08:28:39.132046",
    "udh": {
      "ref_num": 541,
      "count": 3
    },
    "parts": [
      {"id": "3322dcb5-d668-4148-b94c-3f4b3faf670e"},
      {"id": "b5fe304f-374e-4558-95f7-4a3ffdfb7784"},
      {"id": "fbfb2ddc-f7e4-42b5-9bb8-6778f6d45987"}
    ],
    "type": "outbound",
    "to": "12342341234",
    "status": "new",
    "scheduled_at": null,
    "expires_at": null,
    "processed_at": null,
    "object": "sms",
    "location": null,
    "inserted_at": "2017-09-28T08:28:39.132038",
    "id": "3322dcb5-d668-4148-b94c-3f4b3faf670e",
    "from": "15550555055",
    "encoding": 3,
    "delivery_receipt": 0,
    "delivered_at": null,
    "body": "hello world [..]"
  }
}
```






## Encoding

In most cases, we handle the encoding for you: we efficiently transcode it to either fit ASCII, Latin-1 or UTF-16.

The API supports UTF-8. Characters outside of the Latin-1 set will set the encoding to UCS2 (i.e. UTF-16). You can override the encoding by using the `force_encoding` field instead.

Below is a table of all the encodings, however only a few are supported for the API.

| int | Description                                        | Supported by API | Segment size (single / multipart) |
| --- | -------------------------------------------------- | ---------------- | --------------------------------- |
| 0   | SMSC Default (GSM 7 bit / GSM 3.38)                | Yes              | 160 / 153                         |
| 1   | IA5 (CCITT T.50) / ASCII (ANSI X3.4)               | No               |                                   |
| 2   | Octet unspecified (8-bit binary)                   | No               |                                   |
| 3   | Latin 1 (ISO-8859-1)                               | Yes              | 140 / 134                         |
| 4   | Octet unspecified (8-bit binary)                   | No               |                                   |
| 5   | JIS (X 0208-1990)                                  | No               |                                   |
| 6   | Cyrillic (ISO-8859-5)                              | No               |                                   |
| 7   | Latin/Hebrew (ISO-8859-8)                          | No               |                                   |
| 8   | UCS2 / UTF-16 (ISO/IEC-10646)                      | Yes              | 70 / 67                           |
| 9   | Pictogram Encoding                                 | No               |                                   |
| 10  | Music Codes (ISO-2022-JP)                          | No               |                                   |
| 13  | Extended Kanji JIS (X 0212-1990)                   | No               |                                   |
| 14  | Korean Graphic Character Set (KS C 5601/KS X 1001) | No               |                                   |



> **Info**


**Good to know:** message scheduling can be specified for up to 2 years in advance. We guarantee up to the minute accuracy.



### SMS message length

Messages have limited length and exceeding that length will cause message to split into multiple messages that need to be concatenated at the destination (as per GSM messaging standard).

| Encoding | 1 segment max length | Multi segment max length | Max segments |
| -------- | -------------------- | ------------------------ | ------------ |
| 0        | 160                  | 153                      | 6            |
| 3        | 140                  | 134                      | 5            |
| 8        | 70                   | 67                       | 6            |

Since multipart messages need to contain additional information on segment ordering and concatenation rules those segments can carry a little less information than single-segment messages.

Each segment is technically another SMS message.

## Example request

Simple message sent from one number to another using only the required parameters.

```json
{
    "from": "12003004000",
    "to": ["12003004001"],
    "body": "This is a sample test SMS message"
}
```

```bash
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":"This is a sample test SMS message","registered_delivery":1}'
```

---

# Receive an SMS Message

Source: https://support.tsgglobal.com/docs/api-reference/programmable-sms/receive-an-sms-message
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-sms/receive-an-sms-message.md
Last updated: 2024-09-18T21:15:16.985Z

Fetch a message by ID for testing, register an inbound SMS webhook, and understand the message and delivery-receipt objects TSG posts to it.

## Overview

Receive inbound SMS messages to your numbers. Get your message returned via SMPP or via a webhook URL that you provide. For production traffic, we don’t recommend using this endpoint, but instead registering a webhook.

## Authentication



> **Info**


Authentication is done by passing your TSG Global API key via the Authorization header in the format "Authorization: Bearer \<api\_key>" (using the messaging API key specifically). API credentials can be found here: <https://customer-portal.tsgglobal.com/account>



## Method

## Returns a single message. Useful for manually checking message status.

<mark style="color:blue;">`GET`</mark> `https://sms.tsgglobal.world/messages/<uuid>`

You can either use a message id, or one of the part ids. In the case of the latter, you will see detailed information about the part (the raw SMS).

We don’t recommend using this endpoint - perhaps only for testing. For production traffic, we recommend registering a webhook (see below).

#### Path Parameters

| Name                                   | Type   | Description                                           |
| -------------------------------------- | ------ | ----------------------------------------------------- |
| uuid<mark style="color:red;">\*</mark> | String | The UUID for the message ID you are wanting to query. |

## Example Responses

Single message

```json
{
  "id": "03b4641f-17a6-4565-bdba-1ce905be3312",
  "type": "outbound",
  "from": "12341234",
  "to": "12342341234",
  "object": "sms",
  "body": "hello",
  "encoding": 3,
  "delivery_receipt": "no",
  "status": "new",
  "location": null,
  "inserted_at": "2017-09-17T19:12:32.792699",
  "updated_at": "2017-09-17T19:12:32.792704",
  "scheduled_at": null,
  "processed_at": null,
  "delivered_at": null,
  "expires_at": null
}
```

Longer message consisting of multiple UDH parts

```json
{
  "id": "0ab46aaa-17a6-a5a5-7dba-1ce905be3312",
  "udh": {
    "ref_num": 541,
    "count": 3
  },
  "parts": [
    {"id": "3322dcb5-d668-4148-b94c-3f4b3faf670e"},
    {"id": "b5fe304f-374e-4558-95f7-4a3ffdfb7784"},
    {"id": "fbfb2ddc-f7e4-42b5-9bb8-6778f6d45987"}
  ],
  "type": "outbound",
  "from": "12341234",
  "to": "12342341234",
  "object": "sms",
  "body": "hello this is an extremely long message that spans 3 actual SMS messages sent from the carrier to the user. The phone will reassemble all of these messages into one longer, single message. We're currently at 2 parts, but let's keep going until we hit 3 parts. At a simple text message (no emoji), that will probably be around 3*140 characters, encoded as latin-1",
  "encoding": 3,
  "delivery_receipt": "no",
  "status": "new",
  "location": null,
  "inserted_at": "2017-09-17T19:12:32.792699",
  "updated_at": "2017-09-17T19:12:32.792704",
  "scheduled_at": null,
  "processed_at": null,
  "delivered_at": null,
  "expires_at": null
}
```

## Set your webhook URL for your Number

Register the webhook URL with [Update inbound SMS webhook/URI](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-sms-and-10dlc/update-inbound-sms-webhook-uri.md). The webhook will deliver both new messages as well as delivery receipts. You can distinguish the event type based on the `object` parameter (`sms` for messages, `sms_dlr` for delivery receipts).

**Note: Webhook objects will also return Message objects, and include a `parts` section in the case of a UDH multi-part message.**

Your webhook **must** return 200 OK HTTP status code to acknowledge the event, otherwise we’ll attempt to redeliver up to 17 times over 2-3 days (with exponential backoff).

```json
{ "body": "Thank you for texting my webhook number!" }
```

You can optionally send back a JSON response with the `body` key, containing a message response (which will be encoded with the same encoding rules mentioned under the Message Send API) to be sent back to the originator. *We currently only support the `body` key, but are evaluating adding `encoding` and other functionality supported by Message Send.*

## Message Object

Represents a single message. This can be either one actual SMS, or more if the message was longer and split into multiple UDH parts.

This is done because of convenience for our users, generally it’s more important to track the status of a whole message, instead of individual parts. Note that you can still retrieve the number of parts sent (for billing purposes) etc., as well as view part information as needed.

If the low level SMS details are important (down to the PDU), then our SMPP API might be more suitable for you.

In the case of a single message, id, represents the actual sms id.

In the case of a multipart message, the id is representing all the parts. The object will also contain a parts section which will contain information about each of the individual sms parts that were sent. (currently just the part ids, you can use those to retrieve more information via the above Message Get API). To get the number of actual sms sent (in v1, that was the X-Message-Count header), you can either check the length of parts array, or check udh.count.

Below is an example of the package that will be sent to your webhook.

```json
{
  "body": "Test 4",
  "delivered_at": null,
  "delivery_receipt": "no",
  "encoding": 3,
  "expires_at": null,
  "from": "14252437709",
  "id": "0658b5fd-d36d-49ae-9e58-d0a7f053f1bb",
  "inserted_at": "2022-04-06T21:49:29.926166",
  "location": null,
  "object": "sms",
  "processed_at": null,
  "scheduled_at": null,
  "status": "new",
  "to": "13462239287",
  "type": "inbound",
  "udh": {
    "count": null,
    "ref_num": null,
    "seq_num": null
  },
  "updated_at": "2022-04-06T21:49:29.926166"
}
```

## Delivery Receipts

### Delivery Receipt Object

| Name                  | Description                                                                                                                    |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| id                    | <p><strong>string</strong><br>Unique identifier for the object</p>                                                             |
| type                  | <p><strong>string</strong><br>Message type, either <code>inbound</code> or <code>outbound</code>.</p>                          |
| from                  | <p><strong>string</strong><br>Number (or sender ID) of the original sender</p>                                                 |
| to                    | <p><strong>string</strong><br>Number of the message recipient</p>                                                              |
| object                | <p><strong>string</strong><br>Always set to <code>sms\_dlr</code>.</p>                                                         |
| delivery\_status      | <p><strong>string</strong><br>Delivery status.</p>                                                                             |
| submitted\_at         | <p><strong>timestamp</strong><br>Time at which the message was submitted</p>                                                   |
| done\_at              | <p><strong>timestamp</strong><br>Time at which the message has reached it’s final state (minute accuracy, seconds ignored)</p> |
| delivery\_error\_code | <p><strong>string</strong><br>If unsuccessful, will contain upstream error code.</p>                                           |
| inserted\_at          | <p><strong>timestamp</strong><br>Denotes when the message was initially received.</p>                                          |
| updated\_at           | <p><strong>timestamp</strong><br>Denotes when the data last changed.</p>                                                       |
| sms.id                | <p><strong>uuid</strong><br>ID of the matching SMS.</p>                                                                        |

### Delivery Status

| Id          | Description                                                                   |
| ----------- | ----------------------------------------------------------------------------- |
| delivered   | Message was successfully delivered.                                           |
| expired     | Message validity period has expired (for instance, the phone was turned off). |
| deleted     | Message has been deleted.                                                     |
| undelivered | Message is undeliverable (for instance the number doesn’t exist)              |
| accepted    | Message was accepted and will be sent.                                        |
| unknown     | Delivery status is unknown.                                                   |
| rejected    | Message was rejected by the carrier                                           |
| failed      | Delivery was unsuccessful.                                                    |
| enroute     | Message is enroute.                                                           |
| skipped     | Message was skipped.                                                          |

### Example DLR

```json
{
  "id": "500fe938-fd2d-4dc1-a186-592e71112388",
  "type": "inbound",
  "from": "15678234",
  "to": "12342341234",
  "object": "sms_dlr",
  "delivery_status": "delivered",
  "delivery_error_code": "000",
  "inserted_at": "2017-09-17T19:12:32.792699",
  "updated_at": "2017-09-17T19:12:32.792704",
  "submitted_at": "2017-06-01T18:00:00",
  "done_at": "2017-06-01T18:00:05",
  "sms": {
    "id": "03b4641f-17a6-4565-bdba-1ce905be3312"
  }
}
```

---

# Delivery Receipts (DLRs)

Source: https://support.tsgglobal.com/docs/api-reference/programmable-sms/delivery-receipts-dlrs
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-sms/delivery-receipts-dlrs.md
Last updated: 2024-01-29T19:05:27.117Z

How SMS delivery receipts work: requested per message, delivered to your inbound webhook as sms\_dlr objects, with a link to the DLR error-code list.

## Overview



> **Danger**


DLRs are requested on a per-message basis. If you do not request a DLR, you will not have a record of the result of the transaction.



A Delivery Receipt (DLR) is **an acknowledgement from a destination carrier network that a message was successfully accepted or rejected** (and the reason the message was rejected). TSG Global supports DLRs on SMS and MMS if a customer has their requested delivery status flag set appropriately. The DLRs will be delivered to your inbound webhook/URI if requested.

## DLR Example

Below is an example DLR:

```
{
  "delivery_error_code": "000",
  "delivery_status": "delivered",
  "done_at": "2022-04-13T21:35:00",
  "from": "14252437709",
  "id": "a2692312-2050-4a50-9123-ca7b4cde0db7",
  "inserted_at": "2022-04-13T21:35:22.401373",
  "object": "sms_dlr",
  "sms": {
    "id": "a4c56a01-4daf-4ae1-9732-025b427add13"
  },
  "submitted_at": "2022-04-13T21:35:00",
  "to": "18574914340",
  "type": "inbound",
  "updated_at": "2022-04-13T21:35:22.401373"
}
```

## DLR Error Codes

A list of current DLR error codes can be found here:\
<https://support.tsgglobal.com/hc/en-us/articles/4643124175131-Common-DLR-Error-Codes>

---

# SMPP

Source: https://support.tsgglobal.com/docs/api-reference/programmable-sms/smpp
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-sms/smpp.md
Last updated: 2023-01-19T16:51:47.000Z

Connect over SMPP 3.4 on port 2775 (TCP) or 2776 (TLS) for high-volume SMS, using the SMPP credentials from the Customer Portal.

## SMPP

We also provide an SMPP interface for high-volume users. SMPP is available on the canonical port 2775. An encrypted, secure connection is also provided over TLS (1.1 or 1.2) on port 2776.

We highly recommend you connect via TLS in order to securely transport your messages to us. The normal, non-TLS connection is provided mainly for legacy backwards compatibility reasons.

## Authentication 



> **Info**


Authentication is done by SMPP credentials you received from TSG team or can be found in the customer portal.&#x20;

---

# Headers

Source: https://support.tsgglobal.com/docs/api-reference/programmable-sms/smpp/headers
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-sms/smpp/headers.md
Last updated: 2022-04-20T21:38:34.000Z

Request conventions for the messaging REST APIs: Bearer API key, JSON bodies, UUIDv4 ids and ISO 8601 UTC timestamps.

## Authentication



> **Info**


Authentication is done by passing your TSG Global API key via the Authorization header in the format "Authorization: Bearer \<api\_key>"



## Parameters & Content-Type

Parameters should be JSON encoded and passed in the request body (with the Content-Type header set to `application/json`). IDs are always UUIDv4. Timestamps are in the ISO8601 format and in UTC.

## <br>

---

# Errors

Source: https://support.tsgglobal.com/docs/api-reference/programmable-sms/smpp/errors
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-sms/smpp/errors.md
Last updated: 2022-05-17T16:57:29.000Z

HTTP status codes and machine-readable error types returned by the TSG Global REST APIs.

We use HTTP response codes to indicate specific error classes (2xx range is success, 4xx failed based on the provided parameters, 5xx are server errors). Each error has a machine readable id, and a human readable explanation. Authentication is done by passing the API key via the Authorization header.

### Status Codes 

| Code | Description                                                                                         |
| ---- | --------------------------------------------------------------------------------------------------- |
| 200  | The request was a success.                                                                          |
| 401  | Request failed because user is not authenticated.                                                   |
| 403  | Request failed because user does not have authorization to access a specific resource.              |
| 404  | Resource doesn’t exist.                                                                             |
| 409  | The request conflicts with another request.                                                         |
| 422  | Your request was understood, but contained invalid parameters.                                      |
| 500  | Something went wrong on the server, check status site and/or report the issue.                      |
| 503  | Service is temporarily unavailable. Generally this is temporary and the requests should be retried. |

### Error Types 

| Type            | Description                                           |
| --------------- | ----------------------------------------------------- |
| unauthenticated | Request failed because the user is not authenticated. |
| unauthorized    | User does not have access to the specified resource.  |
| not\_found      | Resource was not found.                               |
| server\_error   | Internal server error.                                |
| invalid\_params | Parameters were not valid.                            |

---

# Programmable MMS

Source: https://support.tsgglobal.com/docs/api-reference/programmable-mms
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-mms.md
Last updated: 2026-03-23T15:31:00.768Z

Send and receive MMS over the HTTP API or MM4/SMTP, with reusable templates and delivery reports.

---

# Send an MMS Message

Source: https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message.md
Last updated: 2026-03-23T15:36:27.721Z

POST /mms: send an MMS with text, hosted, data-URI or embedded parts, and request delivery reports. Includes part rules, size limits and escaping FAQs.

## Overview

Easily send an MMS message with some media content.

## Authentication



> **Info**


Authentication is done by passing your TSG Global API key via the Authorization header in the format "Authorization: Bearer \<api\_key>" (using the messaging API key specifically). API credentials can be found here: <https://customer-portal.tsgglobal.com/account>



## Method

## Send an MMS message.

<mark style="color:green;">`POST`</mark> `https://mmsc.tsgglobal.world/mms`

The MMS API attempts to mirror an MM4 request, as such it shares some structural similarities and naming. Particularly the use of the ‘type’ field to denote the type of request. Currently only Forward Requests are available.

#### Request Body

All fields live under `data.attributes`, except `data.type` and `data.id`.

| Name                                    | Type                 | Description                                                                                                                                                                  |
| --------------------------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id                                      | string               | An id, this id may be used to track the message. Note: this can be considered a reference\_id.                                                                               |
| type<mark style="color:red;">\*</mark>  | string               | What type of data should we expect with this message. Should always be `"mms-forward-req"`. Note: failure to provide this value will cause the request to fail immediately.  |
| expires\_at                             | datetime             | An ISO8601 formatted timestamp, this designates when the message should expire within the system, expired messages will be dropped if they expire before leaving the queues. |
| expires\_in                             | integer              | A duration in seconds after the message has been received to expire, this will be added to the time of receiving the message to create an `expires_at` value.                |
| transaction\_id                         | string               | This field will be used as the transaction-id of the message, if none is provided, one will be generated.                                                                    |
| from<mark style="color:red;">\*</mark>  | string               | The originator number, should be formatted as E164.                                                                                                                          |
| to<mark style="color:red;">\*</mark>    | list\<string>        | A list of recipients, each number should be formatted as E164.                                                                                                               |
| subject                                 | string               | An optional subject header to apply to the message.                                                                                                                          |
| headers                                 | map                  | An optional map of additional headers to include in the message.                                                                                                             |
| metadata                                | map                  | Any additional data to include in the payload, will be returned on response.                                                                                                 |
| parts<mark style="color:red;">\*</mark> | list                 | A list of parts that make up the body of the message.                                                                                                                        |
| parts\[].kind                           | string               | What kind of content does the part contain? Default “plain”.                                                                                                                 |
| parts\[].headers                        | map\<string, string> | Any additional headers to include in the part.                                                                                                                               |
| parts\[].content\_type                  | string               | What is the media type of the part? If none is given this will default to text/plain, unless the kind is a uri or data-uri.                                                  |
| parts\[].content\_location              | string               | The name of the attachment, in case a custom SMIL is provided, this will allow referencing the part.                                                                         |
| parts\[].content\_encoding              | string               | Any special encodings applied to the body of the part, usually a compression method.                                                                                         |
| parts\[].transfer\_encoding             | string               | Any special encodings applied to the body of the part, normally for transport over HTTP/S.                                                                                   |
| parts\[].body                           | string               | The body or content of the part, may or not be encoded as required. Required for `plain` and `embedded` parts.                                                               |
| parts\[].uri                            | string               | A URI that is publicly accessible that can be downloaded to get the content of the MMS. Content exceeding 3 MB will be rejected. Required for `uri` and `data-uri` parts.    |
| request\_delivery\_reports              | boolean              | Requesting DLR for the message to be sent to you. Defaults to false                                                                                                          |





### 200: OK


A 200 means the request was accepted for processing, not that the MMS has been sent or delivered. `data.attributes.messages` contains one entry per recipient; its `message_id` is the id used in delivery reports.

```json
{
  "data": {
    "id": "4e36a1f7-fd9c-4851-8087-918902fc204e",
    "type": "mms-forward-res",
    "attributes": {
      "inserted_at": "2019-10-24T00:48:53.312285Z",
      "transaction_id": "e7184cf1-1837-4318-a2cd-82c847830541",
      "from": "12003004005",
      "to": ["13746648333"],
      "subject": "Hello",
      "headers": {},
      "messages": [{
        "message_id": "9f3a72e9-7dc2-4741-96c7-ff2049b49b11",
        "to": "13746648333"
      }],
      "parts": [
        {
          "id": "text-part@localhost",
          "content_type": "text/plain",
          "content_length": "11",
          "content_encoding": "identity",
          "transfer_encoding": "identity",
          "kind": "plain"
        }
      ]
    }
  }
}
```






### 400: Bad Request


The JSON payload was malformed, most often because of an unescaped new line inside a string. See the escaping examples below.





## Example POST

Minimal request with a text part and a hosted image:

```json
{
  "data": {
    "type": "mms-forward-req",
    "attributes": {
      "from": "+12223334444",
      "to": [
        "+14252437709"
      ],
      "headers": {},
      "metadata": {},
      "parts": [
        {
          "headers": {},
          "metadata": {},
          "content_location": "body.txt",
          "kind": "plain",
          "content_type": "text/plain",
          "body": "This is a test MMS for the body"
        },
        {
          "headers": {},
          "metadata": {},
          "content_location": "aurora.jpg",
          "kind": "uri",
          "uri": "https://s3.amazonaws.com/content.mms.smshub.world/sample/sample-768x1024.jpg"
        }
      ]
    }
  }
}
```

Fuller request showing a subject, transaction id, delivery reports and extra headers:

```json
{
  "data": {
    "id": "1354f59f-7cfc-46de-981a-f750d443f9ec",
    "type": "mms-forward-req",
    "attributes": {
      "from": "+12342341234",
      "to": ["+12003004000"],
      "subject": "This is a test",
      "transaction_id": "c52e6196-4ef6-4ce4-8c89-a0a12791c298",
      "request_delivery_reports": true,
      "headers": {
        "cc": ["+12003005000@example.com"],
        "to": ["+12003004000@example.com", "+12003004001@example.com"]
      },
      "parts": [
        {
          "kind": "plain",
          "headers": {},
          "content_type": "text/plain",
          "content_location": "my_text.txt",
          "content_encoding": "identity",
          "transfer_encoding": "identity",
          "body": "Hello, World",
          "uri": null,
          "metadata": {}
        },
        {
          "body": null,
          "content_encoding": "identity",
          "content_location": null,
          "content_type": "image/png",
          "decoded": false,
          "headers": {},
          "kind": "uri",
          "metadata": {},
          "transfer_encoding": "identity",
          "uri": "http://example.com/image.png"
        }
      ]
    }
  }
}
```

**Delivery Receipts (DLRs)**

DLRs for MMS messages are customer-enabled by optionally flagging a request for a DLR when POSTing to the API. Please include `"request_delivery_reports": true` as in the above example, requesting that a DLR be sent to you. Omitting or setting it to false will result in no DLRs being forwarded to you. See [Receive DLRs](https://support.tsgglobal.com/docs/api-reference/programmable-mms/receive-dlrs.md) for the payload.

**Part Kinds**

* `plain`

```json
{
  "kind": "plain",
  "body": "Hello, World"
}
```

Plain parts are used for text attachments, these include `text/*` media types that do not include any binary or restricted characters (i.e. nulls).

* `data-uri`

```json
{
  "kind": "data-uri",
  "content_location": "MyText.txt",
  "uri": "data:text/plain;name=<MyText.txt>,Hello%20World"
}
```

RFC2397 data URIs may be used to specify content\_encoding, content\_type and body in a single string. These strings however have a 65535 character limit.

* `uri`

```json
{
  "kind": "uri",
  "content_type": "image/png",
  "uri": "http://example.org/item.png"
}
```

Parts can also be provided as URIs, the content\_type will be taken from the request or determined based on the extension of the link.

Content downloaded from a URI must be 3 MB or less, otherwise it will be rejected and the message will have a nulled attachment.



> **Warning**


The requested resource MUST return a valid `Content-Length`, failure to do so will result in the attachment being nullified. **NOTE:** The server MUST respond to HEAD and GET requests for the attachment to be retrieved.



* `embedded`

```json
{
  "kind": "embedded",
  "content_type": "image/png",
  "transfer_encoding": "base64",
  "body": "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QwLFhYQGrly9gAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAApUlEQVQ4y2P8//8/Q1N6wH8GMkDdzA2MjI1p/v+l5MQYRMQESNL85tUHhmePXjEwMTAwkKwZWQ8TqRovnbmFwmeiRDNJBsA065mokW4ATLOUnBiGHAu5NmO44NKZWxh+xGczhgEwGy6ducXw5tUHFMPwRTNKGMBsevboFYYYUQaIiAlgaCCUyJiwpTCYIbgCjmAsiIgJEJ28mWAZg1QA08NIaXYGABYVP8mp45LoAAAAAElFTkSuQmCC"
}
```

Parts MAY be embedded, in which all the data is included but MAY be compressed or encoded in a different format for transfer. Data in an embedded body must NOT exceed 1 MB (when compressed).

The body of the part will be decoded by applying:

* `transfer_encoding`
* `content_encoding`

To encode the part, apply the encodings in the reverse.

**Note:** All headers are subject to filter and may be excluded.

Any headers that start with the following will not be added to the message:

* `x-mms-`
* `content-`
* `checksum-`
* `x-checksum-`
* `message-id`

## Example 200 OK Response

```http
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Server: Cowboy
Date: Wed, 23 Oct 2019 18:50:03 GMT
X-Request-ID: FdBbQM5NGxGrvxkAAAUG

{
  "data": {
    "id": "4e36a1f7-fd9c-4851-8087-918902fc204e",
    "type": "mms-forward-res",
    "attributes": {
      "inserted_at": "2019-10-24T00:48:53.312285Z",
      "transaction_id": "e7184cf1-1837-4318-a2cd-82c847830541",
      "from": "12003004005",
      "to": ["13746648333"],
      "subject": "Hello",
      "headers": {},
      "messages": [{
        "message_id": "9f3a72e9-7dc2-4741-96c7-ff2049b49b11",
        "to": "13746648333"
      }],
      "parts": [
        {
          "id": "text-part@localhost",
          "content_type": "text/plain",
          "content_length": "11",
          "content_encoding": "identity",
          "transfer_encoding": "identity",
          "kind": "plain"
        }
      ]
    }
  }
}
```

`data.attributes.messages` will contain a message for each recipient. The provided `message_id` will be used to reference the message in DLRs.

## Additional Examples

### Example - Escape Special Characters

```
# Single character
\n - Line-feed / New-line
\r - Carriage-return
\s - Whitespace (spaces are printable however)
\t - Horizontal-tab
# Unicode
\uXXXX - Unicode character, here X is a hexadecimal value
```

### Example - New Lines in Body

```javascript
// Incorrect
{
  "body": "These
    are
    new
    lines
    that
    aren't
    escaped
    "
}

// Correct
{
  "body": "These\nare\nnew\nlines\nthat\nare\nescaped"
}
```

### Example - the UTF-8 character - for more information please refer to RFC8259

```json
{
  "body": "Have a smile 😁"
}
```

### Example - JSON Unicode escape

```json
{
  "body": "Have a smile 😀"
}
```

## Frequently Asked Questions

**What is the maximum plain body text limit for an MMS message?** We recommend using 1000 characters or less.

**How many participants can I have in an MMS conversation?** We recommend having 10 or fewer participants in an MMS conversation.

**My request failed with a 400 Bad Request and a message saying unexpected character at X.** The JSON payload was malformed; did you include any new lines inside strings?

**How can I send a line-feed, carriage-return or other non-printable characters?** JSON supports several escape sequences for handling non-printable characters (see above).

**Can I send UTF-8 characters?** Yes, the API supports UTF-8 encoding.

**Can I send an emoji?** Yes, either using the unicode escape sequence or the UTF-8 character.

---

# Send an MMS Message Using Templates

Source: https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates.md
Last updated: 2026-03-30T17:47:34.583Z

Why MMS templates exist, common use cases, and a three-call quickstart: create a template, preview it, send it.

## Overview

This functionality enables users to create MMS templates (both content and attachments) which they can use to send MMS messages in a simpler and more performant (less resource intensive) way.

### Why Use MMS Templates?

MMS templates let you define your message content and media attachments once, then send personalized messages at scale, without re-uploading media or rebuilding payloads for every request.

* **Faster sends**: pre-staged media means smaller payloads and lower latency per message. Skip the base64 encoding and inline attachment overhead.
* **Personalization at scale**: use `{placeholder}` syntax to inject per-recipient details (names, appointment times, order numbers) into both subject lines and message bodies.
* **Brand consistency**: lock down approved copy and creative assets in a template so every message stays on-brand, regardless of who triggers the send.
* **Preview before you send**: render a fully-resolved preview with real placeholder values to catch issues before they reach your customers' phones.
* **Simpler integration**: your send call is just a template ID, a recipient list, and a params object. No need to reconstruct the full message every time.

***

### Common Use Cases

#### Appointment Reminders with Rich Media

A healthcare provider creates a template with their clinic's logo and a message: *"Hi {patient\_name}, your appointment with {doctor\_name} is on {date} at {time}. Reply CONFIRM or call us to reschedule."* One template, thousands of personalized reminders, each with consistent branding and a professional look that SMS can't match.

#### Marketing Campaigns with Branded Creative

A retail brand launches a flash sale. Their marketing team uploads a promotional image once, locks the copy, *"{first\_name}, our Summer Sale starts now! Show this MMS in-store for an extra 10% off."*, and triggers sends to segmented customer lists via API. No re-uploading the image per batch. No copy drift between segments.

#### Transactional Notifications

An e-commerce platform sends order confirmations with a product thumbnail: *"Thanks {customer\_name}! Your order #{order\_id} has shipped. Track it here: {tracking\_url}"* The product image and layout stay consistent across millions of orders, while every detail is unique per customer.

***

### Quickstart: Send Your First Template MMS

Go from zero to a delivered MMS in three API calls. This guide walks through the full lifecycle: create a template, preview it, and send it.

**Prerequisites**

* A TSG Global account with MMS enabled
* Your messaging API key (found in Customer Portal, Account)
* A provisioned phone number capable of sending MMS

**Authentication**

All requests require your TSG Global messaging API key passed via the Authorization header:

```http
Authorization: Bearer <api_key>
```

***

#### Step 1: Create a Template

Define your message copy with placeholders and attach media. Placeholders use `{variable_name}` syntax and will be replaced with real values when you preview or send.





### cURL



```bash
curl -X POST https://mmsc.tsgglobal.world/mms/templates \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <api_key>" \
  -d '{
    "data": {
      "type": "mms-template",
      "attributes": {
        "name": "order-confirmation",
        "subject_template": "Order #{order_id} Confirmed",
        "body_template": "Hi {customer_name}, your order #{order_id} has shipped! Track it here: {tracking_url}",
        "parts": [
          {
            "kind": "uri",
            "uri": "https://cdn.example.com/brand-logo.png",
            "content_type": "image/png",
            "content_location": "brand-logo.png"
          }
        ]
      }
    }
  }'
```






### Python



```python
import requests

resp = requests.post(
    "https://mmsc.tsgglobal.world/mms/templates",
    headers={"Content-Type": "application/json", "Authorization": "Bearer <api_key>"},
    json={
        "data": {
            "type": "mms-template",
            "attributes": {
                "name": "order-confirmation",
                "subject_template": "Order #{order_id} Confirmed",
                "body_template": "Hi {customer_name}, your order #{order_id} has shipped! Track it here: {tracking_url}",
                "parts": [
                    {
                        "kind": "uri",
                        "uri": "https://cdn.example.com/brand-logo.png",
                        "content_type": "image/png",
                        "content_location": "brand-logo.png",
                    }
                ],
            },
        }
    },
)

template = resp.json()
template_id = template["data"]["id"]
print(f"Created template: {template_id}")
```






Save the returned `template_id`; you'll need it for the next two steps.

***

#### Step 2: Preview (Optional but Recommended)

Render the template with real values to verify everything looks right, without actually sending anything.





### cURL



```bash
curl -X POST https://mmsc.tsgglobal.world/mms/templates/TEMPLATE_ID/preview \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <api_key>" \
  -d '{
    "data": {
      "type": "mms-template-preview-req",
      "attributes": {
        "from": "18005551234",
        "to": ["19175559876"],
        "params": {
          "customer_name": "Jane",
          "order_id": "78432",
          "tracking_url": "https://track.example.com/78432"
        }
      }
    }
  }'
```






### Python



```python
preview = requests.post(
    f"https://mmsc.tsgglobal.world/mms/templates/{template_id}/preview",
    headers={"Content-Type": "application/json", "Authorization": "Bearer <api_key>"},
    json={
        "data": {
            "type": "mms-template-preview-req",
            "attributes": {
                "from": "18005551234",
                "to": ["19175559876"],
                "params": {
                    "customer_name": "Jane",
                    "order_id": "78432",
                    "tracking_url": "https://track.example.com/78432",
                },
            },
        }
    },
)

print(preview.json())
```






Check the response. The subject should read "Order #78432 Confirmed" and the body should start with "Hi Jane, your order #78432 has shipped!"

***

#### Step 3: Send It

Same shape as the preview call; just swap the endpoint from `/preview` to `/send`.





### cURL



```bash
curl -X POST https://mmsc.tsgglobal.world/mms/templates/TEMPLATE_ID/send \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <api_key>" \
  -d '{
    "data": {
      "type": "mms-template-send-req",
      "attributes": {
        "from": "18005551234",
        "to": ["19175559876"],
        "params": {
          "customer_name": "Jane",
          "order_id": "78432",
          "tracking_url": "https://track.example.com/78432"
        },
        "request_delivery_reports": true
      }
    }
  }'
```






### Python



```python
send = requests.post(
    f"https://mmsc.tsgglobal.world/mms/templates/{template_id}/send",
    headers={"Content-Type": "application/json", "Authorization": "Bearer <api_key>"},
    json={
        "data": {
            "type": "mms-template-send-req",
            "attributes": {
                "from": "18005551234",
                "to": ["19175559876"],
                "params": {
                    "customer_name": "Jane",
                    "order_id": "78432",
                    "tracking_url": "https://track.example.com/78432",
                },
                "request_delivery_reports": True,
            },
        }
    },
)

result = send.json()
print(f"Message sent! ID: {result['data']['id']}")
```






That's it: three calls from template creation to a delivered MMS.

***

### What's Next?

* List your templates: `GET /mms/templates` to see all saved templates
* Clean up: `DELETE /mms/templates/:id` to remove templates you no longer need
* Send at scale: pass multiple numbers in the `to` array to reach a list in one call
* Track delivery: set `request_delivery_reports: true` and configure a webhook to receive DLRs

### Relevant pages:

---

# Create MMS Template

Source: https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/create-mms-template
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/create-mms-template.md
Last updated: 2026-03-30T17:40:32.133Z

POST /mms/templates: create a reusable MMS template with {placeholder} text and pre-staged attachments.

### Authentication



> **Info**


Authentication is done by passing your TSG Global API key via the Authorization header in the format "Authorization: Bearer \<api\_key>" (using the messaging API key specifically). API credentials can be found here: <https://customer-portal.tsgglobal.com/account>



<mark style="color:green;">`POST`</mark> `https://mmsc.tsgglobal.world/mms/templates`

Creates a new MMS template. The template has placeholders so you can fill in per-customer information when you send.

### **Request body**

| Name                                       | Type   | Description                                                                        |
| ------------------------------------------ | ------ | ---------------------------------------------------------------------------------- |
| `data.type`                                | string | Must be `"mms-template"`                                                           |
| `data.attributes.name`                     | string | **Required.** Template name                                                        |
| `data.attributes.body_template`            | string | **Required.** Body text with `{placeholder}` syntax                                |
| `data.attributes.subject_template`         | string | Optional. Subject line with `{placeholder}` syntax                                 |
| `data.attributes.parts`                    | array  | Optional. List of attachment parts (see below)                                     |
| `data.attributes.parts[].kind`             | string | **Required.** One of `"data-uri"`, `"uri"`, `"plain"`, `"embedded"`                |
| `data.attributes.parts[].content_location` | string | Optional. Filename for the attachment                                              |
| `data.attributes.parts[].uri`              | string | Required for `"uri"` and `"data-uri"` kinds. The resource URI or RFC 2397 data URI |
| `data.attributes.parts[].body`             | string | Required for `"plain"` kind                                                        |
| `data.attributes.parts[].content_type`     | string | Optional. MIME type (default: `"text/plain"`)                                      |

Placeholders use the pattern `{key}` where key matches `[a-zA-Z_][a-zA-Z0-9_]*`. Extracted placeholders are returned in the response. Attachments are copied to TSG-hosted storage at creation, so the `uri` values in the response differ from the ones you sent.

### Example with placeholders

#### Example of a request

Besides the text in `body_template` there are 2 parts: a data URI attachment (`kind: "data-uri"`) and an image referenced by URL (`kind: "uri"`).

```json
{
  "data": {
    "type": "mms-template",
    "attributes": {
      "name": "visit-thank-you",
      "subject_template": "Hello {name}",
      "body_template": "Dear {name}, welcome to {company}.",
      "parts": [
        {
          "kind": "data-uri",
          "content_location": "brochure.txt",
          "uri": "data:text/plain,Hello%20Brochure"
        },
        {
          "kind": "uri",
          "content_location": "unnamed-1.png",
          "uri": "https://www.tsgglobal.com/wp-content/uploads/2025/01/unnamed-1.png"
        }
      ]
    }
  }
}
```

#### Example response

```json
{
  "data": {
    "attributes": {
      "name": "visit-thank-you",
      "parts": [
        {
          "uri": "https://content-mms.staging.smshub.world/templates/491aa990-1fbb-4058-8af0-c78049010d2f/attachments/1-brochure.txt",
          "content_type": "text/plain",
          "content_location": "brochure.txt"
        },
        {
          "uri": "https://content-mms.staging.smshub.world/templates/491aa990-1fbb-4058-8af0-c78049010d2f/attachments/2-unnamed-1.png",
          "content_type": "image/png",
          "content_location": "unnamed-1.png"
        }
      ],
      "inserted_at": "2026-03-20T19:53:02.165449",
      "updated_at": "2026-03-20T19:53:02.165449",
      "placeholders": [
        "name",
        "company"
      ],
      "body_template": "Dear {name}, welcome to {company}.",
      "subject_template": "Hello {name}"
    },
    "id": "491aa990-1fbb-4058-8af0-c78049010d2f",
    "type": "mms-template"
  }
}
```

### Example without placeholders

A template does not have to contain placeholders. This example has none and a single image attachment provided by URL (`kind: "uri"`). **Note:** the attachment has to be publicly accessible.

#### Example of a request

```json
{
  "data": {
    "type": "mms-template",
    "attributes": {
      "name": "no-placeholder-example",
      "subject_template": "New deals!",
      "body_template": "Check our new deals!",
      "parts": [
        {
          "kind": "uri",
          "content_location": "unnamed-1.png",
          "uri": "https://www.tsgglobal.com/wp-content/uploads/2025/01/unnamed-1.png"
        }
      ]
    }
  }
}
```

#### Example response

```json
{
  "data": {
    "attributes": {
      "name": "no-placeholder-example",
      "parts": [
        {
          "uri": "https://content-mms.staging.smshub.world/templates/7c0e2d1a-5b3f-4c8e-9a21-0f6d4e8b2c17/attachments/1-unnamed-1.png",
          "content_type": "image/png",
          "content_location": "unnamed-1.png"
        }
      ],
      "inserted_at": "2026-03-20T19:55:10.412001",
      "updated_at": "2026-03-20T19:55:10.412001",
      "placeholders": [],
      "body_template": "Check our new deals!",
      "subject_template": "New deals!"
    },
    "id": "7c0e2d1a-5b3f-4c8e-9a21-0f6d4e8b2c17",
    "type": "mms-template"
  }
}
```

---

# Preview MMS Template

Source: https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/preview-mms-template
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/preview-mms-template.md
Last updated: 2026-03-23T16:23:29.551Z

For testing and debugging purposes, you can preview how the resulting MMS will look like without actually sending.

<mark style="color:green;">`POST`</mark> `https://mmsc.tsgglobal.world/mms/templates/:id/preview`

Renders a preview of the template with the given parameters without sending, where `:id`  is the ID of the created template.

### **Request body**

| Name                     | Type             | Description                                                                                            |
| ------------------------ | ---------------- | ------------------------------------------------------------------------------------------------------ |
| `data.type`              | string           | Must be `"mms-template-preview-req"`                                                                   |
| `data.attributes.from`   | string           | **Required.** Sender number (E.164)                                                                    |
| `data.attributes.to`     | array of strings | **Required.** Recipient numbers (E.164)                                                                |
| `data.attributes.params` | object           | **Required.** Key-value map of placeholder values. Must match all placeholders defined in the template |

### Example

#### Example request

```json
{
  "data": {
    "type": "mms-template-preview-req",
    "attributes": {
      "from": "18003004001",
      "to": ["17818434375"],
      "params": {
        "name": "Jane",
        "company": "TSG"
      }
    }
  }
}
```

#### Example response

<pre class="language-json"><code class="lang-json"><strong>{
</strong>  "data": {
    "attributes": {
      "metadata": {},
      "from": "18003004001",
      "parts": [
        {
          "metadata": {},
          "uri": null,
          "body": "Dear Jane, welcome to TSG.",
          "kind": "plain",
          "headers": {},
          "content_type": "text/plain",
          "content_location": null
        },
        {
          "metadata": {},
          "uri": "https://content-mms.staging.smshub.world/templates/491aa990-1fbb-4058-8af0-c78049010d2f/attachments/1-brochure.txt",
          "body": null,
          "kind": "uri",
          "headers": {},
          "content_type": null,
          "content_location": "brochure.txt"
        },
        {
          "metadata": {},
          "uri": "https://content-mms.staging.smshub.world/templates/491aa990-1fbb-4058-8af0-c78049010d2f/attachments/2-unnamed-1.png",
          "body": null,
          "kind": "uri",
          "headers": {},
          "content_type": null,
          "content_location": "unnamed-1.png"
        }
      ],
      "to": [
        "17818434375"
      ],
      "subject": "Hello Jane",
      "request_delivery_reports": false
    },
    "id": "f67481a0-a532-4dda-b931-6973ce292558",
    "type": "mms-forward-req"
  }
}
</code></pre>

### Example without placeholders

#### Example request

```json
{
  "data": {
    "type": "mms-template-preview-req",
    "attributes": {
      "from": "18003004001",
      "to": ["17818434375"],
      "params": {}
    }
  }
}
```

#### Example response

<pre class="language-json"><code class="lang-json"><strong>{
</strong>  "data": {
    "attributes": {
      "metadata": {},
      "from": "18003004001",
      "parts": [
        {
          "metadata": {},
          "uri": null,
          "body": "New deals available!",
          "kind": "plain",
          "headers": {},
          "content_type": "text/plain",
          "content_location": null
        },
        {
          "metadata": {},
          "uri": "https://content-mms.staging.smshub.world/templates/491aa990-1fbb-4058-8af0-c78049010d2f/attachments/2-unnamed-1.png",
          "body": null,
          "kind": "uri",
          "headers": {},
          "content_type": null,
          "content_location": "unnamed-1.png"
        }
      ],
      "to": [
        "17818434375"
      ],
      "subject": "New deals!",
      "request_delivery_reports": false
    },
    "id": "f67481a0-a532-4dda-b931-6973ce292558",
    "type": "mms-forward-req"
  }
}
</code></pre>

---

# Send MMS Using Template

Source: https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/send-mms-using-template
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/send-mms-using-template.md
Last updated: 2026-03-23T16:24:38.997Z

POST /mms/templates/:id/send: send an MMS from a saved template by supplying recipients and placeholder values.

<mark style="color:green;">`POST`</mark> `https://mmsc.tsgglobal.world/mms/templates/:id/send`

Uses an existing template and sends the MMS.

### **Request body**

| Name                                       | Type             | Description                                                                                            |
| ------------------------------------------ | ---------------- | ------------------------------------------------------------------------------------------------------ |
| `data.type`                                | string           | Must be `"mms-template-send-req"`                                                                      |
| `data.attributes.from`                     | string           | **Required.** Sender number (E.164)                                                                    |
| `data.attributes.to`                       | array of strings | **Required.** Recipient numbers (E.164)                                                                |
| `data.attributes.params`                   | object           | **Required.** Key-value map of placeholder values. Must match all placeholders defined in the template |
| `data.attributes.transaction_id`           | string           | Optional. Client-provided transaction identifier                                                       |
| `data.attributes.request_delivery_reports` | boolean          | Optional. Requesting DLR for the message to be sent to you. Defaults to false. Default: `false`        |
| `data.attributes.metadata`                 | object           | Optional. Additional metadata (default: `{}`)                                                          |

### Example

#### Example request

```json
{
  "data": {
    "type": "mms-template-send-req",
    "attributes": {
      "from": "18003004001",
      "to": ["17818434375"],
      "params": {
        "name": "Jane",
        "company": "TSG"
      }
    }
  }
}
```

#### Example response

```json
{
  "data": {
    "attributes": {
      "messages": [
        {
          "to": "17818434375",
          "message_id": "035273d3-c20d-47ee-9d4c-7b732d36fbe0"
        }
      ],
      "from": "18003004001",
      "parts": [
        {
          "kind": "plain",
          "content_type": "text/plain",
          "transfer_encoding": "identity",
          "content_encoding": "identity"
        },
        {
          "kind": "uri",
          "transfer_encoding": "identity",
          "content_encoding": "identity",
          "content_location": "brochure.txt"
        },
        {
          "kind": "uri",
          "transfer_encoding": "identity",
          "content_encoding": "identity",
          "content_location": "unnamed-1.png"
        }
      ],
      "to": [
        "17818434375"
      ],
      "inserted_at": "2026-03-20T19:53:33.795259",
      "subject": "Hello Jane",
      "headers": {},
      "expires_at": null,
      "transaction_id": "e261793b-da9a-400f-9231-22e736af4d1c"
    },
    "id": "e13b4f90-5a39-405d-a729-0f2b9bca9d60",
    "type": "mms-forward-res"
  }
}
```

### Example without placeholders

### Example request

```json
{
  "data": {
    "type": "mms-template-send-req",
    "attributes": {
      "from": "18003004001",
      "to": ["17818434375"],
      "params": {}
    }
  }
}
```

### Example response

```json
{
  "data": {
    "attributes": {
      "messages": [
        {
          "to": "17818434375",
          "message_id": "035273d3-c20d-47ee-9d4c-7b732d36fbe0"
        }
      ],
      "from": "18003004001",
      "parts": [
        {
          "kind": "plain",
          "content_type": "text/plain",
          "transfer_encoding": "identity",
          "content_encoding": "identity"
        },
        {
          "kind": "uri",
          "transfer_encoding": "identity",
          "content_encoding": "identity",
          "content_location": "unnamed-1.png"
        }
      ],
      "to": [
        "17818434375"
      ],
      "inserted_at": "2026-03-20T19:53:33.795259",
      "subject": "New deals!",
      "headers": {},
      "expires_at": null,
      "transaction_id": "e261793b-da9a-400f-9231-22e736af4d1c"
    },
    "id": "e13b4f90-5a39-405d-a729-0f2b9bca9d60",
    "type": "mms-forward-res"
  }
}
```

---

# List MMS templates

Source: https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/list-mms-templates
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/list-mms-templates.md
Last updated: 2026-03-23T16:14:12.457Z

GET /mms/templates: list every MMS template on the account.

<mark style="color:$success;">`GET`</mark> `https://mmsc.tsgglobal.world/mms/templates`

Returns all the templates for the account.

### Example response

```json
{
  "data": [
    {
      "attributes": {
        "name": "visit-thank-you",
        "parts": [
          {
            "metadata": {},
            "uri": "https://content-mms.staging.smshub.world/templates/491aa990-1fbb-4058-8af0-c78049010d2f/attachments/1-brochure.txt",
            "headers": {},
            "content_type": "text/plain",
            "content_location": "brochure.txt"
          },
          {
            "metadata": {},
            "uri": "https://content-mms.staging.smshub.world/templates/491aa990-1fbb-4058-8af0-c78049010d2f/attachments/2-unnamed-1.png",
            "headers": {},
            "content_type": "image/png",
            "content_location": "unnamed-1.png"
          }
        ],
        "inserted_at": "2026-03-20T19:53:02.165449",
        "updated_at": "2026-03-20T19:53:02.165449",
        "placeholders": [
          "name",
          "company"
        ],
        "body_template": "Dear {name}, welcome to {company}.",
        "subject_template": "Hello {name}"
      },
      "id": "491aa990-1fbb-4058-8af0-c78049010d2f",
      "type": "mms-template"
    },
    {
      "attributes": {
        "name": "visit-thank-you",
        "parts": [
          {
            "metadata": {},
            "uri": "https://content-mms.staging.smshub.world/185f821e-aac8-4296-88f4-035f155087f5/templates/1-brochure.txt",
            "headers": {},
            "content_type": "text/plain",
            "content_location": "brochure.txt"
          },
          {
            "metadata": {},
            "uri": "https://content-mms.staging.smshub.world/185f821e-aac8-4296-88f4-035f155087f5/templates/2-unnamed-1.png",
            "headers": {},
            "content_type": "image/png",
            "content_location": "unnamed-1.png"
          }
        ],
        "inserted_at": "2026-03-20T17:08:33.315490",
        "updated_at": "2026-03-20T17:08:33.315490",
        "placeholders": [
          "name",
          "company"
        ],
        "body_template": "Dear {name}, welcome to {company}.",
        "subject_template": "Hello {name}"
      },
      "id": "185f821e-aac8-4296-88f4-035f155087f5",
      "type": "mms-template"
    },
    {
      "attributes": {
        "name": "visit-thank-you",
        "parts": [
          {
            "metadata": {},
            "uri": "https://content-mms.staging.smshub.world/0a4cfbcc-533f-4a87-aed7-e49bdfc20025/templates/1-brochure.txt",
            "headers": {},
            "content_type": "text/plain",
            "content_location": "brochure.txt"
          }
        ],
        "inserted_at": "2026-03-20T16:53:12.572326",
        "updated_at": "2026-03-20T16:53:12.572326",
        "placeholders": [
          "name",
          "company"
        ],
        "body_template": "Dear {name}, welcome to {company}.",
        "subject_template": "Hello {name}"
      },
      "id": "0a4cfbcc-533f-4a87-aed7-e49bdfc20025",
      "type": "mms-template"
    }
  ]
}
```

---

# Get Single MMS template

Source: https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/get-single-mms-template
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/get-single-mms-template.md
Last updated: 2026-03-23T16:14:12.457Z

GET /mms/templates/:id: fetch one MMS template with its placeholders and attachments.

<mark style="color:$success;">`GET`</mark> `https://mmsc.tsgglobal.world/mms/templates/:id`

Returns a single template by ID.

### Example response

```json
{
  "data": {
    "attributes": {
      "name": "visit-thank-you",
      "parts": [
        {
          "metadata": {},
          "uri": "https://content-mms.staging.smshub.world/templates/491aa990-1fbb-4058-8af0-c78049010d2f/attachments/1-brochure.txt",
          "headers": {},
          "content_type": "text/plain",
          "content_location": "brochure.txt"
        },
        {
          "metadata": {},
          "uri": "https://content-mms.staging.smshub.world/templates/491aa990-1fbb-4058-8af0-c78049010d2f/attachments/2-unnamed-1.png",
          "headers": {},
          "content_type": "image/png",
          "content_location": "unnamed-1.png"
        }
      ],
      "inserted_at": "2026-03-20T19:53:02.165449",
      "updated_at": "2026-03-20T19:53:02.165449",
      "placeholders": [
        "name",
        "company"
      ],
      "body_template": "Dear {name}, welcome to {company}.",
      "subject_template": "Hello {name}"
    },
    "id": "491aa990-1fbb-4058-8af0-c78049010d2f",
    "type": "mms-template"
  }
}
```

---

# Delete MMS Template

Source: https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/delete-mms-template
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-mms/send-an-mms-message-using-templates/delete-mms-template.md
Last updated: 2026-03-23T16:25:55.606Z

DELETE /mms/templates/:id: remove an MMS template. Returns 204 No Content.

<mark style="color:$danger;">`DELETE`</mark> `https://mmsc.tsgglobal.world/mms/templates/:id`

Deletes a MMS template. Returns `204 No Content` on success.

---

# Receive an MMS Message

Source: https://support.tsgglobal.com/docs/api-reference/programmable-mms/receive-an-mms-message
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-mms/receive-an-mms-message.md
Last updated: 2026-03-23T16:25:55.606Z

Receive inbound MMS by HTTP webhook or MM4: routing address formats, request headers, payload, acknowledgement and retry rules.

## Overview

Get your message returned via SMTP or via a webhook URL that you provide.

## Routing Address

When requesting routing for your MMS messages, you may either specify an MM4 (SMTP) or HTTP endpoint.

It’s possible to provide Basic authentication details with the routing address:

HTTP Routing Address

`(http|https)://[<username>:<password>@]<hostname>[:<port>][/*<path>]`&#x20;

**Examples**

* `http://example.com/inbound_messages`
* `http://username:password@example.com:8080/inbound_messages`
* `https://johndoe:secret@example.com:8080/messages/mms/tsg_inbound`

MM4 Routing Address

`mm4://[<username>:<password>@]<hostname>[:<port>]`

**Examples**

* `mm4://example.com:2526`
* `mm4://johndoe:secret@example.com:2526`

## Webhook Format

All requests are made using the POST HTTP Verb to the specified endpoint.

Similar to the HTTP API, the webhook uses the very same format for delivering messages.

The request will include the following headers:

```http
Accept: application/json
Content-Type: application/json
User-Agent: Marshmallow/prod-x.y.z
X-Session-ID: aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa
```

**NOTE:** additional headers may be included that are not listed here.

## Webhook Response

When responding to the webhook request, respond with a 2xx status, more specifically:

* 200 OK
* 202 Accepted
* 204 No Content

Any of these statuses will be accepted as an acknowledgement of receive.

Otherwise the MMS system will assume delivery failed and will retry an additional 2 times within it’s current timeframe. If this fails once more, the message will be placed unto the retry and tried at a later time. The message will be retried a total of 20 times with an exponential backoff.

Once a message is received by the system and it’s routing is determined, it cannot be re-routed.

**Note:** All messages will keep their routing, changing a did’s routing will NOT affect messages already in-flight, this ensures that a message meant for an old endpoint will be delivered to that endpoint and nowhere else.

## Example Response

```
{
  "data": [
    {
      "attributes": {
        "expires_at": null,
        "from": "14252437709",
        "headers": {
          "to": [
            "+13462239287/TYPE=PLMN@mmsc.tsgglobal.world"
          ]
        },
        "inserted_at": "2022-04-06T21:50:06.316116",
        "metadata": {},
        "parts": [
          {
            "body": null,
            "content_encoding": "identity",
            "content_length": null,
            "content_location": "476CC8E7CD30DBE0..unk",
            "content_type": "application/smil",
            "decoded": false,
            "headers": {},
            "id": "7a1ebff0-a8b7-4a24-b951-85b04ac6855a",
            "kind": "uri",
            "metadata": {},
            "transfer_encoding": "identity",
            "uri": "https://content.mms.smshub.world/prod/7160ce4c-0205-4e47-9eb7-3954991911c2/parts/476CC8E7CD30DBE0..unk"
          },
          {
            "body": null,
            "content_encoding": "identity",
            "content_length": null,
            "content_location": "image0000.JPG",
            "content_type": "image/jpeg",
            "decoded": false,
            "headers": {},
            "id": "7c2459ec-95b9-454d-8d9a-0293442b6459",
            "kind": "uri",
            "metadata": {},
            "transfer_encoding": "identity",
            "uri": "https://content.mms.smshub.world/prod/7160ce4c-0205-4e47-9eb7-3954991911c2/parts/photo.JPG"
          }
        ],
        "pool_name": null,
        "request_delivery_reports": false,
        "subject": "",
        "to": [
          "13462239287"
        ],
        "transaction_id": "74def178-695b-4f04-9acd-efb3b0e7dab9",
        "version": "2020-01-14"
      },
      "id": "61d55de8-8ccd-4bf3-8b51-848a8c21919b",
      "type": "mms-forward-req"
    }
  ]
}
```

---

# Receive DLRs

Source: https://support.tsgglobal.com/docs/api-reference/programmable-mms/receive-dlrs
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-mms/receive-dlrs.md
Last updated: 2023-12-05T09:20:57.619Z

MMS delivery reports: status codes, webhook headers and payload, and how retries work.

## Overview

You can receive DLR messages via SMTP or HTTP webhook on the same URL as regular messages. The original message is referenced in the `message_id` attribute. DLRs are only sent for messages submitted with `request_delivery_reports: true`.

## DLR status codes

| status code   | Description                                                                                                                                                            |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Deferred      | The handset has retrieved the MMS header, but has not downloaded the full message from the mobile network. The handset may still download the message at a later time. |
| Expired       | The handset did not retrieve the message before the message expiration time.                                                                                           |
| Forwarded     | The message has been sent successfully to the mobile network.                                                                                                          |
| Indeterminate | The mobile network could not determine if the message was delivered correctly.                                                                                         |
| Rejected      | The message has been rejected by the MMS gateway or mobile network.                                                                                                    |
| Retrieved     | The message was successfully delivered to the handset and the handset was configured to acknowledge the message with a delivery receipt.                               |
| Unrecognised  | The handset of the mobile subscriber does not recognize the message content.                                                                                           |

## Webhook Format

All requests are made using the POST HTTP Verb to the specified endpoint.

The request will include the following headers:

```http
Accept: application/json
Content-Type: application/json
User-Agent: Marshmallow/prod-x.y.z
X-Session-ID: aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa
```

**NOTE:** additional headers may be included that are not listed here.

Example payload:

```json
{
    "data": [
        {
            "id": "465542bf-6cf0-4023-8c72-cc9eede0ce01",
            "type": "mms-delivery-report-res",
            "attributes": {
                "id": "465542bf-6cf0-4023-8c72-cc9eede0ce01",
                "message_id": "9f3a72e9-7dc2-4741-96c7-ff2049b49b11",
                "mm_status_code": "Retrieved",
                "from": "12345678912",
                "to": [
                    "+92345678912/TYPE=PLMN"
                ],
                "transaction_id": "baf01b87-b987-4625-ae56-2ed506c41f7a"
            }
        }
    ]
}
```

## Webhook Response

You must respond with a 2xx status code to acknowledge the DLR message.

If you respond with a 5xx status code the MMS system will retry delivery later with an exponential backoff, similar to MMS delivery.

3xx and 4xx status codes will be considered as a permanent failure and we won't attempt re-delivery.

---

# SMTP

Source: https://support.tsgglobal.com/docs/api-reference/programmable-mms/smtp
Markdown: https://support.tsgglobal.com/docs/api-reference/programmable-mms/smtp.md
Last updated: 2023-04-13T17:42:48.000Z

Send MMS over MM4/SMTP: endpoints and ports, AUTH LOGIN/PLAIN with your SMPP system ID and API key, supported commands and an example exchange.

## Overview

It is possible to send MMS messages via SMTP using the MM4 services instead of the HTTP API.

## Authentication

MM4 servers support PLAIN and LOGIN AUTH mechanism.

Use the provided SMPP system\_id as the username, and the API Key as the password.

System IDs are normally 15 characters in length

## Available MM4 Endpoints

**TCP**

* `mmsc.tsgglobal.world:2525`

**TLS/SSL**

* `mmsc.tsgglobal.world:2465`

It is recommended to utilize the TLS port when capable. TLS supports versions 1.1 and 1.2.

## MM4 Commands

* `AUTH` - Mandatory
* `DATA` - Mandatory
* `EHLO` - Mandatory
* `HELO` - Available
* `MAIL` - Mandatory
* `NOOP` - Available, use to test if the connection is working
* `QUIT` - Available, optional, closing the connection also works
* `RCPT` - Mandatory
* `RSET` - Available
* `STARTTLS` - Disabled, use the TLS port instead
* `VRFY` - Unimplemented, and would be disabled

## MM4 Exchange Example

All lines must end with a `CRLF`. Some data has been omitted for brevity.

Note, arrows `> <` have been included in the example to denote origin of message.

* `>` Is a response from the server
* `<` Is input from the client

```
#
< NOOP
> 250 OK
< EHLO your_hostname
> MM4 server babble
< AUTH LOGIN
> 334 VXNlcm5hbWU6
< base64-encoded-system-id
> 334 UGFzc3dvcmQ6
< base64-encoded-api-key
> 235 Authentication successful
< MAIL FROM:<E164-number@hostname>
> 250 Sender OK
< RCPT TO:<E164-number@hostname>
> 250 Recipient OK
< DATA
> 354 enter mail, end with line containing only '.'
< your-mms-content-here
< .
> 250 queued as <message-id>
< QUIT
> 221 BYE
```

Note the order of the commands:

* AUTH must be used before MAIL and RCPT.
* RCPT can only be used after a MAIL command.
* DATA can only be used after a MAIL and RCPT commands.
* QUIT, NOOP can be used at anytime (except while entering mail.)

Failure to do so will result in various errors

```
#
# AUTH before HELO
503 ERROR: send EHLO first

# RCPT or MAIL before EHLO
503 ERROR: send EHLO or HELO first

# RCPT before MAIL
503 ERROR: send MAIL first

# DATA before MAIL
503 ERROR: need MAIL command

# DATA before RCPT
503 ERROR: need RCPT command
```

<br>

---

# Phone Numbers

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers.md
Last updated: 2024-04-30T19:19:39.542Z

Get new numbers and manage existing numbers on your account.

---

# Search For New Available Numbers

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/search-for-new-available-numbers
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/search-for-new-available-numbers.md
Last updated: 2024-10-04T10:39:10.708Z

GraphQL numbers query: find local numbers by state and rate center or by NPANXX prefix, up to 100 at a time.

## Overview

Use this API to find a new local numbers that you can instantly use for messaging and voice. We allow users to search for numbers based on a contains field (NPANXX), or based on state + ratecenter. We allow you to search for consecutive numbers, and let you specify a quantity of numbers (up to 100 at a time).

These local numbers are instantly available for voice and SMS, or MMS (if you manually enable MMS on these numbers).



> **Info**


**Note:** this is for long-code numbers only, for toll-free numbers check this section:

[Toll-free phone numbers - search & ordering](https://support.tsgglobal.com/docs/api-reference/phone-numbers/toll-free-phone-numbers-search-and-ordering.md).



## Authentication



> **Info**


This function is available via our new GraphQL API. You can read more about how to authenticate to this API [here](https://support.tsgglobal.com/docs/graphql-api-and-authentication.md).



## Example Query Using State and Rate Center

```
query {
  numbers(state: "MA", rateCenter:"BOSTON", quantity: 5, consecutive:false) {
    numbers {
      city
      telephoneNumber
      province
      e911Allowed
      mmsAllowed
    }
  }
}
```

## Example Response

```
{
  "data": {
    "numbers": {
      "numbers": [
        {
          "city": "Chelsea",
          "e911Allowed": "Y",
          "mmsAllowed": "Y",
          "province": "MA",
          "telephoneNumber": "8572391650"
        },
        {
          "city": "Chelsea",
          "e911Allowed": "Y",
          "mmsAllowed": "Y",
          "province": "MA",
          "telephoneNumber": "8572391651"
        },
        {
          "city": "Chelsea",
          "e911Allowed": "Y",
          "mmsAllowed": "Y",
          "province": "MA",
          "telephoneNumber": "8572391653"
        },
        {
          "city": "Chelsea",
          "e911Allowed": "Y",
          "mmsAllowed": "Y",
          "province": "MA",
          "telephoneNumber": "8572391654"
        },
        {
          "city": "Chelsea",
          "e911Allowed": "Y",
          "mmsAllowed": "Y",
          "province": "MA",
          "telephoneNumber": "8572391655"
        }
      ]
    }
  }
}
```

## Example Query Using Contains

```
query {
  numbers(contains: "425", quantity: 5, consecutive:false) {
		numbers {
      city
      telephoneNumber
      province
      e911Allowed
      mmsAllowed
    }
  }
}
```

## Example Response

```
{
  "data": {
    "numbers": {
      "numbers": [
        {
          "city": "Everett",
          "e911Allowed": "Y",
          "mmsAllowed": "Y",
          "province": "WA",
          "telephoneNumber": "4253864153"
        },
        {
          "city": "Everett",
          "e911Allowed": "Y",
          "mmsAllowed": "Y",
          "province": "WA",
          "telephoneNumber": "4253864154"
        },
        {
          "city": "Everett",
          "e911Allowed": "Y",
          "mmsAllowed": "Y",
          "province": "WA",
          "telephoneNumber": "4253864157"
        },
        {
          "city": "Everett",
          "e911Allowed": "Y",
          "mmsAllowed": "Y",
          "province": "WA",
          "telephoneNumber": "4253864159"
        },
        {
          "city": "Everett",
          "e911Allowed": "Y",
          "mmsAllowed": "Y",
          "province": "WA",
          "telephoneNumber": "4253864163"
        }
      ]
    }
  }
}
```

---

# Add Number to Cart

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/add-number-to-cart
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/add-number-to-cart.md
Last updated: 2024-10-04T09:30:06.547Z

GraphQL numbersReserve mutation: reserve up to 100 searched numbers in your cart before checkout.

## Overview

Reserve up to 100 numbers at any time in your cart.

## Authentication



> **Info**


This function is available via our new GraphQL API. You can read more about how to authenticate to this API [here](https://support.tsgglobal.com/docs/graphql-api-and-authentication.md).



## Example Mutation

```
mutation ReserveNumbers($numbers: [String]) {
  numbersReserve(numbers: $numbers) {
    reserved
    reservedTotal
    excluded
    excludedTotal
    requested
    requestedTotal
  }
}
```

### Query Variables

```
{
  "numbers": ["8572144932", "8572144940"]
}
```

## Example Response

```
{
  "data": {
    "numbersReserve": {
      "excluded": [],
      "excludedTotal": 0,
      "requested": [
        "8572391650",
        "8572391651"
      ],
      "requestedTotal": 2,
      "reserved": [
        "8572391651",
        "8572391650"
      ],
      "reservedTotal": 2
    }
  }
}
```

---

# Get Reserved Numbers In Cart

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/get-reserved-numbers-in-cart
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/get-reserved-numbers-in-cart.md
Last updated: 2024-10-04T09:30:06.467Z

GraphQL reservedList query: see the numbers currently reserved in your cart.

## Overview

View all the numbers currently reserved in your cart.

## Authentication



> **Info**


This function is available via our new GraphQL API. You can read more about how to authenticate to this API [here](https://support.tsgglobal.com/docs/graphql-api-and-authentication.md).



## Example Query

```
query {
  reservedList {
      numbers {
      telephoneNumber
      city
      lata
    }
  }
}
```

## Example Response

```
{
  "data": {
    "reservedList": {
      "numbers": [
        {
          "city": "BOSTON",
          "lata": "128",
          "telephoneNumber": "8572391650"
        },
        {
          "city": "BOSTON",
          "lata": "128",
          "telephoneNumber": "8572391651"
        }
      ]
    }
  }
}
```

---

# Remove Reserved Number From Cart

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/remove-reserved-number-from-cart
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/remove-reserved-number-from-cart.md
Last updated: 2024-10-04T09:30:06.487Z

GraphQL releaseReserved mutation: release reserved numbers you no longer want.

## Overview

Remove reserved numbers you no longer want from your cart.

## Authentication



> **Info**


This function is available via our new GraphQL API. You can read more about how to authenticate to this API [here](https://support.tsgglobal.com/docs/graphql-api-and-authentication.md).



## Example Mutation

```
mutation CartRemove($numbers:[String]) {
  releaseReserved(numbers:$numbers) {
    excluded
    excludedCount
    releasedCount
    totalCount
  }
}
```

### Query Variables

```
{
  "numbers": ["8572391651"]
}
```

## Example Response

```
{
  "data": {
    "releaseReserved": {
      "excluded": [],
      "excludedCount": 0,
      "releasedCount": 1,
      "totalCount": 1
    }
  }
}
```

---

# Checkout Numbers in Cart

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/checkout-numbers-in-cart
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/checkout-numbers-in-cart.md
Last updated: 2024-10-04T09:06:42.119Z

GraphQL numbersOrder mutation: purchase every number reserved in your cart and add it to your account.

## Overview

Checkout and purchase all of the currently reserved numbers in your cart.

## Authentication



> **Info**


This function is available via our new GraphQL API. You can read more about how to authenticate to this API [here](https://support.tsgglobal.com/docs/graphql-api-and-authentication.md).



## Example Mutation

This function will add all the numbers currently reserved in your cart to your TSG Global account.

```
mutation OrderNumbers {
  numbersOrder {
    orderId
    items {
      tn
      trunkGroup
      tnNote
    }
  }
}
```

### Example Response

```
{
  "data": {
    "numbersOrder": {
      "items": [
        {
          "tn": "8572391650",
          "tnNote": null,
          "trunkGroup": null
        }
      ],
      "orderId": 0
    }
  }
}
```

---

# Disconnect Number

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/disconnect-number
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/disconnect-number.md
Last updated: 2024-10-04T09:30:06.547Z

GraphQL disconnectNumbers mutation: release a number from your account, subject to the 90-day holding requirement.

## Overview

Disconnect a number currently assigned to your account.

## Authentication



> **Info**


This function is available via our new GraphQL API. You can read more about how to authenticate to this API [here](https://support.tsgglobal.com/docs/graphql-api-and-authentication.md).



Per your MSA, there is a 90 day number holding requirement. You can not specify a disconnect date, and the number will be disconnected at the earliest possible time (immediately if outside of the 90 day window).

## Example Mutation

```
# if a number is 12345600000
mutation {
  disconnectNumbers(numbers: ["12345600000"]) {
    internalId
    orderId
    orderName
    requests {
      disconnectAt
      numbers
      requestId
      requestName
      requestNotes
    }
  }
}
```

### Example Response

This is an example of a response - this one will disconnect right away (a disconnectAt timestamp is provided to provide some info for the user):

```
{
  "data": {
    "disconnectNumbers": {
      "internalId": "999000053-ORD",
      "orderId": "a0d0512f-7b61-4517-9e23-fd708344d52e",
      "orderName": "Disconnect order",
      "requests": [
        {
          "disconnectAt": "2021-09-21T13:52:36.664129Z",
          "numbers": [
            "15013929384"
          ],
          "requestId": "2551e1c6-b99b-469a-b4b0-10439685f536",
          "requestName": "Disconnect request",
          "requestNotes": "Disconnect request will be executed right away"
        }
      ]
    }
  }
}
```

Another response example - this one has a delayed disconnect request:

```
{
  "data": {
    "disconnectNumbers": {
      "internalId": "999000030-ORD",
      "orderId": "bf8a1a4d-9d4c-48e6-9feb-720bb3fc529e",
      "orderName": "Disconnect order",
      "requests": [
        {
          "disconnectAt": "2021-09-15T23:49:59.000000Z",
          "numbers": [
            "15013929405"
          ],
          "requestId": "f9cd9320-a32f-43d6-bcf3-90652446e3a5",
          "requestName": "Delayed disconnect request",
          "requestNotes": "Disconnect request delayed due to too recent activation date (90 day disconnect rule)"
        }
      ]
    }
  }
}
```

<br>

---

# Get Number Information

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/get-number-information
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/get-number-information.md
Last updated: 2024-10-01T21:11:17.085Z

Look up a number's SMS/MMS configuration and 10DLC status (GET /v5/dids/\<number>), or its rate center, routing and activation data (GET /v1/did/lookup).

## Overview

Get basic information relating to a number, including rate center, state, sms enablement, and other data.

## Authentication



> **Info**


Authentication is done by passing your TSG Global API key via the Authorization header in the format "Authorization: Bearer \<api\_key>"



## SMS and MMS Configuration Method

## Returns information about the did (currently SMS and MMS configuration only).

<mark style="color:blue;">`GET`</mark> `https://api-service.tsgglobal.world/v5/dids/<number>`

Please ensure that your client processes only recognized properties from the response, as new properties may be added without prior notice. All added props will be documented here.

#### Path Parameters

| Name                                     | Type   | Description                    |
| ---------------------------------------- | ------ | ------------------------------ |
| number<mark style="color:red;">\*</mark> | string | The number that was looked up. |





### 200: OK 


Each property below lists its possible values.

```json
{
    "number": "13603556404",
    "number_type": "long-code" | "short-code" | "toll-free",
    "mms_enabled": true | false,
    "mms_uri": "mm4://hooks.staging.tsgglobal.com",
    "sms_enabled": true | false,
    "campaign_id": null | "C12345",
    "compliance_status": "non_compliant" | "pending" | "compliant",
    "sms_status": "NONE" | "PENDING" | "ACTIVE" | "ERROR" | "DSBL-PND",
    "use_case_type": "" | "p2p" | "a2p",
    "nnid": "" | "12345" | null,
    "sms_post_ver": "smpp" | "postv1" | "postv2" | "post3jam",
    "sms_uri": null | "https://hooks.staging.tsgglobal.com",
    "x_api_key_header": null | "" | "abcd1234",
    "ten_dlc_registered": true | false,
    "tmobile_ten_dlc_registered": true | false
}
```

Possible `sms_status` values:

* `N/A` or `NONE`: number not SMS enabled
* `PENDING`: number pending to be enabled
* `DSBL-PND`: number pending to be disabled
* `ACTIVE`: number SMS enabled
* `ERROR`: unable to SMS enable number, contact support
  

  


## Additional Data Method

## Lookup additional phone number information.

<mark style="color:blue;">`GET`</mark> `https://api-service.tsgglobal.world/v1/did/lookup?did=<1NPANXXXXXX>`

If the `did` parameter is omitted all numbers on the matching account will be listed one per line.

#### Query Parameters

| Name | Type   | Description                                                 |
| ---- | ------ | ----------------------------------------------------------- |
| did  | string | `1NPANXXXXXX`, `+NPANXXXXXX`, `12022011234`, `+12022011234` |





### 200: OK 



```csv
DID, ROUTING INFO, ACTIVATION DATE, LAST USED DATE, SEC USED, DID RATE, ORDER ID, RATE CENTER, STATE, TIER, PORTED, SMS ENABLED, SMS STATUS, SMS POST VERSION, SMS POST URL, PROVISIONING DATA, MAX CHANNELS
"17867469428","SIP/XXXX","2022-01-11 00:00:00","2022-05-01 00:00:01","0","0.0030000000","CUS9079-SMS","MIAMI","FL","0","N","t","ACTIVE","postv1","","ppm-did-billing-RFC2833-no+","2000"
```

---

# Manage Number for SMS & 10DLC

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-sms-and-10dlc
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-sms-and-10dlc.md
Last updated: 2024-11-08T23:58:10.377Z

Enable or disable SMS on a number, attach a 10DLC campaign, and set the inbound SMS webhook.

---

# Enable SMS/10DLC on a Number

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-sms-and-10dlc/enable-sms-10dlc-on-a-number
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-sms-and-10dlc/enable-sms-10dlc-on-a-number.md
Last updated: 2026-01-27T20:49:52.926Z

POST /v2/sms-enablement: enable SMS on a number, choose the inbound webhook format, and assign a 10DLC campaign.

## Overview

This method allows you to enable SMS on (almost) any number with TSG Global.



> **Success**


Numbers that are searched and ordered in your cart are already SMS enabled, and you do not need to perform this function to make them SMS enabled.



## Authentication



> **Info**


Authentication is done by passing your TSG Global API key via the Authorization header in the format "Authorization: Bearer \<api\_key>"



## Method

## Enable SMS on a phone number.

<mark style="color:green;">`POST`</mark> `https://api-service.tsgglobal.world/v2/sms-enablement`

#### Request Body

| Name                                     | Type   | Description                                                                                                                                                                                                                                           |
| ---------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| did<mark style="color:red;">\*</mark>    | String | The DID you would like to modify"                                                                                                                                                                                                                     |
| action<mark style="color:red;">\*</mark> | String | \[add \| update] (use update if you need to ammend information for already SMS-enabled number - eg. change webhook url or add campaign id)                                                                                                            |
| use\_case\_type                          | String | \[a2p \| p2p \| account\_default] - p2p can be used only if you have p2p use-case approved                                                                                                                                                            |
| p2p\_nnid                                | String | to be used with use\_case\_type p2p and approved nnid for p2p traffic                                                                                                                                                                                 |
| mms\_enable                              | String | \[true \| false] - if not set, account default value will be used                                                                                                                                                                                     |
| mms\_routing                             | String | http, https, mm4, mm4s url to deliver inbound mms to - if not set, account default value will be used                                                                                                                                                 |
| webhook\_url                             | String | http or https SMS webhook url if you want inbound SMS delivered via webhook (leave blank for SMPP or account default value)                                                                                                                           |
| webhook\_type                            | String | \[smpp, postv1, postv2, post3jam] - leave blank for account default settings. It determines inbound message format. postv2 recommended for http(s) deliveries (if webhook url set)                                                                    |
| x\_api\_key\_header                      | String | This value will be passed as x-api-key header in the webhook http call. Can be used to secure your webhook API. (should not be provided if webhook\_type is smpp)                                                                                     |
| campaign\_id                             | String | If the number is needs to be 10DLC registered and assigned to an active campaign, the campaign id should be provided here to complete 10DLC provisioning. Note: sole proprietor campaigns only allow 1 number at a time.                              |
| campaign\_sub\_id                        | String | In case your campaign is associated with the sub id please provide one. Otherwise, do not provide this parameter.                                                                                                                                     |
| skip\_number\_validation                 | String | Setting this optional prop to "true" allows you to provision number that you provided LOA for and you got confirmation from TSG team that it was accepted. Using this prop without TSG confirmation will have no effect - your request will be stale. |



> **Info**


Please be aware that this API endpoint has strict parameter parsing. In case an unknown or invalid parameter is provided in the request body, the request will be rejected with an error.







### 200: OK Success



```javascript
Success
```

---

# Disable SMS on a Number

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-sms-and-10dlc/disable-sms-on-a-number
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-sms-and-10dlc/disable-sms-on-a-number.md
Last updated: 2026-01-27T20:49:52.926Z

Remove SMS capability from a phone number with the sms-enablement endpoint (action: delete).

## Overview

This method allows you to remove SMS functionality from a number.

## Authentication



> **Info**


Authentication is done by passing your TSG Global API key via the Authorization header in the format "Authorization: Bearer \<api\_key>"



## Method

## Disable SMS on a DID.

<mark style="color:green;">`POST`</mark> `https://api-service.tsgglobal.world/v2/sms-enablement`

#### Request Body

| Name                                     | Type   | Description                     |
| ---------------------------------------- | ------ | ------------------------------- |
| did<mark style="color:red;">\*</mark>    | String | The DID you want to sms disable |
| action<mark style="color:red;">\*</mark> | String | `delete`                        |



> **Info**


Please be aware that this API endpoint has strict parameter parsing. In case an unknown or invalid parameter is provided in the request body, the request will be rejected with an error.







### 200: OK Success



```javascript
Success
```






## Example CURL

```bash
curl https://api-service.tsgglobal.world/v2/sms-enablement -XPOST -H "Authorization: Bearer <api_key>" \
-H "Content-Type: application/json" -d '{
  "did": "12003004000",
  "action": "delete"
}'
```

---

# Update inbound SMS webhook/URI

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-sms-and-10dlc/update-inbound-sms-webhook-uri
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-sms-and-10dlc/update-inbound-sms-webhook-uri.md
Last updated: 2026-01-27T20:50:27.289Z

Set or change the inbound SMS webhook URL, format and shared secret for a phone number, or switch the number back to SMPP delivery.

## Overview

This method allows you to update your inbound messaging webhook/URI for a phone number.



> **Danger**


If you are an HTTP API customer and do not use SMPP, `webhook_url` must be a fully qualified URL, for example `https://api.example.com/inbound-sms`.\
\
Leaving `webhook_url` blank or omitting it converts the number from HTTP POST delivery to SMPP delivery.\
\
Make sure you have SMPP credentials set up and tested before converting numbers to SMPP, otherwise inbound messages can be lost.



## Authentication



> **Info**


Authentication is done by passing your TSG Global API key via the Authorization header in the format "Authorization: Bearer \<api\_key>"



## Method

## Update per-DID configuration. Currently only the SMS webhook URL can be changed with this endpoint.

<mark style="color:green;">`POST`</mark> `https://api-service.tsgglobal.world/v1/sms/webhook`

#### Request Body

| Name                                  | Type   | Description                                                                                                                                                       |
| ------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| webhook\_url                          | String | e.g. <https://example.com/webhook>                                                                                                                                |
| did<mark style="color:red;">\*</mark> | String | DID you want to set/update SMS webhook endpoint for                                                                                                               |
| webhook\_type                         | String | postv2 (default) \| postv1 \| post3jam \| smpp                                                                                                                    |
| x\_api\_key\_header                   | String | This value will be passed as x-api-key header in the webhook http call. Can be used to secure your webhook API. (should not be provided if webhook\_type is smpp) |





### 200: OK 



```javascript
Success
```






## Example CURL

```bash
curl -n https://api-service.tsgglobal.world/v1/sms/webhook -XPOST -H "Authorization: Bearer <api_key>" \
-H "Content-Type: application/json" -d '{
  "webhook_url": "https://example.com/webhook",
  "did": "12003004000"
}'
```

---

# Manage Number for MMS

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-mms
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-mms.md
Last updated: 2024-12-06T17:09:24.404Z

Enable or disable MMS on a number and set where inbound MMS is delivered.

---

# Enable MMS on a Number

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-mms/enable-mms-on-a-number
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-mms/enable-mms-on-a-number.md
Last updated: 2024-12-06T17:09:24.398Z

POST /v2/dids/\<number>/mms/enable: turn on MMS for an SMS-enabled number and set its inbound HTTP(S) or MM4 URI.

## Overview

This method allows you to enable MMS on a phone number.



> **Danger**


As a prerequisite to use MMS, the number you are enabling must already be SMS enabled, and your account must have MMS enabled. Contact <support@tsgglobal.com> if you have any concerns.



## Authentication



> **Info**


Authentication is done by passing your TSG Global API key via the Authorization header in the format "Authorization: Bearer \<api\_key>"



## Method

<mark style="color:green;">`POST`</mark> `https://api-service.tsgglobal.world/v2/dids/<number>/mms/enable`

#### Path Parameters

| Name                                     | Type   | Description                             |
| ---------------------------------------- | ------ | --------------------------------------- |
| number<mark style="color:red;">\*</mark> | String | The phone number you want to MMS enable |

#### Request Body

| Name                                  | Type   | Description                                                                                                          |
| ------------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------- |
| uri<mark style="color:red;">\*</mark> | String | A URI pointing to the destination at which you want to receive the messages. Can either be HTTP(S) or an MMS server. |





### 200: OK 



```javascript
{
  "mms_enabled": true,
  "mms_uri": "http://mms.example.com",
  "number": "12342341234",
  "sms_enabled": true,
  "sms_uri": null # null means SMPP
}
```

---

# Disable MMS on a Number

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-mms/disable-mms-on-a-number
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-mms/disable-mms-on-a-number.md
Last updated: 2022-12-19T09:44:57.000Z

Turn off MMS on a phone number. The number keeps its SMS configuration.

## Overview

This method allows you to disable MMS on a phone number.

## Authentication



> **Info**


Authentication is done by passing your TSG Global API key via the Authorization header in the format "Authorization: Bearer \<api\_key>"



## Method

## Disable MMS on a phone number.

<mark style="color:green;">`POST`</mark> `https://api-service.tsgglobal.world/v2/dids/<number>/mms/disable`

#### Path Parameters

| Name                                     | Type   | Description                           |
| ---------------------------------------- | ------ | ------------------------------------- |
| number<mark style="color:red;">\*</mark> | string | The phone number you want to disable. |

The response is the number's updated SMS/MMS configuration, in the same shape as [Enable MMS on a Number](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-mms/enable-mms-on-a-number.md), with `mms_enabled` set to `false`.





### 200: OK 



```json
{
  "mms_enabled": false,
  "mms_uri": null,
  "number": "12342341234",
  "sms_enabled": true,
  "sms_uri": null
}
```






## Example CURL

```bash
curl https://api-service.tsgglobal.world/v2/dids/12342341234/mms/disable -XPOST -H "Authorization: Bearer <api_key>"
```

---

# Update inbound MMS webhook/URI

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-mms/update-inbound-mms-webhook-uri
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-mms/update-inbound-mms-webhook-uri.md
Last updated: 2022-12-19T10:21:15.000Z

Change the HTTP(S) or MM4 destination that receives inbound MMS for a phone number. Uses the same endpoint as Enable MMS.

## Overview

Update the webhook/URI for inbound MMS messages. This uses the same endpoint as [Enable MMS on a Number](https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-mms/enable-mms-on-a-number.md): calling it on a number that already has MMS enabled replaces the inbound URI.



> **Danger**


As a prerequisite to use MMS, the number must already be SMS enabled, and your account must have MMS enabled. Contact <support@tsgglobal.com> if you have any concerns.



## Authentication



> **Info**


Authentication is done by passing your TSG Global API key via the Authorization header in the format "Authorization: Bearer \<api\_key>"



## Method

To change where inbound MMS is delivered, call the endpoint below with the new `uri`.

<mark style="color:green;">`POST`</mark> `https://api-service.tsgglobal.world/v2/dids/<number>/mms/enable`

#### Path Parameters

| Name                                     | Type   | Description                                               |
| ---------------------------------------- | ------ | --------------------------------------------------------- |
| number<mark style="color:red;">\*</mark> | String | The phone number whose inbound MMS URI you want to update |

#### Request Body

| Name                                  | Type   | Description                                                                                                          |
| ------------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------- |
| uri<mark style="color:red;">\*</mark> | String | A URI pointing to the destination at which you want to receive the messages. Can either be HTTP(S) or an MMS server. |





### 200: OK 



```json
{
  "mms_enabled": true,
  "mms_uri": "http://mms.example.com",
  "number": "12342341234",
  "sms_enabled": true,
  "sms_uri": null
}
```






`sms_uri` of `null` means inbound SMS for the number is delivered over SMPP.

---

# Manage Number for Voice

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice.md
Last updated: 2024-04-30T19:19:39.067Z

List, add, update and delete the voice destination priorities (VoIP gateways or PSTN numbers) for your phone numbers.

---

# List Destination Priority

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice/list-destination-priority
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice/list-destination-priority.md
Last updated: 2023-02-15T12:25:01.000Z

List the voice destination priorities configured for your phone numbers (GET /v1/did/priority/lookup, CSV response).

## Overview

This method lets you list the voice destination priority for phone numbers.

## Authentication



> **Info**


Authentication is done by passing your TSG Global API key via the Authorization header in the format "Authorization: Bearer \<api\_key>"



## Method

## List destination priorities associated with your phone numbers.

<mark style="color:blue;">`GET`</mark> `https://api-service.tsgglobal.world/v1/did/priority/lookup`





### 200: OK 



```csv
DID,ROUTING INFO,PRIORITY,CALL TYPE
13603556939,SIP/+13603556939@SIP/13603556939@209.119.133.123,1,1
13603556939,SIP/13603556939@SIP/13603556939@209.119.133.123,2,1
13603556404,SIP/13603556404@8.30.173.27,1,1
13603556404,SIP/13603556404@8.36.70.27,2,1
```

---

# Add Destination Priority

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice/add-destination-priority
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice/add-destination-priority.md
Last updated: 2022-12-19T10:44:11.000Z

Add a voice destination (VoIP gateway or PSTN number) at priority 1–3 for a phone number.

## Overview

This method lets you add a voice destination priority for a phone number.

## Authentication



> **Info**


Authentication is done by passing your TSG Global API key via the Authorization header in the format "Authorization: Bearer \<api\_key>"



## Method

## Add a destination priority associated with a phone number.

<mark style="color:green;">`POST`</mark> `https://api-service.tsgglobal.world/v1/did/priority`

#### Request Body

| Name                                          | Type   | Description                                        |
| --------------------------------------------- | ------ | -------------------------------------------------- |
| did<mark style="color:red;">\*</mark>         | String | The phone number (e.g. 12022011234)                |
| priority<mark style="color:red;">\*</mark>    | String | 1-3 in order of preferred priority.                |
| destination<mark style="color:red;">\*</mark> | String | `192.168.1.1` (for VOIP), `16352321233` (for PSTN) |
| call\_type<mark style="color:red;">\*</mark>  | String | `VOIP`, `PSTN`                                     |
| call\_option                                  | String | `WP`, `NP`                                         |

For VOIP Call Type you need to enter just the IP Address of the Gateway and we will format the rest of the destination. For PSTN Call Type you need to just enter the PSTN Destination in E.164 format, with or without the leading plus.

`call_type` must be exactly one of `VOIP` (VoIP destination) or `PSTN` (PSTN destination). This value is case sensitive.

`call_option`: `NP` = DID sent to the gateway without a plus, `WP` = DID sent to the gateway with a plus. This value is case sensitive.

### Example POST (PSTN)

```bash
curl -n https://api-service.tsgglobal.world/v1/did/priority -XPOST -H "Authorization: Bearer <api_key>" \
-H "Content-Type: application/json" -d '{
  "did": "12003004000",
  "destination": "16352321233",
  "priority": 2,
  "call_type": "PSTN",
  "call_option": "NP"
}'
```

### Example POST (VOIP)

```bash
curl -n https://api-service.tsgglobal.world/v1/did/priority -XPOST -H "Authorization: Bearer <api_key>" \
-H "Content-Type: application/json" -d '{
  "did": "12003004000",
  "destination": "192.168.1.1",
  "priority": 3,
  "call_type": "VOIP",
  "call_option": "NP"
}'
```

## **Error Codes**

* `-1000` Invalid or Blank API Key
* `-1001` Invalid or Blank Call Option
* `-1003` Invalid or No DID Provided
* `-1004` Invalid or No Priority Provided
* `-1005` Invalid or No Destination Provided
* `-1006` Invalid or No Call Type Provided
* `-1007` Priority Already Exists Use Another Priority
* `-1008-V` Priority Added to Database as VoIP Destination
* `-1008-P` Priority Added to Database as PSTN Destination
* `-1010` Unknown Error Please Contact TSG Support with URL String for Review

---

# Update Destination Priority

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice/update-destination-priority
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice/update-destination-priority.md
Last updated: 2022-12-19T10:43:46.000Z

Change an existing voice destination priority for a phone number, optionally overriding the dialed number (DNIS) sent to your switch.

## Overview

This method allows you to update existing destination priorities for phone numbers.

## Authentication



> **Info**


Authentication is done by passing your TSG Global API key via the Authorization header in the format "Authorization: Bearer \<api\_key>"



## Method

## Update a destination priority associated with a phone number.

<mark style="color:purple;">`PATCH`</mark> `https://api-service.tsgglobal.world/v1/did/priority`

#### Request Body

| Name                                           | Type   | Description                                                                                                                                                                   |
| ---------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| did<mark style="color:red;">\*</mark>          | String | The phone number (e.g. 12022011234)                                                                                                                                           |
| priority<mark style="color:red;">\*</mark>     | String | 1-3 in order of preferred priority.                                                                                                                                           |
| destination<mark style="color:red;">\*</mark>  | String | `192.168.1.1` (for VOIP), `16352321233` (for PSTN)                                                                                                                            |
| call\_type<mark style="color:red;">\*</mark>   | String | `VOIP`, `PSTN`                                                                                                                                                                |
| call\_option<mark style="color:red;">\*</mark> | String | `WP`, `NP`                                                                                                                                                                    |
| dnis                                           | String | Number for TSG to send to your switch as the Dialed Number ID, e.g. `DID == 13605551212` but you want TSG to send you `3605551212` or `14085551212` instead of the DID number |

For VOIP Call Type you need to enter just the IP Address of the Gateway and we will format the rest of the destination. For PSTN Call Type you need to just enter the PSTN Destination in E.164 format, with or without the leading plus.

`call_type` must be exactly one of `VOIP` (VoIP destination) or `PSTN` (PSTN destination). This value is case sensitive.

`call_option`: `NP` = DID sent to the gateway without a plus, `WP` = DID sent to the gateway with a plus. This value is case sensitive.

### Example PATCH

```bash
curl -n https://api-service.tsgglobal.world/v1/did/priority -XPATCH -H "Authorization: Bearer <api_key>" \
-H "Content-Type: application/json" -d '{
  "did": "12003004000",
  "destination": "16352321233",
  "priority": 2,
  "call_type": "PSTN",
  "call_option": "NP"
}'
```

## **Error Codes**

* `-1000` Invalid or Blank API Key
* `-1001` Invalid or Blank Call Option
* `-1003` Invalid or No DID Provided
* `-1004` Invalid or No Priority Provided
* `-1005` Invalid or No Destination Provided
* `-1006` Invalid or No Call Type Provided
* `-1007` Priority Already Exists Use Another Priority
* `-1008-V` Priority Added to Database as VoIP Destination
* `-1008-P` Priority Added to Database as PSTN Destination
* `-1010` Unknown Error Please Contact TSG Support with URL String for Review

---

# Delete Destination Priority

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice/delete-destination-priority
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/manage-number-for-voice/delete-destination-priority.md
Last updated: 2022-12-19T10:43:11.000Z

Remove a voice destination priority (2 or 3) from a phone number. Priority 1 cannot be deleted through the API.

## Overview

This method allows you to remove destination priorities for phone numbers.

## Authentication



> **Info**


Authentication is done by passing your TSG Global API key via the Authorization header in the format "Authorization: Bearer \<api\_key>"



## Method

## Delete a destination priority associated with a phone number.

<mark style="color:red;">`DELETE`</mark> `https://api-service.tsgglobal.world/v1/did/priority`

#### Request Body

| Name                                       | Type   | Description                         |
| ------------------------------------------ | ------ | ----------------------------------- |
| did<mark style="color:red;">\*</mark>      | String | The phone number (e.g. 12022011234) |
| priority<mark style="color:red;">\*</mark> | String | 1-3 in order of preferred priority. |

## Example DELETE

```bash
curl -n https://api-service.tsgglobal.world/v1/did/priority -XDELETE -H "Authorization: Bearer <api_key>" \
-H "Content-Type: application/json" -d '{
  "did": "12003004000",
  "priority": 2
}'
```

## **Error Codes**

* `-1000` Invalid or Blank API Key
* `-1003` Invalid or No DID Provided
* `-1004` Invalid or No Priority Provided
* `-1007` Priority Does NOT Exist, Delete an already created priority.
* `-1008` Deleted Priority from Routing.
* `-1010` Can not Delete Priority 1, Please Submit a DID cancel request.

---

# Protect your phone number

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/protect-your-phone-number
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/protect-your-phone-number.md
Last updated: 2023-03-30T08:46:30.000Z

Have you ever experienced the discomfort and frustration of your phone number is changed to a different SMS carrier without your consent?

We offer a solution for that. With TSG you can protect messaging portion of your number from being SMS enabled with another SMS vendor in just a few clicks and get notified every time an attempt is made.\
If you would like to Text Protect your numbers, change the webhook notifications URL or remove protection for some of the numbers please reach out to <support@tsgglobal.com> and we will be happy to assist.\
\
For webhook API specification please check the [next page](https://support.tsgglobal.com/docs/api-reference/phone-numbers/protect-your-phone-number/textprotect-webhook.md).

---

# TextProtect Webhook

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/protect-your-phone-number/textprotect-webhook
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/protect-your-phone-number/textprotect-webhook.md
Last updated: 2023-03-30T08:23:02.000Z

Payload TSG posts to your URL whenever TextProtect blocks an attempt to move your number to another SMS provider, retried for 72 hours.

To receive notification on every unauthorized attempt for changing your number messaging provider please provide an URL that exposes HTTP POST endpoint and accepts the body model like in the example below.

```json
{
 "number": "1200300400",
 "sms_account": "TSG100000",
 "requester_nnid": "123456",
 "requester": "carrier",
 "timestamp": "2023-03-30T08:14:19.688501",
 "description": "Request rejected by TextProtect"
}
```

Please respond with 200 OK on success, otherwise, our webhook will retry for the next 72 hours with exponential backoff. If we are unable to deliver the webhook after 72 hours the retry will stop.&#x20;

---

# Toll-free phone numbers - search & ordering

Source: https://support.tsgglobal.com/docs/api-reference/phone-numbers/toll-free-phone-numbers-search-and-ordering
Markdown: https://support.tsgglobal.com/docs/api-reference/phone-numbers/toll-free-phone-numbers-search-and-ordering.md
Last updated: 2024-10-04T10:35:50.869Z

Shows how to search and order toll-free numbers.

Use this API to find new toll-free numbers. We allow users to search for numbers based on a contains field. We allow you to search for consecutive numbers, and let you specify a quantity of numbers (up to 10 at a time).

To use Toll-free numbers there's only 2 steps - search and order, no reservation or checkout necessary.

## Authentication



> **Info**


This function is available via our new GraphQL API. You can read more about how to authenticate to this API [here](https://support.tsgglobal.com/docs/graphql-api-and-authentication.md).



## Search for toll-free numbers

To search for numbers use the `searchPhoneNumbersQuery` GraphQL query, it'll return a list of numbers you can order. The numbers aren't reserved, so maybe they won't be available until you decide to order, in that case, just search for new numbers.

```graphql
query searchPhoneNumbersQuery(
  $contains: String
  $quantity: Int
  $consecutive: Boolean
) {
  tollfreeNumbers(
    contains: $contains
    quantity: $quantity
    consecutive: $consecutive
  ) {
    numbers
  }
}
```

### Example variables

```json
{
  "contains":"888xxxxxxx",
  "quantity":2,
  "consecutive":false
}
```

### Example response

```json
{
  "data": {
    "tollfreeNumbers": {
      "numbers": [
        "18886834580",
        "18886834690"
      ]
    }
  }
}
```

## Order toll-free numbers

To order toll-free numbers, pass the numbers from the previous call and set smsEnable to true or false, depending if you want to enable the numbers for SMS.

It usually takes about 10 minutes for voice service activation. For SMS you need to submit a Verified Sender form for ordered numbers.

```graphql
mutation orderTollfreeNumbersMutation(
  $numbers: [String]
  $smsEnable: Boolean
) {
  orderTollfreeNumbers(numbers: $numbers, smsEnable: $smsEnable) {
    numbers
    orderId
  }
}
```

### Example variables

```json
{
  "numbers": ["18886830411"],
  "smsEnable":true
}
```

### Example response

```json
{
  "data": {
    "orderTollfreeNumbers": {
      "numbers": ["18886830411"],
      "orderId":"999000261-ORD"
    }
  }
}
```



> **Info**


**Remember:** After ordering toll-free numbers, you should register a campaign for them using the Toll-Free Verified Sender Form, you can find the [form here](https://customer-portal.tsgglobal.com/tf-verification-form).

More info on campaign registration can be [here](https://support.tsgglobal.com/hc/en-us/articles/5872363711387-New-Toll-Free-SMS-MMS-Verified-Sender-Requirements).



## Disconnecting toll-free numbers

To disconnect a toll-free number, check the following section.



[Disconnect Number](https://support.tsgglobal.com/docs/api-reference/phone-numbers/disconnect-number.md)

---

# Reports

Source: https://support.tsgglobal.com/docs/api-reference/reports
Markdown: https://support.tsgglobal.com/docs/api-reference/reports.md
Last updated: 2024-03-21T15:56:06.115Z

Call and message detail records (CDRs) through the GraphQL API.

---

# CDR Records

Source: https://support.tsgglobal.com/docs/api-reference/reports/cdr-records
Markdown: https://support.tsgglobal.com/docs/api-reference/reports/cdr-records.md
Last updated: 2024-03-21T15:56:06.115Z

Count and list CDRs for a period, page through them with cursors, and export them as CSV.

---

# Get Count of CDR Records

Source: https://support.tsgglobal.com/docs/api-reference/reports/cdr-records/get-count-of-cdr-records
Markdown: https://support.tsgglobal.com/docs/api-reference/reports/cdr-records/get-count-of-cdr-records.md
Last updated: 2024-03-21T15:54:53.035Z

How to count CDR records for a period using the cdrRecords GraphQL query.

## Overview

Get the total number of CDR records between a start and end datetime.

## Authentication



> **Info**


This function is available via our GraphQL API. You can read more about how to authenticate to this API in [GraphQL API & Authentication](https://support.tsgglobal.com/docs/graphql-api-and-authentication.md).



## Method

The GraphQL API does not expose a separate count field. To count records for a period, run the `cdrRecords` query described in [Get CDR Records](https://support.tsgglobal.com/docs/api-reference/reports/cdr-records/get-cdr-records.md) with the maximum page size and follow `paginationInfo.nextCursor` until it is `null`, summing the length of `cdrs` on each page. For very large periods, generate the `exportLink` instead and count the rows of the CSV.

```graphql
query($type: CdrType!, $startDatetime: DateTime!, $endDatetime: DateTime!, $limit: Int, $cursor: String) {
  cdrRecords(type: $type, startDatetime: $startDatetime, endDatetime: $endDatetime, limit: $limit, cursor: $cursor) {
    paginationInfo {
      limit
      nextCursor
    }
    cdrs {
      __typename
    }
  }
}
```

```json
{
  "type": "SMS",
  "startDatetime": "2026-09-01T00:00:00.000Z",
  "endDatetime": "2026-09-02T00:00:00.000Z",
  "limit": 1000
}
```

---

# Get CDR Records

Source: https://support.tsgglobal.com/docs/api-reference/reports/cdr-records/get-cdr-records
Markdown: https://support.tsgglobal.com/docs/api-reference/reports/cdr-records/get-cdr-records.md
Last updated: 2024-03-21T15:53:20.027Z

Query call and message detail records with the cdrRecords GraphQL query: arguments, fragments per CDR type, cursor pagination and CSV export.

## Overview

Get call (and messaging) delivery records from your account.

## Authentication



> **Info**


This function is available via our GraphQL API. You can read more about how to authenticate to this API in [GraphQL API & Authentication](https://support.tsgglobal.com/docs/graphql-api-and-authentication.md).



## Endpoint

<mark style="color:green;">`POST`</mark> <https://api.portal.tsgglobal.world/graphql>

## Method

After sending messages or creating calls, you can check those by using the `cdrRecords` query which returns a `paginatedCdrResult` object type. This query is a bit more complex due to the usage of advanced GraphQL features like fragments and cursor based pagination.

Arguments which can be sent are listed below. The exclamation mark (`!`) means a parameter is mandatory, otherwise it's optional:

```
companyId: ID
For which company to list CDRs (only for admin users)

type: CdrType!
The type of the CDR records to list

startDatetime: DateTime!
Will return all records with datetime >= startDatetime

endDatetime: DateTime!
Will return all records with datetime < endDatetime (UTC based), max value is now

cursor: String
Used to paginate, returns results for the passed cursor (if any)

limit: Int
Limit the number of results per page, default is 100, max is 1000
```

### Sample Query

```graphql
query cdrRecordsQuery(
      $type: CdrType!
      $startDatetime: DateTime!
      $endDatetime: DateTime!
      $limit: Int
      $cursor: String
    ) {
      cdrRecords(
        type: $type
        startDatetime: $startDatetime
        endDatetime: $endDatetime
        limit: $limit
        cursor: $cursor
      ) {
        exportLink
        paginationInfo {
          nextCursor
          limit
        }
        cdrs {
          ... on ApiCdr {
            datetime
            from
            destination
            status
            charge
            type
          }
          ... on MessageCdr {
            datetime
            fromNumber
            toNumber
            direction
            status
            charge
            type
          }
          ... on VoiceCdr {
            datetime
            callId
            sourceAni
            destinationNumber
            didUsed
            sessionTime
            status
            calledRate
            charge
            callType
            aniIi
          }
        }
      }
    }
```

In this query GraphQL fragments are used (e.g. `... on MessageCdr { ... }`). They are needed because what we return is a union of types for `cdrs`, and the fields depend on the passed `type`. In our example below we're using `SMS`, but the fragments can be specified for each field in a general query, only change the type.

In our case the type is `SMS`, you send it as an uppercase string. Example of variables sent:

### Sample Variables

```json
{
  "type": "SMS",
  "startDatetime": "2022-04-26T07:00:00.000Z",
  "endDatetime": "2022-04-26T17:13:05.377Z",
  "limit": 20
}
```

### Sample Response

```json
{
  "data": {
    "cdrRecords": {
      "cdrs": [
        {
          "__typename": "MessageCdr",
          "account": "ACMEANCHO",
          "charge": "0.0095000000",
          "cost": "0.0051500000",
          "datetime": "2022-01-02T00:00:00Z",
          "direction": "SMS / MO Surcharge: T-Mobile - TF",
          "fromNumber": "12247512345",
          "status": "SENT",
          "surcharge": "0.0025000000",
          "toNumber": "18447312345",
          "uniqueId": "45e868c1-96b2-474c-a60f-98b76d812343"
        },
        {
          "__typename": "MessageCdr",
          "account": "ACMEANCHO",
          "charge": "0.0010000000",
          "cost": "0.0000000000",
          "datetime": "2022-01-02T00:00:00Z",
          "direction": "SMS / MO: AT&T - LO-ZERO",
          "fromNumber": "18134512345",
          "status": "SENT",
          "surcharge": "0.0000000000",
          "toNumber": "19725212345",
          "uniqueId": "22854899-1bc9-47b2-9a90-98b76d812344"
        }
      ],
      "exportLink": "https://api.portal.tsgglobal.world/export/call_records?sig=abe5dfefb701b284db7b8d18e4673654e788ab42a1ef51bcbc4f153ga218f2fa&end_datetime=2022-01-10T23%3A59%3A59.999Z&fields=account%2Cunique_id%2Ccharge%2Cfrom_number%2Cto_number%2Cstatus%2Cdatetime%2Ccost%2Csurcharge%2Cdirection&start_datetime=2022-01-01T00%3A00%3A00.000Z&type=sms&company_internal_id=ACMEANCHO&new_export=true&user_id=e17bbdf0-e72a-4998-bcfb-8f3e92123456",
      "paginationInfo": {
        "limit": 100,
        "nextCursor": null
      }
    }
  }
}
```

### Pagination

We're using pagination for this endpoint because there can be millions of records for short time frames. To paginate through the results, tweak the previous query so it looks like this (notice the `$limit` and `$cursor` arguments):

```graphql
query($type: CdrType!, $startDatetime: DateTime!, $endDatetime: DateTime!, $companyId: ID, $limit: Int, $cursor: String) {
  cdrRecords(type: $type, startDatetime: $startDatetime, endDatetime: $endDatetime, companyId: $companyId, limit: $limit, cursor: $cursor) {
    cdrs {
      __typename
      ... on MessageCdr {
        account
        uniqueId
        charge
        fromNumber
        toNumber
        status
        datetime
        cost
        surcharge
        direction
      }
      ... on ApiCdr {
        account
        charge
        destination
        datetime
        status
        from
        uniqueId
        type
      }
      ... on VoiceCdr {
        account
        charge
        destination
        datetime
        status
        uniqueId
        aniIi
        callId
        callType
        destinationNumber
        sourceAni
        calledRate
        didUsed
        sessionTime
      }
    }
    paginationInfo {
      limit
      nextCursor
    }
    exportLink
  }
}
```

and variables (`limit=2` and `cursor=null`):

```json
{
  "type": "SMS",
  "startDatetime": "2022-01-01T00:00:00.000Z",
  "endDatetime": "2022-01-10T23:59:59.999Z",
  "companyId": "65deb62c-bb16-4a9d-927a-ec1abb37a832",
  "limit": 2,
  "cursor": null
}
```

The results we get have `paginationInfo` filled differently, notice the `limit` and `nextCursor` properties below:

```json
{
  "data": {
    "cdrRecords": {
      "cdrs": ["...edited for readability..."],
      "exportLink": "...edited for readability...",
      "paginationInfo": {
        "limit": 2,
        "nextCursor": "123456"
      }
    }
  }
}
```

We need to use the `nextCursor` value to get the next page, so the variables now look like the following:

```json
{
  "type": "SMS",
  "startDatetime": "2022-01-01T00:00:00.000Z",
  "endDatetime": "2022-01-10T23:59:59.999Z",
  "companyId": "65deb62c-bb16-4a9d-927a-ec1abb37a832",
  "limit": 2,
  "cursor": "123456"
}
```

This will get us the next round of results with another `nextCursor` value. We can paginate until the result we get has `nextCursor: null`; when it's `null` it means we reached the end.

### Exporting CDRs

You can export CDRs by using the `exportLink` which the `cdrRecords` query provides. The easiest way is to click on the link, but you can also do a server-side or client-side download if you want to save the results.

The links in the above example won't work since they're fake but you can generate one with your queries. The export will trigger a CSV file download (via HTTP streams) and include the fields you specified in the query, but the pagination options will be ignored.

Example of an export link:

```
https://api.portal.tsgglobal.world/export/call_records? \
sig=abe5dfefb701b284db7b8d18e4673654e788ab42a1ef51bcbc4f153ga218f2fa& \
fields=account,unique_id,charge,from_number,to_number,status,datetime,cost,surcharge,direction& \
start_datetime=2022-01-01T00:00:00.000Z& \
end_datetime=2022-01-10T23:59:59.999Z& \
type=sms& \
company_internal_id=ACMEANCHO& \
new_export=true& \
user_id=e17bbdf0-e72a-4998-bcfb-8f3e92123456
```

#### Notes

* The export link is protected by a signature and cannot be tampered with; once generated it's public.
* The export process has a timeout of 20 minutes, so if you notice the export timing out reduce the startDatetime and endDatetime period to something manageable and try again.

---

# Compliance & Identity

Source: https://support.tsgglobal.com/docs/api-reference/compliance-and-identity
Markdown: https://support.tsgglobal.com/docs/api-reference/compliance-and-identity.md
Last updated: 2022-11-03T15:04:47.000Z

Toll-Free Verified Sender forms and short code orders through the GraphQL API.

---

# Toll-Free Verified Sender (Order)

Source: https://support.tsgglobal.com/docs/api-reference/compliance-and-identity/toll-free-verified-sender-order
Markdown: https://support.tsgglobal.com/docs/api-reference/compliance-and-identity/toll-free-verified-sender-order.md
Last updated: 2023-03-21T15:12:38.000Z

Submit a Toll-Free Verified Sender Form and list your VSF orders with the GraphQL API. Unverified toll-free numbers are blocked to Canada and throttled to the US.

## Overview

Use this API to create and query the status of current Verified Sender Forms (VSFs). Failure to provide VSFs results in blocking to Canada and lower throughputs to US destinations for toll-free numbers. Submitting a VSF removes the block temporarily until the VSF is either approved, or rejected.

## Authentication



> **Info**


This function is available via our GraphQL API. You can read more about how to authenticate to this API in [GraphQL API & Authentication](https://support.tsgglobal.com/docs/graphql-api-and-authentication.md).



## Mutation - to Create a new VSF

```graphql
mutation (
  $businessName: String!,
  $businessRegisteredAddress: String!,
  $businessRegisteredCity: String!,
  $businessRegisteredState: String!,
  $businessRegisteredZip: String!,
  $businessContactFirstName: String!,
  $businessContactLastName: String!,
  $businessContactEmail: String!,
  $businessContactPhone: String!,
  $fortune500Or1000Company: String!,
  $numbers: [VerifiedSenderFormNumberInput!]!,
  $numbersExplanation: String!,
  $useCase: String!,
  $howDoConsumersOptIn: String!,
  $commercialMessages: String!,
  $numberPublishedLocation: String!,
  $messageSenderWebsite: String!,
  $termsAndPrivacy: String!,
  $callToAction: String!,
  $sampleMessages: [String!]!,
  $helpMessageContainsOptOutInstructions: String!,
  $stopKeywordIsSupportedAsAnOptOutMethod: String!,
  $estimatedMonthlyMessageVolume: String!,
  $previouslyAnotherMessagingServiceTraffic: String!,
  $previouslyAnotherMessagingServiceContent: String,
  $previouslyAnotherMessagingServiceNumbers: [String],
  $canadianTrafficMostly: String!,
  $covid19Related: String!,
  $attachments: [String!]!
) {
  submitVerifiedSenderForm(
    businessName: $businessName,
    businessRegisteredAddress: $businessRegisteredAddress,
    businessRegisteredCity: $businessRegisteredCity,
    businessRegisteredState: $businessRegisteredState,
    businessRegisteredZip: $businessRegisteredZip,
    businessContactFirstName: $businessContactFirstName,
    businessContactLastName: $businessContactLastName,
    businessContactEmail: $businessContactEmail,
    businessContactPhone: $businessContactPhone,
    fortune500Or1000Company: $fortune500Or1000Company,
    numbers: $numbers,
    numbersExplanation: $numbersExplanation,
    useCase: $useCase,
    howDoConsumersOptIn: $howDoConsumersOptIn,
    commercialMessages: $commercialMessages,
    numberPublishedLocation: $numberPublishedLocation,
    messageSenderWebsite: $messageSenderWebsite,
    termsAndPrivacy: $termsAndPrivacy,
    callToAction: $callToAction,
    sampleMessages: $sampleMessages,
    helpMessageContainsOptOutInstructions: $helpMessageContainsOptOutInstructions,
    stopKeywordIsSupportedAsAnOptOutMethod: $stopKeywordIsSupportedAsAnOptOutMethod,
    estimatedMonthlyMessageVolume: $estimatedMonthlyMessageVolume,
    previouslyAnotherMessagingServiceTraffic: $previouslyAnotherMessagingServiceTraffic,
    previouslyAnotherMessagingServiceContent: $previouslyAnotherMessagingServiceContent,
    previouslyAnotherMessagingServiceNumbers: $previouslyAnotherMessagingServiceNumbers,
    canadianTrafficMostly: $canadianTrafficMostly,
    covid19Related: $covid19Related,
    attachments: $attachments
  ) {
    id
    finishedAt
    insertedAt
    name
    status
    data {
      ...VerifiedSenderFormFields
    }
  }
}

fragment VerifiedSenderFormFields on VerifiedSenderFormOrderData {
  type
  businessName
  businessRegisteredAddress
  businessRegisteredCity
  businessRegisteredState
  businessRegisteredZip
  businessContactFirstName
  businessContactLastName
  businessContactEmail
  businessContactPhone
  fortune500Or1000Company
  numbers {
    number
  }
  numbersExplanation
  useCase
  howDoConsumersOptIn
  commercialMessages
  numberPublishedLocation
  messageSenderWebsite
  termsAndPrivacy
  callToAction
  sampleMessages
  helpMessageContainsOptOutInstructions
  stopKeywordIsSupportedAsAnOptOutMethod
  estimatedMonthlyMessageVolume
  previouslyAnotherMessagingServiceTraffic
  previouslyAnotherMessagingServiceContent
  previouslyAnotherMessagingServiceNumbers
  canadianTrafficMostly
  covid19Related
}
```

### Sample Arguments

```json
{
  "businessName": "[TESTTEST] ACME Inc.",
  "businessRegisteredAddress": "[TESTTEST] Street 1B",
  "businessRegisteredCity": "[TESTTEST] Denver",
  "businessRegisteredState": "Colorado",
  "businessRegisteredZip": "123467",
  "businessContactFirstName": "John",
  "businessContactLastName": "Doe",
  "businessContactEmail": "email@acme.org",
  "businessContactPhone": "12345678910",
  "fortune500Or1000Company": "no",
  "numbers": [
    { "number": "12345678910" },
    { "number": "12345678911" }
  ],
  "numbersExplanation": "",
  "useCase": "[TESTTEST] actions, discounts, etc.",
  "howDoConsumersOptIn": "via website",
  "commercialMessages": "yes",
  "numberPublishedLocation": "https://acme.org/numbers",
  "messageSenderWebsite": "https://acme.org",
  "termsAndPrivacy": "https://acme.org/terms",
  "callToAction": "Text JOIN to 12345678910 to receive offers",
  "sampleMessages": [
    "this is a sample message"
  ],
  "helpMessageContainsOptOutInstructions": "yes",
  "stopKeywordIsSupportedAsAnOptOutMethod": "yes",
  "estimatedMonthlyMessageVolume": "10000",
  "previouslyAnotherMessagingServiceTraffic": "yes, on Bandwidth",
  "previouslyAnotherMessagingServiceContent": "hello customer",
  "previouslyAnotherMessagingServiceNumbers": [
    "123456789"
  ],
  "canadianTrafficMostly": "unsure",
  "covid19Related": "unsure",
  "attachments": ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="]
}
```

## Query - to List VSF Orders

Use the below query to list your Verified Sender Form Orders and retrieve the status of the request.

```graphql
query($page: Int, $publicId: String, $type: String, $addedStartDate: DateTime, $addedEndDate: DateTime) {
  orders(page: $page, publicId: $publicId, type: $type, addedStartDate: $addedStartDate, addedEndDate: $addedEndDate) {
    page
    pageSize
    totalPages
    orders {
      id
      publicId
      name
      insertedAt
      data {
        ...VerifiedSenderFormFields
      }
    }
  }
}

fragment VerifiedSenderFormFields on VerifiedSenderFormOrderData {
  type
  businessName
  businessRegisteredAddress
  businessRegisteredCity
  businessRegisteredState
  businessRegisteredZip
  businessContactFirstName
  businessContactLastName
  businessContactEmail
  businessContactPhone
  fortune500Or1000Company
  numbers {
    number
  }
  numbersExplanation
  useCase
  howDoConsumersOptIn
  commercialMessages
  numberPublishedLocation
  messageSenderWebsite
  termsAndPrivacy
  callToAction
  sampleMessages
  helpMessageContainsOptOutInstructions
  stopKeywordIsSupportedAsAnOptOutMethod
  estimatedMonthlyMessageVolume
  previouslyAnotherMessagingServiceTraffic
  previouslyAnotherMessagingServiceContent
  previouslyAnotherMessagingServiceNumbers
  canadianTrafficMostly
  covid19Related
}
```

### Sample Arguments

All arguments are optional.

```json
{
  "page": 1,
  "publicId": "VSF",
  "type": "verified_sender_form",
  "addedStartDate": "2022-01-01T12:00:00Z",
  "addedEndDate": "2022-12-01T12:00:00Z"
}
```

---

# Short Code Submission (Order)

Source: https://support.tsgglobal.com/docs/api-reference/compliance-and-identity/short-code-submission-order
Markdown: https://support.tsgglobal.com/docs/api-reference/compliance-and-identity/short-code-submission-order.md
Last updated: 2023-03-21T15:12:27.000Z

Order short code numbers by submitting the short code form with the GraphQL API, and list your short code orders to track status.

## Overview

This form allows you to order short code numbers for your messaging campaigns.

## Authentication



> **Info**


This function is available via our GraphQL API. You can read more about how to authenticate to this API in [GraphQL API & Authentication](https://support.tsgglobal.com/docs/graphql-api-and-authentication.md).



## Mutation - Submit a short code form (order)

Using a GraphQL mutation you can submit the form, the example command is below. This creates an order which will be verified and the short code numbers will be ordered based on the submitted data.

```graphql
mutation (
    $businessName: String!
    $businessRegisteredAddress: String!
    $businessRegisteredCity: String!
    $businessRegisteredState: String!
    $businessRegisteredZip: String!
    $businessContactFirstName: String!
    $businessContactLastName: String!
    $businessContactEmail: String!
    $businessContactPhone: String!
    $useCase: String!
    $termsAndConditionsWebsite: String!
    $privacyPolicyWebsite: String!
    $callToActionLocations: String!
    $callToActionLanguage: String!
    $optInKeywords: String!
    $optInConfirmation: String!
    $welcomeMessage: String!
    $exampleAlerts: String!
    $helpResponseText: String!
    $stopResponseText: String!
    $customerSupportContactEmail: String!
    $customerSupportContactPhone: String!
    $customerSupportUrl: String!
    $attachments: [String!]!
  ) {
    submitShortcodeForm(
      businessName: $businessName,
      businessRegisteredAddress: $businessRegisteredAddress,
      businessRegisteredCity: $businessRegisteredCity,
      businessRegisteredState: $businessRegisteredState,
      businessRegisteredZip: $businessRegisteredZip,
      businessContactFirstName: $businessContactFirstName,
      businessContactLastName: $businessContactLastName,
      businessContactEmail: $businessContactEmail,
      businessContactPhone: $businessContactPhone,
      useCase: $useCase,
      termsAndConditionsWebsite: $termsAndConditionsWebsite,
      privacyPolicyWebsite: $privacyPolicyWebsite,
      callToActionLocations: $callToActionLocations,
      callToActionLanguage: $callToActionLanguage,
      optInKeywords: $optInKeywords,
      optInConfirmation: $optInConfirmation,
      welcomeMessage: $welcomeMessage,
      exampleAlerts: $exampleAlerts,
      helpResponseText: $helpResponseText,
      stopResponseText: $stopResponseText,
      customerSupportContactEmail: $customerSupportContactEmail,
      customerSupportContactPhone: $customerSupportContactPhone,
      customerSupportUrl: $customerSupportUrl,
      attachments: $attachments,
    ) {
      id
      publicId
      insertedAt
      name
      status
      statusNote
      finishedAt
      data {
        ...ShortcodeFormFields
      }
    }
  }

fragment ShortcodeFormFields on ShortcodeFormOrderData {
  type
  businessName
  businessRegisteredAddress
  businessRegisteredCity
  businessRegisteredState
  businessRegisteredZip
  businessContactFirstName
  businessContactLastName
  businessContactEmail
  businessContactPhone
  useCase
  termsAndConditionsWebsite
  privacyPolicyWebsite
  callToActionLocations
  callToActionLanguage
  optInKeywords
  optInConfirmation
  welcomeMessage
  exampleAlerts
  helpResponseText
  stopResponseText
  customerSupportContactEmail
  customerSupportContactPhone
  customerSupportUrl
  attachments
}
```

## Sample arguments

The payload should be formatted like this. Note that `attachments` is an array of base64-encoded images and/or documents.

```json
{
  "businessName": "ACME Inc.",
  "businessRegisteredAddress": "Street 1B",
  "businessRegisteredCity": "Denver",
  "businessRegisteredState": "Colorado",
  "businessRegisteredZip": "123467",
  "businessContactFirstName": "John",
  "businessContactLastName": "Doe",
  "businessContactEmail": "john.doe@acme.org",
  "businessContactPhone": "12345678910",
  "useCase": "We'll be sending promo messages using short code numbers",
  "termsAndConditionsWebsite": "terms_and_conditions.acme.com",
  "privacyPolicyWebsite": "privacy_policy.acme.com",
  "callToActionLocations": "top and bottom of the page at acme.com",
  "callToActionLanguage": "JOIN NOW, SAVE MONEY, etc.",
  "optInKeywords": "JOIN",
  "optInConfirmation": "YES",
  "welcomeMessage": "Welcome to our shortcode campaign!",
  "exampleAlerts": "New offers available! Join now to save 20%.",
  "helpResponseText": "This is the HELP menu:\n\nSend STOP to stop all messages.",
  "stopResponseText": "You used STOP to stop all messages, you'll no longer receive any promo messages from us.",
  "customerSupportContactEmail": "our_support@company.com",
  "customerSupportContactPhone": "18881231234",
  "customerSupportUrl": "www.our_support.com",
  "attachments": [
    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="
  ]
}
```

## Query - list short code form orders

To retrieve the status of the request, and to list your short code orders, use the query below.

```graphql
query($page: Int, $publicId: String, $type: String, $addedStartDate: DateTime, $addedEndDate: DateTime) {
  orders(page: $page, publicId: $publicId, type: $type, addedStartDate: $addedStartDate, addedEndDate: $addedEndDate) {
    page
    pageSize
    totalPages
    orders {
      id
      publicId
      name
      insertedAt
      data {
        ...ShortcodeFormFields
      }
    }
  }
}

fragment ShortcodeFormFields on ShortcodeFormOrderData {
  type
  businessName
  businessRegisteredAddress
  businessRegisteredCity
  businessRegisteredState
  businessRegisteredZip
  businessContactFirstName
  businessContactLastName
  businessContactEmail
  businessContactPhone
  useCase
  termsAndConditionsWebsite
  privacyPolicyWebsite
  callToActionLocations
  callToActionLanguage
  optInKeywords
  optInConfirmation
  welcomeMessage
  exampleAlerts
  helpResponseText
  stopResponseText
  customerSupportContactEmail
  customerSupportContactPhone
  customerSupportUrl
  attachments
}
```

And the variables look like this:

```json
{
  "page": 1,
  "publicId": "SCF",
  "type": "shortcode_form"
}
```

You can do a more detailed search, e.g. by using the full `publicId`:

```json
{
  "page": 1,
  "publicId": "SCF-5XXY1YJHLK",
  "type": "shortcode_form"
}
```

You can also specify a date range:

```json
{
  "page": 1,
  "publicId": "SCF",
  "type": "shortcode_form",
  "addedStartDate": "2022-01-01T12:00:00Z",
  "addedEndDate": "2022-12-01T12:00:00Z"
}
```

---

# GraphQL API & Authentication

Source: https://support.tsgglobal.com/docs/graphql-api-and-authentication
Markdown: https://support.tsgglobal.com/docs/graphql-api-and-authentication.md
Last updated: 2024-03-21T15:51:32.973Z

Describes how to authenticate to our GraphQL API.

## What is GraphQL?

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.

You can learn more about the GraphQL framework here: <https://graphql.org/>

For testing it would be good to use [Postman](https://www.postman.com/) or [Insomnia](https://insomnia.rest/) or some other similar API client.

## How do I access the TSG Global GraphQL API?



> **Danger**


This authentication method is different than the API key authentication method used for other TSG Global services, and the TNID service.



You can generate a Bearer token to access our GraphQL API using the username and password you use to access our [Customer Portal](https://customer-portal.tsgglobal.com). This token lasts for 7 days.

## Generate Bearer Token

<mark style="color:green;">`POST`</mark> `https://api.portal.tsgglobal.world/account/login`

#### Request Body

| Name                                       | Type   | Description              |
| ------------------------------------------ | ------ | ------------------------ |
| email<mark style="color:red;">\*</mark>    | string | Your user email address. |
| password<mark style="color:red;">\*</mark> | string | Your password.           |





### 200: OK 



```javascript
{
    "token": "POAPK_*********",
    "user": {
        "email": "test.user@tsgglobal.com",
        "first_name": "Test",
        "id": "*****",
        "last_name": "User",
        "level": "basic_user"
    }
}
```






### 401: Unauthorized Invalid email or password.



```javascript
{
    "errors": [
        {
            "id": "unauthorized",
            "message": "Invalid email or password."
        }
    ]
}
```






When you query the API, you will want to pass your credentials in the header, with the header name "Authorization" and the value as "Bearer \<token>".

If you are missing these credentials, please email us at: <support@tsgglobal.com>

## Where can I test the GraphQL API and view more documentation?

You can test various features and view additional documentation in the GraphiQL interface we provide here: <https://api.portal.tsgglobal.world/graphiql>

## What URL should I use to perform my queries and mutations?

Please use: <https://api.portal.tsgglobal.world/graphql> (note this is different than the GraphiQL UI).

---

# Changelog

Source: https://support.tsgglobal.com/docs/changelog
Markdown: https://support.tsgglobal.com/docs/changelog.md

Dated log of changes to the TSG Global APIs and to this documentation.

Newest first. This log starts on 2026-09-11; API changes before that date were not recorded here.

## 2026-09-11: documentation

* New pages: [API Quick Reference](https://support.tsgglobal.com/docs/api-quick-reference.md), [AI Assistants & MCP](https://support.tsgglobal.com/docs/ai-assistants-and-mcp.md) and this changelog.
* An OpenAPI 3.1 description of the REST APIs (SMS, MMS, MMS templates, number configuration) is published in GitBook as `tsg-global-rest`; see OpenAPI Specification.
* Corrections: `PSTN` (not `PTSN`) in the Destination Priority examples; the staging MMS-over-SMTP section no longer repeats the SMPP settings; the inbound SMS webhook page now names the real `webhook_url` field; the `unauthenticated` error type definition; invalid JSON in the Receive an SMS Message example; placeholder responses on Send an MMS Message, Disable SMS and Disable MMS replaced with real ones; the MMS Templates quickstart code restored to readable blocks; the template example without placeholders now shows an empty placeholder list; nested code fences fixed on Receive DLRs, Get Number Information and List Destination Priority; the stray scheduling hint removed from Delete Destination Priority; Get Count of CDR Records now explains how to count; typos on the Verified Sender and Short Code pages.
* Every page now carries a description, which also improves `llms.txt` and MCP search results.

## Known gaps

* Production SMPP hostname and per-account rate limits are not published; contact <support@tsgglobal.com>.
