8MS API Overview
Interface Details
     Generating Requests
     Request Results
     Handling Timeouts
     Request Generation Failure
     Reading Unsolicited Messages
     Syntax and Validation
     Error Messages
     Resource Management

8MS API Overview
Somos has released a new API, known as the Somos Registry API, intended to replace their legacy MGI interface. 8MS was built on the MGI interface. We are in the process of converting 8MS API calls from MGI-based to Registry-based calls.

If you are an existing 8MS API customer, please be sure to read the Somos Registry Impact section of this guide as you may be impacted by these changes.

The 8MS API allows application programs to generate messages to SMS/800, and receive replies. The API provides a means to automate SMS/800 provisioning over the MGI, without the need of extensive MGI knowledge. An application program initiates a request of the 8MS API, which then sends the appropriate MGI message or messages. Responses to the messages are gathered up, and presented as one result to the caller. The application program then interprets the result, and takes whatever action is appropriate in its environment.

Calls to the 8MS API are the form of HTTP requests, sent via TCP/IP, to a web server running the 8MS application. The URL defining the HTTP request will contain the name of the appropriate server, and its post data will define the parameters of the request. Minimally, the type of the request will be provided, along with access information (user ID and password). Other information relevant to a particular request type may also be provided. These request parameters will vary from request to request.

The result of an 8MS API request is one or more responses from SMS/800. The SMS response messages are gathered up and returned in the form of an XML document.

8MS API requests are grouped into the following categories:
Message Requests
Batch Message Requests
Carrier Express Requests
ROC (Resp Org Change) Requests
Miscellaneous Requests

Message requests are those involving a single toll-free number. Batch message requests are those that allow the same operation to be performed on arbitrarily large groups of numbers. The Miscellaneous section contains requests that do not result in messages to SMS/800.

Each of the sections listed above contain a description of the request and the parameters it requires. After reading the details below, which describe how the API functions regardless of request type, you can reference the sections above to discover how to construct any of the 8MS API request calls.

Note that all required parameters are marked with an asterix (*) character to the left of the parameter name. In the following example dn is a required field while ed is not.
* dn The number to be queried.
ed The effective date of the record to be queried.
8MS API service is provided by a Java servlet running within the web server that also supports the 8MS GUI. This servlet is accessed by passing one or more of the following parameters as part of an HTTP request. The URL of this request will be of the form https://8msServer.8msweb.com/8ms/api, where 8msServer is the name of the 8MS web server machine.

request The type of request; the possible values are those listed in the three sections described above.
userid The login of the person making the request (for authentication and logging purposes).
loguserid This parameter works in conjunction with the userid parameter for activity logging purposes. It allows API calls to have a client-application id (any string) associated with the userid in the activity log. A user interface user may search in the Activity Log (in the User Id field) by either the userid or loguserid. Additionally, each API entry in the the Activity Log screen shows the userid followed by the loguserid in parentheses.
password The password of the person making the request (for authentication purposes).
reqparams A set of semicolon-separated, name/value pairs that define the parameters for the particular request being made. Name and value are separated by the tilde (~) character.
timeout Number of seconds to wait for a response. The default value is 30 seconds.
requestid In the event of an incomplete response due to a timeout, a requestid is returned to the user. The user may resubmit the request with this requestid. See Handling Timeouts below.
routeid An SMS/800 route ID, used to retrieve unsolicited messages. See Reading Unsolicited Messages below.

The following is a simple example of an 8MS API URL. This is a request to search SMS/800 for 5 spare toll-free numbers:

https://web.8mscorp.com/8ms/api?userid=jsmith& password=bbbbbb& request=Search&reqparams=count~5
Using HTTP GET rather than POST Is An Extremely Bad Idea!

Developers coding to the 8MS API should always use POST, not GET, for submitting requests. Additionally, all data sent in the POST should be included in the POST body, not as part of the URL.

There are 2 primary reasons for this:

  1. GET is insecure.

    Any data specified as part of the URL is sent as clear text. This enables anyone to grab your login and password.

  2. GET has size limitations.

    Depending on the language or tool being used to send requests, GET often has a maximum size limit for the number of characters specified in the URL.

When data for a POST is included in the POST body, your request will be secure and you will not run into size limitations.

Use POST.

