> This page is for Developers.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.emnify.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.emnify.com/_mcp/server.

# SMS callbacks

> Receive mobile-originated SMS via API callbacks with JWT authentication and delivery receipts for A2P and P2P messaging.

Receive MO SMS via API callback.

The system can dispatch [mobile originated (MO) SMS](https://www.emnify.com/iot-glossary#sms-mo) from endpoints as HTTP `POST` requests toward a user-configurable URL.
The URL of the receiving server needs to be specified in a [service profile](/developers/reference/service-profile) that the endpoint has assigned.
The emnify system then sends the MO SMS as a JSON payload if the destination address of the SMS is an invalid [MSISDN](https://www.emnify.com/iot-glossary#msisdn) (that is, 7 digits or less).

Example service profile with an API callback URL and API secret:

```json focus={6-12, 16-20} maxLines=0
{
   "organisation_id": "1337",
   "name": "SMS MO Callback",
   "description": "This service profile demonstrates the API callback URL and signing key",
   // Application server URL
   "api_callback": {
      "organisation_id": "1337",
      "url": "http://my-application-server.io",
      "created": "2019-10-11 08:54:20",
      "purpose": "Receiving SMS-MO",
      "id": 12
   },
   // This secret is used to sign the JWT included in the Authorization header of callbacks.
   // These secrets should be kept securely as they are used to validate the authenticity of incoming POST requests to your callback URL.
   // Note: API secrets may be created (POST) and retrieved (GET) via /api/v1/api_secret
   "api_secret":{
      "organisation_id":"1337",
      "purpose":"Custom Signing Key",
      "id":123
   },
  // ...
}
```

> **Info**
>
> The application server receiving the API callback needs to respond with HTTP Code `2XX` to accept the request.

## API callback secret

If an API secret is provided in the service profile, callbacks using this URL contain an `Authorization` header with a JSON Web Token (JWT) included.
The `api_secret` is used as the *signing key* of the JWT in this header.

API callback auth header:

```json
{
  "Authorization": "Bearer JWT_SIGNED_WITH_API_SECRET"
}
```

By verifying the signing key of the JWT, your server can ensure the request is coming from emnify.
If no `api_secret` exists in the service profile, the request won't contain an `Authorization` header.

Example request body sent to API callback URL:

```json maxLines=0
{
   "submit_date": "2019-10-29 10:36:01",
   "dcs": 0,
   "pid": 0,
   "organisation": {
      "id": "1337"
   },
   "multi_part_info": {
      "identifier": 20426339,
      "partno": 1,
      "total": 1
   },
   "payload": "The SMS Content",
   "endpoint": {
      "id": "10",
      "name": "My Test SIM"
   },
   "id": "12345",
   "source_address": "42366391012345",
   "dest_address": "12345"
}
```

> **Tip**
>
> If you're new to JWTs, here are some helpful resources:
>
> * [JWT.io](https://jwt.io) lists libraries designed for decoding and encoding JWTs.
> * [JJWT](https://github.com/jwtk/jjwt) is a library for creating and verifying JWTs on the Java Virtual Machine (JVM) and Android.

## Delivery receipts

The callback URL may also be used to receive SMS delivery receipts in the form of a `PATCH` request.
When the SMS interface for an endpoint is set to use the REST API in the corresponding service profile, [mobile terminated (MT) messages](https://www.emnify.com/iot-glossary#sms-mt) triggered via API generate payloads toward the callback URL with a payload in the following format:

```json
{
  "organisation": {
    "id": "1337"
  },
  "id": "20801096",
  "final_date": "2019-11-15 09:35:18",
  "submit_date": "2019-11-15 09:35:14",
  "endpoint": {
    "id": "9689516",
    "name": "My Test SIM"
  },
  "status": {
    "id": "4",
    "status": "DELIVERED"
  }
}
```

## A2P and P2P routing

The emnify system distinguishes [application-to-peer (A2P) SMS](https://www.emnify.com/iot-glossary#a2p-sms) from [peer-to-peer (P2P) SMS](https://www.emnify.com/iot-glossary#p2p-sms) based on the length of the source (MO SMS) or the destination (MT SMS) address.

* If there are 7 digits or less (that is, an invalid MSISDN), an SMS is considered **A2P**.
* If there are 8 digits or more, an SMS is processed as MSISDN and considered **P2P**.

To dispatch SMS MO to your application (A2P) and at the same time have P2P SMS enabled, the destination number (`dest_address`) must be limited to 7 digits or less.

```json {12}
{
  "id": 123,
  "endpoint": {
    "id": 1,
    "name": "Your endpoint"
  },
  "organisation": {
    "id": 4,
    "name": "Your organization name"
  },
  "source_address": 432311234,
  "dest_address": 1234567,
  "payload": "This is the message text",
  "dcs": 0,
  "pid": 0,
  "submit_date": {}
}
```