# SMS

Register and manage SMS channels. See [SMS Platform Information](/developer/api-integrations/sms/) to get started with SMS notifications.


## Custom SMS response {#createcustomsmsresponse}

Respond to a mobile-originated message based on a keyword consumed by your custom-response webhook, using a mobile-originated ID. See [SMS Keyword Webhooks](/docs/developer/api-integrations/sms/inbound-message-handling/) for information about setting up a custom response webhook server.


[Jump to examples ↓](#createcustomsmsresponse-examples)

### `POST /api/sms/custom-response`

**Security:**

- [bearerAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-bearerAuth)

**Request headers:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `X-UA-Appkey` | `string` | Required | The application key for your project. |

**Request body**

**Content-Type:** `application/json`

**One of:**

  - **`mobile_originated_id`** `string` **REQUIRED**

    The identifier that you received through your SMS webhook corresponding to the mobile-originated message that you're issuing a custom response to. The `mobile_originated_id` is valid for 10 minutes from the `received_timestamp` in the payload sent to your webhook server's `/inbound-sms` endpoint.


    Format: `uuid`

  - **`sms`** `object` **REQUIRED**
    **OBJECT PROPERTIES**

    - **`alert`** `string` **REQUIRED**

      Your custom SMS message.

    - **`shorten_links`** `boolean`

      If true, Airship will shorten HTTP/HTTPS links (space delimited) in the message text fields, producing unique, 25 character URLs for each member of your audience. Airship produces `short_link_click` events in the Real-Time Data Stream for each link that a user engages with.

When this setting is enabled, you can add or remove tags from users who click your links by adding query strings to your URLs. You can serialize tag operations with `&`:
* `?ua-tag-add=tag_group:tag&another_group:tag2` — adds a tag in `tag_group` to the `channel_id`.
* `?ua-tag-remove=tag_group:tag&another_group:tag2` — removes a tag in `tag group` from the `channel_id`.
* `?ua-list-add=subscription_list_id` — adds the user's channel to the `subscription list`.
* `?ua-list-remove=subscription_list_id` — removes the user's channel from the `subscription list`.


      Default: `false`

  - **`mms`** `object` <[MMS platform overrides]({{< ref "/developer/rest-api/ua/schemas/platform-overrides/" >}}#mmsoverrideobject)> **REQUIRED**

    Provides the content for a push to MMS channels. If `sms` is in the `device_type` array, your request may include this object.
It cannot be combined with an SMS Platform Override as a single push can only include either an SMS or MMS payload.


  - **`mobile_originated_id`** `string` **REQUIRED**

    The identifier that you received through your SMS webhook corresponding to the mobile-originated message that you're issuing a custom response to. The `mobile_originated_id` is valid for 10 minutes from the `received_timestamp` in the payload sent to your webhook server's `/inbound-sms` endpoint.


    Format: `uuid`


**Responses**

**`200`** The operation was successful.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

- **`ok`** `boolean`

  If `true`, your request was successful.

- **`operation_id`** `string`

  A unique identifier for an operation; you can use this identifier to find the operation for troubleshooting purposes.

  Format: `uuid`

- **`push_id`** `string`

  A unique identifier for a push operation.

  Format: `uuid`

**`404`** The mobile_originated_id could not be found.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

- **`error`** `string`

  A plain-text explanation of the error.

- **`ok`** `boolean`

  If false, your request was unsuccessful.

- **`operation_id`** `string`

  A unique identifier for an operation; you can use this identifier to find the operation for troubleshooting purposes.

  Format: `uuid`

**Examples**

*SMS example*

```http
POST /api/sms/custom-response HTTP/1.1
Authorization: Bearer <authorization token>
X-UA-Appkey: <app key>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
  "sms" : {
      "alert": "Your balance is $1234.56. Go to https://www.example.com/myaccount/my-balance?ua-tag-add=balance_prefs:sms to see more about your account.",
      "shorten_links": true
  },
  "mobile_originated_id" : "28883743-4868-4083-ab5d-77ac4542531a"
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setBearerToken("<token>")
        .build();

CustomSmsResponseSmsPayload customSmsResponseChannelSms = CustomSmsResponseSmsPayload.newBuilder()
        .setAlert("Your balance is $1234.56. Go to https://www.example.com/myaccount/my-balance?ua-tag-add=balance_prefs:sms to see more about your account.")
        .setMobileOriginatedId("28883743-4868-4083-ab5d-77ac4542531a")
        .setShortenLinks(true)
        .build();

CustomSmsResponseRequest customSmsResponseRequest = CustomSmsResponseRequest.newRequest(customSmsResponseChannelSms);
Response<CustomSmsResponseResponse> response = client.execute(customSmsResponseRequest);

```

```python
from urbanairship import (
    BearerTokenClient, SmsCustomResponse,
    sms, mms
)

client = BearerTokenClient(
    app_key='<app_key>',
    token='<bearer_token>'
)

custom_response = SmsCustomResponse(
    client=client,
    mobile_originated_id="28883743-4868-4083-ab5d-77ac4542531a"
)

custom_response.sms = sms(
    alert="Your balance is $1234.56. Go to https://www.example.com/myaccount/my-balance?ua-tag-add=balance_prefs:sms to see more about your account.",
    shorten_links=True
)

response = custom_response.send()

```

*MMS example*

```http
POST /api/sms/custom-response HTTP/1.1
Authorization: Bearer <bearer token>
X-UA-Appkey: <app key>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
  "mms" : {
    "fallback_text": "See fun cat pics at https://example.com/cat/pics/12345678",
    "slides": [
      {
        "media": {
          "url": "https://example.com/cat/pics/12345678.gif",
          "content_type": "image/gif",
          "content_length": 23098
        }
      }
    ],
    "shorten_links": true
  },
  "mobile_originated_id" : "3e1e4fb3-2d3c-431e-96bf-9b235a12f84b"
}

```

```http
HTTP/1.1 200 OK
Content-Type: application/vnd.urbanairship+json; version=3

{
      "ok": true,
      "operation_id": "f3d0993e-e3e1-4aae-b1c0-864a715bfaff",
      "push_id": "7502abe6-e6ea-4f2b-906f-ebbab612c69e"
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setBearerToken("<token>")
        .build();

MmsSlides mmsSlides = MmsSlides.newBuilder()
        .setText("Test")
        .setMediaUrl("https://example.com/cat/pics/12345678.gif")
        .setMediaContentType("image/gif")
        .setMediaContentLength(23098)
        .build();

CustomSmsResponseMmsPayload customSmsResponseMmsPayload = CustomSmsResponseMmsPayload.newBuilder()
        .setFallbackText("See fun cat pics at https://example.com/cat/pics/12345678")
        .setMobileOriginatedId("28883743-4868-4083-ab5d-77ac4542531a")
        .setSlides(mmsSlides)
        .build();

CustomSmsResponseRequest customSmsResponseRequest = customSmsResponseRequest.newRequest(customSmsResponseMmsPayload);
Response<CustomSmsResponseResponse> response = client.execute(customSmsResponseRequest);

```

```python
from urbanairship import (
    BearerTokenClient, SmsCustomResponse,
    mms
)

client = BearerTokenClient(
    app_key='<app_key>',
    token='<bearer_token>'
)

custom_response = SmsCustomResponse(
    client=client,
    mobile_originated_id="3e1e4fb3-2d3c-431e-96bf-9b235a12f84b"
)

custom_response.mms = mms(
    fallback_text="See fun cat pics at https://example.com/cat/pics/12345678",
    slides=[{
        "media": {
            "url": "https://example.com/cat/pics/12345678.gif",
            "content_type": "image/gif",
            "content_length": 23098
        }
    }],
    shorten_links=True
)

response = custom_response.send()

```

---

## Manually trigger a keyword interaction {#triggersmskeywordinteraction}

Trigger Mobile Originated (MO) keyword interactions on behalf of an MSISDN.


[Jump to examples ↓](#triggersmskeywordinteraction-examples)

### `POST /api/sms/{msisdn}/keywords`

**Security:**

- [basicAppAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAppAuth)
- [basicAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAuth)
- [bearerAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-bearerAuth)

**Path parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `msisdn` | `string` | Required | The identifier for the SMS channel you want to trigger a mobile originated keyword from. |

**Request headers:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `X-UA-Appkey` | `string` | Required | The application key for your project. |

**Request body**

**Content-Type:** `application/json`

- **`keyword`** `string` **REQUIRED**

  The keyword you want to trigger an action for. Must be an alphanumeric string with no spaces.

- **`sender_ids`** `array` <[Sender ID]({{< ref "/developer/rest-api/ua/schemas/others/" >}}#sender_id)> **REQUIRED**

  The [sender IDs](/docs/developer/rest-api/ua/schemas/others/#sender_id) with keyword actions that you want to test. Airship returns a 400 if the `keyword` is not configured for one or more of the senders in the array.

  Min items: 1

- **`timestamp`** `string`

  The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when the MO keyword was sent. If absent, Airship uses the server-time of your request.

  Format: `date-time`

**Responses**

**`200`** The operation was successful.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

- **`ok`** `boolean`

  If `true`, your request was successful.

**`400`** The operation was not successful. If the request is formatted correctly, one or more `sender_ids` does not exist or the keyword is not configured for one or more of the `sender_ids`.


Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**Examples**

*Example*

```http
POST /api/sms/15035556789/keywords HTTP/1.1
User-Agent: Apache-HttpAsyncClient/4.0.1 (java 1.5)
Content-Type: application/json
Authorization: Basic <user:pass>
Connection: close

{
  "keyword" : "stop",
  "sender_ids" : [ "54321", "1234"]
}

```

```http
HTTP/1.1 200 OK
Content-Type: application/json

{
  "ok": true
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

KeywordInteractionRequest request = KeywordInteractionRequest.newRequest("15035556789")
        .addKeyword("stop")
        .addSenderId("54321")
        .addSenderId("1234");

Response<CustomSmsResponseResponse> response = client.execute(request);

```

```python
from urbanairship import (
    BasicAuthClient, KeywordInteraction
)
from datetime import datetime

client = BasicAuthClient(
    key='<app_key>',
    secret='<master_secret>'
)

interaction = KeywordInteraction(
    client=client,
    keyword="stop",
    sender_ids=["54321", "1234"],
    timestamp=datetime(2021, 10, 8, 12, 0, 0)
)
response = interaction.post()

```

*Failure response (Keyword not configured for Sender ID)*

```http
HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "ok" : false,
  "error" : "The following sender(s) are not configured for the 'stop' keyword: ['1234']",
  "error_code" : 400
}

```

---

## Opt-out of SMS messages {#optoutsmschannel}

This will mark an SMS channel as opted-out (inactive) and it will not receive alerts even when they are addressed in the future. To opt the user back in, call the registration function again with a valid `opted_in` value.


[Jump to examples ↓](#optoutsmschannel-examples)

### `POST /api/channels/sms/opt-out`

**Security:**

- [basicAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAuth)
- [bearerAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-bearerAuth)
- [oauth2Token]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-oauth2Token): chn

**Request body**

**Content-Type:** `application/json`

- **`msisdn`** `string` **REQUIRED**

  The mobile phone number you want to opt-out of SMS messages. Must be numeric characters only, without leading zeros. 15 digits maximum.

  Max length: 15

- **`sender`** `string` **REQUIRED**

  A long or short code the app is configured to send from. For example, `12345`.

**Responses**

**`202`** The msisdn/channel is opted-out of SMS notifications.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

- **`ok`** `boolean`

  If true, the operation completed successfully.

**`400`** The request body is not valid.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

- **`details`** `object`
  **OBJECT PROPERTIES**

  - **`error`** `string`

    Specific error message that explains why the request was unsuccessful.

- **`error`** `string`

  Returned with 40x responses; explains why the request was unsuccessful.

- **`error_code`** `integer`

  The 5-digit Airship error code, pointing to a more specific error than the HTTP status.

- **`ok`** `boolean`

  If false, the request was unsuccessful.

**Examples**

*Example*

```http
POST /api/channels/sms/opt-out HTTP/1.1
Authorization: Basic <master authorization string>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
    "sender": "12345",
    "msisdn": "15035556789"
}

```

```http
HTTP/1.1 202 Accepted
Content-Type: application/vnd.urbanairship+json; version=3

{
    "ok": true
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

SmsRegistrationRequest request = SmsRegistrationRequest
        .newOptOutRequest("12345", "15035556789");

Response<SmsRegistrationResponse> response = client.execute(request);

```

```python
from urbanairship import (
    BasicAuthClient, Sms
)

client = BasicAuthClient(
    key='<app_key>',
    secret='<master_secret>'
)

sms = Sms(
    client=client,
    sender='12345',
    msisdn='15035556789'
)
response = sms.opt_out()

```

```ruby
require 'urbanairship'

UA = Urbanairship
airship = UA::Client.new(key: '<app key>', secret: '<master secret>')

sms_channel = UA::Sms.new(client: airship)
sms_channel.msisdn = '15035556789'
sms_channel.sender = '12345'
sms_channel.opt_out

```

---

## Register SMS channel {#registersmschannel}

Create an SMS channel. If the channel has not opted in yet (the request did not contain `opted_in`), Airship creates the channel with `opt_in` set to `false` and the user receives a message prompting them to complete the opt-in flow; you can assign tags and organize `pending` channels before the user has finished the opt-in process, but you cannot send messages to channels until they opt in to your audience.

SMS notifications require a `sender` - a number that recipients will receive SMS notifications from. [Contact Airship Sales](https://www.airship.com/contact-us/) or your Account Manager to provision your project for SMS notifications and complete the configuration.


[Jump to examples ↓](#registersmschannel-examples)

### `POST /api/channels/sms`

{{< note >}}
Avoid repeated registration attempts. Repeated registrations of the same MSISDN and sender without an `opted_in` value will result in multiple opt-in instruction messages being sent to the MSISDN.
{{< /note >}}

**Security:**

- [basicAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAuth)
- [bearerAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-bearerAuth)
- [oauth2Token]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-oauth2Token): chn

**Request body**

**Content-Type:** `application/json`

- **`attributes`** `object`

  An optional object containing the customer-provided attributes associated with the SMS channel.

- **`locale_country`** `string`

  The ISO 3166 two-character country code. The value for this field becomes a tag in the `ua_locale_country` tag group.

- **`locale_language`** `string`

  The ISO 639-1 two-character language code. The value for this field becomes a tag in the `ua_locale_language` tag group.

- **`msisdn`** `string` **REQUIRED**

  The mobile phone number you want to register as an SMS channel (or send a request to opt-in). Must be numeric characters only, without leading zeros.

  Max length: 15

- **`opted_in`** `string`

  The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) that represents the date and time when explicit permission was received from the user to receive messages.

  Format: `date-time`

- **`sender`** `string` **REQUIRED**

  A long or short code the app is configured to send from. For example, `12345`.

- **`tag_operations`** `object` <[Tag Group object]({{< ref "/developer/rest-api/ua/schemas/tags/" >}}#taggroupobject)>

  Optionally one or more tag group objects associated with the SMS channel.

  Tags belong to Tag Groups. Tag Groups appear within the `tags` object for a Named User or the `tag_groups` object for a channel. See also [Device Properties](/docs/reference/data-collection/device-properties/)
``ua_`` is a reserved prefix for Airship-specific tag groups.

A Tag Group has two parts: a "name" string of 1-128 characters, and an array of tags, containing 0-100 tags. Each tag in the array is also a string consisting of 1-128 characters.

- **`timezone`** `string`

  The IANA identifier for a time zone, e.g., `America/Los_Angeles`. The value in this field becomes a tag in the `timezone` tag group.

**Responses**

**`200`** A channel with this msisdn/sender combination already exists.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

**One of:**

  - **`attributes`** `object`
    **OBJECT PROPERTIES**

    - **`ok`** `boolean`

      If `true`, the attributes were set correctly.

  - **`channel_id`** `string`

    Unique Channel ID for the SMS channel.

    Format: `uuid`

  - **`ok`** `boolean`

    If true, Airship creates a channel value with `opt_in` set to `true`.

  - **`operation_id`** `string`

    A unique identifier for an operation; you can use this identifier to find the operation for troubleshooting purposes.

    Format: `uuid`

  - **`tags`** `object`
    **OBJECT PROPERTIES**

    - **`ok`** `boolean`

      If `true`, the tags were set correctly.

  - **`attributes`** `object`
    **OBJECT PROPERTIES**

    - **`ok`** `boolean`

      If `true`, the attributes were set correctly.

  - **`channel_id`** `string` **REQUIRED**

    Unique Channel ID for the SMS channel. This channel is created with `opt_in` set to `false`, as the user has not yet opted in to your audience.

    Format: `uuid`

  - **`ok`** `boolean` **REQUIRED**

    If true, Airship creates a channel with `opt_in` set to `false` and Airship sends a message prompting the user to opt in to your audience.

  - **`operation_id`** `string` **REQUIRED**

    A unique identifier for an operation; you can use this identifier to find the operation for troubleshooting purposes.

    Format: `uuid`

  - **`push_id`** `string` **REQUIRED**

    Identifies the message prompting the user to opt in to your audience, sent as a result of a request without an `opted_in` value.

    Format: `uuid`

  - **`status`** `string` **REQUIRED**

    The channel has been created but has not yet opted-in.

    Possible values: `pending`

  - **`tags`** `object`
    **OBJECT PROPERTIES**

    - **`ok`** `boolean`

      If `true`, the tags were set correctly.


**`201`** The channel was created. If the request did not contain an `opted_in` value, the channel is created with a `pending` status and the channel's `opt_in` value is set to `false`; you can assign assign tags and organize `pending` channels before the user has finished the opt-in process, but you cannot send messages to channels until they complete the opt-in flow.

Response headers:

| Name | Type | Description |
|------|------|-------------|
| `location` | `string` | URI of the channel, used for later registrations. |

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

**One of:**

  - **`attributes`** `object`
    **OBJECT PROPERTIES**

    - **`ok`** `boolean`

      If `true`, the attributes were set correctly.

  - **`channel_id`** `string`

    Unique Channel ID for the SMS channel.

    Format: `uuid`

  - **`ok`** `boolean`

    If true, Airship creates a channel value with `opt_in` set to `true`.

  - **`operation_id`** `string`

    A unique identifier for an operation; you can use this identifier to find the operation for troubleshooting purposes.

    Format: `uuid`

  - **`tags`** `object`
    **OBJECT PROPERTIES**

    - **`ok`** `boolean`

      If `true`, the tags were set correctly.

  - **`attributes`** `object`
    **OBJECT PROPERTIES**

    - **`ok`** `boolean`

      If `true`, the attributes were set correctly.

  - **`channel_id`** `string` **REQUIRED**

    Unique Channel ID for the SMS channel. This channel is created with `opt_in` set to `false`, as the user has not yet opted in to your audience.

    Format: `uuid`

  - **`ok`** `boolean` **REQUIRED**

    If true, Airship creates a channel with `opt_in` set to `false` and Airship sends a message prompting the user to opt in to your audience.

  - **`operation_id`** `string` **REQUIRED**

    A unique identifier for an operation; you can use this identifier to find the operation for troubleshooting purposes.

    Format: `uuid`

  - **`push_id`** `string` **REQUIRED**

    Identifies the message prompting the user to opt in to your audience, sent as a result of a request without an `opted_in` value.

    Format: `uuid`

  - **`status`** `string` **REQUIRED**

    The channel has been created but has not yet opted-in.

    Possible values: `pending`

  - **`tags`** `object`
    **OBJECT PROPERTIES**

    - **`ok`** `boolean`

      If `true`, the tags were set correctly.


**`400`** The channel could not be created. This error occurs when the project is not configured with a valid sender, the request was missing required fields, or the MSISDN does not meet the E.164 international standard.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

- **`errors`** `string`

  Returned with 40x responses; explains reason for the unsuccessful request.

  Example: `Unable to retrieve details for sender 12345 with app_key <application key>`

- **`ok`** `boolean`

  If false, the request was unsuccessful.

**Examples**

*Example*

```http
POST /api/channels/sms HTTP/1.1
Authorization: Basic <application authorization string>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
  "msisdn" : "15035556789",
  "sender": "12345",
  "opted_in": "2020-02-13T11:58:59",
  "timezone": "America/Los_Angeles",
  "locale_country": "US",
  "locale_language": "en",
  "tag_operations": {
    "add": {
      "my_fav_tag_group1": ["tag1", "tag2", "tag3"],
      "my_fav_tag_group2": ["tag1", "tag2", "tag3"],
      "my_fav_tag_group3": ["tag1", "tag2", "tag3"]
    }
  },
  "attributes": {
      "my_fav_attribute1": "attribute1",
      "my_fav_attribute2": "attribute2"
  }
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

SmsRegistrationRequest request = SmsRegistrationRequest
        .newRegistrationRequest("12345", "15035556789", DateTime.parse("2020-02-13T11:58:59Z"));

Response<SmsRegistrationResponse> response = client.execute(request);

```

```python
from urbanairship import (
    BearerTokenClient, Sms
)
from datetime import datetime

client = BearerTokenClient(
    app_key='<app_key>',
    token='<bearer_token>'
)

sms_channel = Sms(
    client=client,
    sender="12345",
    msisdn="15035556789",
    opted_in=datetime.fromisoformat("2020-02-13T11:58:59"),
    locale_country="US",
    locale_language="en",
    timezone="America/Los_Angeles"
)

response = sms_channel.register()

```

```ruby
require 'urbanairship'

UA = Urbanairship
airship = UA::Client.new(key: '<app key>', secret: '<master secret>')

sms_channel = UA::Sms.new(client: airship)
sms_channel.msisdn = '15035556789'
sms_channel.sender = '12345'
sms_channel.opted_in = '2020-02-13T11:58:59'
sms_channel.register

```

*Response (With 'opted_in')*

```http
HTTP/1.1 201 Created
Location: https://go.urbanairship.com/api/channels/7c5d7328-9bb4-4ff7-86b0-96a5f1da5868
Content-Type: application/json

{
  "ok": true,
  "operation_id": "62077236-d032-11e9-af71-ab156113d166",
  "channel_id": "7c5d7328-9bb4-4ff7-86b0-96a5f1da5868",
  "attributes": {"ok": true},
  "tags": {"ok": true}
}

```

*Response (Without 'opted_in')*

```http
HTTP/1.1 202 Accepted
Content-Type: application/json
Location: https://go.urbanairship.com/api/channels/79fbe330-d033-11e9-adfb-df10b89c5e04

{
  "ok": true,
  "operation_id": "62077236-d032-11e9-af71-ab156113d166",
  "push_id": "26350f60-d033-11e9-80e3-33def0e528d1",
  "channel_id": "79fbe330-d033-11e9-adfb-df10b89c5e04",
  "status": "pending",
  "attributes": {"ok": true},
  "tags": {"ok": true}
}

```

*Response (Project not configured with sender)*

```http
HTTP/1.1 400 Bad Request
Content-Type: application/json

{
    "ok": false,
    "errors": "Unable to retrieve details for sender 12345 with app_key <application key>"
}

```

---

## SMS channel lookup {#getsmschannel}

Lookup an SMS channel by `msisdn` and `sender`.

[Jump to examples ↓](#getsmschannel-examples)

### `GET /api/channels/sms/{msisdn}/{sender}`

**Security:**

- [basicAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAuth)
- [bearerAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-bearerAuth)
- [oauth2Token]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-oauth2Token): chn

**Path parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `msisdn` | `integer` | Required | The mobile phone number you want to lookup a channel for. 15 digits maximum; may not contain leading zeroes. |
| `sender` | `integer` | Required | A long or short code the app is configured to send from. |

**Responses**

**`200`** Returns an SMS channel object. An SMS channel object includes tag groups for `ua_channel_type`,
`ua_sender_id`, and `ua_opt_in`.


Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

- **`channel`** `object` <[Channel listing object]({{< ref "/developer/rest-api/ua/schemas/channels/" >}}#channellistingobject)>

  Describes a channel listing object.

- **`ok`** `boolean`

  Success.

**`404`** A `channel_id` does not exist for the `msisdn` and `sender`.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

- **`error`** `string`

  Returned with 40x responses; explains why the request was unsuccessful.

- **`error_code`** `integer`

  The 5-digit Airship error code, pointing to a more specific error than the HTTP status.

- **`ok`** `boolean`

  If false, the request was unsuccessful.

**Examples**

*Example*

```http
GET /api/channels/sms/15035556789/12345 HTTP/1.1
Authorization: Bearer <authorization token>
Accept: application/vnd.urbanairship+json; version=3

```

```http
HTTP/1.1 200 OK
Data-Attribute: channel
Content-Type: application/vnd.urbanairship+json; version=3

{
   "ok": true,
   "channel": {
      "channel_id": "84e36d69-873b-4ffe-81cd-e74c9f002057",
      "device_type": "sms",
      "installed": true,
      "push_address": null,
      "named_user_id": null,
      "alias": null,
      "tags": [],
      "tag_groups": {
         "ua_channel_type": [
            "sms"
         ],
         "ua_sender_id": [
            "12345"
         ],
         "ua_opt_in": [
            "true"
         ]
      },
      "created": "2020-04-27T22:06:21",
      "opt_in": true,
      "opt_in_date": "2022-07-07T03:23:13",
      "msisdn": "150355551234",
      "last_registration": "2020-05-14T19:51:38"
   }
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

ChannelRequest channelRequest = ChannelRequest.newSmsLookupRequest("15035556789","12345");
Response<ChannelResponse> response = client.execute(channelRequest);

```

```python
from urbanairship import (
    BasicAuthClient, Sms
)

client = BasicAuthClient(
    key='<app_key>',
    secret='<master_secret>'
)

sms = Sms(
    client=client,
    sender='12345',
    msisdn='15035556789'
)
channel_info = sms.lookup()

```

```ruby
require 'urbanairship'

UA = Urbanairship
airship = UA::Client.new(key: '<app key>', secret: '<master secret>')

sms_channel = UA::Sms.new(client: airship)
sms_channel.msisdn = '15035556789'
sms_channel.sender = '12345'
sms_channel.lookup

```

*Example opt_out_date*

```http
HTTP/1.1 200 OK
Data-Attribute: channel
Content-Type: application/vnd.urbanairship+json; version=3

{
   "ok": true,
   "channel": {
      "channel_id": "84e36d69-873b-4ffe-81cd-e74c9f002057",
      "device_type": "sms",
      "installed": true,
      "push_address": null,
      "named_user_id": null,
      "alias": null,
      "tags": [],
      "tag_groups": {
         "ua_channel_type": [
            "sms"
         ],
         "ua_sender_id": [
            "12345"
         ],
         "ua_opt_in": [
            "true"
         ]
      },
      "created": "2020-04-27T22:06:21",
      "opt_in": false,
      "opt_in_date": "2022-07-07T03:23:13",
      "opt_out_date": "2022-07-08T03:23:13",
      "msisdn": "150355551234",
      "last_registration": "2020-05-14T19:51:38"
   }
}

```

---

## SMS tags {#modifysmschanneltags}

Add, remove, or set tags for a single SMS channel.

[Jump to examples ↓](#modifysmschanneltags-examples)

### `POST /api/channels/sms/tags`

{{< important >}}
A tag must be < 128 characters. A request with one or more tags longer than 128 characters will return a 400 response.
We support up to 1,000 tags per channel. Adding more than 1,000 tags per channel can cause latency and service interruptions. We strongly recommend removing unused tags whenever possible, and using Custom Events when appropriate. Please [contact Support](https://support.airship.com/) if you believe your use case requires more than 1,000 tags per channel, and they will help you find an alternative.
{{< /important >}}

**Security:**

- [basicAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAuth)
- [bearerAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-bearerAuth)
- [oauth2Token]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-oauth2Token): chn

**Request body**

A single request body can contain an `add` and/or `remove` field or a single `set` field. One or more of the `add`, `remove`, or `set` keys must be present in the request.

**Content-Type:** `application/json`

- **`add`** `object` <[Tag Group object]({{< ref "/developer/rest-api/ua/schemas/tags/" >}}#taggroupobject)>

  Adds the specified tags to the channel. Tags that are already present are not modified/removed as a result of this operation.

  Tags belong to Tag Groups. Tag Groups appear within the `tags` object for a Named User or the `tag_groups` object for a channel. See also [Device Properties](/docs/reference/data-collection/device-properties/)
``ua_`` is a reserved prefix for Airship-specific tag groups.

A Tag Group has two parts: a "name" string of 1-128 characters, and an array of tags, containing 0-100 tags. Each tag in the array is also a string consisting of 1-128 characters.

- **`audience`** `object` **REQUIRED**

  Specifies the MSISDN and sender you want to perform tag operations against.

  **OBJECT PROPERTIES**

  - **`msisdn`** `string`

    The mobile phone number corresponding to the SMS channel. Must be numeric characters only, without leading zeros. 15 digits maximum.

    Max length: 15

  - **`sender`** `string`

    A long or short code the app is configured to send from. For example, `12345`.

- **`remove`** `object` <[Tag Group object]({{< ref "/developer/rest-api/ua/schemas/tags/" >}}#taggroupobject)>

  Removes the specified tags from the channel.

  Tags belong to Tag Groups. Tag Groups appear within the `tags` object for a Named User or the `tag_groups` object for a channel. See also [Device Properties](/docs/reference/data-collection/device-properties/)
``ua_`` is a reserved prefix for Airship-specific tag groups.

A Tag Group has two parts: a "name" string of 1-128 characters, and an array of tags, containing 0-100 tags. Each tag in the array is also a string consisting of 1-128 characters.

- **`set`** `object` <[Tag Group object]({{< ref "/developer/rest-api/ua/schemas/tags/" >}}#taggroupobject)>

  Assigns a list of tags exactly. Any previously set tags that are not in this current list are removed.

  Tags belong to Tag Groups. Tag Groups appear within the `tags` object for a Named User or the `tag_groups` object for a channel. See also [Device Properties](/docs/reference/data-collection/device-properties/)
``ua_`` is a reserved prefix for Airship-specific tag groups.

A Tag Group has two parts: a "name" string of 1-128 characters, and an array of tags, containing 0-100 tags. Each tag in the array is also a string consisting of 1-128 characters.

**Responses**

**`200`** Returns OK for success. If a tag request is partially valid, i.e., at least one tag group exists and is active, a 200 will be returned with a warning in the response about the tag groups that failed to update. The tag groups listed in the warning will be CSV-formatted.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

[OK response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#okresponseobject)

**`400`** There was a parsing or validation error in the request. Bad Request errors typically include `path` and `location` in the response to help you find the cause of the error.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`401`** Authentication information (the app key and secret or bearer token) was either incorrect or missing.

Response body:

**Content-Type:** `text/plain`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`403`** Authentication was correct, but the user does not have permission to access the requested API, e.g., if the feature in question is not included in your pricing plan.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**Examples**

*Example*

```http
POST /api/channels/sms/tags HTTP/1.1
Authorization: Bearer <authorization token>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
   "audience": {
    "sender": "12345",
    "msisdn": "15035556789"
   },
   "add": {
      "my_fav_tag_group1": ["tag1", "tag2", "tag3"],
      "my_fav_tag_group2": ["tag1", "tag2", "tag3"],
      "my_fav_tag_group3": ["tag1", "tag2", "tag3"]
   }
}

```

---

## Uninstall SMS channel {#uninstallsmschannel}

**Removes phone numbers and accompanying data from Airship. Use with caution.** Uninstalling an SMS channel will prevent you from retrieving opt-in and opt-out history for the corresponding msisdn. If the uninstalled msisdn opts-in again, it will generate a new channel_id. The new channel_id cannot be reassociated with any opt-in information, tags, Named Users, Performance Analytics reports, or other information from the uninstalled SMS channel.


[Jump to examples ↓](#uninstallsmschannel-examples)

### `POST /api/channels/sms/uninstall`

**Security:**

- [basicAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAuth)
- [bearerAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-bearerAuth)
- [oauth2Token]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-oauth2Token): chn

**Request body**

**Content-Type:** `application/json`

- **`msisdn`** `string` **REQUIRED**

  The mobile phone number you want to remove from the Airship system. Must be numeric characters only, without leading zeros. 15 digits maximum.

  Max length: 15

- **`sender`** `string` **REQUIRED**

  A long or short code the app is configured to send from. For example, `12345`.

**Responses**

**`202`** The SMS channel and all information associated with the msisdn is uninstalled.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

- **`ok`** `boolean`

  If true, the operation was successful.

**`400`** The request body is not valid.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

- **`details`** `object`
  **OBJECT PROPERTIES**

  - **`error`** `string`

    Specific error message that explains why the request was unsuccessful.

- **`error`** `string`

  Returned with 40x responses; explains why the request was unsuccessful.

- **`error_code`** `integer`

  The 5-digit Airship error code, pointing to a more specific error than the HTTP status.

- **`ok`** `boolean`

  If false, the request was unsuccessful.

**Examples**

*Example*

```http
POST /api/channels/sms/uninstall HTTP/1.1
Authorization: Bearer <authorization token>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
    "sender": "12345",
    "msisdn": "15035556789"
}

```

```http
HTTP/1.1 202 Accepted
Content-Type: application/vnd.urbanairship+json; version=3

{
   "ok": true
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

SmsRegistrationRequest request = SmsRegistrationRequest
        .newUninstallRequest("12345", "15035556789");

Response<SmsRegistrationResponse> response = client.execute(request);

```

```python
from urbanairship import (
    BasicAuthClient, Sms
)

client = BasicAuthClient(
    key='<app_key>',
    secret='<master_secret>'
)

sms = Sms(
    client=client,
    sender='12345',
    msisdn='15035556789'
)
response = sms.uninstall()

```

```ruby
require 'urbanairship'

UA = Urbanairship
airship = UA::Client.new(key: '<app key>', secret: '<master secret>')

sms_channel = UA::Sms.new(client: airship)
sms_channel.msisdn = '15035556789'
sms_channel.sender = '12345'
sms_channel.uninstall

```

---

## Update SMS channel {#updatesmschannel}

Update an existing SMS channel to reflect opt-in date, time zone and/or locale changes. The `msisdn` and `sender` in the request must match the existing channel or the request will 404.


[Jump to examples ↓](#updatesmschannel-examples)

### `PUT /api/channels/sms/{channel_id}`

**Security:**

- [basicAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAuth)
- [bearerAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-bearerAuth)
- [oauth2Token]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-oauth2Token): chn

**Path parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel_id` | `string` | Required | The identifier for the SMS channel you want to update. |

**Request body**

**Content-Type:** `application/json`

- **`locale_country`** `string`

  The ISO 3166 two-character country code. The value for this field becomes a tag in the `ua_locale_country` tag group.

- **`locale_language`** `string`

  The ISO 639-1 two-character language code. The value for this field becomes a tag in the `ua_locale_language` tag group.

- **`msisdn`** `string` **REQUIRED**

  The phone number corresponding to the `channel_id` in the request. You cannot change this value for the existing channel.

  Max length: 15

- **`opted_in`** `string`

  The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) that represents when explicit permission was received from the user to receive messages.

  Format: `date-time`

- **`sender`** `string` **REQUIRED**

  The sender corresponding to the `channel_id` in the request. You cannot change this value for an existing channel.

- **`timezone`** `string`

  The IANA identifier for a time zone, e.g., `America/Los_Angeles`. The value in this field becomes a tag in the `timezone` tag group.

**Responses**

**`200`** The SMS channel was updated successfully.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

- **`ok`** `boolean`

  True if the request was successful.

- **`operation_id`** `string`

  A unique identifier for an operation; you can use this identifier to find the operation for troubleshooting purposes.

  Format: `uuid`

**`400`** The request to update the channel failed. This error occurs when the MSISDN does not fall into the geographical region supported by the sender or the request is incorrect, e.g., missing
or mismatching `msisdn` or `sender`, the `msisdn` is not a valid E.164 standard MSISDN, or invalid timezone/locale values are supplied.


Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

- **`errors`** `string`

  Returned with 40x responses; explains reason for the unsuccessful request.

  Example: `Unable to retrieve details for sender 12345 with app_key <application key>`

- **`ok`** `boolean`

  If false, the request was unsuccessful.

**`404`** Occurs when the `msisdn` and/or `sender` don't match any existing `channel_id`.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

- **`errors`** `string`

  A plain-text explanation of the error.

- **`ok`** `boolean`

  If false, your request was unsuccessful.

**Examples**

*Example*

```http
PUT /api/channels/sms/{channel_id} HTTP/1.1
Authorization: Basic <application authorization string>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
  "msisdn": "15035556789",
  "sender": "12345",
  "opted_in": "2020-02-13T11:58:59",
  "timezone": "America/Los_Angeles",
  "locale_country": "US",
  "locale_language": "en"
}

```

```http
HTTP/1.1 200 OK
Content-Type: application/json

{
  "ok": true,
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

UpdateSmsChannel updateSmsChannel = UpdateSmsChannel.newBuilder()
        .setMsisdn("13609048615")
        .setSender("17372004196")
        .setOptedIn(DateTime.parse("2021-10-11T02:03:03"))
        .setLocaleCountry("US")
        .setLocaleLanguage("en")
        .setTimeZone("America/Los_Angeles")
        .build();

UpdateSmsChannelRequest updateSmsChannelRequest = UpdateSmsChannelRequest.newRequest("308303cf-9c10-4d71-9bc2-d9f3a671ed0c", updateSmsChannel);

Response<GenericResponse> response = client.execute(updateSmsChannelRequest);

```

```python
from urbanairship import (
    BearerTokenClient, Sms
)
from datetime import datetime

client = BearerTokenClient(
    app_key='<app_key>',
    token='<bearer_token>'
)

sms_channel = Sms(
    client=client,
    sender="12345",
    msisdn="15035556789",
    opted_in=datetime.fromisoformat("2021-02-13T11:58:59"),
    locale_country="US",
    locale_language="en",
    timezone="America/Los_Angeles"
)

# Update properties
sms_channel.locale_country = "FR"
sms_channel.opted_in = datetime.fromisoformat("2020-02-13T11:58:59")

response = sms_channel.update()

```

---

