Toshl Developer

OAuth

Apps can connect to the API using the OAuth 2.0 authorization framework. Currently only authorization code and implicit grant authorization grant types are available.

Before you can start using the API, you need a toshl account and then register an application. It will take you about a minute to set everything up.

In order to authenticate a user a client must:

  1. Ask the user for access permissions.
  2. Exchange the authorization code for an access token.
  3. Use the access token to make authenticated requests.
  4. Use the refresh token to obtain a new access token if it expires.

Authorize a user

To authorize a user simply redirect her to this URL:

GET https://toshl.com/oauth2/authorize

Parameters

client_id
required
string
The value provided to you when you registered your application.
response_type
required
string
Set to code indicating that an authorization code will be returned to the application after the user approves the authorization request.

For insecure clients use token (indicating implicit grant) which will directly return a token after the user approves the authorization request.
scope
optional
string
The data your application is requesting access to. Send a space separated list of scope types. If scope is not provided the scope set during app registration will be used.
redirect_uri
optional
string
The location URI where the user should be returned to after they approve access for your app. If no redirect_uri is provided the one used when registering the app will be used.
state
recommended
string
A unique value used by your application in order to prevent cross-site request forgery (CSRF) attacks on your implementation. Value will be truncated to 255 characters and returned as is in the response.

Scope types

The following is a list of data your application is requesting access to. Send a space separated list of scope types. If scope is not provided the scope set during app registration will be used. If scope is used during the authorization step, it must be the same as the one used during app registration.

user:r Read access to users information (email, name etc).
user:rw Read & write access to users information (email, name etc).
entries:r Read access to users entries.
entries:rw Read & write access to users entries.
budgets:r Read access to users budgets.
budgets:rw Read & write access to users budgets.
accounts:r Read access to users accounts.
accounts:rw Read & write access to users accounts.
images:r Read access to images.
images:rw Read & write access to images.
categories:r Read access to categories.
categories:rw Read & write access to categories.
tags:r Read access to tags.
tags:rw Read & write access to tags.
locations:r Read access to users locations.
locations:rw Read & write access to users locations.

Note: If user grants access to entries that implicitly means they give access to tags, repeats and export as well.

Access granted

When the user grants access, the client will be redirected to the provided redirect_uri with additional query parameters.

GET https://client.example.com/cb?code=xyz&state=abc
code
string
The authorization code that you will use to obtain an access token.
state
optional
string
The value of the state parameter passed in the initial request to the authorization server.

Note: Code is valid for 30 seconds. If the token request is not made in that time the process must start over again. The client must not use the same code twice. If so, all tokens issued for this code will be revoked.

If used (recommended), the state value should be compared against the original value. If the values do not match, it is possible a malicious user is attempting to perform a cross-site request forgery attack on the application, so the OAuth flow should not be continued.

The callback endpoint ideally should not load HTML but only extract the provided parameters and then redirect to a new page without the provided parameters (thus not exposing the code to the end-user). Toshl staff will make security audits of your implementations on a periodical basis and will block your app if any problems are detected in your implementation. For more information refere to the OAuth 2.0 specification.

Errors

If the user declines or the request itself is malformed, the server will inform the client by adding the parameters error and state (if present) to the query part of the redirect_uri.

GET https://client.example.com/cb?error=access_denied&state=xyz
invalid_request The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
unauthorized_client The client is not authorized to request an authorization code using this method.
access_denied The resource owner or authorization server denied the request.
unsupported_response_type The authorization server does not support obtaining an authorization code using this method.
invalid_scope The requested scope is invalid, unknown, or malformed.
server_error The authorization server encountered an unexpected condition that prevented it from fulfilling the request.
temporarily_unavailable The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.

Obtaining an access token

To complete the authorization process you must use the code to obtain an access_token which you can then use to make authorized requests on behalf of the user.

POST https://toshl.com/oauth2/token

Parameters

