Soocial API
The Soocial API allows developers to integrate Soocial into their applications. It allows applications to access and modify Soocial data, and is implemented as Vanilla XML over HTTP. All clients that access and use the API are seen as syncing devices in the Soocial ecosystem.
Introduction
The API is a RESTful service. All data is available through the API as a resource to which can be referred using a unique identifier. It responds to a number of the HTTP methods, specifically GET, PUT, POST and UPDATE, and all responses from the API are in a simple XML format encoded as UTF-8.
Notes about the documentation
A few conventions have been applied in the documentation, these are:
ID's in a resource URL indicate that the resource's unique ID needs to be inserted there...indicates that unimportant bits of response data have been removed to eliminate noise from the documentation
All examples make use of cURL with Basic HTTP authentication.
Authentication
Soocial supports OAuth authentication. In short this means that you can allow external applications to access your contacts in a manner that doesn't require you to reveal your Soocial username or password. It also enables you to revoke that access at any time. The users of Soocial are always in control of who has access to their data.
Authentication can also be realised by using Basic HTTP authentication. Your Soocial.com username and password can be used as the authentication credentials for the API.
IMPORTANT: Depending on your url library you may need to escape your username and password before you connect. Your soocial username is an emailaddress with an at sign (@), which can cause problems because the at sign is sometimes used as a delimiter for the credentials and hostname.
wrong:
http://user**@**domain.com:p4ssw0rd**@**www.soocial.com/contacts.xml
Escaping the username in ruby with CGI.escape(username) will avoid that problem. Most languages will have their own escape implementation so check the documentation.
right:
http://user**%40**domain.com:p4ssw0rd**@**www.soocial.com/contacts.xml
The preferred authentication option is OAuth, the examples in this documentation use Basic HTTP authentication for its simplicity. You don't give your bankcard and PIN number to a waiter to pay at a restaurant and you shouldn't have to give your username and password to any service in order to give them access to your contacts.
Registering your OAuth application
For your application to get access to Soocial you need to get your key and secret values for your application by registering it.
We will post a screencast about using & setting up OAuth soon.
Retrieving data from the API
To retrieve data you only need to do an HTTP GET on a resource identifier. For example, if you want to get all the contacts with cURL:
$ curl -u user%40domain.com:p4ssw0rd http://www.soocial.com/contacts.xml
>> <?xml version="1.0" encoding="UTF-8"?>
<contacts type="array">...</contacts>
Pagination of the results is available when using the parameters page_num and page_size. When passing page_num in the parameters pagination will be used, the default page_size will be 20 contacts unless specified otherwise.
$ curl -u user%40domain.com:p4ssw0rd "http://www.soocial.com/contacts.xml\
?page_num=1&page_size=10"
>> <?xml version="1.0" encoding="UTF-8"?>
<contacts type="array">...</contacts>
An authenticated user's total number of contacts is available under /user.xml. See the example on ActiveResource below.
Retrieving a single contact:
$ curl -u user%40domain.com:p4ssw0rd \
http://www.soocial.com/contacts/397.xml
>> <?xml version="1.0" encoding="UTF-8"?>
<contact>...</contact>
Retrieving the telephone entries of a contact:
$ curl -u user%40domain.com:p4ssw0rd \
http://www.soocial.com/contacts/397/telephones.xml
>> <?xml version="1.0" encoding="UTF-8"?>
<telephones type="array">...</telephones>
And likewise, retrieving a single telephone entry:
$ curl -u user%40domain.com:p4ssw0rd \
http://www.soocial.com/contacts/397/telephones/0.xml
>> <?xml version="1.0" encoding="UTF-8"?>
<telephone>...</telephone>
All data is available according to the following resource paths:
- /contacts.xml
- /contacts/
ID.xml - /contacts/
ID/telephones.xml - /contacts/
ID/telephones/ID.xml - /contacts/
ID/emails.xml - /contacts/
ID/emails/ID.xml - /contacts/
ID/organisations.xml - /contacts/
ID/organisations/ID.xml - /contacts/
ID/urls.xml - /contacts/
ID/urls/ID.xml - /contacts/
ID/addresses.xml - /contacts/
ID/addresses/ID.xml - /user.xml
- /users.xml
- /devices.xml
Writing to the API
The API can be written to using the HTTP methods PUT, POST and DELETE in combination with the appropriate request headers.
Creating a new contact, using curl:
$ curl -u user%40domain.com:p4ssw0rd@www.soocial.com \
-d "contact[first_name]=Dennis&contact[last_name]=Jackson" \
http://www.soocial.com/contacts.xml -i
>> HTTP/1.1 201 Created
Location: http://www.soocial.com/contacts/414.xml
...
The response is an HTTP/1.1 201 Created with Location header indicating where the new contact resource can be found. Now we can add phone numbers to this contact, using curl:
$ curl -u user%40domain.com:p4ssw0rd@www.soocial.com -d \
"telephone[location]=cell&telephone[number]=+1 202-456-1111" \
http://www.soocial.com/contacts/414/telephones.xml -i
>> HTTP/1.1 201 Created
Location: http://www.soocial.com/contacts/414/telephones/1.xml
...
The response is a again an HTTP/1.1 201 Created with Location header indicating where the new phone number resource can be found. Changing the phonenumber label, again using curl:
$ curl -u user%40domain.com:p4ssw0rd@www.soocial.com -X PUT \
-d "telephone[location]=home" \
http://www.soocial.com/contacts/414/telephones/1.xml -i
>> HTTP/1.1 200 OK
...
<?xml version="1.0" encoding="UTF-8"?>
<telephone>
...
<location>home</location>
<number>+1 202-456-1111</number>
...
</telephone>
The response is an HTTP/1.1 200 OK with in the body the XML representation of the new contact.
If we want to delete that phone number we can call its unique resource identifier (the URL) with the HTTP method DELETE, again with curl:
$ curl -u user%40domain.com:p4ssw0rd@www.soocial.com -X DELETE \
http://www.soocial.com/contacts/414/telephones/1.xml -i
>> HTTP/1.1 200 OK
...
The API returns an HTTP/1.1 200 OK and the phone number is now deleted.
Dealing with the response and response status
All succesful operations respond with a status code of 200 OK or 201 Created depending on the operation.
Sometimes a list, say GET /devices.xml will not have any items, it will return an empty list.
Empty lists XML responses look like this, again with curl:
$ curl -u user%40domain.com:p4ssw0rd@www.soocial.com \
http://www.soocial.com/devices.xml
>> <?xml version="1.0" encoding="UTF-8"?>
<nil-classes type="array"/>
Reserved fields
In contrast to the contact resources (/contacts/*), the resources for the user and the phone information only allow a limited set of operations, these are:
- /user.xml allows a full GET but only allows a PUT for the name field
- /users.xml allows a full GET but only returns the user info for the logged in user
- /devices.xml and /devices/
ID.xml only allow GET
Consuming the API with ActiveResource
ActiveResource is a thin but powerful wrapper around RESTful services exposed by Ruby on Rails.
It is part of Rails 2.0 and you can get it with gem install activeresource --include-dependencies. If you're developing on the bleeding edge of Rails you already have ActiveResource installed.
$ script/console
Loading development environment (Rails 2.0.2)
>> ActiveResource::Base.site = "http://www.soocial.com/"
=> "http://www.soocial.com/"
>> ActiveResource::Base.site.user = CGI.escape "user@domain.com"
=> "user%domain.com"
>> ActiveResource::Base.site.password = CGI.escape "p4ssw0rd"
=> "p4ssw0rd"
>> class Contact < ActiveResource::Base; end
=> nil
>> Contact.find :first
=> #<Contact:0x262396c @prefix_options={}, @attributes={...}>
>> Contact.find :all
=> [#<Contact:0x274cfc8 @prefix_options={}, @attributes={...}, ...]
>> Contact.find(:all,:params => {:page_num => 1, :page_size => 5})
=> [#<Contact:0x274cfc8 @prefix_options={}, @attributes={...}, ...]
>> Contact.find(:all,:params => {:page_num => 1, :page_size => 5}).size
=> 5
>> class User < ActiveResource::Base; end
=> nil
>> user = User.find :first
=> #<User:0x344b080 @prefix_options={}, @attributes={...}>
>> user.invites_available
=> 5
>> user.number_of_contacts
=> 185
Inspired by 37 Signals's Highrise wrapper, we've put together a small ruby wrapper for the API which sets up the ActiveResource models for you to play with in an IRB session:
$ irb -r api_helper.rb
irb(main):001:0> Soocial::API.user="user@domain.com"
irb(main):002:0> Soocial::API.password="p4ssw0rd"
irb(main):003:0> Soocial::API.host="www.soocial.com"
irb(main):004:0> Soocial::API.port=80
irb(main):005:0> millard = Soocial::API::Contact.find :first
irb(main):006:0> millard.first_name
=> "Millard"
irb(main):007:0>