Developer's API Documentation : Authentication
Overview
Authentication is done via a standard OAuth2 flow. This means that your app does not need to store the user's password and you should be able to use an off the shelf OAuth2 library to authenticate with Toodledo.
The general flow is as follows:
- When a user wants to setup syncing, send them to Toodledo's authorization page.
- User signs into their Toodledo account and authorizes your app.
- User is redirected back to your app with an authorization code.
- Using your app's secret, you sign and exchange this code for an access token and a refresh token.
- Store the tokens in your app. Use the access token to make API requests.
- When the access token expires (2 hours), use the refresh token to get a new one.
- If the user does not use your app for 30 consecutive days, the refresh token will expire and you will need to start over from the top.
Authorization
You must first register your app. This will allow the Toodledo API to recognize your app and properly authenticate it. You will need to set a Redirect URI for your app, and you will be given an app secret that you will need to save for later.
Once you are registered, you will redirect your users to the following URL.
https://api.toodledo.com/3/account/authorize.php?response_type=code&client_id=YourClientID&state=YourState&scope=basic%20tasks
- response_type : This will always have the value of "code" (required).
- client_id : A text string identifying your application as registered with Toodledo (required).
- state : A string used to prevent cross-site request forgery. You should generate a random string for each request (required).
- scope : A string specifying the type of permissions that you wish to be granted on the user's account. You can specify multiple scopes by separating them by a space (encoded as %20) as in the example above. To request read/edit permissions to notes you would send scope "basic notes write". To nurture trust with your users you should request the minimal scope that you need for your app to function. Possible values are:
- basic - access to basic account information.
- tasks - access to tasks.
- notes - access to notes.
- outlines - access to outlines.
- lists - access to lists.
- share - access to user's collaborator's information.
- write - ability to edit the above information.
Your users will be asked to sign into Toodledo (if not already) and authorize your app. Once they do this, they will be redirected to the Redirect URI that you specified when you registered. That URI will be given the following information:
- code : This will be an alphanumeric authorization code that you can use in the next step to get an access token.
- state : This will be an echo of the state that you sent with the authorize request. Make sure it matches what you sent previously to prevent cross site request forgery.
- error : If the user denied the request or if there was some other error, it will be indicated in this string.
REDIRECT_URI?code=49075c51ed30133f909f7c0dd03996e8f395be57&state=YourState
If you are making an app, there are two ways to handle the redirect. The first is to set a custom URL scheme for your project. This tells the device that a link such as "myToodledoApp://authorize" should be opened with your app. You would redirect the user to the device's built in web browser and the web browser will automatically launch your app with the authorization code in your apps launch options.
The second option is to keep the user in your app by implementing a custom web view (like an iframe) that contains our authorization page. You can then override the redirect method and grab the returned URL without actually fetching it. In this case the redirect URI would never be called, so it doesn't need to be an actual valid URI, although for obvious security reasons you should not have the Redirect URI go to valid URL not controlled by you.
There are OAuth2 libraries for iOS, Android and other platforms that can help with this and we have provided some sample code as well.
Getting an Access Token
Once you have an authorization code, you can exchange it for an access token. To do this you would POST an SSL encrypted request to /3/account/token.php using basic authentication with your Client ID and secret and passing the authorization code. The response will contain an access token and refresh token.
When requesting a token, you can optionally send a few details about your application, which may be helpful for you. These details will be visible to you on the statistics page. This can give you information about what devices your users are using.
Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3 https://api.toodledo.com/3/account/token.php grant_type=authorization_code code=49075c51ed30133f909f7c0dd03996e8f395be57 vers=3 os=7 device=iphone5s
- grant_type : A string with value "authorization_code". (required)
- code : The authorization code that your got from the authorization step. (required)
- vers : An integer representing the version number of your application. (optional)
- device : A text string identifying the device or platform that your application runs on. (optional)
- os : An integer identifying the operating system version number of the device or platform that your application runs on. (optional)
- f : A string with value "json" or "xml" to determine the format of the response. Defaults to json. (optional)
Example Response (JSON):
{ "access_token":"66fa5a5252fa17afdd3b84f71ccfd7c02c3fb40f", "expires_in":7200, "token_type":"bearer", "scope":"basic", "refresh_token":"389d276132d7d256e48e9056dd5d6d6f313be246" }
Example Response (XML):
<response> <access_token>66fa5a5252fa17afdd3b84f71ccfd7c02c3fb40f</access_token> <expires_in>7200</expires_in> <token_type>Bearer</token_type> <scope>basic</scope> <refresh_token>389d276132d7d256e48e9056dd5d6d6f313be246</refresh_token> </response>
The access token is good for 2 hours and you should cache it and reuse it for the full 2 hours. Token requests are rate limited. The access token can be used to make any API call allowed by the scope given. Once an access_token expires, you will need to get a new one. You can do this without bothering the user by using the refresh_token.
Using Refresh Token
Using a refresh token to get a new access_token is very similar to how you exchanged an authorization code. You make a POST to the same /3/account/token.php API endpoint with different parameters. This request should also be done over SSL using basic authentication to authenticate your app.
Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3 https://api.toodledo.com/3/account/token.php grant_type=refresh_token refresh_token=389d276132d7d256e48e9056dd5d6d6f313be246 vers=3 os=7 device=iphone5s
- grant_type : A string with value "refresh_token". (required)
- refresh_token : The refresh_token that your got from the previous step. (required)
- vers : An integer representing the version number of your application. (optional)
- device : A text string identifying the device or platform that your application runs on. (optional)
- os : An integer identifying the operating system version number of the device or platform that your application runs on. (optional)
- f : A string with value "json" or "xml" to determine the format of the response. Defaults to json. (optional)
Example Response (JSON):
{ "access_token":"66fa5a5252fa17afdd3b84f71ccfd7c02c3fb40f", "expires_in":7200, "token_type":"bearer", "scope":"basic", "refresh_token":"389d276132d7d256e48e9056dd5d6d6f313be246" }
Example Response (XML):
<response> <access_token>66fa5a5252fa17afdd3b84f71ccfd7c02c3fb40f</access_token> <expires_in>7200</expires_in> <token_type>Bearer</token_type> <scope>basic</scope> <refresh_token>389d276132d7d256e48e9056dd5d6d6f313be246</refresh_token> </response>
You will get a new access_token and a new refresh_token. You should save both and discard the old ones because the old refresh_token will no longer work. A refresh_token can only be used once. A refresh_token is valid for 30 days, so as long as your app syncs at least once a month, your user will never have to authorize again. Refresh tokens can expire under normal situations, so an invalid refresh token error should not be ignored. If a refresh token does expire or become invalid you should ask your user to re-authorize the app. You will get a "102" error (described below) if your token is expired or if there is any other problem with it.
Error Codes
Any of the API calls can return error messages. Here is a list of the error messages that you may receive from the token API endpoint.
- 101 : SSL connection is required.
- 102 : There was an error requesting a token.
- 103 : Too many token requests.
Examples:
JSON: {"errorCode":101,"errorDesc":"SSL connection required"}
XML: <error id="101">SSL connection required</error>