# SMS Apps

An SMS App represents a configured SMS sender tied to a specific region. Once provisioned, it can be used with the Sinch Conversation API to send SMS messages.

What you'll find here:

- Prerequisites: account, project credentials, and project ID
- Creating an SMS App: request shape and sample code
- Connecting an SMS App to a Conversation Application (post-creation)
- Listing SMS Apps: paginated retrieval
- Updating an SMS App: changing the name
- Deleting an SMS App


## Prerequisites

Before creating an SMS App, ensure you have:

- A Sinch account: Register and sign in via Sinch Build: [dashboard.sinch.com](https://dashboard.sinch.com/)
- Project credentials: Create an Access Key and Access Secret for the specific project you intend to use. These credentials authenticate calls to Provisioning API.
- Project ID: The UUID of the project that will own the SMS App and Conversation App.


Quick links:

- Sinch Build dashboard: [dashboard.sinch.com](https://dashboard.sinch.com/)
- Create project credentials: [Access Keys](https://dashboard.sinch.com/settings/access-keys)


## Creating an SMS App

The following **Node.js** code sample demonstrates how to create a new SMS App for a specific project:

```javascript
import fetch from 'node-fetch';

async function createSmsApp() {
  const response = await fetch(
    `https://provisioning.api.sinch.com/v1/projects/${PROJECT_ID}/sms/smsApps`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization:
          'Basic ' +
          Buffer.from(ACCESS_KEY + ':' + ACCESS_SECRET).toString('base64'),
      },
      body: JSON.stringify({
        name: 'My SMS App',
        region: 'EU',
      }),
    }
  );

  const data = await response.json();
  return data;
}
```

### Creating an SMS App with a new Conversation Application

To automatically create a linked Conversation Application alongside the SMS App, set `convApiApp` to `true`:

```javascript
import fetch from 'node-fetch';

async function createSmsAppWithConvApp() {
  const response = await fetch(
    `https://provisioning.api.sinch.com/v1/projects/${PROJECT_ID}/sms/smsApps`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization:
          'Basic ' +
          Buffer.from(ACCESS_KEY + ':' + ACCESS_SECRET).toString('base64'),
      },
      body: JSON.stringify({
        name: 'My SMS App with Conversation',
        region: 'US',
        convApiApp: true,
      }),
    }
  );

  const data = await response.json();
  return data;
}
```

### Creating an SMS App linked to an existing Conversation Application

To link the SMS App to an existing Conversation Application, provide its ID via `convApiAppId`:

```javascript
import fetch from 'node-fetch';

async function createSmsAppWithExistingConvApp() {
  const response = await fetch(
    `https://provisioning.api.sinch.com/v1/projects/${PROJECT_ID}/sms/smsApps`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization:
          'Basic ' +
          Buffer.from(ACCESS_KEY + ':' + ACCESS_SECRET).toString('base64'),
      },
      body: JSON.stringify({
        name: 'My SMS App linked',
        region: 'BR',
        convApiAppId: 'your-existing-conversation-app-id',
      }),
    }
  );

  const data = await response.json();
  return data;
}
```

Important
You cannot provide both `convApiApp: true` and `convApiAppId` in the same request. Use one or the other.

### Response

All create variants return an SMS App object:

```json
{
  "id": "01fc866f5e3e48c9a6fd0e8de407459a",
  "smsServiceId": "a3f2b8c14d5e6f7890abcdef12345678",
  "name": "My SMS App",
  "status": "PENDING_ADD",
  "regions": ["EU"],
  "conversationApiAppDetails": {
    "id": "01KSHM8N1YZNCGAC24JK3B9VBQ",
    "projectId": "e1a2b3c4-d5e6-f7a8-b9c0-d1e2f3a4b5c6",
    "region": "EU",
    "channelStatus": "PENDING"
  },
  "test": false
}
```

| Field | Type | Description |
|  --- | --- | --- |
| `id` | `string` | Unique identifier of the SMS App (UUID without hyphens). This is the resource you interact with for all SMS App operations. |
| `smsServiceId` | `string` | The parent SMS Service container ID. One SMS Service is created per project (on the first SMS App creation) and shared by all SMS Apps in that project. |
| `name` | `string` | Name of the SMS App |
| `status` | `string` | Provisioning status — typically `PENDING_ADD` on creation, transitioning to `ACTIVE` once fully provisioned |
| `regions` | `string[]` | Regions the SMS App is provisioned in (`BR`, `EU`, `US`). Always a single-element array matching the input `region`. |
| `conversationApiAppDetails` | `object | undefined` | Linked Conversation Application details (present when `convApiApp` or `convApiAppId` was used) |
| `conversationApiAppDetails.id` | `string` | Conversation Application ID |
| `conversationApiAppDetails.projectId` | `string` | Project ID the Conversation App belongs to |
| `conversationApiAppDetails.region` | `string` | Region of the Conversation App (`EU`, `US`, `BR`) |
| `conversationApiAppDetails.channelStatus` | `string | undefined` | SMS channel integration status on the Conversation App (`PENDING`, `ACTIVE`, `FAILING`) |
| `test` | `boolean` | Whether this is a test SMS App |


Note
The `status` field will be `PENDING_ADD` immediately after creation. It transitions through `IN_PROGRESS_ADD` to `ACTIVE` as the upstream SMS platform completes provisioning. When using `convApiApp` or `convApiAppId`, the `channelStatus` will also initially be `PENDING` and transition to `ACTIVE` asynchronously. For standalone creation (no conv app flags), `conversationApiAppDetails` will be `undefined`.

## Connecting an SMS App to a Conversation Application

If you created an SMS App without linking it at creation time, you can connect it to a Conversation Application afterwards using the channels endpoint on the Conversation service.

This is also the mechanism used in the [three-request creation flow](/docs/provisioning-api/getting-started/sms) when you want full control over each resource.

```javascript
import fetch from 'node-fetch';

