Authentication

Last Updated: August 10, 2015

OAuth2.0

TSheets uses OAuth2 for authentication and authorization of our API. OAuth2 is a protocol designed to let third-party applications authenticate to perform actions as a user, without getting the user's password. There are several libraries available that implement the protocol, a good list can be found at the OAuth2 home page. Through the use of OAuth2, you'll go through the process of obtaining a token and then you'll use that token in every request made to the API to verify your identity.

Obtaining a token

Before you can make any request of the API, you must first authenticate. Once you've authenticated, you will be given an access token that may be used for all subsequent requests.

NOTE: If you need a small number of access tokens, implementing the full OAuth2 flow can be cumbersome. Sometimes you just want a token for something simple like a command-line utility or script.

As a convenience to you, we allow access tokens to be created through the web UI via the API Add-on preferences page (Company Settings -> Add-ons -> API -> click 'Preferences'). You can also extend the expiration date on these tokens via the web UI, so that you don't have to deal with refreshing tokens. Remember to keep your access tokens secret; treat them just like passwords!

Performing the OAuth2 token request flow requires an OAuth client ID and an OAuth client secret. To obtain these application credentials, you will need to install the API Add-On in your TSheets account and follow the instructions found there. The OAuth client secret should never be shared.

There are 2 steps required in order to obtain an access token, as described below.

Step 1. Authorization Request

This first step consists of a user authorizing your application to access their information on TSheets. To do this, you'll create a link somewhere on your site that they can use to initiate the process. The link will contain several parameters that are necessary for TSheets to consider it valid. The user should use a web browser to follow the link and perform the authorization request.

Once the user is directed to access the authorization endpoint at TSheets ('authorization server' in OAuth2-speak), two things will happen:

  • The user ('resource owner' in OAuth2-speak) will need to log in using their TSheets credentials.
  • Once they've successfully logged in, they're given a choice of whether or not to grant your application access to their data within TSheets. If they do, TSheets will generate an authorization 'code' and redirect the user back to your redirect_uri with the authorization code as one of the parameters in the request.
The link that a user will follow to perform an authorization request is made to the /authorize end-point:

https://rest.tsheets.com/api/v1/authorize
    

An example of a link that calls this URL is shown below:

https://rest.tsheets.com/api/v1/authorize?response_type=code&client_id=MYAPPCLIENTID&redirect_uri=https://somedomain.com/callback&state=MYSTATE
    

The parameters for this call are described in the following table:

HTTP Method GET
Endpoint https://rest.tsheets.com/api/v1/authorize
Response Format json
Parameter Description
response_type This parameter MUST always be set to the string 'code'.
client_id This parameter MUST always be set to the value of the OAuth client ID that you obtained when you registered your app in the TSheets API Add-On in your TSheets account.
redirect_uri The HTTPS url that you submitted as the 'OAuth Redirect URI' when you set up your app in the TSheets API Add-On.

If the user grants access to your application, we'll redirect them back to this url with a temporary code in a code parameter. They'll use this code to obtain an access token.
state A random value used by the client to maintain state between the request and callback. The authorization server includes this value when redirecting the user-agent back to the client. It is used to protect against cross-site request forgery attacks. If the states don't match, the request has been created by a third party and the process should be aborted.

