SMS API documentation

1.4



API

General

API Keys

Every client Application (APP) has an API Key associated with it. This key is generated during the creation of the APP and can be re-generated from the show / edit screens in the Service Layer (SL) administrative console.

This key uniquely identifies an APP during the calls the APP does to the SL.

Calls

All calls should be performed with POST request. The API Key (api_key) is the only form field required to be present in every call to the service layer since it is necessary to identify the application.

There’s an API URL that is used at all times to which the name of the operation is appended:

URL: http://sl.holmesmobile.com/api/<operation> or https://sl.holmesmobile.com/api/<operation> (SSL support)

Data Types

Parameters that you specify in the calls to API and receive in callbacks from the API can be of different types.

String

Regular text string.

Integer

Integer number, either positive or negative.

Boolean

We are quite flexible with booleans.

  • They are case-insensitive and can take the following shapes:
    • TRUE: 1, t, true, y, yes
    • FALSE: 0, f, false, n, no

Dates / Times

Dates and times parsing is very liberal in the SL. We are capable of parsing almost everything that can be interpreted as a date / time or even a clue of them. Here are some examples of what the dates can look like:

  • 16:30 — takes current date as basis and uses provided time
  • Aug 31 — take current year, users the given date and sets time to 00:00
  • 7/31 — the same as above
  • 2/9/2007 or 2007-02-09 — date only
  • 02-09-2007 12:30:44 AM or 2007-09-02T00:30:44Z — UTC (GMT) time
  • 02-09-2007 12:30:44 PM EST or 2007-09-02T12:30:44-0500 — localized time
  • Wednesday, January 10, 2001 — human-readable date

If you need a stricter definition, you can refer to RFC2822 (3.3. Date and Time Specification).

Keywords

Keywords

This set of calls let the application to associate / dissociate more keywords with itself. All necessary checks are performed automatically to avoid conflicts.

Associate Keyword (associate_keyword)

Associates the keyword with the application.

Parameters:

  • api_key – (String) API key of the application
  • keyword – (String) keyword
  • mode – (Integer) 0 – match exactly, 1 – start with
  • auto_subscribe – (Boolean, Optional) TRUE – keyword will initiate the subscription
  • auto_subscribe_tags – (String, Optional) comma-separated list of tags to assign to the newly created auto-subscription

Responses:

  • HTTP Code 500 and error message in the body
  • HTTP Code 200 with JSON hash (text/javascript):
    • errors – optional array of error messages, in case of any problems with the keyword registration (duplicates, incorrect format etc). If this element isn’t present, the operation was successful.

Dissociate Keyword (dissociate_keyword)

Breaks the link between the keyword and the application.

Parameters:

  • api_key – (String) API key of the application
  • keyword – (String) keyword

Responses:

  • HTTP Code 500 and error message in the body
  • HTTP Code 200 with JSON hash (text/javascript):
    • errors – optional array of error messages. For example, when the keyword belongs to a different application.

Messaging

Send Message (send_message)

If an application needs to send a message to a certain phone number, it uses this call. The message can be of arbitrary size. If it doesn’t fit into the standard message size (160 characters), the message will be broken into several parts automatically, like this:

  • (1/3) The beginning …
  • (2/3) … continuation …
  • (3/3) … the ending.

Scheduled messages are sent in batches every 15 minutes. The format of the date (“on” field) may vary from very strict “10/12/2008 12:55AM -0500” to the relaxed “Tuesday 9 1:15PM”. If the timezone isn’t specified, the EST (GMT-5) is assumed.

Split Modes:

When message breaking is necessary, it can be performed in one of three predefined ways. The way can be chosen on per-application basis and is set in the Application preferences on the Service Layer side.

  • Character Boundary – the message will be split in part without looking for gaps between the words and the ends of sentences. It’s the most compact way of breaking the messages that ensures the minimal number of parts being sent.
  • Word Boundary – the message text is analyzed for the gaps between the words and split so that no word is broken unless the message becomes severely under-filled (more than a half of the message is empty). In this case the Character Boundary mode is used to fill the rest of the part and the operation switches back to normal Word Boundary operation for the next part.
  • Sentence Boundary – the message is broken into parts preferably on the sentence edges which are (commas, exclamation and question marks, and line breaks). Again if the message appears to be under-filled, the mode is switched to the Word Boundary and if even this doesn’t help, it is lowered to the Character Boundary.