The following is sample Java code fragment that illustrates how to use the URL and URLConnection classes to access the 8MS API.  This request will reserve two 877 numbers, waiting up to 20 seconds for a response, with XML as the response format.

    String line;
    String urlString = "https://web8ms.corp.com/8ms/api";
    String postData = "userid=bso&password=bbbbbb&" +
    		"timeout=20&request=Reserve&" +
		reqparams=npa~877;count~2;cname~BSO;" +
		"cphone~7323020222";
    
    try
    { 
    				// Make the connection.
    
    	URL url = new URL(urlString);
    
    	HttpURLConnection conn = 
		(HttpURLConnection) url.openConnection();
    	conn.setDoOutput(true);
    
    				// Post the data.
    
    	OutputStreamWriter wr = 
		new OutputStreamWriter(conn.getOutputStream()); 
    
    	wr.write(postData);
    	wr.flush();
    	wr.close();
    
    				// Get the results.
    	conn.connect();
    
    	BufferedReader br = 
		new BufferedReader( 
			new InputStreamReader(conn.getInputStream()));
    
    	while ( (line = br.readLine()) != null)
    		System.out.println(line);
    }
    catch (Exception ex)
    {
    	System.out.println(ex);
    }
    
Note that all data in the URL must be encoded as specified in RFC 1738 published by the Internet Engineering Task Force (IETF). Newer versions of Java provide a java.net.URLEncoder class to properly encode a URL.

When a response to a request is received from SMS/800, the results will be returned to the caller in XML format. For example:

    <API8MS>
    <reqid>OA01417659</reqid>
    <message>
     <routeid>RSR</routeid>
    <termrpt>COMPLD</termrpt>
    <errorcd>0</errorcd>
    <msgparams>
    ID=ART01000
    RO=ART01
    CNT=02
    NUM=8774328699
    NUM=8774328701
    </msgparams>
    </message>
    </API8MS>

The following are the tags that appear in the XML response:

<API8MS> The entire response.
<error> If request generation fails, or the request does not complete within the given timeout, this tag will contain a message from the 8MS API.
<reqid> If request succeeds, this tag will contain a request ID. This request ID can be used to subsequently determine when the request completes, and to obtain the results (more on this below).
<message>   A single message in the response (see below).
<routeid>   The type of the SMS/800 response message as defined by the MGI.
<termrpt> The termination report from SMS/800; either COMPLD or DENIED.
<errorcd>   The SMS/800 error code; 0 for COMPLD messages, or an error code for DENIED messages.
<msgparams>  The contents of the SMS/800 response; space-separated name/value pairs. The tags are defined by the MGI.

Requests that result in more than one response from SMS/800 will produce an XML document with multiple <message> tags.  For example, searching for 30 877 numbers might produce:

    <API8MS>
    <reqid>OA00453294</reqid>
    <message>
    <routeid>RSR</routeid>
    <termrpt>COMPLD</termrpt>
    <errorcd>0</errorcd>
    <msgparams>
    ID=ART01000
    RO=ART01
    CNT=10 
    NUM=8772340467
    NUM=8772340525
    NUM=8772340534
    NUM=8772340535
    NUM=8772344868
    NUM=8772348692
    NUM=8772348728
    NUM=8772348824
    NUM=8772348926
    NUM=8772349726
    </msgparams>
    </message>
    <message>
    <routeid>RSR</routeid>
    <termrpt>COMPLD</termrpt>
    <errorcd>0</errorcd>
    <msgparams>
    ID=ART01000
    RO=ART01
    CNT=10 
    NUM=8772700406
    NUM=8772700470
    NUM=8772700544
    NUM=8772700586
    NUM=8772700593
    NUM=8772700711 
    NUM=8772700733
    NUM=8772700803
    NUM=8772700825
    NUM=8772700830
    </msgparams>
    </message>
    <message>
    <routeid>RSR</routeid>
    <termrpt>COMPLD</termrpt>
    <errorcd>0</errorcd>
    <msgparams>
    ID=ART01000
    RO=ART01
    CNT=10 
    NUM=8772693069
    NUM=8772693070
    NUM=8772693071
    NUM=8772693085
    NUM=8772693130
    NUM=8772693136 
    NUM=8772693222
    NUM=8772693230
    NUM=8772693301
    NUM=8772693302
    </msgparams>
    </message>
    </API8MS>

If a request does not complete within the given timeout period, the following will be returned:

     <API8MS>
     <error>Information Incomplete</error>
     <reqid>OA01921131</reqid>
     </API8MS>
    

The user can then use the returned request ID to check if all responses have been received For example, submitting a subsequent the following will determine if the given request has completed:

     userid=bso&password=bbbbbb&requestid=OA1921131

