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
Before creating an SMS App, ensure you have:
- A Sinch account: Register and sign in via Sinch Build: 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
- Create project credentials: Access Keys
The following Node.js code sample demonstrates how to create a new SMS App for a specific project:
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;
}To automatically create a linked Conversation Application alongside the SMS App, set convApiApp to true:
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;
}To link the SMS App to an existing Conversation Application, provide its ID via convApiAppId:
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;
}You cannot provide both convApiApp: true and convApiAppId in the same request. Use one or the other.
All create variants return an SMS App object:
{
"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 |
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.
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 when you want full control over each resource.
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 |
If the SMS App region and the Conversation Application region do not match, the request will fail.
You can also use the Bundles endpoint to create the SMS App and Conversation Application together in a single atomic request:
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 for full details.
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.
Retrieve a paginated list of SMS Apps for your project:
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 |
Get details of a specific SMS App by its ID:
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 |
Update the name of an existing SMS App:
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;
}Delete an SMS App by its ID:
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');
}
}Deleting an SMS App is irreversible. The associated SMS service will be deprovisioned.
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.
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:
{
"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
}conversationApiAppDetailsis 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. channelStatusreflects the SMS channel integration state on the Conversation App:PENDING,ACTIVE, orINACTIVE.
The following errors may be returned by the SMS provisioning endpoints:
| 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 |
| HTTP | Error Code | Message | When |
|---|---|---|---|
| 404 | SMS_APP_NOT_FOUND | SmsApp not found. | The provided smsAppId doesn't exist in the project |
| 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 |
| HTTP | Error Code | Message | When |
|---|---|---|---|
| 404 | SMS_APP_NOT_FOUND | SmsApp not found. | The provided smsAppId doesn't exist in the project |
| 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. |