Parameters:

  • api_key – (String) API key of the application
  • phone_number or phone_numbers – (String) destination phone number (10 digits with or without country code) or a comma-separated list of phone numbers.
  • body – (String) message text
  • action_expected – (Boolean, Optional) send TRUE if the response from the target phone is expected. In this case, the session between the phone and the Application is established for seamless directing of the response MO’s to the application without the need of sending the Keyword to select the Application first.
  • on – (String, Optional) time when the message is to be sent

Responses:

  • HTTP Code 500 and error message in the body
  • HTTP Code 200
    • Comma-separated list of scheduled message IDs is returned with the “message_ids” key. This is useful for matching sent messages with delivery reports and message cancellation.

Send Messages (send_messages)

Sometimes you need to send several slightly different messages to several phone numbers. You could issue multiple “send_message” requests, but there’s a better way. Basically, you specify a template to use as a basis for your messages and then for each number you only give the different parts to paste into the template for each number. Here’s an example:

  • template = “Hello {{name}}. You have {{credits}} credits left.”
  • recipients = ‘{"0123456789": {"name": “John”, “credits”: "5"}, “9876543210”: {"name": “Mary”, “credits”: "10"}}’

The phone number 0123456789 will receive “Hello John. You have 5 credits left.” and the phone number 9876543210 will receive “Hello Mary. You have 10 credits left.”

Parameters:

  • api_key – (String) API key of the application
  • template – (String) template string to use for generation of recipient messages.
  • recipients – (String) JSON-hash with phone numbers (10 digits) as keys and the substitution hash as values. Each substitution hash contains the names of tags you mentioned in the template body as keys and the replacement values as values.
  • action_expected – (Boolean, Optional) send TRUE if the response from the target phone is expected. In this case, the session between the phone and the Application is established for seamless directing of the response MO’s to the application without the need of sending the Keyword to select the Application first.
  • on – (String, Optional) time when the message is to be sent

Responses:

  • HTTP Code 500 and error message in the body
  • HTTP Code 200
    • Comma-separated list of scheduled message IDs is returned with the “message_ids” key. This is useful for matching sent messages with delivery reports and message cancellation.

Cancel Messages (cancel_messages)

This call cancels messages scheduled for future delivery with the send_message call with parameter “on”. The send_message call returned the list of IDs corresponding to all scheduled messages or parts of the bigger message that didn’t fit into a single text message. You can use these IDs to cancel future messages at any moment.

Please note that this call can cancel only non-subscription messages. To cancel subscription-level messages, use “cancel_subscription_messages” call.

Parameters:

  • message_ids – (String) comma-separated list of scheduled message IDs

Responses:

  • HTTP Code 500 and error message in the body
  • HTTP Code 200
    • canceled_count – (Integer) the number of canceled messages

Delivery status (delivery_status)

This call accepts a single sent message ID or the list of IDs separated by commas and returns the status for each of the messages. If the message wasn’t found, it’s not mentioned in the results. The statuses have numeric values and are as follows:

  • 0 – Pending delivery
  • 1 – Delivered to the user phone
  • 2 – Not delivered to the user phone (failed)

Parameters:

  • message_ids – (String) comma-separated list of message IDs (either scheduled or not) returned from the send_message call

Responses:

  • The JSON-formatted map of found message IDs to their statuses

Subscriptions

Tag Subscribers (tag_subscribers)

Assigns the list of tags to the list of phone numbers among the subscribers of your application.

Parameters:

  • api_key – (String) API key of the application
  • tags – (String) comma-separated list of tags
  • phone_numbers – (String) comma-separated list of phone numbers with or without the country code

Responses:

  • HTTP Code 500 and error message in the body
  • HTTP Code 200

Un-tag Subscribers (untag_subscribers)

Removes the tags in the list from the phone numbers (all or specific, if they are given).

Parameters:

  • api_key – (String) API key of the application
  • tags – (String) comma-separated list of tags
  • phone_numbers – (String, Optional) comma-separated list of phone numbers with or without the country code

Responses:

  • HTTP Code 500 and error message in the body
  • HTTP Code 200

Count Tagged Subscribers (count_tagged_subscribers)

Returns the number of subscribers in each tag.

Parameters:

  • api_key – (String) API key of the application
  • tags – (String) comma-separated list of tags

Responses:

  • HTTP Code 500 and error message in the body
  • HTTP Code 200 with JSON hash (text/javascript) with tag-count pairs

Send Subscription Message (send_subscription_message)

Sends a message to the application subscribers. The message is split into multiple parts using the preferred application splitting mode automatically.