async function connectSmsAppToConvApp(convAppId, smsAppId) {
  const response = await fetch(
    `https://provisioning.api.sinch.com/v1/projects/${PROJECT_ID}/conversation/apps/${convAppId}/channels/connectSender`,
    {
      method: 'PATCH',
      headers: {
        'Content-Type': 'application/json',
        Authorization:
          'Basic ' +
          Buffer.from(ACCESS_KEY + ':' + ACCESS_SECRET).toString('base64'),
      },
      body: JSON.stringify({
        senderId: smsAppId,
        channel: 'SMS',
      }),
    }
  );

  const data = await response.json();
  return data;
}
```

The request body:

| Field | Type | Description |
|  --- | --- | --- |
| `senderId` | `string` | The ID of the SMS App to connect |
| `channel` | `string` | Must be `SMS` |


Region requirement
If the SMS App region and the Conversation Application region do not match, the request will fail.

## Creating an SMS App using Bundles

You can also use the Bundles endpoint to create the SMS App and Conversation Application together in a single atomic request:

```javascript
POST /v1/projects/:projectId/bundles

{
  "name": "My SMS Setup",
  "region": "EU",
  "smsApp": true,
  "convApp": true
}
```

The Bundles endpoint also supports linking existing SMS Apps (`smsApp: { smsAppId: "..." }`) and existing Conv Apps (`convApp: { convAppId: "..." }`), creating subprojects, and registering webhooks — all in one atomic request.

See the [Bundles guide](/docs/provisioning-api/getting-started/bundles/sms-apps) for full details.

Async processing
Both the SMS endpoint (with `convApiApp` or `convApiAppId`) and the Bundles endpoint process linking asynchronously. The SMS channel activation on the Conversation App transitions through `PENDING` → `ACTIVE` behind the scenes. Register a webhook with the `BUNDLE_DONE` trigger to be notified when the process completes.

## Listing SMS Apps

Retrieve a paginated list of SMS Apps for your project:

```javascript
import fetch from 'node-fetch';

async function listSmsApps(pageToken, pageSize) {
  const params = new URLSearchParams();
  if (pageToken) params.set('pageToken', pageToken);
  if (pageSize) params.set('pageSize', pageSize);

  const response = await fetch(
    `https://provisioning.api.sinch.com/v1/projects/${PROJECT_ID}/sms/smsApps?${params}`,
    {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        Authorization:
          'Basic ' +
          Buffer.from(ACCESS_KEY + ':' + ACCESS_SECRET).toString('base64'),
      },
    }
  );

  const data = await response.json();
  return data;
}
```

The response includes:

| Field | Description |
|  --- | --- |
| `totalSize` | Total number of SMS Apps in the project |
| `pageSize` | Number of items returned in this page |
| `previousPageToken` | Token for the previous page (if available) |
| `nextPageToken` | Token for the next page (if available) |
| `smsApps` | Array of SMS App objects |


## Retrieving an SMS App

Get details of a specific SMS App by its ID:

```javascript
import fetch from 'node-fetch';

async function getSmsApp(smsAppId) {
  const response = await fetch(
    `https://provisioning.api.sinch.com/v1/projects/${PROJECT_ID}/sms/smsApps/${smsAppId}`,
    {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        Authorization:
          'Basic ' +
          Buffer.from(ACCESS_KEY + ':' + ACCESS_SECRET).toString('base64'),
      },
    }
  );

  const data = await response.json();
  return data;
}
```

The response includes:

| Field | Description |
|  --- | --- |
| `id` | Unique identifier of the SMS App |
| `smsServiceId` | The associated SMS service ID |
| `name` | Name of the SMS App |
| `status` | Current provisioning status (e.g. `ACTIVE`, `IN_PROGRESS_ADD`) |
| `regions` | Array of regions the SMS App is available in |
| `conversationApiAppDetails` | Linked Conversation App details (if any) |
| `test` | Whether this is a test SMS App |


## Updating an SMS App

Update the name of an existing SMS App:

```javascript
import fetch from 'node-fetch';