code
required
string
Code obtained in the authorization step.
grant_type
required
string
Grant type.
Possible values: [authorization_code]
redirect_uri
optional
string
Redirect URI must be included if it was included in the Authorization step. The values of both must be the same for the request to succeed.

In addition you must specify your client_id and client_secret in a HTTP Basic Authorization header (client_id as the user and client_secret as the password). This is what an example of the final request would look like:

$ curl -i "https://toshl.com/oauth2/token" \
  --user CLIENT_ID:CLIENT_SECRET \
  -X POST -d "grant_type=authorization_code" -d "code=CODE"

Response

If the request is properly authenticated the server will issue and return an OAuth access and refresh token in a JSON-encoded response.

{
    "access_token": "f2eb339292dd1cd22a064797129b3de4",
    "token_type": "bearer",
    "expires_in": 3600,
    "refresh_token": "swl3839021ddjjwoowlksmdsao190921AbhUkdsajHH",
    "scope": "entries:rw"
}

Note: Special care must be taken in storing access_token and refresh_token on the client.

access_token
required
string
The issued access token.
token_type
required
string
The issued access token type. For authorization code always set to bearer.
expires_in
required
integer
Access token lifetime in seconds.
refresh_token
required
string
Refresh token that can be used to prolong users authorization without requiring the user to re-authenticate. The refresh can be revoked at any time by the user or Toshl staff.
scope
optional
string
Returned if the list requested by the client is not identical to the one granted by the user.

Errors

The authorization server will respond with an HTTP 400 (Bad Request) status code and a JSON document that includes a single error parameter with one of the following values:

invalid_request The request is missing a required parameter, includes an unsupported parameter value (other than grant type), repeats a parameter, includes multiple credentials, utilizes more than one mechanism for authenticating the client, or is otherwise malformed.
invalid_client Client authentication failed.
invalid_grant The provided authorization grant (e.g. authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
unauthorized_client The authenticated client is not authorized to use this authorization grant type.
unsupported_grant_type The authorization grant type is not supported by the authorization server.
invalid_scope The requested scope is invalid, unknown, or malformed.

Dealing with two-factor authentication

For users with two-factor authentication enabled, obtaining an access token requires one additional step. When you attempt to login a user that has two-factor enabled, the server will respond with 401 Unauthorized with an additional header X-Toshl-OTP: required. This indicates that a two-factor authentication code is needed to login the user. To perform the login, send the same request as before, but include the header X-Toshl-OTP with the value set to the authentication code entered by the user. If code is valid, the response is returned as described in the previous section.

Refreshing an access token

When the access token expires you can use the issued refresh_token to obtain a new access token.

POST https://toshl.com/oauth2/token

Parameters

grant_type
required
string
Grant type must be set to refresh_token.
refresh_token
required
string
The refresh token issued with the expired access token.
scope
optional
string
The scope must be the same as the one initially returned during authorization code exchange.

In addition you must specify your client_id and client_secret in a HTTP Basic Authorization header (client_id as the user and client_secret as the password). This is what an example of the final request would look like:

$ curl -i "https://toshl.com/oauth2/token" \
  --user CLIENT_ID:CLIENT_SECRET \
  -X POST -d "grant_type=refresh_token" -d "refresh_token=TOKEN" -d "scope=SCOPE"

For a list of possible errors see “token request error list”:#tokenerrors.

Revoke access

A user may decide to revoke access to the application. To do so send the refresh_token retrieved in the token step to the following endpoint.

$ curl -i "https://toshl.com/oauth2/revoke" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -X POST -d "refresh_token=REFRESH_TOKEN"

This will remove all access and refresh tokens thus essentially logging the user out of the application.

Parameter

refresh_token
required
Refresh token retrieved in the token step.

Accessing protected resources

API utilises the use of bearer tokens for authorization. The preferred way of authorizing requests is by sending the bearer token in a HTTP Authorization header.

Errors

For a list of possible errors check the endpoint error list.