If the request has since completed, the results will be returned.  If the request is still in progress, the Information Incomplete message defined above will again be returned.

If an error occurs in trying to create the request, the following XML document will result:

     <API8MS>
     <error>Request Generation Failed</error>
     </API8MS>

Generation of requests may fail for a number of reasons, such as bad/missing request type, bad/missing reqparams, etc.

The 8MS API interface provides a way to retrieve unsolicited messages from the 8MS database. Unsolicited messages are generated by SMS/800 to signal certain events not related to a particular request. Two examples are customer record activations and RespOrg changes.

The following query string will look for messages with a route ID of URC (an unsolicited RespOrg change message):

      userid=bso&password=bbbbbb&routeid=URC

If any messages with the given route ID exist, they are returned, and deleted from the 8MS database. Each message is represented as described above, except that unsolicited messages have neither a termination report or error code. The following is a sample XML document that might result from a query for URC messages:

     <API8MS>
     <message>
     <routeid>URC</routeid>
     <msgparams>
     RO=ART01
     NUM=8005418128
     OLDRO=ALN01
     NEWRO=ART01
     STAT=WORKING
     </msgparams>
     </message>
     <message>
     <routeid>URC</routeid>
     <msgparams>
     RO=ART01
     NUM=8776287250
     OLDRO=ALN01
     NEWRO=ART01
     STAT=WORKING
     </msgparams>
     </message>
     <message>
     <routeid>URC</routeid>
     <msgparams>
     RO=ART01
     NUM=8663674709
     OLDRO=CWC02
     NEWRO=ART01
     STAT=WORKING
     </msgparams>
     </message>
     </API8MS>

The current 8MS API does very little error checking. The URL passed must contain a valid user ID and password, as well as a known API request type. Failing either of these cases will result in an error message as listed below.

Validation of parameters specific to each request type are not currently part of the API. Values will be passed on to SMS/800, where error detection will take place. Thus, bad input to a particular API request will not result in an error from the 8MS API, but rather a reponse message from SMS/800 containing error reports.

The following are some general guidelines for data sent through the 8MS API:

  • Toll free numbers should always be provided as 10 numeric digits (i.e., they cannot contain formatting characters such as dashes or parens).
  • Except where noted, the date and time format used by the API is the same as the SMS/800 effective date/time format. An example of this format might be: 10/15/04 10:15A.
  • Generally speaking, the case of the values for API request parameters is irrelevant; SMS/800 will translate everything to upper case.

The following are the error messages that may be produced by the 8MS API:

Unable to get database handle: The database connection failed. Should not happen.

Database Error: A database error occurred. The database connection failed. Should not happen.

Incomplete Request: Required information in the request was missing (e.g., user name and password, request type).

Invalid Request: The request type is not known.

User Access Denied: The given user name/password combination is not valid.

Information Incomplete: The request timed out.

No Active Transactions for Request ID: Results for the given request were already retrieved.

No Unsolicited Messages for Route ID: No unsolicited messages exist for the given route ID.

Request Generation Failed: 8MS failed to generate the request.

This section discusses resource management when coding to the 8MS API.

The 8MS user interface should be viewed as an API client operating at the same level as any API client that you develop. Whenever a user submits a request, the user interface generates the request via the 8MS API. The user interface then waits, by default, for 30 seconds for the request to be processed. In the case of the user interface, the vast majority of the time, users are actively waiting to see what happens as they need to know as soon as possible if their request succeeded, so the 30 second delay is reasonable and necessary.

The 8MS API supports polling to see if a request was successful, so it is not necessary to wait for a response. When an 8MS API client submits a request, that client must support polling because there is always a chance that the request could time out. (See Coding for Somos, below, for more information.) Resources such as database connection are tied up from the time the request is submitted until the response is sent back. Just like the user interface, the API defaults to waiting 30 seconds for a request to complete. This means that all these resources are tied up for as long as 30 seconds. Since polling code must be written for the possibility of a time out, it is in your company's best interest to design your API client to support polling for all cases.

To keep any single company from tying up too many resources, 8MS does not allow a company to have more than four simultaneous API requests. Designing your API client to start up hundreds or thousands of threads and allowing those threads to connection to 8MS with requests of a single number will not speed up your processing time, they will slow it down. Large numbers of connections that 8MS must process only to determine that they have exceeded the per-company limit is just busy work and will result in the following error.

<error>Unable to get company connection<error>
<error>Access Denied: Unable to get company conn<error>
Since the maximum-of-four is a per-company restriction, and since the user interface also submits requests via the API, the API user shares these resources with user interface users. If the API client always has four requests being submitted, user interface users are unable to submit their requests, effectively preventing your own users from getting their work done. To avoid locking out your users, you should uses the Batch Message Requests rather than single number API calls.
API clients should only submit one request at a time.

The primary benefit of batch calls is that the user can let the 8MS batch manager process large requests efficiently and effectively, ensuring that resources are tied up for the barest minimal amount of time. However, to reduce locking of resources you must set the API timeout parameter is set to 0. Your API client can then poll for completed responses. Polling will only ever return completed responses, so the API client can quickly determine what requests are complete. If results exist, then they will be returned immediately. As discussed above, in the section Handling Timeouts, when a timeout occurs, you will see a response similar to the following:

<API8MS>
<error>Information Incomplete<error>
<reqid>OA01921131<reqid>
<API8MS>

The Information Incomplete indicates that the request did not complete and you should poll for results.

Set API timeout to 0 and use the polling mechanism to check back for completed batches.

To take advantage of 8MS batch management and to minimize resource usage, API clients should seek to put large amounts of toll-free numbers into a single batch request. 8MS can easily support requests with 50,000 numbers, or more, in a single batch.

8MS also limits the number of batches that any one company can submit. It is strongly recommended that API clients limit the current number of batches to around 20. By creating large batches, it is less likely your company will need to exceed 20 batches at any one instant.

Submit single large batches rather than many small (1-10 numbers) batches.

Somos typically has one downtime per month and that downtime can range from 1 or 2 hours up to 12 or more. During that downtime, Somos will not respond to any messages, so 8MS effectively enters a holding state in which it tries to connect and send messages, fails, waits, and then tries again. No messages you sent to 8MS will be lost during that time. However your API design must take into account that, at some times, it can be many hours before responses are returned. This is one more reason why you should set the timeout parameter to 0 and use the polling mechanism. To avoid flooding 8MS with polling requests that will continually return an Information Incomplete response, allow some time to pass between polling requests.

Poll for results roughly every 60 seconds and specify a timeout of 5 seconds on polling API calls.

There is one more item you should take into consideration in regards to the Somos system. Most 8MS API developers begin their work in an 8MS test platform, which connects to a Somos Sandbox (test) platform. Somos production is orders of magnitude faster than their sandbox. Do not base your expected performance on how the Sandbox behaves.

If you follow the above recommendations, you will find that user interface users will have a better experience and your API client will get overall better performance. To summarize, you can optimize your use of API Calls by the following:

  1. Group as many TFNs as possible in a single batch request.
  2. Make the Batch API call with a timeout of 0 so resources are locked up for the least amount of time.
  3. Only submit one request at a time; avoid submitting parallel requests.
  4. Poll for results every 60 seconds and specify a timeout of 5 seconds on polling API calls.

The remainder of this section provides an example of submitting a request designed for polling.

  1. Submit a POST request.

    URL
    https://test.8msweb.com/8ms/api

    POST Data
    userid=apiuser&password=apipwd& timeout=0& request=BatchCopyRecord&
    reqparams=source~8554617560; dnlist~8554617561,8554617562,8554617563; destDateTime~04/01/21 08:00A; sourceDateTime~03/03/21 08:00A

  2. Receive a timeout (Information Incomplete) response.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE API8MS>
    <API8MS>
    <error>Information Incomplete</error>
    <reqid>OA89ZWZ06H</reqid>
    <API8MS>
  3. Submit a poll request using the returned reqid in the above Information Incomplete response.

    https://test.8msweb.com/8ms/api
    userid=apiuser&password=apipwd&timeout=0&requestid= OA89ZWZ06H
  4. When a response other than Information Incomplete is returned, your request has completed and you may process the response.

    Note that an incomplete requestid may be polled an unlimited number of times, but when a completed requestid has been polled, 8MS removes the response details. It is the API client's responsibility to retain this data at this point.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE API8MS>
    <API8MS>
    <reqid>
    OA89ZWZ04G
    <reqid>
    <message>
    <routeid>
    TXU
    <routeid>
    <termrpt>
    COMPLD
    <termrpt>
    <errorcd>
    0
    <errorcd>
    <msgparams>

    detailed response removed for clarity

    <msgparams>
    </message>
    </API8MS>