This documentation describes the YoolinkPro API interface. It's designed for developers who wants to interconnect YoolinkPro with their own applications, or create new application relying on their YoolinkPro account.
In this section we will cover the concepts every developer should know before interacting with the API.
The API uses a REST-like interface. This means that our YoolinkPro method calls are made over the internet by sending HTTP GET, POST, PUT or DELETE requests to the YoolinkPro API server (http://api.yoolinkpro.com). Nearly any computer language can be used to communicate over HTTP with the REST server.
Any application that want to use the YoolinkPro API must be able either to access api.yoolinkpro.com via HTTP (80) or via HTTPS (443).
Before starting developing a YoolinkPro third-party application, an administrator of the YoolinkPro account should ask us to enable the YoolinkPro API support for his account.
When the API support is enabled, three informations are provided to allow the communication between the third-party application and the YoolinkPro API:
api_public_key
This key will be used to identify the yoolinkpro account which is sending the request.
Any request sent must provide that key along with the given parameters.
api_private_key
This key is private and must not be sent with the request parameters. It's used by the third-party application to sign its requests (as explained below, in the Request Authentication section).
That key is only known by YoolinkPro API and the third-party application, it must be kept secret by the third-party application.
This key is private and must not be sent with the request parameters.
api_admin_key
That key is used by the third-party application for making privileged actions.
All of the requests for actions described in the Administrator section should be signed with this key, rather than with api_private_key.
First of all, we'll see in this section how to build and send a valid authenticated request to the YoolinkPro API. In order to make sure a request is sent by the third-party application, YoolinkPro API will perform a signature verification before processing the request.
This section will explain how it works.
The thrid-party application must sign every request it sends. To do so, it has to do build the signature string like the following:
Sort the parameters hash table alphabetically by key.
Concatenate all key/value pairs together in the format key=value (omitting the signature itself, since that is what we are calculating).
a_var=a_value other_var=other_value
Concatenate to the HTTP method string in lowercase (get), the path string (/user/42.json) and the params string created during the previous step.
get /user/42.json a_var=a_value other_var=other_value
Append the api_private_key and two mandatory parameters :
X-YP-MilliTime
Unix time in milliseconds, defined as the number of milliseconds elapsed since midnight UTC of January 1, 1970
X-YP-Int
a uniq integer or at least a random one
Take the base64 of the SHA1 hash of the whole string (wihout any spaces) :
get /user/42.json a_var=a_value other_var=other_value 87e1f221a672a14a323e57bb65eaea19d3ed3804 1334742783000 282
Note that for all administrator actions, the key to use for signing the request is not api_private_key but api_admin_key.
Below is a Ruby code example that shows how to implement the signing method:
require 'base64'
millitime = Time.now.to_i*1000
int = rand(1000)
query_string = params.sort.map{|v| v.join('=')}.join
key = "get/user/search.json#{query_string}#{PRIVATE_KEY}#{millitime}#{int}"
signature = Base64.encode64(Digest::SHA1.digest(key)).gsub(/=$/, '')
# Important note : we do not append '=' at the end of the signature.
# If your library adds a trailing '=' remove it.
Once the signature has been built, the request can be sent to the YoolinkPro API. To do so, all meta-data such as the public key and the signature should be sent via the request headers:
X-YP-AppKey
This header should contain the api_public_key of the application.
X-YP-Signature
This header should contain the signature built for the request.
X-YP-MilliTime
This header should contain the unix time in milliseconds, defined as the number of milliseconds elapsed since midnight UTC of January 1, 1970.
X-YP-Int
This header should contain a uniq integer or at least a random one.
Here is an example of a signed GET request:
GET /user/42.json?a_var=a_value&other_var=other_value
X-YP-AppKey: api_public_key
X-YP-Signature: signature
X-YP-MilliTime: millitime
X-YP-Int : int
Whenever a request is received by YoolinkPro API, it first checks that the signature is valid. To do so, it does the very same process as described above to rebuild the signature, and makes sure both signatures are the same.
If so, the request is authenticated and granted for processing.
Note, the request can played only once and is valid for 30 minutes after X-YP-MilliTime.
All requests performed on the YoolinkPro API should provide a format argument, as the file extension in the path of the request.
Here is an example:
GET http://api.yoolinkpro.com/users/24.json
When an error is triggered, the action will always return a response with the following entries:
error: the error code of the error
message: a message with details about the error that occurs
Checking if error is present in the response object is a good way to check if the actions succeeded or not.
There are 3 levels of privileges:
Unprivileged: Read-only actions (retreiving a link, a user)
User: Actions executed on the behalf of a specific user (posting in the company's feed).
Administrator: Actions with administration privileges (creating/revoking users).
When the YoolinkPro API is enabled, another key is given to the client: the api_admin_key.
This key is provided to allow an API request to perform privileged actions.
This key gives to the application the power of a regular administrator.
As a developer of a third-party application,
you should not consider shipping your application with your api_admin_key (for example if you deploy a desktop app within your company).
Ideally and if you need it, that key should be prompted to the user (if they are administrator, they have access to the YoolinkPro API information in their account).
All requests for actions described in the section Administrator must been signed with the api_admin_key.
All the actions described in this section are read-only. These actions aren't privileged and don't require any identity_token.
This method retreives a user corresponding to the given email.
GET /user/search.json?email=vincent@yoolink.fr
GET /user/search.json?external_id=123ABC
{
"user": {
"id": 1,
"customer_id": 1,
"slug": "yoolink",
"activation_hash": "09fdca3e7825007813820dfd9436f5bb",
"firstname": "Vincent",
"lastname": "Durand",
"name": "Vincent Durand",
"is_active": true,
"email": "vincent@yoolink.fr",
"disabled": false,
"locale": "fr",
"external_id": "123ABC",
"telephone": "0123456789",
"im": "vincent.durand"
"im_type": "3",
"mobile_phone": "0623456789",
"description": "Yoolink CTO",
"birth_day": "25",
"birth_month": "12",
"has_full_feed": true,
"role": "CTO",
"past_experience": "Rails Developer",
"education": "",
"profile_like": "Ruby, Rails",
"profile_dislike": "",
"twitter_url": "",
"facebook_url": "",
"linkedin_url": "",
"viadeo_url": "",
"office_number": "1337",
"company": "Yoolink",
"address": "",
"country": "France",
"website": "http://www.yoolinkpro.com",
"project": "YoolinkPro"
}
}
This method retreives a user corresponding to the given id.
GET /user/42.json
{
"user": {
"id": 1,
"customer_id": 1,
"slug": "yoolink",
"activation_hash": "09fdca3e7825007813820dfd9436f5bb",
"firstname": "Vincent",
"lastname": "Durand",
"name": "Vincent Durand",
"is_active": true,
"email": "vincent@yoolink.fr",
"disabled": false,
"locale": "fr",
"external_id": "123ABC",
...
}
}
This method retreives a link object corresponding to the given id.
GET /link/42.json
{
"title": "Yoolink Pro",
"url": "http://www.yoolinkpro.com",
"tags": "Pro, Corporate, Yoolink"
}
All of the actions (except /user/authenticate) described here require an identity_token.
This token is used to execute the action under the corresponding user's identity.
This token is provided either by /user/authenticate or by the administrator action /user/identity_token.
This method authenticates a user for a given email and encrypted password.
If the authentication succeeds, returns an identity_token.
Note that the password must be encrypted with Blowfish with the private key of the application.
The following pseudo-code example shows how to encrypt the password:
function crypt_password(clear_password) {
encrypted_data = crypt_string_with_blowfish(clear_password, api_private_key);
return encode_base64(encrypted_data);
}
POST /user/authenticate.json
email: vincent@yoolink.fr
password: 8rY1deHMesM=
identity_token: an identity_token that allows next requests to be executed
on behalf of that user
{
"identity_token": "09fdca3e7825007813820dfd9436f5bb"
}
This method creates a new link object corresponding to the params given in the request body.
Note that at least one tag is expected. The API won't accept a new link if no tag is given.
POST /link.json
identity_token: 09fdca3e7825007813820dfd9436f5bb
url: http://www.yoolinkpro.com
title: Yoolink Pro
tags: Pro,Corporate,Yoolink
description:
{
"post_id": 42
}
This method retreives the existing link object identified by the given id in the path and updates it with the parameters given in the request body.
In order to remove an existing value for a given attribute, the attribute must be given with a null value (when an attribute is not given in the request params, its value is untouched).
Note that it's not possible to change the URL of an existing link. If you want to actually change the URL, you have to first DELETE the object and re-create it with the good URL.
In the following example, we alter the link object #42, changing the value of its attributes title and tags and removing the value of the attribute description.
PUT /link/42.json
identity_token: 09fdca3e7825007813820dfd9436f5bb
title: YoolinkPro
tags: YoolinkPro
description:
This method deletes the existing link object identified by the id given in the path.
DELETE /link/42.json
identity_token: 09fdca3e7825007813820dfd9436f5bb
In this section, we'll see all the methods available in the YoolinkPro API that require an api_admin_key.
All the actions must be signed with the api_admin_key rahter than whith the api_private_key.
These actions are performed with administrator privileges.
This method returns an identity_token for the requested user.
Note that you can use the email address of the user instead of the id with this action. Other actions refering to a user will need the id though.
An identity_token has a limited time-to-live: it expires 30 minutes after the last request received with it.
If an expired token is used in a request, a specific error is triggered, this action will have to be used to get a new token for that user.
GET /user/identity_token.json?id=42
{
"identity_token": "09fdca3e7825007813820dfd9436f5bb"
}
This method retreives all users.
GET /users.json
{ "users":
[
{
"user": {
"id": 1,
"customer_id": 1,
"slug": "yoolink",
"activation_hash": "09fdca3e7825007813820dfd9436f5bb",
"firstname": "Vincent",
"lastname": "Durand",
"name": "Vincent Durand",
"is_active": true,
"email": "vincent@yoolink.fr",
"disabled": false,
"locale": "fr",
"external_id": "123ABC",
...
}
},
{
"user": {...}
},
{
"user": {...}
}
]
}
Creates a new user in the YoolinkPro account.
POST /user.json
email: john.smtih@company.com
firstname: John
lastname: Smith
{
"user": {
"id": 123,
"customer_id": 123,
"slug": "company",
"activation_hash": "09fdca3e7825007813820dfd9436f5bb",
"firstname": "John",
"lastname": "Smith",
"name": "John Smith",
"is_active": false,
"email": "john.smtih@company.com",
"disabled": false,
"locale": "en",
"external_id": "",
...
}
}
Update the user.
As for any resource, in order to remove an existing value for a given attribute, the attribute must be given with a null value (when an attribute is not given in the request params, its value is untouched).
PUT /user/42.json
lastname: Doe
email: john.doe@company.com
{
"user": {
"id": 123,
"customer_id": 123,
"slug": "company",
"activation_hash": "09fdca3e7825007813820dfd9436f5bb",
"firstname": "John",
"lastname": "Doe",
"name": "John Doe",
"is_active": false,
"email": "john.doe@company.com",
"disabled": false,
"locale": "en",
"external_id": "",
...
}
}
Upload photo for user corresponding to the given id.
The photo_data parameter given in the request body must not be concatenate in the key for signing the request.
method path api_admin_key X-YP-MilliTime X-YP-Int
post /user/photo/42.json 87e1f221a672a14a323e57bb65eaea19d3ed3804 1334742783000 282
POST /user/photo/42.json
photo_data: File.open('/home/vdurand/pictures/John-Doe.jpg') # Ruby example
{
"user": {
"id": 123,
"customer_id": 123,
"slug": "company",
"activation_hash": "09fdca3e7825007813820dfd9436f5bb",
"firstname": "John",
"lastname": "Doe",
"name": "John Doe",
"is_active": false,
"email": "john.doe@company.com",
"disabled": false,
"locale": "en",
"external_id": "",
...
}
}
Disables the requested user. Once disabled, the user woin't be able to access the YoolinkPro account or to use the service anymore.
DELETE /user/42.json
Enables a previously disabled user. Once enabled, the user is able to check in again to the service.
PUT /user/enable/42.json
Disable a user. Once disabled, the user is not able to check in again to the service.
PUT /user/disable/42.json
This section describes all the error codes you might receive when using the YoolinkPro API. It's organized by categories corresponding ot the king of error.
Internals
Error codes representing failures during request processing.
101. Runtime error
102. Service unavailable
Protocol
Error codes representing protocol violation
201. The api key is not given (header X-YP-AppKey is mandatory)
202. The signature is not given (header X-YP-Signature is mandatory)
203. Invalid signature
204. Missing parameter
205. The api key is invalid
Resources
Error codes representing failures during resources handling.
301. Unknown resource
302. Create failure
303. Update failure
304. Delete failure
User
Error codes representing failures during user actions (that needs an identity token).
401. Authentication failed
402. Missing identitiy token
403. Invalid identitiy token
404. Expired identity token
Administrator
Error codes representing failures during administrator actions (that needs an admin key).
501. Missing Admin Key
502. Invalid Admin Key
require 'base64'
require 'uri'
require 'net/http'
require 'json'
PUBLIC_KEY = "09fdca3e7825007813820dfd9436f5bb"
PRIVATE_KEY = "bb5f6349dfd0283187005287e3acdf90"
millitime = Time.now.to_i*1000
int = rand(1000)
key = "get/user/1.json#{PRIVATE_KEY}#{millitime}#{int}"
signature = Base64.encode64(Digest::SHA1.digest(key)).gsub(/=$/, '')
uri = URI("http://api.yoolinkpro.com/user/1.json")
res = Net::HTTP.start(uri.host, uri.port) do |http|
http.get(uri.request_uri,
{ 'X-YP-AppKey' => PUBLIC_KEY, 'X-YP-Signature' => signature, 'X-YP-MilliTime' => "#{millitime}", 'X-YP-Int' => "#{int}" })
end
puts res.body
user = JSON.parse(res.body)['user']
puts user['email']
{
"user": {
"id": 1,
"customer_id": 1,
"slug": "yoolink",
"activation_hash": "09fdca3e7825007813820dfd9436f5bb",
"firstname": "Vincent",
"lastname": "Durand",
"name": "Vincent Durand",
"is_active": true,
"email": "vincent@yoolink.fr",
"disabled": false,
"locale": "fr",
"external_id": "123ABC",
"telephone": "0123456789",
"im": "vincent.durand"
"im_type": "3",
"mobile_phone": "0623456789",
"description": "Yoolink CTO",
"birth_day": "25",
"birth_month": "12",
"has_full_feed": true,
"role": "CTO",
"past_experience": "Rails Developer",
"education": "",
"profile_like": "Ruby, Rails",
"profile_dislike": "",
"twitter_url": "",
"facebook_url": "",
"linkedin_url": "",
"viadeo_url": "",
"office_number": "1337",
"company": "Yoolink",
"address": "",
"country": "France",
"website": "http://www.yoolinkpro.com",
"project": "YoolinkPro"
}
}
vincent@yoolink.fr