If the list of tags is given, subscribers with these tags are chosen. If no tag is specified, all subscribers receive the message.

If the time in the “on” field is given the call operates in the scheduling mode. It schedules a message to be sent to the application subscribers in a future. The message text will be split and otherwise processed as in the usual subscription message sending. The date of the message sending has to be tomorrow or later. The date can contain the suggested time and the application will use it as a guidance. The message is guaranteed to not be sent before this time, but can be sent later. The messages are supposed to be sent in batches periodically during the day (currently every two hours). The format of the date may vary from very strict “10/12/2008 12:55AM -0500” to the relaxed “Tuesday 9 1:15PM”. If the timezone isn’t specified, the EST (GMT-5) is assumed.

Parameters:

  • api_key – (String) mandatory API Key
  • body – (String) message text
  • on – (String, Optional) time when the message is to be sent
  • tags – (String, Optional) comma-separated list of tags
  • description – (String, Optional) description of this message or any other info that you want to save

Responses:

  • HTTP Code 500 and error message in the body
  • HTTP Code 200 with JSON hash (text/javascript)
    • If immediate subscription message:
      • recipient_count – number of recipients that received the message (only if it wasn’t a scheduled message)

Cancel Subscription Messages (cancel_subscription_messages)

This call cancels subscription messages scheduled for future delivery with the send_subscription_message call with the parameter “on”. The send_subscription_message call returned the list of IDs corresponding to all scheduled messages. You can use these IDs to cancel future messages at any moment.

Please note that this call is for scheduled subscription messages. Use “cancel_messages” call for regular future messages cancellation.

Parameters:

  • message_ids – (String) comma-separated list of scheduled subscription message IDs

Responses:

  • HTTP Code 500 and error message in the body
  • HTTP Code 200
    • canceled_count – (Integer) the number of canceled messages

Callbacks

General

Client applications receive callbacks from the Service Layer through their Gateway URL. There are difference callbacks that let the application know of certain events with the user sessions, subscriptions and more.

Format

Callback date and type are set as individual fields in the POST request to the client application. Field “type” contains the name / type of the function, and other fields contain additional information that may be useful to the application in its processing of the callback — phone numbers, message bodies and other parameters.

Implementation on the Client Application side

Callbacks aren’t required to be implemented. In fact, you can ignore all of them, although this application may be not very useful. We imagine that you will want to at least listen to incoming messages through the “incoming_message” callback.

Responses

Some of callbacks have optional responses expected, such as the list of tags to assign to a newly created subscription (see subscription_created callback). The format of the response is currently set to the plain text, but later this may be changed to the JSON. This step may be required to facilitate rich and structured responses.

Processing

It’s suggested that you process the callback as fast as possible on the client application side to release Service Layer resources.

Incoming Message (incoming_message)

Received when new MO arrives and it’s routed to this client application.

When the message initiates the session and the keyword that was a match is marked as for the auto-subscription, the “auto-subscribe” flag is set meaning that after this callback is processed there will be an automatic subscription of the texter performed by the service layer. As the result of this process, there will be a subscription confirmation message sent to the texter, meaning that you may decide not to send a normal response from this (incoming_message) call to avoid sending two messages.

If the message is marked as “auto_responded”, it means that the texter has already received the message that was associated with the keyword. You may choose to send another message or stay silent to avoid duplicates.

Parameters:

  • type = incoming_message
  • phone_number – phone number of a texter
  • body – message body
  • sent_at – origination timestamp
  • auto_subscribe – (optional, boolean) flags that this message initiated the session with auto-subscription
  • auto_responded – (optional, boolean) flags that this message was already responded with the keyword-associated message
  • carrier_id – (optional) carrier ID
  • carrier_name – (optional) carrier name

Responses:

  • Empty response not to send anything back to the texter
  • The message to send

Delivery report (delivery_report)

When the message is sent with send_message (either in the future or immediately), the list of message IDs is returned. Each ID represents the part of the original message if it was larger than the maximum allowed number of characters in the single SMS message.

Parameters:

  • message_id – ID of the message the status of which has changed
  • final – (boolean) TRUE if this report is final and no updates are to be expected
  • status – new status of the message, where possible values are:
    • 0 – Pending delivery
    • 1 – Delivered
    • 2 – Delivery failed
    • 4 – Queued for delivery

Responses:

  • Ignored. This is a one-way fire and forget notification.

Sessions

Session Closed (session_closed)