Upon successful authorization and if the user grants access for their data to the app, TSheets will redirect the connected user to the redirect_uri (https://somedomain.com/callback in this example) found in the original request, and two parameters will be appended to it:

  • 'code' - the unique code generated for this request - to be used in the token call later in the flow.
  • 'state' - the value passed in 'state' in the original authorization request.
For example:
https://somedomain.com/callback?code=bbcaef03191517dfb60d0305bfea38ea995af1az&state=MYSTATE
        

The server that handles the request to https://somedomain.com/callback should extract and save the 'code' parameter value, as it is required as part of the next step in the flow. The 'state' value should be compared to what was originally sent and verified to be the same.

If the call to the /authorize end-point is malformed, or if the user denies access to the requesting app, then TSheets will still redirect the user back to the 'redirect_uri', but instead it will append 'error' and 'error_description' parameters. Like so:

https://somedomain.com/callback?error=SOME_ERROR&error_description=SOME_DESCRIPTION
        

NOTE: We do not currently support 'scope' for our clients, so the 'scope' parameter mentioned in the OAuth 2.0 specification is not required.

Step 2. Access Token Request

At this point you have an authorization 'code' for the user of your app. To exchange the code for an access token, your application needs to do a POST to our /grant API end-point. In this step, TSheets will check that the authorization code was issued to the same application that is making the token request.

You make your server-side request to:

https://rest.tsheets.com/api/v1/grant
        

Your application must include the redirect_uri, OAuth client_id, OAuth client_secret, grant_type and code parameters in this request. An example of how to make the request to the /grant end-point via curl is shown below:

curl -i -X POST "https://rest.tsheets.com/api/v1/grant" -d "grant_type=authorization_code" -d "client_id=MYAPPCLIENTID" -d "client_secret=MYAPPSECRET" -d "code=bbcaef03191517dfb60d0305bfea38ea995af1az" -d "redirect_uri=https://somedomain.com/callback"
        

The parameters for this call are described in the table below:

HTTP Method POST
Endpoint https://rest.tsheets.com/api/v1/grant
Response Format json
Parameter Description
grant_type This parameter MUST always be set to the string 'authorization_code'. This tells us what type of code is included.
client_id This parameter MUST always be set to the value of the OAuth client ID that you obtained when you set up your app in the API Add-On in your TSheets account.
client_secret This parameter MUST always be set to the value of the OAuth client secret that you obtained when you set up your app in the API Add-On in your TSheets account.
code The 'code' being exchanged for an access token. This should be the authorization code received above ('bbcaef03191517dfb60d0305bfea38ea995af1az' in this example).
redirect_uri The HTTPS url that was included in Step 1 of the authorization request. The value must be identical.

If successful, the call to the /grant end-point will return a status of 200, and the response body will contain a JSON object that contains the token:

HTTP/1.1 200 OK
Content-Type: application/json
    
{
    "access_token":"84ec7a2f2b1379990caea347d67e713f34f2d5dz",
    "expires_in":5184000,
    "token_type":"bearer",
    "scope":"",
    "refresh_token":"0ed645dbcfaca681e37df26df6f39d273330e7a0",
    "user_id":"12345",
    "company_id":"12345",
    "client_url":"blakemoving"
}
        

The access_token should be included with every call to the API. Failure to include the access_token or using an expired token will result in a 401 response. Note that when you receive your access token, you also receive the 'user_id' and 'client_id' properties that are associated with the user that the access_token is for. These properties are provided for convenience, to potentially save you the need for making a request to the current_user endpoint.

Make Requests With the Access Token

Once you have an OAuth access token, you can use it to make API requests. Use the HTTP Authorization header when making a request. Example using curl:

curl -H "Authorization: Bearer <Access-Token>" -i "https://rest.tsheets.com/api/v1/users?per_page=1"
    

Storing a Token

When appropriate, applications should store the token locally, rather than requesting a new token for the same user each time the user uses the application. If the token is deleted or expires, the application will get a 401 Unauthorized error from the API, in which case the application should perform the OAuth flow again to receive a new token. Storing a token is in many ways equivalent to storing the user's password, so tokens should be stored and used in a secure manner.

Refreshing an Access Token

Access tokens expire after 'expires_in' seconds (see example response above). In order to avoid sending the user through the OAuth2 process described above every time they want to access resources, API consumers can exchange a refresh_token for a new access_token before the current one expires. To do so, you make a request similar to the original request described above.

HTTP Method POST
Endpoint https://rest.tsheets.com/api/v1/grant
Response Format json
Parameter Description
grant_type This parameter MUST be set to the string 'refresh_token'.
client_id This parameter MUST always be set to the value of the OAuth client ID that you obtained when you set up your app in the API Add-On in your TSheets account.
client_secret This parameter MUST always be set to the value of the OAuth client secret that you obtained when you set up your app in the API Add-On in your TSheets account.
refresh_token This parameter is the refresh_token that you're exchanging for a new access_token.

Example request:

curl -i -X POST -H "Authorization: Bearer 84ec7a2f2b1379990caea347d67e713f34f2d5dz" -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=refresh_token" -d "client_id=MYAPPCLIENTID" -d "client_secret=MYAPPSECRET" -d "refresh_token=0ed645dbcfaca681e37df26df6f39d273330e7a0" "https://rest.tsheets.com/api/v1/grant"
        

Example result:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "access_token":"c65931f72f0a905bea92fb2dce8e4c25151c02e9",
    "expires_in":5184000,
    "token_type":"bearer",
    "scope":"",
    "refresh_token":"9eaec192df27b22e6575e438a4159639937605c7",
    "user_id":"12345",
    "company_id":"12345",
    "client_url":"blakemoving"
}