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:
- Ask the user for access permissions.
- Exchange the authorization code for an access token.
- Use the access token to make authenticated requests.
- 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
codestring |
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.