This callback is performed when the user session with an application is closed for any reason. It can be the session expiry or the explicit command from the user.

Parameters:

  • type = session_closed
  • phone_numbers – comma-separated list of user phone numbers

Subscriptions

Service Layer, when it takes care of the subscription management (Subscription Module is enabled for the application), consumes all messages related to the subscription cycle, such as STOP, SUB, Y and others. In order to still let the application know and react to subscription / cancellation events, we provide convenient callbacks.

Subscription Created (subscription_created)

This callback is performed when a new subscription is created. The application may decide that this particular subscription has to be tagged in some way. If it does, the comma-separated list of tags can be returned as the HTTP response to this callback request. Tags can contain spaces, letters, digits, ‘-’ and ‘_’ characters.

Parameters:

  • type = subscription_created
  • phone_number – phone number of a new subscriber

Responses:

  • Empty response if no tagging is required
  • Comma-separated list of tags to assign to the corresponding subscription record

Subscription Canceled (subscription_canceled)

This is invoked when a user decides to unsubscribe from the application.

Parameters:

  • type = subscription_canceled
  • phone_number – phone number of the unsubscribed user

Modules

General

Basics

Modules let developers to add more standard processing options to the service layer. Modules are called when an incoming message arrives to the application, and are expected to return either nil (if they don’t know how to handle the message), or the hash with the following fields:

  • body – (string) the response message to return to the cell phone (empty – no response)
  • free – (boolean) TRUE to send the response through the FTEU gateway

