# SMS API

{% hint style="success" %}
**- NEW! - Interactive API docs, now live!**

Visit [api-docs.plumvoice.com](https://api-docs.plumvoice.com/) to **read** Plum API documentation, **build and test requests** in our interactive API sandbox, **review** the responses, and **share** it all with your team.
{% endhint %}

## Overview

Plum offers four services for its SMS REST API:

| Method                   | Service                               | Description                                                                           |
| ------------------------ | ------------------------------------- | ------------------------------------------------------------------------------------- |
| [POST](#queue-sms)       | [sms/queue](#queue-sms)               | [Queues an SMS message and returns an SMS message resource](#queue-sms)               |
| [GET](#sms-status)       | [sms/status](#sms-status)             | [Returns a single SMS message resource](#sms-status)                                  |
| [GET](#sms-messages)     | [sms/messages](#sms-messages)         | [Returns a filtered list of SMS message resources](#sms-messages)                     |
| [GET](#sms-conversation) | [sms/conversation](#sms-conversation) | [Returns SMS messages exchanged between two defined phone numbers](#sms-conversation) |

{% hint style="warning" %}
Please note that each of these SMS REST APIs use HTTP AUTH for authentication. The username/password to be used for authentication are the same as your standard Plum DEV login credentials.
{% endhint %}

All of the SMS REST APIs have the same return format that includes a status (success or failure), error message and the result data.

### **Sample Responses**

{% tabs %}
{% tab title="XML (success)" %}

```markup
<sample>
  <status>success</status>
  <error/>
  <result>
    <!-- SAMPLE RESULT DATA -->
  </result>
</sample>
```

{% endtab %}

{% tab title="XML (failure)" %}

```markup
<sample>
  <status>failure</status>
  <error>Unauthorized access to sample service</error>
</sample>
```

{% endtab %}

{% tab title="JSON (success)" %}

```javascript
{
  "status":"success",
  "error":"",
  "result": {
    // SAMPLE RESULT DATA
  }
}
```

{% endtab %}

{% tab title=" JSON (failure)" %}

```javascript
{
  "status":"failure",
  "error":"Unauthorized access to sample service",
}
```

{% endtab %}

{% tab title="JSON (invalid phone number)" %}

```javascript
{
  "status":"failure",
  "error":"Invalid 'to' phone number",
}
```

{% endtab %}
{% endtabs %}

### Special Notifications

#### Blocked numbers & landlines

Messages to unsubscribed numbers or landlines will fail, returning the [message delivery status](#delivery-status-types) `undelivered`. This also triggers an immediate notification describing why the messages failed.&#x20;

The notification is for user information and **will not** appear as part of the response.

***Examples:***

Message sent to a phone number that previously sent a STOP request (i.e., unsubscribed):

```json
{"status":"failure","error":""Attempt to send to unsubscribed recipient""}
```

Message sent to landline:&#x20;

```json
{"status":"failure","error":""To number: +1xxxxxxxxx, is not a mobile number""}
```

## Sending SMS

## Queue SMS

<mark style="color:green;">`POST`</mark> `https://hosting.vxml.sharpencx.com/ws/sms/{resource_type}`

Queues an SMS message to be sent

#### Path Parameters

| Name           | Type   | Description                 |
| -------------- | ------ | --------------------------- |
| resource\_type | string | `queue.xml` or `queue.json` |

#### Headers

| Name         | Type   | Description                       |
| ------------ | ------ | --------------------------------- |
| Content-type | string | application/x-www-form-urlencoded |
| Accept       | string | application/xml, application/json |

#### Request Body

| Name        | Type   | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| ----------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| to          | string | 10-digit phone number that will receive the SMS message.                                                                                                                                                                                                                                                                                                                                                                                                                         |
| from        | string | <p>Phone number that the SMS will appear from.</p><p></p><p><em>Note: This phone number must appear as an “SMS Number” on the “Account Configuration” page in your Plum DEV account. Any attempt to send an SMS using a number not listed as an “SMS Number” in your account will fail.</em></p><p></p><p><em>Your SMS-enabled number <strong>must be non-PCI</strong>. SMS is unencrypted, which makes SMS messaging incompatible with PCI numbers and infrastructure.</em></p> |
| body        | string | <p>SMS message to be sent<br><em>Note: messages larger than 160 characters will be split into multiple messages.</em></p>                                                                                                                                                                                                                                                                                                                                                        |
| result\_url | string | <p>URL for tracking the SMS result status<br><em>Note: after the SMS is sent this URL will receive a POST with the following variables: 'sms\_message\_id' and 'status'. This should be used to get the status of an SMS message rather than polling the status REST service.</em> </p>                                                                                                                                                                                          |

{% tabs %}
{% tab title="200 " %}
{% tabs %}
{% tab title="JSON" %}

```javascript
{
  "status":"success",
  "error":"",
  "result": {
    "sms_messages": [
      {
        "sms_message_id":"e7f41fdc813d481081ec2840d68838b5",
        "to":"19998881234",
        "from":"2435678910",
        "body":"This is a notification",
        "request_timestamp":1330464356,
        "result_url":"http://myserver.com/storesmsresults.php",
        "status":"queued"
      }
    ]
  }
}
```

{% endtab %}

{% tab title="XML" %}

```markup
<queue>
  <status>success</status>
  <error/>
  <result>
    <sms_messages>
      <sms_message>
        <sms_message_id>e7f41fdc813d481081ec2840d68838b5</sms_message_id>
        <to>19998881234</to>
        <from>2435678910</from>
        <body>This is a notification</body>
        <request_timestamp>1330464356</request_timestamp>
        <result_url>http://myserver.com/storesmsresults.php<result_url>
        <status>queued</status>
      </sms_message>
    </sms_messages>
  </result>
</queue>
```

{% endtab %}
{% endtabs %}
{% endtab %}
{% endtabs %}

**Sample Code**

{% tabs %}
{% tab title="queuesms.php" %}

```php
<?php
header("Content-type: text/xml");

$params['to'] = "19998881234";
$params['from'] = "2435678910";
$params['body'] = "This is a notification.";
$params['result_url'] = "http://myserver.com/storesmsresults.php";

// initialize curl
$ch = curl_init();

// set necessary curl options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_URL, "https://hosting.plumvoice.com/ws/sms/queue.xml");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, "username:password");

echo(curl_exec($ch));

curl_close($ch);
?>
```

{% endtab %}

{% tab title="storesmsresults.php" %}

```php
<?php
// make sure the log file has read/write permissions from the web server
$logfile = "logs/smsresults.log"
if (!is_readable($logfile) || !is_writable($logfile)) {
  die("Unable to write to log file.");
}

if (isset($_POST['sms_message_id'], $_POST['status'])) {
  if ($fp = fopen($logfile, 'a+')) {
    $date = date("r");
    $message_id = $_POST['sms_message_id'];
    $status = $_POST['status'];
    fwrite($fp, "$date $message_id $status\n");
    fclose($fp);
  }
}
?>
```

{% endtab %}

{% tab title="CURL (command line)" %}

```
curl -u username:password -d to=19998881234 -d from=2435678910 -d body='This is a notification' https://hosting.plumvoice.com/ws/sms/queue.xml
```

{% endtab %}
{% endtabs %}

## Receiving SMS

## SMS Status

<mark style="color:blue;">`GET`</mark> `https://hosting.vxml.sharpencx.com/ws/sms/{resource_type}/{sms_message_id}`

Returns the status of an SMS message

#### Path Parameters

| Name             | Type   | Description                                                                                                                                      |
| ---------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| resource\_type   | string | `status.xml` or `status.json`                                                                                                                    |
| sms\_message\_id | string | <p>Unique 128-bit hexidecimal identifier for this SMS message<br><em>Note: this value is provided in the result of a queued SMS message</em></p> |

#### Headers

| Name         | Type   | Description                       |
| ------------ | ------ | --------------------------------- |
| content-type | string | application/x-www-form-urlencoded |
| accept       | string | application/json, application/xml |

{% tabs %}
{% tab title="200 " %}
{% tabs %}
{% tab title="JSON" %}

```javascript
{
  "status":"success",
  "error":"",
  "result": {
    "sms_message_id":"e7f41fdc813d481081ec2840d68838b5",
    "to":"19998881234",
    "from":"2435678910",
    "body":"This is a notification",
    "request_timestamp":"1330464356",
    "response_timestamp":"1330464357",
    "status":"sent",
    "delivery_status":"delivered"
  }
}
```

{% endtab %}

{% tab title="XML" %}

```markup
<status>
  <status>success</status>
  <error/>
  <result>
    <sms_message_id>e7f41fdc813d481081ec2840d68838b5</sms_message_id>
    <to>19998881234</to>
    <from>2435678910</from>
    <body>This is a notification</body>
    <request_timestamp>1330464356</request_timestamp>
    <response_timestamp>1330464357</response_timestamp>
    <status>sent</status>
    <delivery_status>delivered</delivery_status>
  </result>
</status>
```

{% endtab %}
{% endtabs %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
This method with return result `status` as `queued`, `sent`, `received`, or `failed`. When the value of `status` is `sent`, then the method will also return a result `delivery_status` as `delivered` or `undelivered`.
{% endhint %}

### Statuses Explained

#### Message Status Types:

* **Queued**: your message has been added to the queue to be sent.
* **Sent**: your message has been sent.
* **Received**: you have received an incoming message.
* **Failure**: your message could not be sent. Failed messages can happen for a variety of reasons including queue overflows, account suspensions, etc.

#### Delivery Status Types:

* **Delivered**: your message has been successfully delivered to your recipient.
* **Undelivered**: your message was not delivered. There are many reasons why this may occur including, destination number is not a mobile number, carrier content filtering, the availability of the destination number, etc.
* **Unconfirmed**: There is no indication whether or not your message reached your recipient.

{% hint style="danger" %}
**Please be advised!** The delivery status will only be available up to 7 days after the SMS message was sent.
{% endhint %}

**Sample Code**

{% tabs %}
{% tab title="checkstatus.php" %}

```php
<?php
header("Content-type: text/xml");

// for this example, our sms_message_id is e7f41fdc813d481081ec2840d68838b5
$sms_message_id = 'e7f41fdc813d481081ec2840d68838b5';

// initialize curl
$ch = curl_init();

// set necessary curl options
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, "username:password");
curl_setopt($ch, CURLOPT_URL, "https://hosting.plumvoice.com/ws/sms/status.xml/".$sms_message_id);

echo(curl_exec($ch));

curl_close($ch);
?>
```

{% endtab %}

{% tab title="CURL (command line)" %}

```
curl -u username:password https://hosting.plumvoice.com/ws/sms/status.json/e7f41fdc813d481081ec2840d68838b5
```

{% endtab %}
{% endtabs %}

### Special Notifications

#### Blocked numbers & landlines

Messages to unsubscribed numbers or landlines will fail, returning the [message delivery status](#delivery-status-types) `undelivered`. This also triggers an immediate notification describing why the messages failed.&#x20;

The notification is for user information and **will not** appear as part of the response.

***Examples:***

Message sent to a phone number that previously sent a STOP request (i.e., unsubscribed):

```json
{"status":"failure","error":""Attempt to send to unsubscribed recipient""}
```

Message sent to landline:&#x20;

```json
{"status":"failure","error":""To number: +1xxxxxxxxx, is not a mobile number""}
```

## SMS Messages

<mark style="color:blue;">`GET`</mark> `https://hosting.vxml.sharpencx.com/ws/sms/{resource_type}`

Lists SMS messages that have been sent and/or received.

#### Path Parameters

| Name           | Type   | Description                       |
| -------------- | ------ | --------------------------------- |
| resource\_type | string | `messages.xml` or `messages.json` |

#### Query Parameters

| Name             | Type    | Description                                                                                                                                                                                                                                                              |
| ---------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| offset           | integer | Number of SMS messages to skip before returning results                                                                                                                                                                                                                  |
| limit            | integer | <p>Maximum number of SMS messages to return.<br><em>Note: minimum limit is 50, maximum limit is 1000.</em></p>                                                                                                                                                           |
| order            | string  | <p>Sort the SMS messages in ascending or descending order by date.<br>Accepted values are <code>asc</code>, <code>desc</code>, or <code>blank</code></p>                                                                                                                 |
| start\_timestamp | integer | Start timestamp to begin searching for SMS messages.                                                                                                                                                                                                                     |
| end\_timestamp   | integer | End timestamp to stop searching for SMS messages.                                                                                                                                                                                                                        |
| msg\_type        | string  | <p>Type of messages to be returned.<br><em>Note: Accepted values are 'inbound', 'outbound', 'all' (for both inbound and outbound), or <code>blank</code></em>.</p>                                                                                                       |
| phone\_number    | integer | The phone number to filter results on.                                                                                                                                                                                                                                   |
| number\_type     | string  | <p>Available and required <strong>only</strong> when message type is inbound or outbound <strong>AND</strong> a phone number is provided.<br><em>Note: accepted values are 'account' (your SMS phone number) and 'customer' (your end user's SMS phone number)</em> </p> |

{% tabs %}
{% tab title="200 " %}
{% tabs %}
{% tab title="JSON" %}

```javascript
{
  "status":"success",
  "error":"",
  "result": {
    "offset":0,
    "limit":50,
    "total":"2",
    "sms_messages": [
      {
        "sms_message_id":"e7f41fdc813d481081ec2840d68838b5",
        "to":"19998881234",
        "from":"2435678910",
        "body":"This is a notification",
        "request_timestamp":"1330464356",
        "response_timestamp":"1330464357",
        "result_url":"",
        "status":"sent"
      },
      {
        "sms_message_id":"bf811cfb5e864a2793d9b6b81ec2185f",
        "to":"19998881234",
        "from":"2435678910",
        "body":"Resending notification",
        "request_timestamp":"1330464386",
        "response_timestamp":"1330464387",
        "result_url":"",
        "status":"sent"
      }
    ]
  }
}
```

{% endtab %}

{% tab title="XML" %}

```markup
<messages>
  <status>success</status>
  <error/>
  <result>
    <offset>0</offset>
    <limit>50</limit>
    <total>2</total>
    <sms_messages>
      <sms_message>
        <sms_message_id>e7f41fdc813d481081ec2840d68838b5</sms_message_id>
        <to>19998881234</to>
        <from>2435678910</from>
        <body>This is a notification</body>
        <request_timestamp>1330464356</request_timestamp>
        <response_timestamp>1330464357</response_timestamp>
        <result_url/>
        <status>sent</status>
      </sms_message>
      <sms_message>
        <sms_message_id>bf811cfb5e864a2793d9b6b81ec2185f</sms_message_id>
        <to>19998881234</to>
        <from>2435678910</from>
        <body>Resending notification</body>
        <request_timestamp>1330464386</request_timestamp>
        <response_timestamp>1330464387</response_timestamp>
        <result_url/>
        <status>sent</status>
      </sms_message>
    </sms_messages>
  </result>
</messages>
```

{% endtab %}
{% endtabs %}
{% endtab %}
{% endtabs %}

**Sample Code**

{% tabs %}
{% tab title="getmessages.php" %}

```php
<?php
header("Content-type: text/xml");

// initialize curl
$ch = curl_init();

// set necessary curl options
curl_setopt($ch, CURLOPT_URL, "https://hosting.plumvoice.com/ws/sms/messages.xml?offset=0&limit=50&start_timestamp=0&end_timestamp=0&msg_type=inbound&phone_number=xxxxxxxxxx&number_type=account");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, "username:password");

echo(curl_exec($ch));

curl_close($ch);
?>
```

{% endtab %}

{% tab title="CURL (command line)" %}

```
curl -u username:password "https://hosting.plumvoice.com/ws/sms/messages.json/?offset=0&limit=50&start_timestamp=0&end_timestamp=0&msg_type=inbound&phone_number=xxxxxxxxxx&number_type=account"
```

{% endtab %}
{% endtabs %}

## SMS Conversation

<mark style="color:blue;">`GET`</mark> `https://hosting.vxml.sharpencx.com/ws/sms/{resource_type}`

Lists messages between two phone numbers

#### Path Parameters

| Name           | Type   | Description                                |
| -------------- | ------ | ------------------------------------------ |
| resource\_type | string | `conversation.xml` or  `conversation.json` |

#### Query Parameters

| Name             | Type    | Description                                                                                                                                              |
| ---------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| offset           | integer | Number of SMS messages to skip before returning results.                                                                                                 |
| limit            | integer | <p>Maximum number of SMS messages to return.<br><em>Note: minimum limit is 50, maximum limit is 1000.</em></p>                                           |
| order            | string  | <p>Sort the SMS messages in ascending or descending order by date.<br>Accepted values are <code>asc</code>, <code>desc</code>, or <code>blank</code></p> |
| start\_timestamp | integer | Start timestamp to begin searching for SMS messages.                                                                                                     |
| end\_timestamp   | integer | End timestamp to stop searching for SMS messages.                                                                                                        |
| phone\_number1   | integer | First phone number to filter on for the returned conversation.                                                                                           |
| phone\_number2   | integer | Second phone number to filter on for the returned conversation.                                                                                          |

{% tabs %}
{% tab title="200 " %}
{% tabs %}
{% tab title="JSON" %}

```javascript
{
  "status":"success",
  "error":"",
  "result":{
    "offset":"0",
    "limit":"50",
    "total":"4",
    "sms_messages":[
      {
        "sms_message_id":"b84b2dbfadcc49e1a697aabfdb1f2730",
        "to":"19998881234",
        "from":"2435678910",
        "body":"GREAT",
        "request_timestamp":"1594662275",
        "response_timestamp":"1594662276",
        "result_url":"",
        "type":"inbound",
        "status":"received"
      },
      {
        "sms_message_id":"4beb4b8ace954ff694bdadb8cca99ac9",
        "to":"2435678910",
        "from":"19998881234",
        "body":"Thanks for visiting us today! Tell us how we did. Reply back with \"OK\", \"GOOD\", \"GREAT\" or \"EXCELLENT\".",
        "request_timestamp":"1594662276",
        "response_timestamp":"1594662279",
        "result_url":"",
        "type":"outbound",
        "status":"sent"
      },
      {
        "sms_message_id":"dd2ee079413f48b49e45879241af09d4",
        "to":"19998881234",
        "from":"2435678910",
        "body":"CONFIRM",
        "request_timestamp":"1594662276",
        "response_timestamp":"1594662276",
        "result_url":"",
        "type":"inbound",
        "status":"received"
      },
      {
        "sms_message_id":"6b8e2bd2e9e5485d9123ec929f462efd",
        "to":"2435678910",
        "from":"19998881234",
        "body":"This is a notification of your appointment tomorrow. Please reply with \"CONFIRM\", to confirm your appointment.",
        "request_timestamp":"1594662313",
        "response_timestamp":"1594662314",
        "result_url":"",
        "type":"outbound",
        "status":"sent"
      }
    ]
  }
}
```

{% endtab %}

{% tab title="XML" %}

```markup
<conversation>
    <status>success</status>
    <error></error>
    <result>
        <offset>0</offset>
        <limit>50</limit>
        <total>4</total>
        <sms_messages>
            <sms_message>
                <sms_message_id>b84b2dbfadcc49e1a697aabfdb1f2730</sms_message_id>
                <to>19998881234</to>
                <from>2435678910</from>
                <body>GREAT</body>
                <request_timestamp>1594662275</request_timestamp>
                <response_timestamp>1594662276</response_timestamp>
                <result_url></result_url>
                <type>inbound</type>
                <status>received</status>
            </sms_message>
            <sms_message>
                <sms_message_id>4beb4b8ace954ff694bdadb8cca99ac9</sms_message_id>
                <to>2435678910</to>
                <from>19998881234</from>
                <body>Thanks for visiting us today! Tell us how we did. Reply back with "OK", "GOOD", "GREAT" or "EXCELLENT".</body>
                <request_timestamp>1594662276</request_timestamp>
                <response_timestamp>1594662279</response_timestamp>
                <result_url></result_url>
                <type>outbound</type>
                <status>sent</status>
            </sms_message>
            <sms_message>
                <sms_message_id>dd2ee079413f48b49e45879241af09d4</sms_message_id>
                <to>19998881234</to>
                <from>2435678910</from>
                <body>CONFIRM</body>
                <request_timestamp>1594662276</request_timestamp>
                <response_timestamp>1594662276</response_timestamp>
                <result_url></result_url>
                <type>inbound</type>
                <status>received</status>
            </sms_message>
            <sms_message>
                <sms_message_id>6b8e2bd2e9e5485d9123ec929f462efd</sms_message_id>
                <to>2435678910</to>
                <from>19998881234</from>
                <body>This is a notification of your appointment tomorrow. Please reply with "CONFIRM", to confirm your appointment.</body>
                <request_timestamp>1594662313</request_timestamp>
                <response_timestamp>1594662314</response_timestamp>
                <result_url></result_url>
                <type>outbound</type>
                <status>sent</status>
            </sms_message>
        </sms_messages>
    </result>
</conversation>
```

{% endtab %}
{% endtabs %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
Be sure to filter based on your Plum-provided SMS number and the end-user's phone number to yield the correct results. Use the `phone_number1` or `phone_number2` parameters with either filtered number.
{% endhint %}

**Sample Code**

{% tabs %}
{% tab title="getconversation.php" %}

```php
<?php
header("Content-type: text/xml");

// initialize curl
$ch = curl_init();

// set necessary curl options
curl_setopt($ch, CURLOPT_URL, "https://hosting.plumvoice.com/ws/sms/conversation.xml?offset=0&limit=50&start_timestamp=0&end_timestamp=0&phone_number1=xxxxxxxxxx&phone_number2=xxxxxxxxxx");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, "username:password");

echo(curl_exec($ch));

curl_close($ch);
?>
```

{% endtab %}

{% tab title="CURL (command line)" %}

```
curl -u username:password "https://hosting.plumvoice.com/ws/sms/messages.json/?offset=0&limit=50&start_timestamp=0&end_timestamp=0&phone_number1=xxxxxxxxxxx&phone_number2=xxxxxxxxxx"
```

{% endtab %}
{% endtabs %}