async function updateSmsApp(smsAppId) {
  const response = await fetch(
    `https://provisioning.api.sinch.com/v1/projects/${PROJECT_ID}/sms/smsApps/${smsAppId}`,
    {
      method: 'PATCH',
      headers: {
        'Content-Type': 'application/json',
        Authorization:
          'Basic ' +
          Buffer.from(ACCESS_KEY + ':' + ACCESS_SECRET).toString('base64'),
      },
      body: JSON.stringify({
        name: 'Updated SMS App Name',
      }),
    }
  );

  const data = await response.json();
  return data;
}
```

## Deleting an SMS App

Delete an SMS App by its ID:

```javascript
import fetch from 'node-fetch';

async function deleteSmsApp(smsAppId) {
  const response = await fetch(
    `https://provisioning.api.sinch.com/v1/projects/${PROJECT_ID}/sms/smsApps/${smsAppId}`,
    {
      method: 'DELETE',
      headers: {
        'Content-Type': 'application/json',
        Authorization:
          'Basic ' +
          Buffer.from(ACCESS_KEY + ':' + ACCESS_SECRET).toString('base64'),
      },
    }
  );

  if (response.status === 200) {
    console.log('SMS App deleted successfully');
  }
}
```

Important
Deleting an SMS App is irreversible. The associated SMS service will be deprovisioned.

## Conversation App lifecycle

SMS Apps that are linked to a Conversation Application are subject to the following lifecycle rules:

- **Conversation App deleted** — If the linked Conversation Application is deleted, the SMS App is also deleted automatically.
- **SMS channel removed** — If the SMS channel is removed from the linked Conversation Application, the SMS App is deactivated.


## Conversation App details in SMS App responses

When you fetch an SMS App (`GET`) or list SMS Apps (`LIST`), the response includes a `conversationApiAppDetails` field that shows which Conversation Application the SMS App is linked to and its channel integration status:

```json
{
  "id": "01ABC1234DEF56789ABC1234",
  "smsServiceId": "a1b2c3d4e5f6",
  "name": "My SMS App",
  "status": "ACTIVE",
  "regions": ["EU"],
  "conversationApiAppDetails": {
    "id": "4CF9CE97504C4A468F4610919D17ECC1",
    "projectId": "ea026751-3edf-40a9-ad93-1b382bd60a78",
    "region": "EU",
    "channelStatus": "ACTIVE"
  },
  "test": false
}
```

- `conversationApiAppDetails` is present when the SMS App is linked to a Conversation Application.
- It is `undefined` (omitted from the response) when the SMS App was just created and not yet linked, or if no matching Conversation App exists.
- `channelStatus` reflects the SMS channel integration state on the Conversation App: `PENDING`, `ACTIVE`, or `INACTIVE`.


## Error responses

The following errors may be returned by the SMS provisioning endpoints:

### Create SMS App

| HTTP | Error Code | Message | When |
|  --- | --- | --- | --- |
| 409 | `SMS_APP_REGION_MISMATCH` | SMS app region does not match the bundle region. | The SMS App region doesn't match the Conversation App's region (when using `convApiApp` or `convApiAppId`) |
| 404 | `CONVERSATION_APP_NOT_FOUND` | Conversation app not found. | The `convApiAppId` provided doesn't exist in the project's region |
| 409 | `SMS_APP_IS_ALREADY_LINKED_TO_CONVERSATION_APP` | SmsApp is already linked to ConversationApp. | Attempting to link an SMS App that already has a Conversation App association |


### Get SMS App

| HTTP | Error Code | Message | When |
|  --- | --- | --- | --- |
| 404 | `SMS_APP_NOT_FOUND` | SmsApp not found. | The provided `smsAppId` doesn't exist in the project |


### Update SMS App

| HTTP | Error Code | Message | When |
|  --- | --- | --- | --- |
| 400 | `NO_FIELDS_TO_UPDATE` | No fields to be updated. | The request body contains no valid fields |
| 404 | `SMS_APP_NOT_FOUND` | SmsApp not found. | The provided `smsAppId` doesn't exist in the project |


### Delete SMS App

| HTTP | Error Code | Message | When |
|  --- | --- | --- | --- |
| 404 | `SMS_APP_NOT_FOUND` | SmsApp not found. | The provided `smsAppId` doesn't exist in the project |


### Connect SMS App to Conversation Application

| HTTP | Error Code | Message | When |
|  --- | --- | --- | --- |
| 404 | `SENDER_NOT_FOUND` | Sender not found. | The `senderId` (SMS App ID) doesn't exist in the project |
| 404 | `CONVERSATION_APP_NOT_FOUND` | Conversation app not found. | The Conversation Application ID doesn't exist in the project. |