Difference between revisions of "Rest API"
(Updated to reflect latest live version.) |
|||
Line 1: | Line 1: | ||
− | { | + | == Recent Changes == |
+ | |||
+ | '''11/22/09 ''' | ||
+ | {| | ||
+ | | | ||
+ | New features: | ||
+ | *Index/Add/Delete Alternate Domains. | ||
+ | *Show/Edit Domain Spam Settings. | ||
+ | *Index/Add/Delete Domain Blacklist/Safelist. | ||
+ | *Show/Edit Split Domain Routing. | ||
+ | *Show Mailbox ActiveSync Setup Info. | ||
+ | | | ||
+ | |} | ||
+ | |||
== Introduction == | == Introduction == | ||
− | The Email API provides most of the functions of | + | The Email & Apps Control Panel API provides most of the functions of the Control Panel through a HTTP-based REST API ([http://en.wikipedia.org/wiki/Application_programming_interface Application Programming Interface]). Whether it is adding a new customer account, adding mailboxes, or any other of the supported features the API allows your application to administer the changes regardless of your application's language or nature. For more information on RESTful web services refer to the following sites: |
http://en.wikipedia.org/wiki/Representational_State_Transfer | http://en.wikipedia.org/wiki/Representational_State_Transfer | ||
Line 10: | Line 23: | ||
− | + | The API is accessible to resellers only. As of now, most of the supported functions manage only customers, domains, and Exchange accounts. | |
Line 18: | Line 31: | ||
The following pages detail the operations that the API supports. The operations are grouped into sections based on the entity/object types that each operation interacts with. | The following pages detail the operations that the API supports. The operations are grouped into sections based on the entity/object types that each operation interacts with. | ||
− | {| | + | {| class="wikitable" |
!Resource | !Resource | ||
!Example URI | !Example URI | ||
|- | |- | ||
− | | [[ | + | | [[Customer_(Rest_API)| Customer]] |
| /customers/123456789 | | /customers/123456789 | ||
|- | |- | ||
− | | [[ | + | | [[Domain_(Rest_API)| Domain]] |
| /customers/123456789/domains/example.com | | /customers/123456789/domains/example.com | ||
|- | |- | ||
− | | [[ | + | | [[Mailbox_(Rest_API)| Exchange Mailbox]] |
| /customers/123456789/domains/example.com/ex/mailboxes/john.smith | | /customers/123456789/domains/example.com/ex/mailboxes/john.smith | ||
|- | |- | ||
− | | [[ | + | | [[Contact_(Rest_API)| Exchange Contact]] |
+ | | /customers/123456789/domains/example.com/ex/contacts/john.smith | ||
+ | |- | ||
+ | | [[Distribution_List_(Rest_API)| Exchange Distribution List]] | ||
| /customers/123456789/domains/example.com/ex/distributionlists/group.name | | /customers/123456789/domains/example.com/ex/distributionlists/group.name | ||
− | |||
− | |||
− | |||
|} | |} | ||
Line 41: | Line 54: | ||
The examples shown in the operation pages are written in Ruby and extensively use the helper functions shown in the Ruby Examples below. | The examples shown in the operation pages are written in Ruby and extensively use the helper functions shown in the Ruby Examples below. | ||
+ | == Quick Start == | ||
+ | |||
+ | To get a list of mailboxes under a domain: | ||
+ | |||
+ | First, you need to populate some HTTP headers with the correct information. 'Accept' needs to be either 'text/xml' or 'application/json' to indicate the format of the returned data. 'User-Agent' just needs to be any name you choose to identify your client with. 'X-Api-Signature' needs a | ||
== Accessing the API == | == Accessing the API == | ||
− | Your application will need to make HTTP requests to remote servers. Most programming languages have this function provided in its class library. In addition to the common GET and POST HTTP methods, the library used will also need to support PUT and DELETE. All API calls should be directed to a URL in the following format | + | Your application will need to make HTTP requests to remote servers. Most programming languages have this function provided in its class library. In addition to the common GET and POST HTTP methods, the library used will also need to support PUT and DELETE. |
− | <pre> | + | |
+ | <span style="color:red"> | ||
+ | Calls without [http://en.wikipedia.org/wiki/Transport_Layer_Security TLS] (formerly SSL) will complete successfully but it is HIGHLY RECOMMENDED that TLS always be used. Interception of unencrypted communication will allow a third party to have complete access to all functions available via the API.</span> | ||
+ | |||
+ | For some language libraries just using an URL with https:// will cause the library to use TLS. In some other libraries however some options specific to the library may have to be configured to utilize TLS. | ||
+ | |||
+ | |||
+ | All API calls should be directed to a URL in the following format: | ||
+ | <pre>https://api.emailsrvr.com/(version)/(resource)</pre> | ||
Example: | Example: | ||
− | <pre> | + | <pre>https://api.emailsrvr.com/v0/customers/12345678/domains/customerbusiness.com</pre> |
Line 56: | Line 82: | ||
− | {| | + | {| class="wikitable" |
!''Supported Versions'' | !''Supported Versions'' | ||
!''URL'' | !''URL'' | ||
Line 62: | Line 88: | ||
|- | |- | ||
| v0 (current) | | v0 (current) | ||
− | | <nowiki> | + | | <nowiki>https://api.emailsrvr.com/v0/</nowiki> |
− | | http://signup.apps.rackspace.com/api-wiki/index.php/ | + | | http://signup.apps.rackspace.com/api-wiki/index.php/Rest_API |
|} | |} | ||
− | The API version number is a component of the URL that is used to access the API. For example, to access the root of the API, the URL is | + | The API version number is a component of the URL that is used to access the API. For example, to access the root of the API, the URL is https://api.emailsrvr.com/v0/. Bug fixes and minor non-breaking changes will be made without changing the version number. When major features or breaking changes are introduced, the version number will be incremented. It is not yet determined how many versions are going to be supported at any one time. |
− | |||
− | |||
− | |||
− | {| | + | {| class="wikitable" |
!''Non-breaking Changes'' | !''Non-breaking Changes'' | ||
!''Breaking Changes'' | !''Breaking Changes'' | ||
Line 93: | Line 116: | ||
To gain access to the API, your request must include a properly constructed X-Api-Signature HTTP header. Details on what to put in the header are below. To construct the header, you must have the following keys that that are generated from the Control Panel Web interface. | To gain access to the API, your request must include a properly constructed X-Api-Signature HTTP header. Details on what to put in the header are below. To construct the header, you must have the following keys that that are generated from the Control Panel Web interface. | ||
− | {| | + | {| class="wikitable" |
!Key Name | !Key Name | ||
!Description | !Description | ||
Line 115: | Line 138: | ||
Format is as follows: | Format is as follows: | ||
+ | <'''User Key'''>:<'''Timestamp'''>:<'''Signature'''><br> | ||
+ | Example: ''eGbq9/2hcZsRlr1JV1Pi:20010317143725:HKUn0aajpSDx7qqGK3vqzn3FglI='' | ||
− | + | Remember to include the colons between the data strings! | |
− | |||
− | |||
<br> | <br> | ||
'''User Key''':<br> | '''User Key''':<br> | ||
− | This is the public key issued by the Control Panel interface. | + | This is the public key issued by the Control Panel browser interface. |
<br> | <br> | ||
'''Timestamp''':<br> | '''Timestamp''':<br> | ||
− | The format is YYYYMMDDHHmmssff. All values besides year are zero-padded to two spaces. For example, March | + | The format is YYYYMMDDHHmmssff. All values besides year are zero-padded to two spaces. For example, March 08th 2001 at 2:37.25pm would be ''20010308143725''. |
− | {| | + | {| class="wikitable" |
|YYYY | |YYYY | ||
|Four-digit year | |Four-digit year | ||
Line 159: | Line 182: | ||
<'''User Key'''><'''User Agent'''><'''Timestamp'''><'''Secret Key'''> | <'''User Key'''><'''User Agent'''><'''Timestamp'''><'''Secret Key'''> | ||
− | Note that the 'User Agent' must be the exact same as what is specified in the User-Agent HTTP Header. Using the above example data, the string before hashing is:<br>''eGbq9/2hcZsRlr1JV1PiRackspace Management | + | Note that the 'User Agent' must be the exact same as what is specified in the User-Agent HTTP Header. Using the above example data, the string before hashing is:<br>''eGbq9/2hcZsRlr1JV1PiRackspace Management Interface20010308143725QHOvchm/40czXhJ1OxfxK7jDHr3t'' |
− | Resulting base-64 SHA1 Hash:<br>'' | + | Resulting base-64 SHA1 Hash:<br>''46VIwd66mOFGG8IkbgnLlXnfnkU='' |
Be sure to encode the binary hash, not the hex hash, into base-64. The resulting string should be 28 characters long. | Be sure to encode the binary hash, not the hex hash, into base-64. The resulting string should be 28 characters long. | ||
Line 170: | Line 193: | ||
=== Requests === | === Requests === | ||
− | HTTP requests should be sent to the server with the correct URL, HTTP Method, HTTP Headers and form data (if needed). The URLs, corresponding HTTP Methods, and necessary form data for the desired operations are detailed in the [[ | + | HTTP requests should be sent to the server with the correct URL, HTTP Method, HTTP Headers and form data (if needed). The URLs, corresponding HTTP Methods, and necessary form data for the desired operations are detailed in the [[#Operations|operation pages]]. |
Line 184: | Line 207: | ||
The types of operations a certain method performs is consistent and is outlined in the table below. | The types of operations a certain method performs is consistent and is outlined in the table below. | ||
− | {| | + | {| class="wikitable" |
!''HTTP Method'' | !''HTTP Method'' | ||
!''Operations'' | !''Operations'' | ||
+ | !''Response'' | ||
|- | |- | ||
|rowspan=2|GET | |rowspan=2|GET | ||
|Index - returns a list of the resources | |Index - returns a list of the resources | ||
+ | |rowspan=2|XML or JSON formatted data | ||
|- | |- | ||
|Show - returns the details of the resource | |Show - returns the details of the resource | ||
Line 195: | Line 220: | ||
|POST | |POST | ||
|Add - adds a new resource | |Add - adds a new resource | ||
+ | |rowspan=3|Response code and error message (if applicable) only | ||
|- | |- | ||
|PUT | |PUT | ||
Line 208: | Line 234: | ||
All requests to the API must then include HTTP headers with the following information: | All requests to the API must then include HTTP headers with the following information: | ||
− | {| | + | {| class="wikitable" |
!''Header Name'' | !''Header Name'' | ||
!''Description'' | !''Description'' | ||
Line 214: | Line 240: | ||
|- | |- | ||
| Accept | | Accept | ||
− | | The requested content type (required regardless of type of operation) | + | | The requested content type (required regardless of type of operation). See [[#Formats|Response Formats]] |
| ''text/xml'' | | ''text/xml'' | ||
|- | |- | ||
Line 222: | Line 248: | ||
|- | |- | ||
| X-Api-Signature | | X-Api-Signature | ||
− | | An authentication string explained in detail [[ | + | | An authentication string explained in detail [[#X-Api-Signature_Header|here]] |
| ''eGbq9/2hcZsRlr1JV1Pi:20010317143725:HKUn0aajpSDx7qqGK3vqzn3FglI='' | | ''eGbq9/2hcZsRlr1JV1Pi:20010317143725:HKUn0aajpSDx7qqGK3vqzn3FglI='' | ||
|} | |} | ||
Line 235: | Line 261: | ||
Note that "0-9" is a reserved key word for query string "startswith." It represents any result starting with numbers. | Note that "0-9" is a reserved key word for query string "startswith." It represents any result starting with numbers. | ||
− | {| | + | {| class="wikitable" |
!''Index Actions'' | !''Index Actions'' | ||
!''Where the key word will be searched'' | !''Where the key word will be searched'' | ||
Line 267: | Line 293: | ||
==== Throttling ==== | ==== Throttling ==== | ||
− | The server limits the number of requests allowed per user in a certain period of time. The current limit is | + | The server limits the number of requests allowed per user in a certain period of time. The current limit is 1500 requests over 5 minutes. The number of requests made are logged per minute. Calls that were made correctly with a user's API key, but not completed for any reason, including those exceeding the throttle limit, are included in this count. |
If a user is over the throttling limit then a 403 HTTP code will be returned with an "Exceeded request limits" message. | If a user is over the throttling limit then a 403 HTTP code will be returned with an "Exceeded request limits" message. | ||
Line 289: | Line 315: | ||
Accept: text/xml | Accept: text/xml | ||
− | + | ||
Adding New Exchange Mailbox: | Adding New Exchange Mailbox: | ||
Line 304: | Line 330: | ||
[Content length: 53] | [Content length: 53] | ||
Content-Type: application/x-www-form-urlencoded | Content-Type: application/x-www-form-urlencoded | ||
− | + | ||
Line-based text data: application/x-www-form-urlencoded | Line-based text data: application/x-www-form-urlencoded | ||
size=2048&displayName=John%20Smith&password=abcABC123 | size=2048&displayName=John%20Smith&password=abcABC123 | ||
− | + | ||
</pre> | </pre> | ||
Line 317: | Line 343: | ||
On a successfully executed request, a 200 HTTP Code is returned. Requested data is also returned if the operation was a Show or Index action. If the request is unsuccessful, then an error HTTP Code is returned with a message detailing the error. The errors and their corresponding codes are detailed on the operation pages. | On a successfully executed request, a 200 HTTP Code is returned. Requested data is also returned if the operation was a Show or Index action. If the request is unsuccessful, then an error HTTP Code is returned with a message detailing the error. The errors and their corresponding codes are detailed on the operation pages. | ||
− | ==== | + | ==== Formats ==== |
− | Requests for data (index and show requests) are returned with XML or JSON data based on what your application populates the HTTP Accept | + | Requests for data (index and show requests) are returned with XML or JSON data based on what your application populates the [[#HTTP_Headers|HTTP Accept Headers]] with. |
Line 327: | Line 353: | ||
For JSON, populate the header with 'application/json' (ex: Headers!["Accept"] = "application/json"). As with XML, a library will likely be needed to parse the data. | For JSON, populate the header with 'application/json' (ex: Headers!["Accept"] = "application/json"). As with XML, a library will likely be needed to parse the data. | ||
+ | ==== Errors ==== | ||
+ | |||
+ | If a request is not sucessfully completed an HTTP error code in the 400s or 500s will be returned. An error code of 500 generally indicates an error with our servers whereas an error code in the 400s is generally an error with the data sent to the server. In such cases the HTTP response will return a header named 'x-error-message'. Below are some errors that are common to many operations. Each operation also has some specific errors which are outlined with the operation. | ||
+ | |||
+ | {| class="wikitable" | ||
+ | !''Description'' | ||
+ | !''HTTP Response Code'' | ||
+ | !''Sample Message'' | ||
+ | |- | ||
+ | |Format is invalid | ||
+ | |400 | ||
+ | |When requesting an index or show on a resource the 'Accept' header should be either 'text/xml' or 'application/json' | ||
+ | |- | ||
+ | |Customer account number is invalid | ||
+ | |404 | ||
+ | |Invalid account number | ||
+ | |- | ||
+ | |Domain is not found | ||
+ | |404 | ||
+ | |<domain name> not found | ||
+ | |- | ||
+ | |Mailbox is not found | ||
+ | |404 | ||
+ | |Mailbox not found | ||
+ | |- | ||
+ | |Required form field is missing | ||
+ | |400 | ||
+ | |Missing required field: <required field> | ||
+ | |- | ||
+ | |Required form field has null or empty string input | ||
+ | |400 | ||
+ | |Required field <required field> cannot be empty | ||
+ | |- | ||
+ | |Integer form field has non-integer input | ||
+ | |400 | ||
+ | |Invalid format for <field>, input must be an integer | ||
+ | |- | ||
+ | |Boolean form field has non-boolean input | ||
+ | |400 | ||
+ | |Invalid format for <field>, input must be True or False | ||
+ | |- | ||
+ | |Form data has an unrecognized field | ||
+ | |400 | ||
+ | |Unrecognized field: <field> | ||
+ | |- | ||
+ | | Entered invalid IP address | ||
+ | | 400 | ||
+ | | invalid ip address: 123 | ||
+ | |} | ||
==== Paging ==== | ==== Paging ==== | ||
− | The results of Index actions are split into pages to lessen potentially high resource usage. The index URLs have a query string with parameters in the format "?size=xx&offset=xx." If a query parameter is omitted, the default value is used. | + | The results of Index actions are split into pages to lessen potentially high resource usage. The index URLs have a query string with parameters in the format "?size=xx&offset=xx." If a query parameter is omitted, the default value is used. |
− | {| | + | {| class="wikitable" |
!''Query Parameter'' | !''Query Parameter'' | ||
!''Default'' | !''Default'' | ||
Line 358: | Line 433: | ||
<pre> | <pre> | ||
− | module NetMethods | + | module NetMethods |
def get(url_string, format) | def get(url_string, format) | ||
− | url = URI.parse(' | + | url = URI.parse('https://' + server_host + server_port + version + url_string) |
@response = Net::HTTP::start(url.host, url.port) do |http| | @response = Net::HTTP::start(url.host, url.port) do |http| | ||
sign_request | sign_request | ||
assign_format(format) | assign_format(format) | ||
@request = Net::HTTP::Get.new(url.path, @headers) | @request = Net::HTTP::Get.new(url.path, @headers) | ||
− | + | ||
http.request(@request) | http.request(@request) | ||
end | end | ||
Line 371: | Line 446: | ||
def post(url_string, format, fields_hash) | def post(url_string, format, fields_hash) | ||
− | url = URI.parse(' | + | url = URI.parse('https://' + server_host + server_port + version + url_string) |
sign_request | sign_request | ||
Line 386: | Line 461: | ||
@headers['Accept'] = format | @headers['Accept'] = format | ||
end | end | ||
− | + | ||
def sign_request | def sign_request | ||
userAgent = 'Ruby Test Client' | userAgent = 'Ruby Test Client' | ||
Line 392: | Line 467: | ||
apiKey = 'XXXXXXXXXXXXXXXXXXXX' | apiKey = 'XXXXXXXXXXXXXXXXXXXX' | ||
secretKey = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' | secretKey = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' | ||
− | + | ||
data_to_sign = apiKey + userAgent + timestamp + secretKey | data_to_sign = apiKey + userAgent + timestamp + secretKey | ||
− | + | ||
signature = Base64.encode64(Digest::SHA1.digest(data_to_sign)) | signature = Base64.encode64(Digest::SHA1.digest(data_to_sign)) | ||
− | + | ||
@headers = Hash.new | @headers = Hash.new | ||
@headers['User-Agent'] = userAgent | @headers['User-Agent'] = userAgent | ||
Line 413: | Line 488: | ||
'/v0' | '/v0' | ||
end | end | ||
− | end | + | end |
</pre> | </pre> | ||
Line 501: | Line 576: | ||
=== PHP === | === PHP === | ||
− | The PHP Example can be found [ | + | The PHP Example can be found [[PHP_Examples_(Rest_API)| here]]. |
Revision as of 10:16, 30 November 2009
Contents
Recent Changes
11/22/09
New features:
|
Introduction
The Email & Apps Control Panel API provides most of the functions of the Control Panel through a HTTP-based REST API (Application Programming Interface). Whether it is adding a new customer account, adding mailboxes, or any other of the supported features the API allows your application to administer the changes regardless of your application's language or nature. For more information on RESTful web services refer to the following sites:
http://en.wikipedia.org/wiki/Representational_State_Transfer
http://java.sun.com/developer/technicalArticles/WebServices/restful/
The API is accessible to resellers only. As of now, most of the supported functions manage only customers, domains, and Exchange accounts.
Operations
The following pages detail the operations that the API supports. The operations are grouped into sections based on the entity/object types that each operation interacts with.
Resource | Example URI |
---|---|
Customer | /customers/123456789 |
Domain | /customers/123456789/domains/example.com |
Exchange Mailbox | /customers/123456789/domains/example.com/ex/mailboxes/john.smith |
Exchange Contact | /customers/123456789/domains/example.com/ex/contacts/john.smith |
Exchange Distribution List | /customers/123456789/domains/example.com/ex/distributionlists/group.name |
The examples shown in the operation pages are written in Ruby and extensively use the helper functions shown in the Ruby Examples below.
Quick Start
To get a list of mailboxes under a domain:
First, you need to populate some HTTP headers with the correct information. 'Accept' needs to be either 'text/xml' or 'application/json' to indicate the format of the returned data. 'User-Agent' just needs to be any name you choose to identify your client with. 'X-Api-Signature' needs a
Accessing the API
Your application will need to make HTTP requests to remote servers. Most programming languages have this function provided in its class library. In addition to the common GET and POST HTTP methods, the library used will also need to support PUT and DELETE.
Calls without TLS (formerly SSL) will complete successfully but it is HIGHLY RECOMMENDED that TLS always be used. Interception of unencrypted communication will allow a third party to have complete access to all functions available via the API.
For some language libraries just using an URL with https:// will cause the library to use TLS. In some other libraries however some options specific to the library may have to be configured to utilize TLS.
All API calls should be directed to a URL in the following format:
https://api.emailsrvr.com/(version)/(resource)
Example:
https://api.emailsrvr.com/v0/customers/12345678/domains/customerbusiness.com
Versions
Supported Versions | URL | Version Documentation |
---|---|---|
v0 (current) | https://api.emailsrvr.com/v0/ | http://signup.apps.rackspace.com/api-wiki/index.php/Rest_API |
The API version number is a component of the URL that is used to access the API. For example, to access the root of the API, the URL is https://api.emailsrvr.com/v0/. Bug fixes and minor non-breaking changes will be made without changing the version number. When major features or breaking changes are introduced, the version number will be incremented. It is not yet determined how many versions are going to be supported at any one time.
Non-breaking Changes | Breaking Changes |
---|---|
Adding new fields or attributes to form fields sent | Changing or deleting any fields in form fields sent |
Adding fields in returned data | Changing or removing fields in returned data |
Changing the URI of any resource |
Authentication
To gain access to the API, your request must include a properly constructed X-Api-Signature HTTP header. Details on what to put in the header are below. To construct the header, you must have the following keys that that are generated from the Control Panel Web interface.
Key Name | Description | Example |
---|---|---|
User Key | A public key that corresponds to your admin id | eGbq9/2hcZsRlr1JV1Pi |
Secret Key | A shared secret key | QHOvchm/40czXhJ1OxfxK7jDHr3t |
An unsuccessful authentication will result in a 403 HTTP code.
X-Api-Signature Header
Format is as follows:
<User Key>:<Timestamp>:<Signature>
Example: eGbq9/2hcZsRlr1JV1Pi:20010317143725:HKUn0aajpSDx7qqGK3vqzn3FglI=
Remember to include the colons between the data strings!
User Key:
This is the public key issued by the Control Panel browser interface.
Timestamp:
The format is YYYYMMDDHHmmssff. All values besides year are zero-padded to two spaces. For example, March 08th 2001 at 2:37.25pm would be 20010308143725.
YYYY | Four-digit year |
MM | Month |
DD | Day |
HH | Hour in 24h format |
mm | Minute |
ss | Second |
ff | Millisecond |
Signature:
A SHA1 (Secure Hash Algorithm) hash must be applied to a string with the following information:
<User Key><User Agent><Timestamp><Secret Key>
Note that the 'User Agent' must be the exact same as what is specified in the User-Agent HTTP Header. Using the above example data, the string before hashing is:
eGbq9/2hcZsRlr1JV1PiRackspace Management Interface20010308143725QHOvchm/40czXhJ1OxfxK7jDHr3t
Resulting base-64 SHA1 Hash:
46VIwd66mOFGG8IkbgnLlXnfnkU=
Be sure to encode the binary hash, not the hex hash, into base-64. The resulting string should be 28 characters long.
Using the API
Requests
HTTP requests should be sent to the server with the correct URL, HTTP Method, HTTP Headers and form data (if needed). The URLs, corresponding HTTP Methods, and necessary form data for the desired operations are detailed in the operation pages.
URL
The URLs are specifies the resource or resource collection. Objects are organized in a tree collection, starting with customers at the top, then domains, then domain objects next (such as mailboxes, contacts, and distribution lists) and so on. The URLs of the resources and collections accessible are found on the operation pages.
HTTP Method
It is the HTTP Method that specifies what operation will be done on the resource. For example, to get the details of a mailbox a HTTP GET will be done on /customers/12345678/domains/example.com/ex/mailboxes/john.smith. If the mailbox does not exist, a HTTP POST to the same URL with the necessary form data will add the mailbox. Then, a HTTP PUT to the same URL will edit mailbox. And to delete the mailbox, an HTTP DELETE would be used.
The types of operations a certain method performs is consistent and is outlined in the table below.
HTTP Method | Operations | Response |
---|---|---|
GET | Index - returns a list of the resources | XML or JSON formatted data |
Show - returns the details of the resource | ||
POST | Add - adds a new resource | Response code and error message (if applicable) only |
PUT | Edit - changes the details of the resource | |
DELETE | Delete - deletes the resource |
HTTP Headers
All requests to the API must then include HTTP headers with the following information:
Header Name | Description | Example |
---|---|---|
Accept | The requested content type (required regardless of type of operation). See Response Formats | text/xml |
User-Agent | An identifier you choose for your client software | Rackspace Management Interface |
X-Api-Signature | An authentication string explained in detail here | eGbq9/2hcZsRlr1JV1Pi:20010317143725:HKUn0aajpSDx7qqGK3vqzn3FglI= |
Filter/Search
The results of Index actions can be filtered/searched. The index URLs can take either one of the query strings: "?startswith=xx" or "?contains=xx," where "xx" is the key word. If the request specifies more than one of these two query strings, a 400 HTTP error will be returned. Different fields will be searched depending on the resource type, see below.
Note that "0-9" is a reserved key word for query string "startswith." It represents any result starting with numbers.
Index Actions | Where the key word will be searched |
---|---|
Customer | Customer name, account number, reference number |
Domain | Domain name |
Mailbox | Mailbox name, mailbox display name |
Contact | Contact display name, external email |
Group | Group name, group display name |
Mobile Service | Associated mailbox name, mailbox display name |
Reference Number
For the customer object only, the query string "referenceNumber=xx" searches for a customer with an exact reference number. The result if found is the detail page of the customer.
Throttling
The server limits the number of requests allowed per user in a certain period of time. The current limit is 1500 requests over 5 minutes. The number of requests made are logged per minute. Calls that were made correctly with a user's API key, but not completed for any reason, including those exceeding the throttle limit, are included in this count.
If a user is over the throttling limit then a 403 HTTP code will be returned with an "Exceeded request limits" message.
Examples
Example requests:
Index of Exchange Mailboxes: Hypertext Transfer Protocol GET /v0/customers/12345678/domains/example.com/ex/mailboxes?size=100&offset=100 HTTP/1.1 Request Method: GET Request URI: /v0/customers/12345678/domains/example.com/ex/mailboxes?size=100&offset=100 Request Version: HTTP/1.1 Host: api.emailsrvr.com User-Agent: Rackspace Management Interface X-Api-Signature: eGbq9/2hcZsRlr1JV1Pi:20010317143725:HKUn0aajpSDx7qqGK3vqzn3FglI= Accept: text/xml Adding New Exchange Mailbox: Hypertext Transfer Protocol POST /v0/customers/12345678/domains/example.com/ex/mailboxes/john.smith HTTP/1.1 Request Method: POST Request URI: /v0/customers/12345678/domains/example.com/ex/mailboxes/john.smith Request Version: HTTP/1.1 Host: api.emailsrvr.com User-Agent: Rackspace Management Interface X-Api-Signature: eGbq9/2hcZsRlr1JV1Pi:20010317143725:HKUn0aajpSDx7qqGK3vqzn3FglI= Accept: text/xml Content-Length: 53 [Content length: 53] Content-Type: application/x-www-form-urlencoded Line-based text data: application/x-www-form-urlencoded size=2048&displayName=John%20Smith&password=abcABC123
Responses
On a successfully executed request, a 200 HTTP Code is returned. Requested data is also returned if the operation was a Show or Index action. If the request is unsuccessful, then an error HTTP Code is returned with a message detailing the error. The errors and their corresponding codes are detailed on the operation pages.
Formats
Requests for data (index and show requests) are returned with XML or JSON data based on what your application populates the HTTP Accept Headers with.
For XML, populate the header with 'text/xml' (ex: Headers!["Accept"] = "text/xml"). The XML document returned will conform to a published XSD (XML Schema Document). There are many ways to extract data from an XML document, but we have found that the XPath tree-style traversal has served our purposes. In any case, your application will likely need to use a library with the functions necessary for whichever method you choose to use to extract data.
For JSON, populate the header with 'application/json' (ex: Headers!["Accept"] = "application/json"). As with XML, a library will likely be needed to parse the data.
Errors
If a request is not sucessfully completed an HTTP error code in the 400s or 500s will be returned. An error code of 500 generally indicates an error with our servers whereas an error code in the 400s is generally an error with the data sent to the server. In such cases the HTTP response will return a header named 'x-error-message'. Below are some errors that are common to many operations. Each operation also has some specific errors which are outlined with the operation.
Description | HTTP Response Code | Sample Message |
---|---|---|
Format is invalid | 400 | When requesting an index or show on a resource the 'Accept' header should be either 'text/xml' or 'application/json' |
Customer account number is invalid | 404 | Invalid account number |
Domain is not found | 404 | <domain name> not found |
Mailbox is not found | 404 | Mailbox not found |
Required form field is missing | 400 | Missing required field: <required field> |
Required form field has null or empty string input | 400 | Required field <required field> cannot be empty |
Integer form field has non-integer input | 400 | Invalid format for <field>, input must be an integer |
Boolean form field has non-boolean input | 400 | Invalid format for <field>, input must be True or False |
Form data has an unrecognized field | 400 | Unrecognized field: <field> |
Entered invalid IP address | 400 | invalid ip address: 123 |
Paging
The results of Index actions are split into pages to lessen potentially high resource usage. The index URLs have a query string with parameters in the format "?size=xx&offset=xx." If a query parameter is omitted, the default value is used.
Query Parameter | Default | Maximum | Notes |
---|---|---|---|
size | 50 | 250 | This is the number of elements per page. |
offset | 0 | N/A | This is the number of items to offset away from the first item in the list. |
Examples
Ruby
This examples is written in Ruby. To make the examples shorter, helper methods have been written. These methods are part of a NetMethods module. The contents of the NetMethods module is listed below.
module NetMethods def get(url_string, format) url = URI.parse('https://' + server_host + server_port + version + url_string) @response = Net::HTTP::start(url.host, url.port) do |http| sign_request assign_format(format) @request = Net::HTTP::Get.new(url.path, @headers) http.request(@request) end end def post(url_string, format, fields_hash) url = URI.parse('https://' + server_host + server_port + version + url_string) sign_request assign_format(format) @request = Net::HTTP::Post.new(url.path, @headers) @request.set_form_data(fields_hash) @response = Net::HTTP::start(url.host, url.port) do |http| http.request(@request) end end def assign_format (format) @headers['Accept'] = format end def sign_request userAgent = 'Ruby Test Client' timestamp = DateTime.now.new_offset.strftime('%Y%m%d%H%M%S00') apiKey = 'XXXXXXXXXXXXXXXXXXXX' secretKey = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' data_to_sign = apiKey + userAgent + timestamp + secretKey signature = Base64.encode64(Digest::SHA1.digest(data_to_sign)) @headers = Hash.new @headers['User-Agent'] = userAgent @headers['X-Api-Signature'] = apiKey + ":" + timestamp + ":" + signature end def server_host 'api.emailsrvr.com' end def server_port '80' end def version '/v0' end end
C#
This examples is written in C#.
using System; using System.Collections.Specialized; using System.Security.Cryptography; using System.Text; using System.Net; public class WebMethods { private WebClientBase client; private string baseUrl; private string apiKey; private string secretKey; public WebMethods(WebClientBase client, string baseUrl, string apiKey, string secretKey) { this.client = client; this.baseUrl = baseUrl; this.apiKey = apiKey; this.secretKey = secretKey; } public virtual string Get(string url) { return MakeRemoteCall((client) => { return client.DownloadString(baseUrl + url); }, format); } public virtual string Post(string url, NameValueCollection data) { return MakeRemoteCall((client) => { var bytes = client.UploadValues(baseUrl + url, data); return Encoding.UTF8.GetString(bytes); }, format); } private void SignMessage() { var userAgent = "C# Client Library"; client.Headers["User-Agent"] = userAgent; var dateTime = DateTime.UtcNow.ToString("yyyyMMddHHmmssff"); var dataToSign = apiKey + userAgent + dateTime + secretKey; var hash = SHA1.Create(); var signedBytes = hash.ComputeHash(Encoding.UTF8.GetBytes(dataToSign)); var signature = Convert.ToBase64String(signedBytes); client.Headers["X-Api-Signature"] = apiKey + ":" + dateTime + ":" + signature; } private void AssignFormat(string format) { client.Headers["Accept"] = format; } private string MakeRemoteCall(Func<WebClientBase, string> remoteCall, string format) { try { SignMessage(); AssignFormat(format); return remoteCall.Invoke(client); } catch (WebException e) { throw new ApiException(e); } } }
PHP
The PHP Example can be found here.