API Technical Details

We recommend that you use our pre-existing API Libraries for using our API. These libraries are debugged and in widespread use.

But, there are situations where you may need or want to write your own library, or otherwise directly access the API. This document explains the details.

Basic Rules

All API requests are either HTTP GET, POST, or DELETEs to paths on the host api.sailthru.com. You may use either HTTP or HTTPS requests.

The URI will be http://api.sailthru.com/name, where name is the name of the call. For example, send requests are either a GET or POST to http://api.sailthru.com/send

All requests and responses must always be UTF-8 encoded.

In REST style, a GET and a POST have different behaviors and often take different parameters. The documentation for each action type will explain these differences. Consistently, a GET is idempotent and will only return information to you – it will never make any changes or cause any action to be taken; a POST is not idempotent.

Parameters are passed either as part of the GET query string or as the POST body. This means your POSTs must be of the MIME content-type application/x-www-form-urlencoded. All parameters must be properly URL-encoded.

One shortcoming of URL parameters is that they do not preserve type data. For all API calls, you are allowed to pass a single parameter called json containing an object representation of all of your parameters. This is the recommended approach supported by most of the client libraries.

Authentication

We use a simple shared-secret hash authentication mechanism. (For added security, you are strongly recommended to restrict the list of IPs that are allowed to access your API on the API Settings page).

You have to start by knowing your API key and shared secret. You can get that information at the API Settings page.

Every request, whether GET or POST, must pass your API key as one of the parameters, as a parameter named api_key.

Every request must also generate a signature hash called sig according to the following rules:

  1. take the string values of every parameter, including api_key
  2. sort the values alphabetically, case-sensitively (i.e. ordered by Unicode code point)
  3. concatenate the sorted values, and prepend this string with your shared secret
  4. generate an MD5 hash of this string and use this as sig
  5. now generate your URL-encoded query string from your parameters plus sig

Example: Let's suppose your API key is abcdef1234567890abcdef1234567890 and your shared secret is 00001111222233334444555566667777. Let's further suppose you're doing an API call with the following parameters:

  • email=test@example.com
  • format=xml
  • vars[myvar]=TestValue
  • optout=0

Follow the steps:

  1. The string values of every parameter, including api_key are: test@example.com, xml, TestValue, 0, and abcdef1234567890abcdef1234567890.
  2. Sorting these values case-sensitive alphabetically, they are in this order: 0, TestValue, abcdef1234567890abcdef1234567890, test@example.com, xml
  3. Concatenate these sorted values and prepend the string with the shared secret and we get a signature string of 000011112222333344445555666677770TestValueabcdef1234567890abcdef1234567890test@example.comxml
  4. Run md5() on that string and we get a signature hash of b0c1ba5e661d155a940da08ed240cfb9
  5. So our final query string looks like this: email=test@example.com&format=xml&vars[myvar]=TestValue&optout=0&api_key=abcdef1234567890abcdef1234567890&sig=b0c1ba5e661d155a940da08ed240cfb9

To see signature strings and hashing in action, try out some test API requests at the API test page. This page should give you all the information you need to debug.

The Most Common Mistake You Might Make While Authenticating

It's a very common mistake when coding your own client to URL-encode at the wrong time. Do not URL-encode any of your parameters before generating the signature string, but do URL-encode before you send the HTTP request. Depending on what HTTP library you're using, it may take care of URL-encoding for you, but if you have to generate your own query string, you need to do that as the last step. This problem often goes unnoticed until you attempt to pass a character that should be encoded, like = or &.

So for example, if you are trying to pass the value PB & J, you should be sorting and generating the md5() (doing steps 1-4 above) on the literal value PB & J. The ampersand should not be encoded. Then, after you've generated the sig hash, encode it to PB+%26+J when building the query string.

Binary Parameter Values and Authentication

It is permitted to pass binary parameters, e.g. file upload names for the job API call. These binary parameters are not included in the signature hash.

Response Format

For most requests, we support three response formats: simple XML, JSON, and serialized PHP.

If you are coding in PHP, we recommend serialized PHP. Otherwise, we generally recommend JSON. For legacy reasons, though, XML is the default.

You can specify which response format by passing a format parameter and using one of the following values: xml, json, or php.

The response will be a structure with fields that will vary depending on the call you are making. The responses are individually documented for each call.

If we encounter an error, we will return a structure with two fields: error, which will contain a numeric error code, and errormsg, which will return a message. The errormsg is usually technical in nature and most likely not something you will want to expose to an end user.

If you're using JSON or PHP, the response structure will be pretty natural: a JSON object or a PHP associative array. If you're using XML, we convert the JSON object to XML according to consistent rules:

  • key/value pairs become <key>value</key>
  • numeric arrays become <item>element0</item><item>element1</item><item>element2</item> … etc
  • there will be an opening and closing element

So, for instance, a JSON response that read:

{ foo: 'bar',
  baz: 2,
  baps: ['a', 'b', 'c']
}

becomes XML

<triggermail>
  <foo>bar</foo>
  <baz>2</baz>
  <baps>
    <item>a</item>
    <item>b</item>
    <item>c</item>
  </baps>
</triggermail>

Good Luck!

If you are having troubles, feel free to contact us. And if you happen to write a client for a language we don't currently have a client for, please consider donating it back to the larger Sailthru community.

 
/var/www/docs.sailthru.com/htdocs/data/pages/api/technical-details.txt · Last modified: 2012/04/21 17:03 by Ian White
 
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki