OAuth2 flows

The purpose of this document is to describe the OAuth2 flows required to make requests to Poken API. At this moment Poken is using the OAuth2 v13 specification. 
If this document doesn’t clarify what is needed to access the API please feel free to contact us at api[at]poken.com.

Please check the examples page for details of how you can test the Poken API with your client credentials.

1. Simple OAuth2 flows

This section will give you a quick overview of the normal OAuth2 flows supported by poken, no worries if something is unclear, you can see the flows in detail in section 2.

1.1 How to get an account access token

In order to make API requests on a user’s behalf, you’ll need to obtain an access token.
The preferred flow is  to ask the user to authorize your client to access his data:

1) send the user to this url:
https://user.poken.com/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=http://YOUR_SITE/REDIRECT_URI


2) The user is asked to login and authorize your client. 


3) After granting access we redirect the user to something like this :
http://YOUR_SITE/REDIRECT_URI?code=39040976-C-EDNG7jPxYEirEY7AVK5fUQPp&expires_in=899

4) extract the authorization code and make the request explained  at section 1.5 (How to get an account acess token from an authorization code)

Poken API supports a non standard OAUTH2 flow to get an access token when a username and password are provided but this method might be restricted in the future so please use the above method describing the user authorization flow.
You can still get an access_token for a user by making a GET or POST request to 
https://api.poken.com/oauth2/access_token , passing the following parameters:

  • grant_type – use the value “password”
  • client_id – your API client id
  • client_secret – the secret key of your client
  • username – the account username for which you want to obtain an access token
  • password – the account password
  • response_type – use the value “token”

Note that all below flows that require a client_id and client_secret should be done to the same URL as above, we’ll only mention the parameters from now on.

If these parameters are valid an access token will be issued and returned in the response, along the an expiry value(in seconds , normally will be 86400 (24 hours))and a refresh token for retrieving a new token once your access token expires. The access token is what you will use to make API requests on behalf of the user. 

Here is a successful response sample :
{“expires_in”:86400, “refresh_token”:”18927670-R-2v8e8ycA419RaaVWY9Xz4APp”, “access_token”:”18926970-A-nMnSHDqg8Fsunm6Qx1cF1APp”}

All requests to /oauth2/* must be over HTTPS.

1.2 How to make OAuth2 requests

To make Poken API requests on the behalf of a user, pass the OAuth token either in the query string, as a header, or as a parameter in the request body when making a `POST` request.

For example, to get a users profile information, if you have an access token “18926970-A-nMnSHDqg8Fsunm6Qx1cF1APp”, the request would look like this:
GET /rest081/account/profile?access_token=18926970-A-nMnSHDqg8Fsunm6Qx1cF1APp

To pass the OAuth token as a header, use the Authorization header like so:
GET /rest081/account/profile
Authorization: OAuth2 access_token=”18926970-A-nMnSHDqg8Fsunm6Qx1cF1APp”

Pass the OAuth token as a parameter in a `POST` body like so:
POST /rest081/account/profile
access_token=18926970-A-nMnSHDqg8Fsunm6Qx1cF1APp&alias=myusername&…

Note that API requests that use OAuth2 must use HTTPS.
We support JSON and XML responses, in this document you’ll see response examples interchangeably.

1.3 Refreshing an access token

Access tokens expire after 24 hours if they are not used(every time you use an access token the validity is increased to a maximum 24 hours).
After an access token has expired, you can request a new access token using the refresh token that was issued along with the access token.
Fetching a new access token is much like fetching the original access token, except a couple of the parameters are different.

  • grant_type – use refresh_token
  • client_id – the API client id
  • client_secret – the secret key for your client
  • refresh_token – the refresh_token which was issued at the same time as the access token

The response will include a new access token, its expiry value, and a new refresh token. Note that refresh tokens are useable only once and cannot be reused. 

See below an example flow that requires usage of refresh token
:

1.4 How to get a client access token

Some API endpoints does not require an account access token since they have to be executed without an authenticated user. Such an example is the create account endpoint. T
o make a request to such an endpoint a client needs to obtain a 
client access token.
The request is similar to the account access token request using this parameters:

  • grant_type – use client_credentials
  • client_id – the API client id
  • client_secret – the secret key for your client
  • response_type – use token

The response will include just the access_token and the expiry value. No refresh token is returned for a client credentials since the client can obtain a new access token any time using just it’s client_id and client_secret. 
The create account endpoint is an example of an endpoint that returns an authorization code that can be exchange for an account access token. A sequence diagram can be find in section 1.5.

1.5 How to get an account acess token from an authorization code

As we saw above there are endpoints that are executed using a client access token and return an authorization code that can be used to get an account access token.
For this, a request with this parameters should be made:

  • grant_type – use authorization_code
  • client_id – the API client id
  • client_secret – the secret key for your client
  • code – the authorization code returned by some of the endpoints (ex: 18927671-C-LSU58LKcM2xlLLBXNVgUYAPp)
  • redirect_uri – the URI provided when you asked for a Poken API client

The returned response is like for section 1.1 . Also, note that the code can not be reused.

See below an example flow that involves also exchanging of an authorization code for an account access token:

2. Detailed OAuth2 implementation

This section will described with great details all the above OAuth2 flows.
Note, the authentication API layer support adding the 
_format parameter to the requests to get the response in the desired format, supported values are :

  • text (the response will be in plain text and form encoded ) ,for example:

        access_token=18920022-A-flT0Yf4AQ3pnpwUfCK4nGwPp&expires_in=3491

  • json (default , if _format is not present), for example:

        {“expires_in”:3569,”access_token”:”18920022-A-BaNtpjxXdlJm05NiE0ZsAAPp”}

  • xml ( the response will be in xml format), for example:

          <?xml version=”1.0″ encoding=”UTF-8″ standalone=”no”?>
<response>
<access_token>18920022-A-flT0Yf4AQ3pnpwUfCK4nGwPp</access_token>

<expires_in>3550</expires_in>

</response>

Some requests might fail from different reasons, each request has a list of parameters that need to be provided, as described above for each call. 
Here are some general errors in JSON format:

  • Below is an error when an invalid grant_type parameter is provided, there response will have the HTTP code 400

        {“error”:”invalid_grant”, “error_description”:”Please provide a valid grant_type, supported types are : authorization_code, client_credentials, password, poken_external or refresh_token.”}

  • all request have required parameters , in case some are missing a HTTP response with code 400 and body message will be returned:

        {“error”:”parameter_absent”,  “error_description”:”Parameters missing from the request :  client_id&client_secret&response_type . “} 

2.1 Client credential access token

A client credential access token is useful to make API requests to endpoints which do not require an authenticated poken user, for example create account.
To obtain such a token, you can use your browser and make this request: 
https://api.poken.com/oauth2/access_token?grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&response_type=token

If the request is successful an access token is returned in JSON format : 
    {“expires_in”:86400,”access_token”:”18920022-A-BaNtpjxXdlJm05NiE0ZsAAPp”}

You noticed that no refresh token was returned, the client can anytime get a new access token using just it’s client id and secret. 
After obtaining this access token , the client is permitted to make requests to API endpoints that don’t request an account access token, such an example is the create account endpoint.
The expires_in is in seconds and it means that the token is valid for the next 24 hours, every time you make a new request with an access token, the validity is increased.

Here is a list of possible failures in case the request failed to pass  validation:

  • HTTP code 401, body:

    {“error”:”invalid_client”,”error_description”:”No client found for the provided id.”}

  • HTTP code 401, body:

    {“error”:”unauthorized_client”,“error_description”:”Invalid client or doesn’t have the     permission to make this request.”}

2.2 Getting an access token using username and password

Some Poken API endpoints require an access token obtained for a user not a client. 
Note
, this is not a standard OAUTH2 flow but is used by Poken applications that are allow to request a username and password from an user.
This request might be restricted in the future so please use the normal user authorization flow.

To test this flow, use your browser and make a GET request to :
https://api.poken.com/oauth2/access_token?grant_type=password&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&username=ACCOUNT_USERNAME&password=ACCOUNT_PASSWORD&response_type=token

If successful, the response should contain something like this :
{“expires_in”:86400, “refresh_token”:”18927670-R-2v8e8ycA419RaaVWY9Xz4APp”, “access_token”:”18926970-A-nMnSHDqg8Fsunm6Qx1cF1APp”}
Notice a refresh_token was returned in the response, if the access_token expires a client can use the refresh token to obtain a new access token.
Also, like for the client access token , the account access token has a validity for 24 hours but with every usage the validity is maintain

This request might fail also from different reasons:

  • HTTP code 401, body:

    {“error”:”invalid_client”,”error_description”:”No client found for the provided id.”}

  • HTTP code 401, body:

    {“error”:”unauthorized_client”,“error_description”:”Invalid client or doesn’t have the     permission to make this request.”}

  • HTTP code 400, body:

    {“error”:”invalid_request”,”error_description”:”Invalid username provided.”}

  • HTTP code 401, body:

    {“error”:”access_denied”,”error_description”:”Unable to authenticate the provided account.”}

2.3 Refresh an access token

As we saw above an access token has a limited validity, if such a token expires another one can be obtain using the refresh token obtain first time when the access token was obtained. 
refresh_token has a validity of 60 days and can be used only once, a new refresh token will be returned.

Let’s see how we can exchange a refresh token for an access token, open your browser and make this GET request : 
https://api.poken.com/oauth2/access_token?grant_type=refresh_token&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&refresh_token=USER_REFRESH_TOKEN

If successful a new access and refresh token will be return:

{“expires_in”:86400,”refresh_token”:”18927671-R-LSU58LKcM2xlLLBXNVgUYAPp”,”access_token”:”18926970-A-nMnSHDqg8Fsunm6Qx1cF1APp”}

Note that the refresh token will be different then the one already played.

In case of invalid usage one of this errors will be ruturn:

  • HTTP code 401, body:

    {“error”:”invalid_client”,”error_description”:”No client found for the provided id.”}

  • HTTP code 401, body:

    {“error”:”unauthorized_client”, “error_description”:”Invalid client or doesn’t have the     permission to make this request.”}

  • HTTP code 401, body:

    {“error”:”unauthorized_client”,”error_description”:”Request made with an invalid token.”}

  • HTTP code 401, body:

    {“error”:”unauthorized_client”, “error_description”:”Client doesn’t have permission to use the provided token.”}

  • HTTP code 400, body:

    {“error”:”invalid_request”,”error_description”:”Used token doesn’t exist or has an invalid format.”} 

2.4 Exchange an authorization code for an access token

As we already saw, some endpoints are executed using a client access token and return an authorization code that can be used to get an account access token.
Such an endpoint is the 
create account endpoint. A client should follow this flow :

  1. make a request to get a client access token (see 2.1)
  2. make a POST request to create account endpoint passing the access token and the endpoint parameters
  3. if successful, the endpoint returns such a response :

<?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes”?>

<account xmlns=”http://xsd.poken.com”>

<accountId>878752</accountId>

<username>john_doe</username>

<code>23123123-C-T1uVhh8nKayw8CTUDDHgvgPp</code>

<expires_in>900</expires_in>

</account>

Now we can exchange the authorization code to an access token making such a request:
https://api.poken.com/oauth2/access_token?grant_type=authorization_code&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&code=23123123-C-T1uVhh8nKayw8CTUDDHgvgPp&redirect_uri=YOUR_CLIENT_REDIRECT_URI

We get back a response like :
{“expires_in”:86400, “refresh_token”:”18927670-R-2v8e8ycA419RaaVWY9Xz4APp”, “access_token”:”18926970-A-nMnSHDqg8Fsunm6Qx1cF1APp”}

The possible exceptions returned by this type of request are :

  • HTTP code 401, body:

    {“error”:”invalid_client”,”error_description”:”No client found for the provided id.”}

  • HTTP code 401, body:

    {“error”:”unauthorized_client”,

“error_description”:”Invalid client or doesn’t have the     permission to make this request.”}

  • HTTP code 400, body:

    {“error”:”invalid_request”,”error_description”:”Used code doesn’t exist or has an invalid format.”}

  • HTTP code 400, body:

    {“error”:”invalid_request”,”error_description”:”Used code expired, please generate a new code.”}

  • HTTP code 400, body:

    {“error”:”invalid_request”,”error_description”:”Provided redirect_uri mismatch the one used when the code was generated.”}