Modules are organized in the chain (see App#MODULES), and are processed in this order. If the first module returns the result, the second listed isn’t called and even not instantiated.

Processing MO modules

The example of a module is the subscription processing. Given that many applications share this functionality, we extract the processing of keywords “SUB”, “Y”, “STOP” in a module and place it before the “Client App Call” module so that if one of these keywords arrive, we can process them ourselves on the Service Layer instead of sending the request to the client application.

You can have any number of modules.

Configuration

Sometimes modules will require different configuration from application to application. It’s suggested to have a separate table for configuration options for a specific module and link it to the application table through the 1-to-1 relationship. However, with the potential growth of modules the approach may be overlooked in favor of an module settings table that will hold key/value rows suitable for the use by any modules in a unified way.

Help

Help module listens for the HELP keywords to applications and makes sure that the response the application sends is delivered as Free To End User (FTEU) message.

The module doesn’t do anything besides that. It delegates the processing to the client application, and wraps the response in the correct structure.

Static Responses

Static responses module provides an extremely flexible feature — automated responses to certain keywords — to client applications or SMSCs in general. Static responses are stored in the table where keywords are associated with responses.

When MO arrives, its contents are checked against the table associated with the target application (or with SMSC it came through if no application is currently associated with the phone number). If the message finds its response, the client application never receives it, but instead the MT is sent automatically.

An application or SMSC can have any number of static responses that can be registered through the application (or SMSC) details page. Every message can have the Free flag set which means that the response has to be sent as an FTEU message.

Configuration:

  • Keyword-Response pairs can be entered on the application / SMSC details page

Subscriptions

Subscriptions module when enabled controls whole cycle of subscription management and enables the applications to use subscription registration, tagging and message sending.

The module monitors incoming messages for the keywords and processes them when detected without passing the messages to the client applications. Keywords and responses to them are entered in the Subscription Configuration on per-application basis.

All subscribers are registered in the Subscriptions table and can be tagged by the client application for the purpose of grouping.

Configuration:

  • Subscription Keywords – space-separated list of keywords that indicate the subscription request (default, SUB)
  • Subscription Message – message to return the user on successful subscription (default, Subscribed to [STORE] special offers. Up to 5/mo. Std msging rates & other charges may apply. Cancel, reply STOP, for help, HELP. T&Cs: [LINK])
  • Confirmation Keywords – space-separated list of keywords that indicate the confirmation of the subscription request for AT&T users (default, Y)
  • Confirmation Message – message to return when the subscription confirmation is required (default, [STORE] special offers – up to 5/mo. Txt Y to accept. Other charges may apply. Cancel, reply STOP, for help, HELP. T&Cs: [LINK])
  • Cancellation Keywords – space-separated list of keywords that indicate the cancellation of the subscription (default, STOP END QUIT CANCEL UNSUBSCRIBE)
  • Cancellation Message – message to return when the subscription is canceled (default, You’ve canceled your subscription to [STORE] special offers. You will not receive any more messages. More, visit [LINK])
  • Unsubscribed Cancellation Message – message to send when the cancellation request is sent by an unsubscribed user (default, Your subscription to [STORE] special offers is canceled. You will not receive any messages. More, visit [LINK])
  • Renewal Keywords – message to send when the subscription is renewed (default, Renewed: Subscribed to [STORE] special offers. Up to 5/mo. Std msging rates & other charges may apply. Cancel, reply STOP, for help, HELP. T&Cs: [LINK])
  • Limit – number of subscription message per Limit Period that are allowed to this application (default, 5)
  • Limit Period – period of the limit (day, week, month etc)

Welcome

Welcome module is intended to send Welcome responses to the first-time users of SMSCs or applications.

This module works on two levels: SMSCs and Applications. In most cases, responses belong to a specific application and they will be passing through the application-level module. In rare cases, when the message is not associated with any application, the module of the SMSC it came through will be working with it.

This module doesn’t stop the processing of the message. It sends the welcome message (if entered) in addition to the further processing which may or may not result in any additional messages.

Configuration:

  • Welcome text message – the message to send. If the message is not given, the module is inactive. The message field can be found on the application and SMSC edit page in the administrative console.

Architecture

Purpose and Responsibilities

Service Layer lays in the heart of the system. The goals of the Service Layer are:

  • Control the workflow of applications with modules
  • Direct messages to and from the applications
  • Maintain the list of applications and user sessions, and link the two

High-level Design

The high-level design of the system is presented on the first page of the document attached ( Service Layer.pdf ). You can clearly see that the system is composed of three main parts: the database, service layer and web-based front-end.

Service Layer is intended to communicate with Kannel and client applications acting as a midware and controlling the workflow. The web-based front-end is the so-called “face” of the system that is used to configure, manage and monitor the system.

Clients and Applications

  • The Client is a registered entity owning some applications that use Service Layer services to receive and send messages to the mobile users / devices.
  • Every Client can have multiple Applications registered. Each Application has its own URL and an identification key. These two bits of information are used to communicate between the Application and the Service Layer.
  • All traffic between an Application and the Service Layer is recorded in the database (MO and MT tables holding incoming and outgoing messages). This info is used to generate usage reports and do proper volume-based billing.
  • Registration of Clients can be:
    • Self-served – Clients can use the web front-end to register themselves and their Applications
    • Staff-based – company staff can register Clients and their Applications

Service Plans and Billing

Each Client (Application) can be assigned a certain service plan that specifies the prices and (maybe later) available features. Currently there’s a need to have two plans, but the number can grow with time. It’s even possible that current requirement can be reduced to a single plan.

Web-based Front End

Service Layer, as a module, has no graphical interface. Although there’s a web-based front-end that the clients of the system and staff use to:

  • register new clients
  • register applications
  • choose appropriate modules from available to be used with the applications (for example, subscriptions module or static responses)
  • see reports and billing info

The front-end works with the same database as the Service Layer. Even though the front-end and the Service Layer can be fit into the boundaries of the same web application, it’s suggested to think of them as of two different modules to aid proper separation of concepts and responsibilities.

Building Applications

General Information

Building user applications with an operating Service Layer is extremely easy. It’s necessary to understand though that an Application is external to the Service Layer. Service Layer contains no logic specific to any application, but rather abstract common information usually in the form of the workflows.

What is a workflow? A Workflow represents some common logic of the application. For example, many applications use the same logic of providing the response to the HELP message, as well as many applications provide means of SUBSCRIBING and UNSUBSCRIBING to/from some service. These typical scenarios can be handled by the middleware (Service Layer) once it’s instructed about what to do when a certain event happens (what text to show in response to the HELP message, and what URL to use to notify about new subscriptions). A proper workflow can be selected for each application through selecting and configuring any of provided modules.

Service Layer and Applications

API

The two-way communication between an Application and the Service Layer is required. By this I mean that the initiator of the exchange can be both the Service Layer (an external message has arrived and an action from the Application is required) and the Application (something happened on the Application side and messages have to be delivered). This requirement dictates that there have to be at least two URL’s known to the developer of an application:

  • The URL on the server running the application that will be used by the Service Layer to deliver incoming messages and callbacks (Gateway URL). This URL can have an arbitrary format, like:

http://myserver.com/notification.php

  • The URL on the Service Layer server that will be used by the application when it needs to send the messages. To identify the application and provide the means for minimum security the key has to be generated that will be appended to the service URL. To illustrate the point, here’s the sample URL:

http://sl.holmeslabs.com/api/...?api_key=<key>

Receiving MO’s from Service Layer (type = incoming_message)

As you already know, Gateway URL is used to communicate from the Service Layer to the Application when a new MO is to be delivered. Service Layer makes a POST HTTP request and provides the following data:

  • type = incoming_message
  • phone_number – cell number from which the message was sent
  • body – body of the message
  • sent_at – time when the message was sent from the cell (integer timestamp)
  • carrier_id – (optional, available if carrier was detected) carrier ID
  • carrier_name – (optional, available if carrier was detected) carrier name

All MO’s are stored on the Service Layer side for billing and any reviews.

Sending response MT’s to Service Layer

After processing of the Gateway URL request, an Application has two options:

  • Return the text of the message to be delivered to a originating cell
  • Return empty string to indicate no response

Data Exchange Format

We agreed that in order to make the service as simple and as accessible as possible, simple and accessible data transmission formats are to be used. By these formats I mean JSON and possibly XML-RPC. There will be a known degree of flexibility in choosing the format a client wants to work with, and it will be possible to add new formats later.

It’s assumed that the chosen format will be used to send data in both directions, but it’s also very easy to change.

The layout of the messages still has to be defined.

Suggested Technologies

  • NGINX – lightweight web server to serve the static content (images, scripts, stylesheets) and to act as a proxy to the mongrel cluster
  • Mongrel Cluster – to serve dynamic content only
  • Mysql Database – to hold application data

Why not Apache? Apache has a feature which is nice and dangerous at the same time — worker threads reusing. It’s nice because it uses the same worker threads over and over to process requests and return responses. It’s dangerous because the threads grow in size allocating memory. Initially, the server starts with minimum memory requirements. To serve an image it takes, say 100Kb of memory. Now the same worker is used to respond to a dynamic call and allocates 5Mb of memory. Since it never releases this memory (under load if threads don’t have time to terminate and be re-created, or the minimum pool size is set to some value), soon all workers due to the reusing feature will be of the maximum size (5Mb in our example). NGINX + Mongrel Cluster solves this problem. NGINX is used to send these little files quickly, while giving the heavier requests to Mongrels.

FAQ

General

How do I receive messages from phones? Do I need to poll the Service Layer (using websockets, etc.)?

If you have an application that you want to accept incoming messages, all you need to do is to give us (register on your application page) the URL you’d like us to call when they arrive. The response will be in the form of a POST request containing all of the message details. Moreover, you can even respond with the text to send back to that phone as a reply if you’d like.

So, no, you don’t need to poll our system for new messages. Simply write a handler that accepts POST requests and do whatever your business logic requires with it. This handler will receive other events as well (subscriptions, delivery reports, etc.), but you are free to implement only the parts you need. For details, consult with the Callbacks documentation.

Sending Messages to Phones

Single message to a single number

When you want to deliver a message to a single phone number, use the “send_message” API call, specifying the message body, phone number, whether the response is expected, and the time of delivery if you’d like to schedule it to be sent later.

Single message to several numbers

When you have something to say to several phone numbers, you can use the “send_message” API call as you would with a the single phone number (above), but specify all of your numbers as a comma-separated list.

Custom messages to several numbers

When you want to send a personalized message that follows a common pattern to several numbers, you can do that with the “send_messages” API call. Just specify the template (like “Hello {{name}}”) and then provide a JSON-formatted hash of phone numbers to the substitutions map (like “{’0123456789’: {’name’: ’Jack’}, …}”. We will place your custom values for each number in the corresponding placeholders and deliver.

How do I get the delivery status for the message?

When you send a message, we return the ID of this message that you could use for your internal records, and for asking for the delivery status of the message. Even though you will be notified through the callback when the status of the message changes, you can still ask the Service Layer for the status directly at any moment.

What are the delivery statuses?

When the delivery status is reported or you get it back as the result of your direct query, it can be one of the following values:

  • 0 – Message is still in the queue and was not pushed to the mobile provider for delivery. This can happen when you’ve submitted the message for the future delivery or when the mobile provider hasn’t confirmed the reception of the message from us. The latest happens sometimes because of the asynchronous nature of the messaging. Nothing to worry about.
  • 1 – Message was successfully delivered to the phone.
  • 2 – Message was not delivered to the phone. It’s either unsupported carrier, land line or the phone has text messaging disabled.
  • 4 – Message is queued for the delivery on the mobile provider side. Sometimes people have no reception, their phones are off or the network is overloaded. The mobile provider reports that the message is received from us and that it’s in the queue for delivery. There will be another status update after that soon.

Sessions

What is Session and why is it important?

We have one shortcode and several applications. When a message from a cell phone arrives, it’s the Service Layer’s responsibility to identify which application to send this message to. The Service Layer maintains the table of sessions (virtual links with phone numbers and applications). If there’s a record for the cell phone number in question, it knows the application to send the message body to.

Once a user is in session with your application, you can treat the shared shortcode as thought it were dedicated, with a wide-open keyword space. For instance, if you’re building a chat application, there’s no need for your users to memorize strange commands, like “reply to every message with MYCHATKEYWORD then your message,” to send in free-form messages. Just initiate a session and let them text naturally.

How are sessions established?

If there’s no record in the sessions table, the Service Layer takes the body of the message and attempts to find an application that is expecting something resembling that message body. For example, when your application is associated with the keyword “Surf,” when a message with this text arrives, the Service Layer will establish a virtual link between the source phone number and your application. All of the following messages (no matter the content) from this phone number will be sent directly to your application until the session expires (based on inactivity type) or until the phone number sends an opt-out message, such as “STOP.”

Keywords

What are keywords?

Traditionally (so far as SMS has traditions), keywords were the primarmy means of interacting with a text-messaging system. You would set up a simple marketing campaign and have users subscribe to it by texting in a keyword to a shortcode, or set up an auto-responder to kick back a coupon when a user texts in a particular keyword.

With our API, keywords are used to identify which application a user intends to talk to. Any application can have multiple keyword associations. All keywords can be matched in either “Starts with” or “Matches exactly” modes. We treat keywords as only the starting point for a truly functional SMS application.

Why do I need keywords?

If your app has no keywords associated with it, we won’t be able to route any messages to it. When a message from a phone number with no active session comes, we scan it for keywords and see which application matches, create a session for it and send the message over. If you don’t have keywords, your app will never be matched, and your users will be shouting into the ether.

What are the “Starts with” and “Matches exactly” modes?

“Starts with” mode matches any keywords a user texts in that begin with the keyword you associate. For example, if you have a weather forecasting application, you may want to associate the keyword “Forecast” and set the mode to “Starts with.” That will allow your users to send messages like “Forecast Miami, Florida.” The Service Layer will see your target keyword at the beginning, establish a session and send the whole message to your application for processing.

“Matches exactly” mode is used when the message is supposed to contain only the target keyword. It can have spaces and letters in mixed cases, but only this keyword will match and your application will be selected.

Note that keywords are case insensitive. Talk to us if you need more advanced tools, like RegEx-generated keywords.

What are the “Auto-subscribe” and “Auto-subscribe Tags”?

If you have Subscription Module enabled for your application, you can make it so that when a particular keyword is recognized, the user is also automatically subscribed. If you specify the list of tags, they will be used to tag the user when being subscribed through this keyword. Remember, that you can send messages to the users with certain tags, so it’s a flexible way to organize your subscribers list.

What is “Don’t start session”?

Imagine that you have an app that just sends one-off responses, like weather forecasts for a given area or time table information for a given station. You don’t need to maintain a persistent session between the user and the application.

Another scenario is when your application sends alerts of different type and you want to minimize the implementation effort. For different keywords, you enable the auto-subscription feature (along with the Subscription Module) and auto-tag the users without creating a session. Then a user can send several keywords one after another and all you will need to do is to send messages to your subscribers filtered by tags.

What is “Auto-response”?

The auto-response is just the text you want your users to receive when they send you a given keyword. It can be used with other options in different combinations to achieve stunning effects. In the above scenario, the auto-response can be used to send confirmations back to the users saying that you’ve successfully subscribed them to your alerts.

This feature, however, has a side-effect. If you use the Subscription Module in your application and the Auto-response for the keyword that has auto-subscription enabled, your users will receive at least two messages (the third message could be the First-Timers Message when the user texts you for the first time) — one for your Auto-response and another one for the confirmation on successful subscription.

Subscriptions

When do I use “send_message” vs. “send_subscription_message”?

There are currently two ways to send messages in the system:

  • Sending a single message to one or more phone numbers. When you send a message to arbitrary phone numbers, all you need is the text of the message and the list of phone numbers you want this message to be delivered to.
  • Sending a message to subscribers. This option is available only if you use the Subscription Module on the Service Layer side. When you have subscribers, you can send them a message without listing all of them individually. This is convenient when you have hundreds or thousands of numbers, and allows you to selectively send messages to pre-defined groups using our tagging system.

How do I put people on the subscribers list using the Subscription Module?

If you intend to use our Subscription Module features, for example, for sending bulk messages, the only way to put a phone number on the list is to let them subscribe themselves. You cannot tell the system to add numbers to the list, as we keep our system compliant with the Mobile Marketing Association’s Best Practices. Users must go through the full opt-in cycle and confirm that they indeed want to be subscribed, preventing unsolicited messaging. For a slightly more open set of standards, we recommend PennySMS.com, which uses a different, less regulated messaging protocal, but is limited to only outbound texts.

Can I unsubscribe people from the Subscription Module?

Currently, no. Users can only unsubscribe themselves. However, we’ll consider adding this feature if there’s a demand.

What are “tags”?

Tags are used to organize your subscribers in a free-form fashion, familiar to users of Facebook, Flickr or any number of web applications. It’s possible to have a flat subscribers list, but you may want to split it into groups (geographically, for instance) so that you can address each one separately when sending bulk messages. Tags can be stacked and tagged lists rearranged in an intuitive, non-hierarchical way. We use these in place of ‘categories’ and ‘lists.’

A good use for tagging is A/B testing advertising, especially of any marketing you do outside of the internet that’s otherwise hard to measure. For example, you can find out which of several newspapers is the more cost-effective advertising channel by printing the same ads but with a different keyword in each of them. Those keywords should have two tags associated with them: one for the campaign, and another for the paper it was shown in. You could then measure your opt-in rate against the number of impressions (or your CPMs), and still keep all of your subscribers in the same common bucket for sending mass texts later.

Tags make it easy to do any kind of layered segmentation.

How do I tag subscribers?

There are two simple ways to assign tags:

  • If you use the Subscription Module, you will receive “subscription_created” callbacks every time someone subscribes. In the response to this message, you can specify a comma-separated list of tags to assign to this particular number. The Service Layer will receive the response and tag your new subscriber as necessary.
  • If you have some existing subscribers and want to tag them, you can use the “tag_subscribers” API call with the desired tags and the phone numbers to assign tags to existing numbers.

How do I untag subscribers?

If, at any point you need to remove tags from some numbers on your subscriber list, you can use the “untag_subscribers” API call.

Static Responses

What are “static responses” used for?

Static Responses let you build a basic SMS application without writing any code. If all you need is a canned responses to a given set of keywords, you can enter them through your application ‘edit’ screen and the Service Layer will automatically send those back to your users when a matching message arrives. For example, if you want to send your card to everyone who sends “Jack” to your application, you could write an application that would receive a message from the Service Layer, see if it reads “Jack” and respond. But with Static Responses, you can simply tell the Service Layer to send your desired text any time it sees incoming message with the text “Jack.”

When do Static Responses come into play or “why doesn’t my Static Response work”?

Static Responses are canned responses to the known client messages. They work exactly as if the message was sent to your application, recognised and replied with the known text. This means that in order for the Static Responses to work, there has to be a session established between the phone number and your application first. If there’s no session (or virtual link) between the phone number and your application, we don’t know which application to send a message to, and thus it never reaches your Static Responses.

If you’d like to set up simple auto-responders when there’s no session in place (when a new user texts in, for example), you can simply set up a keyword with an “auto-response.”

You can find details on how Sessions work in the corresponding section.

Customizing Module Messages

There are three main modules that work together for the application — Welcome, Help and Subscription Module. Each of them has associated messages that can be customized or left blank. We’ll examine them in the following sections.

Welcome Message

Every application can be configured to welcome its new users with a message. We know when it’s the first time someone texts you and can send a reply to them automatically, but also give you a chance to provide your own content. Think of this welcome message as an optional additional message. Since it’s optional, you can leave it blank if you don’t need it.

Help Message

If your response to HELP message never changes, you may want to use our next module — Help Module. It will send an automatic response to anyone asking for help (case-insensitive messages ‘H’, ‘HLP’ and ‘HELP’ with any number of spaces around). If you leave this message blank, the message will be sent to your application as any other message.

Subscription Messages

Here we have two messages that work only when the Subscription Module is enabled:

  • Subscribe message – used to confirm that the user has been subscribed successfully.
  • Stop message – used to confirm the successful unsubscribing.

Customize these messages to include your store name, and links to your web site. There are guidelines on how to properly compose these messages on example of the HELP message that can be found in one of articles on our blog.

back to top