diff --git a/README.md b/README.md index 148a032..93c1159 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,27 @@ Toggl API Documentation ==================== -Toggl API is divided into two +## ⚠️ Important ⚠️ + +We have migrated our documentation to https://developers.track.toggl.com/docs/. There, you will find up-to date API docs for the Toggl Track, Reports and Webhooks services. + +If you're running into issues or require help with anything, please contact our dedicated 24/5 support staff over on [our support pages](https://support.toggl.com/en/). You can chat with them using the icon on the right bottom. + +---- + +Toggl API is divided into three: * [Toggl API](toggl_api.md) * [Reports API](reports.md) - +* [Webhooks API](webhooks.md) For changing data, including tracking time, you'll need to use the **Toggl API**. If you want to get time entries of all the workspace users and aggregated data for reporting, you need to use the read-only **Reports API**, which gives you many options for filtering, grouping and sorting. -##The API Format## +For monitoring data changes in a workspace, you'll need the **Webhooks API**. + +## The API Format The API accepts only JSON requests. Please make sure you're setting `Content-Type: application/json`in your request header. Each request returns a **JSON-encoded** body. @@ -19,10 +29,13 @@ The result of each action is communicated via standard HTTP response codes. Times and dates use the ISO 8601 standard, more specifically a subset described in [RFC 3339](http://www.ietf.org/rfc/rfc3339.txt). -Please do note that the times and dates are parsed stored in UTC (GMT), on return the data is set into the appropriate timezone according to the setting in user profile. +Please do note that the times and dates are stored in UTC (GMT), on return the data is set into the appropriate timezone according to the setting in user profile. 3rd party applications should make sure that they are using correct timezones and also consider daylight saving (where applicable). -###Example requests### +For rate limiting we have implemented a [Leaky bucket](http://en.wikipedia.org/wiki/Leaky_bucket). When a limit has been hit the request will get a HTTP 429 response and it's the task of the client to sleep/wait until bucket is empty. Limits will and can change during time, but a safe window will be *1 request per second*. +Limiting is applied per api token per IP, meaning two users from the same IP will get their rate allocated separately. + +### Example requests The example requests here are done using a command line tool called [cURL](http://en.wikipedia.org/wiki/CURL). If you want to try the requests out yourself, you can download cURL from [here](http://curl.haxx.se/download.html). It is available for all possible operating systems. @@ -32,22 +45,69 @@ Under Ubuntu installing cURL is very easy: sudo apt-get install curl ``` -##API token## +## API token Each user in Toggl.com has an API token. They can find it under "My Profile" in their Toggl account. -##Help us towards a better API## +## Help us towards a better API The Toggl API has moved to Github so you could actively participate in helping us making the API better. If you have any requests or you found a bug, you can use Github issues to let us know. You can also fork the docs and send a pull request with improvements -##Code examples## +## Code examples -### Java ### -* [Benno](https://github.com/bennob) has updated JToggl, a Java wrapper for the Toggl API to support v8: http://code.google.com/p/jtoggl/ +### Java +* [Benno](https://github.com/bennob) has updated JToggl, a Java wrapper for the Toggl API to support v8: https://github.com/bbaumgartner/jtoggl +* [rocketbase-io](https://github.com/rocketbase-io) build Toggl-Report-Api, a Java wrapper for the Toggl Report API: https://github.com/rocketbase-io/toggl-report-api -### Python ### +### Python * [Mosab Ahmad](https://github.com/mos3abof) has created a project using Toggl API to calculate how many hours he should work to achieve monthly goals: https://github.com/mos3abof/toggl_target +* [Mikhail Novikov](https://github.com/kurtgn) has created a graphical utility for displaying historical data: https://github.com/kurtgn/chronicl +* [Robert Adams](https://github.com/drobertadams) and [Beau Raines](https://github.com/beauraines) have updated [toggl-cli](https://github.com/drobertadams/toggl-cli) to API v8. It provides a set of Python objects for interacting with Toggl, as well as a command-line interface: https://github.com/drobertadams/toggl-cli +* [Matthew Downey](https://github.com/matthewdowney) has started a Toggl API wrapper: https://github.com/matthewdowney/TogglPy +* [Matthias Büchi](https://github.com/ynop) has created a simple tool to calculate the difference between the tracked hours in Toggl and the hours one should work in a given period: https://github.com/ynop/togglore +* [David Cako](https://github.com/david-cako) has written an efficient command line interface for inputting time-insensitive toggl entries: https://github.com/david-cako/toggl-hammer -### Ruby ### +### Ruby * [Tom Kane](https://github.com/kanet77) has written a Ruby wrapper for Toggl API v8: https://github.com/kanet77/togglv8 + +### Node.js +* [Damian Mee](https://github.com/meeDamian) has written a CLI tool in Node.js for Toggl API v8: https://github.com/meeDamian/toggl-cli +* [Alexander Makarenko](https://github.com/estliberitas) has written a library for Node.js for Toggl API v8: https://github.com/7eggs/node-toggl-api + +### C++ + +* TogglDesktop has an [open source, cross platform library](https://github.com/toggl-open-source/toggldesktop/tree/master/src/lib) that can be reused in your own apps. + +### .NET + +* The Toggl mobile apps have [shared C# libraries](https://github.com/toggl/mobileapp) which provide access to the API and also common clientside business logic we use. Feel free to use as little or much of it as you want. + +### Scala +* [Gabriele Alese](https://github.com/gabalese) has written a command line client for Toggl: https://github.com/gabalese/toggl-cli + +### PHP +* [Arend Jan Tetteroo](https://github.com/arendjantetteroo) has written a library for PHP for Toggl API v8, based on the excellent Guzzle library: https://github.com/arendjantetteroo/guzzle-toggl +* [Morning Train](https://morningtrain.dk) has written PHP classes for Toggl API v8 (It is based on Guzzle 6): https://github.com/Morning-Train/toggl-api +* [Ixudra](https://ixudra.be) has written a Laravel PHP library for Toggl API v8: https://github.com/ixudra/toggl + +### Go +* [Doug Chimento](https://github.com/dougEfresh) has written a Go wrapper for Toggl API v8: https://github.com/dougEfresh/gtoggl + +### Elixir +* [Víctor Viruete](https://github.com/hopsor) has written an Elixir wrapper for Toggl API v8 and Reports API: https://github.com/diacode/togglex + +## 3rd party apps +* [Federico Vaga](https://github.com/FedericoVaga) has written a little plasmoid for KDE: https://github.com/FedericoVaga/plasmoggl (on opendesktop: http://opendesktop.org/content/show.php/Plasmoggl?content=168536) +* [rocketbase-io](https://github.com/rocketbase-io/toggl-reporter) has written a tiny SpringBoot-Application, build with vaadin and mongodb, that pulls your TimeEntries from toggl. The stored information allow a fine grained reporting and analysis that aren't possible within toggl (like detailed working hours in comparison between team-members and many more). A [docker-image](https://hub.docker.com/r/rocketbaseio/toggl-reporter/) is also provided... + * [Chingiz Nazar](https://github.com/sultanbekuly) created an Arduino project to track time using Toggl Track API. This project allows building a home-made paper cube which can be configured to start tracking time depending on which side of the cube is facing upwards: [time_tracker_cube](https://github.com/sultanbekuly/time_tracker_cube). An article explaining the development and usage of this project is also available: [Building an Arduino Time Tracker Cube with Toggl's Open API](https://hackernoon.com/building-an-arduino-time-tracker-cube-with-toggls-open-api). + +### Perl +* [Jason Kruczynski](https://github.com/jkruczynski) has written a perl wrapper for the API. It creates and authenticates a session for API V8 or API V2 depending on the URL. It implements a few functions for exporting reports. https://github.com/jkruczynski/Toggl-API-Wrapper-Perl + +### R +* [Vincent Guyader](http://thinkr.fr) has written a simple R and Rstudio implementation for the API. https://github.com/ThinkRstat/togglr + +### Swift +* [Nghia Tran](https://github.com/NghiaTranUIT) has written a macOS wrapper in Swift 4.2. So, we can integrate the Toggl API v8 to your own app easier: https://github.com/NghiaTranUIT/Toggl-Swift + diff --git a/api_v9_reports_v3_basics.md b/api_v9_reports_v3_basics.md new file mode 100644 index 0000000..89e4087 --- /dev/null +++ b/api_v9_reports_v3_basics.md @@ -0,0 +1,29 @@ +# API v9, Reports API v3 - Basics and recommendations + +Given the age of API v8 and Reports API v2 we've are working for new versions of those API-s, +old API-s will still be up and running and there will be an official announcement before the final deprecation. +The documentation for the new API endpoints will become available gradually and there can and will be changes at first. + +## Authentication options + - api_token and basic auth header + - username and password to get a session cookie + + This list may get aditional options + +## Generic responses and what to do +We're using standard HTTP status codes and kindly ask the API clients to respect some recommendations: + - in case of 4xx error - don't try another request with the same payload, inspect the response body, most of the times it has a readable message + - in case of 5xx error - have a random delay before the next request + - in case of 429 (Too Many Requests) - back off for a few minutes (you can expect a rate of 1req/sec to be available) + - in case of 410 (Gone) - don't try this endpoint again + - in case of 402 (Payment required) - workspace should be upgraded to have access to said feature, don't repeat the request until that has happened + +## General principles + - API format is JSON (be nice and include a `Content-type: application/json` header to your request) + - in case of an update request, send only the fields that have changed + - do not include fields that aren't available for current workspace subscription level (example: on a free plan don't send the default workspace rate when updating workspace) + - fetch only the data you need + +## "Scopes" +Endpoints have been grouped by the scope of the entity using it. +Data that's for the currently logged in user is under `/me/*` endpoints, data for one workspace is under `/workspace/{workspace_id}/*` endpoints. diff --git a/chapters/authentication.md b/chapters/authentication.md index d0103a2..996e552 100644 --- a/chapters/authentication.md +++ b/chapters/authentication.md @@ -3,6 +3,8 @@ Authentication To use the API, you need to authenticate yourself. This can be done via HTTP POST or HTTP Basic Auth. After successful authentication a session is created using a cookie. +In the current API implementation and for this documentation, the "username" is simply the user's email. + For HTTP Basic Auth you have to add the Authorization header with the request. The Authorization header is constructed as follows: * Username and password are combined into a string `username:password` or if you use the api token it should be combined `xxxx:api_token` (xxx indicating user's personal token) * The resulting string literal is then encoded using Base64 @@ -11,11 +13,11 @@ For HTTP Basic Auth you have to add the Authorization header with the request. T If authentication fails, HTTP status code 403 is returned. -## HTTP Basic Auth with e-mail and password ## +## HTTP Basic Auth with e-mail and password Example request ([See also chapter about getting detailed user data](users.md)) ```shell -curl -v -u john.doe@gmail.com:secret -X GET https://www.toggl.com/api/v8/me +curl -v -u john.doe@gmail.com:secret -X GET https://api.track.toggl.com/api/v8/me ``` @@ -36,7 +38,12 @@ Response "store_start_and_stop_time":true, "beginning_of_week":1, "language":"en_US", + "duration_format": "improved", "image_url":"https://www.toggl.com/images/profile.png", + "at": "2015-02-17T16:58:53+00:00", + "created_at": "2014-07-31T07:51:17+00:00", + "timezone": "Europe/London", + "retention": 9, "new_blog_post":{}, "projects": [ { @@ -45,7 +52,7 @@ Response "name":"Our best project", "billable":true, "active":true, - "at":"2013-02-12T09:47:57+00:00" + "at":"2013-02-12T09:47:57+00:00", "color":"5" } ], @@ -59,7 +66,15 @@ Response "tasks": [], "workspaces": [ { - "id":777,"name":"John's WS","at":"2012-11-28T11:56:49+00:00" + "id":777, + "name":"John's WS", + "at":"2012-11-28T11:56:49+00:00", + "default_hourly_rate": 0, + "default_currency": "USD", + "projects_billable_by_default": true, + "rounding": 1, + "rounding_minutes": 0, + "api_token": "ea897..." } ], "clients": [] @@ -68,12 +83,12 @@ Response ``` -##HTTP Basic Auth with API token## +## HTTP Basic Auth with API token When using Basic Auth and API token, use the API token as username and string "api_token" as password. Example request ```shell -curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token -X GET https://www.toggl.com/api/v8/me +curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token -X GET https://api.track.toggl.com/api/v8/me ``` Response @@ -109,22 +124,22 @@ Response ``` -## Authentication with a session cookie ## +## Authentication with a session cookie -`POST https://www.toggl.com/api/v8/sessions` +`POST https://api.track.toggl.com/api/v8/sessions` -It's possible to create a session. The session creation request sets a cookie in the response header `toggl_api_session`, which you can use for authentication in all the API requests. The cookie expires in 24 hours. +It's possible to create a session. The session creation request sets a cookie in the response header `__Host-timer-session`, which you can use for authentication in all the API requests. Example request ```shell -curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token -X POST https://www.toggl.com/api/v8/sessions +curl --data="" -v -u 1971800d4d82861d8f2c1651fea4d212:api_token -X POST https://api.track.toggl.com/api/v8/sessions ``` Successful response header includes the cookie ```shell -< Set-Cookie: toggl_api_session=MTM2MzA4MJa8jA3OHxEdi1CQkFFQ180SUFBUkFCRUFBQVlQLUNBQUVHYzNSeWFXNW5EQXdBQ25ObGMzTnBiMjVmYVdRR2MzUnlhVzVuREQ0QVBIUnZaMmRzTFdGd2FTMXpaWE56YVc5dUxUSXRaalU1WmpaalpEUTVOV1ZsTVRoaE1UaGhaalpqWkRkbU5XWTJNV0psWVRnd09EWmlPVEV3WkE9PXweAkG7kI6NBG-iqvhNn1MSDhkz2Pz_UYTzdBvZjCaA==; Path=/; Expires=Wed, 13 Mar 2013 09:54:38 UTC; Max-Age=86400; HttpOnly +< Set-Cookie: __Host-timer-session=MTM2MzA4MJa8jA3OHxEdi1CQkFFQ180SUFBUkFCRUFBQVlQLUNBQUVHYzNSeWFXNW5EQXdBQ25ObGMzTnBiMjVmYVdRR2MzUnlhVzVuREQ0QVBIUnZaMmRzTFdGd2FTMXpaWE56YVc5dUxUSXRaalU1WmpaalpEUTVOV1ZsTVRoaE1UaGhaalpqWkRkbU5XWTJNV0psWVRnd09EWmlPVEV3WkE9PXweAkG7kI6NBG-iqvhNn1MSDhkz2Pz_UYTzdBvZjCaA==; Path=/; HttpOnly; Secure; SameSite=Lax ``` And body contains user's data @@ -162,12 +177,12 @@ And body contains user's data Destroy the session manually by sending an according request to the API. -`DELETE https://www.toggl.com/api/v8/sessions` +`DELETE https://api.track.toggl.com/api/v8/sessions` Example request ```shell -curl -v --cookie toggl_api_session=MTM2MzA4MJa8jA3OHxEdi1CQkFFQ180SUFBUkFCRUFBQVlQLUNBQUVHYzNSeWFXNW5EQXdBQ25ObGMzTnBiMjVmYVdRR2MzUnlhVzVuREQ0QVBIUnZaMmRzTFdGd2FTMXpaWE56YVc5dUxUSXRaalU1WmpaalpEUTVOV1ZsTVRoaE1UaGhaalpqWkRkbU5XWTJNV0psWVRnd09EWmlPVEV3WkE9PXweAkG7kI6NBG-iqvhNn1MSDhkz2Pz_UYTzdBvZjCaA== -X DELETE https://www.toggl.com/api/v8/sessions +curl -v --cookie __Host-timer-session=MTM2MzA4MJa8jA3OHxEdi1CQkFFQ180SUFBUkFCRUFBQVlQLUNBQUVHYzNSeWFXNW5EQXdBQ25ObGMzTnBiMjVmYVdRR2MzUnlhVzVuREQ0QVBIUnZaMmRzTFdGd2FTMXpaWE56YVc5dUxUSXRaalU1WmpaalpEUTVOV1ZsTVRoaE1UaGhaalpqWkRkbU5XWTJNV0psWVRnd09EWmlPVEV3WkE9PXweAkG7kI6NBG-iqvhNn1MSDhkz2Pz_UYTzdBvZjCaA== -X DELETE https://api.track.toggl.com/api/v8/sessions ``` Successful request will return `200 OK`. diff --git a/chapters/clients.md b/chapters/clients.md index d0a7f46..cc89e51 100644 --- a/chapters/clients.md +++ b/chapters/clients.md @@ -5,13 +5,11 @@ Client has the following properties * name: The name of the client (string, required, unique in workspace) * wid: workspace ID, where the client will be used (integer, required) * notes: Notes for the client (string, not required) -* hrate: The hourly rate for this client (float, not required, available only for pro workspaces) -* cur: The name of the client's currency (string, not required, available only for pro workspaces) * at: timestamp that is sent in the response, indicates the time client was last updated -##Create a client## +## Create a client -`POST https://www.toggl.com/api/v8/clients` +`POST https://api.track.toggl.com/api/v8/clients` Example request @@ -19,7 +17,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"client":{"name":"Very Big Company","wid":777}}' \ - -X POST https://www.toggl.com/api/v8/clients + -X POST https://api.track.toggl.com/api/v8/clients ``` @@ -35,15 +33,15 @@ Successful response } ``` -##Get client details## +## Get client details -`GET https://www.toggl.com/api/v8/clients/{client_id}` +`GET https://api.track.toggl.com/api/v8/clients/{client_id}` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X GET https://www.toggl.com/api/v8/clients/1239455 + -X GET https://api.track.toggl.com/api/v8/clients/1239455 ``` @@ -55,15 +53,13 @@ Successful response "wid":777, "name":"Very Big Company", "at":"2013-02-26T08:45:28+00:00", - "notes": "Contact: John Jacob Jingleheimer Schmidt", - "hrate": 12, - "cur": "AUD" + "notes": "Contact: John Jacob Jingleheimer Schmidt" } } ``` -##Update a client## -`PUT https://www.toggl.com/api/v8/clients/{client_id}` +## Update a client +`PUT https://api.track.toggl.com/api/v8/clients/{client_id}` Workspace id (wid) can't be changed. @@ -72,7 +68,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"client":{"name":"Very Big Company","notes":"something about the client"}}' \ - -X PUT https://www.toggl.com/api/v8/clients/1239455 + -X PUT https://api.track.toggl.com/api/v8/clients/1239455 ``` Successful response @@ -88,32 +84,32 @@ Successful response } ``` -##Delete a client## +## Delete a client -`DELETE https://www.toggl.com/api/v8/clients/{client_id}` +`DELETE https://api.track.toggl.com/api/v8/clients/{client_id}` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X DELETE https://www.toggl.com/api/v8/clients/1239455 + -X DELETE https://api.track.toggl.com/api/v8/clients/1239455 ``` Successful request will return `200 OK`. If the user has no access to delete, you'll get a status code `4xx` -##Get workspace clients## +## Get workspace clients Retrieving workspace clients is documented [here](workspaces.md#get-workspace-clients). -##Get clients visible to user## +## Get clients visible to user -`GET https://www.toggl.com/api/v8/clients` +`GET https://api.track.toggl.com/api/v8/clients` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X GET https://www.toggl.com/api/v8/clients + -X GET https://api.track.toggl.com/api/v8/clients ``` Successful response is an array of clients @@ -135,14 +131,14 @@ Successful response is an array of clients ] ``` -##Get client projects## +## Get client projects -`GET https://www.toggl.com/api/v8/clients/{client_id}/projects` +`GET https://api.track.toggl.com/api/v8/clients/{client_id}/projects` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X GET https://www.toggl.com/api/v8/clients/1239455/projects + -X GET https://api.track.toggl.com/api/v8/clients/1239455/projects ``` To filter projects by their state you can add the additional param to the request url: diff --git a/chapters/cors.md b/chapters/cors.md new file mode 100644 index 0000000..5c5ad49 --- /dev/null +++ b/chapters/cors.md @@ -0,0 +1,83 @@ +**Notice** +> This portion of the API is disabled, if you require CORS whitelisting for your website please contact support@toggl.com for further assistance. + +
+


+ +CORS whitelists +==================== + +A CORS whitelist record has the following properties +* id: record ID, where the record will be saved (integer) +* user_id: user ID, for whom the domain is whitelisted (integer) +* domain: the whitelisted domain (string) + +Record id (id) can't be changed on update. + +## Actions +### Create an entry + +`POST https://api.track.toggl.com/api/v9/me/cors` + +Example request + +```shell +curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ + -H "Content-Type: application/json" \ + -d '{"domain":"url.com"}' \ + -X POST https://api.track.toggl.com/api/v9/me/cors + +``` + +Successful response +```json +{ + "id":1335076912, + "domain":"url.com", + "user_id":456 +} +``` + +### Get entries for current user + +`GET https://api.track.toggl.com/api/v9/me/cors` + +Example request + +```shell +curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ + -X GET https://api.track.toggl.com/api/v9/me/cors +``` + +Successful response +```json +[ + { + "id":1335076912, + "domain":"url.com", + "user_id":456 + }, + { + "id":1335076982, + "domain":"url2.com", + "user_id":456 + }, + { + "id":1335076993, + "domain":"url3.com", + "user_id":456 + } +] +``` + +### Delete an entry + +`DELETE https://api.track.toggl.com/api/v9/me/cors/{id}` + +Example request +```shell +curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ + -X DELETE https://api.track.toggl.com/api/v9/me/cors/1335076912 +``` + +Successful request will return `200 OK`. If the user has no access to delete, you'll get a status code `4xx` diff --git a/chapters/dashboard.md b/chapters/dashboard.md index 25313fc..3836ced 100644 --- a/chapters/dashboard.md +++ b/chapters/dashboard.md @@ -6,10 +6,10 @@ Dashboard request returns two objects: * Activity * Most active user -The activity object holds the data of 10 latest actions in the workspace. +The activity object holds the data of 20 latest actions in the workspace. Activity object has the following properties * user_id: user ID -* project_id: project ID (ID is 0 if time entry doesn'y have project connected to it) +* project_id: project ID (ID is 0 if time entry doesn't have project connected to it) * duration: time entry duration in seconds. If the time entry is currently running, the duration attribute contains a negative value, denoting the start of the time entry in seconds since epoch (Jan 1 1970). The correct duration can be calculated as current_time + duration, where current_time is the current time in seconds since epoch. * description: (Description property is not present if time entry description is empty) * stop: time entry stop time (ISO 8601 date and time. Stop property is not present when time entry is still running) @@ -20,14 +20,14 @@ Most active user object has the following properties * user_id: user ID * duration: Sum of time entry durations that have been created during last 7 days -##Get Dashboard data## +## Get Dashboard data -`GET https://www.toggl.com/api/v8/dashboard/{workspace_id}` +`GET https://api.track.toggl.com/api/v8/dashboard/{workspace_id}` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ --X GET https://www.toggl.com/api/v8/dashboard/3134975 +-X GET https://api.track.toggl.com/api/v8/dashboard/3134975 ``` Successful response diff --git a/chapters/groups.md b/chapters/groups.md new file mode 100644 index 0000000..b897fbb --- /dev/null +++ b/chapters/groups.md @@ -0,0 +1,75 @@ +Groups +==================== + +Group has the following properties +* name: The name of the group (string, required) +* wid: workspace ID, where the group will be used (integer, required) +* at: timestamp that is sent in the response, indicates the time group was last updated + +## Create a group + +`POST https://api.track.toggl.com/api/v8/groups` + +Example request + +```shell +curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ + -H "Content-Type: application/json" \ + -d '{"group":{"name":"Developers","wid":777}}' \ + -X POST https://api.track.toggl.com/api/v8/groups + +``` + +Successful response +```json +{ + "data": { + "id":1239455, + "wid":777, + "name":"Developers", + "at":"2013-02-26T08:45:28+00:00" + } +} +``` + +## Update a group +`PUT https://api.track.toggl.com/api/v8/groups/{group_id}` + +Workspace id (wid) can't be changed. + +Example request +```shell +curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ + -H "Content-Type: application/json" \ + -d '{"group":{"name":"Front-end Developers"}}' \ + -X PUT https://api.track.toggl.com/api/v8/groups/1239455 +``` + +Successful response +```json +{ + "data": { + "id":1239455, + "wid":777, + "name":"Front-end Developers", + "at":"2013-02-26T08:55:28+00:00" + } +} +``` + +## Delete a group + +`DELETE https://api.track.toggl.com/api/v8/groups/{group_id}` + +Example request +```shell +curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ + -X DELETE https://api.track.toggl.com/api/v8/groups/1239455 +``` + +Successful request will return `200 OK`. If the user has no access to delete, you'll get a status code `4xx` + + +## Get workspace groups + +Retrieving workspace groups is documented [here](workspaces.md#get-workspace-groups). diff --git a/chapters/project_users.md b/chapters/project_users.md index ee798d5..95d3d73 100644 --- a/chapters/project_users.md +++ b/chapters/project_users.md @@ -11,17 +11,17 @@ Project user has the following properties Workspace id (wid), project id (pid) and user id (uid) can't be changed on update. -###Additional fields### +### Additional fields It's possible to get user's fullname. For that you have to send the `fields` parameter in request with desired property name. * fullname: full name of the user, who is added to the project -##Actions for single project user## +## Actions for single project user -###Create a project user### +### Create a project user -`POST https://www.toggl.com/api/v8/project_users` +`POST https://api.track.toggl.com/api/v8/project_users` Example request @@ -29,7 +29,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"project_user":{"pid":777,"uid":123,"rate":4.0,"manager":true}}' \ - -X POST https://www.toggl.com/api/v8/project_users + -X POST https://api.track.toggl.com/api/v8/project_users ``` @@ -49,9 +49,9 @@ Successful response ``` -###Update a project user### +### Update a project user -`PUT https://www.toggl.com/api/v8/project_users/{project_user_id}` +`PUT https://api.track.toggl.com/api/v8/project_users/{project_user_id}` Workspace id (wid), project id (pid) and user id (uid) can't be changed. @@ -60,7 +60,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"project_user":{"manager":false,"rate":15,"fields":"fullname"}}' \ - -X PUT https://www.toggl.com/api/v8/project_users/4692190 + -X PUT https://api.track.toggl.com/api/v8/project_users/4692190 ``` Successful response @@ -79,25 +79,33 @@ Successful response } ``` -###Delete a project user### +### Delete a project user -`DELETE https://www.toggl.com/api/v8/project_users/{project_user_id}` +`DELETE https://api.track.toggl.com/api/v8/project_users/{project_user_id}` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X DELETE https://www.toggl.com/api/v8/project_users/4692190 + -X DELETE https://api.track.toggl.com/api/v8/project_users/4692190 ``` Successful request will return `200 OK`. If the user has no access to delete, you'll get a status code `4xx` -##Mass Actions## +## Mass Actions -###Create multiple project users for single project### +### Get list of project users in a Workspace +```shell +curl -v -u TOKEN:api_token https://api.track.toggl.com/api/v8/workspaces/{workspace_id}/project_users +``` + +Successful request will return a list of all project users in the workspace. +Note: Does not support the `fields` parameter (hence a `fullname` field won't be returned) + +### Create multiple project users for single project To create multiple project users for a single project, you must add multiple user ids separated with a comma with the `uid` parameter. -`POST https://www.toggl.com/api/v8/project_users` +`POST https://api.track.toggl.com/api/v8/project_users` Example request @@ -105,7 +113,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"project_user":{"pid":777,"uid":"1267998,29624,112047","rate":4.0,"manager":true,"fields":"fullname"}}' \ - -X POST https://www.toggl.com/api/v8/project_users + -X POST https://api.track.toggl.com/api/v8/project_users ``` @@ -119,31 +127,31 @@ Successful response is an array of project_users. "uid":1267998, "wid":99, "manager":true, - "rate":4, + "rate":4 },{ "id":4692192, "pid":777, "uid":29624, "wid":99, "manager":true, - "rate":4, + "rate":4 },{ "id":4692191, "pid":777, "uid":112047, "wid":99, "manager":true, - "rate":4, + "rate":4 } ] } ``` -###Mass update for project users### +### Mass update for project users By supplying multiple project user ids, you can mass update project users. -`PUT https://www.toggl.com/api/v8/project_users/{project_user_ids}` +`PUT https://api.track.toggl.com/api/v8/project_users/{project_user_ids}` Example request @@ -151,7 +159,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"project_user":{"manager":false,"rate":15,"fields":"fullname"}}' \ - -X PUT https://www.toggl.com/api/v8/project_users/4692190,4692192,4692191 + -X PUT https://api.track.toggl.com/api/v8/project_users/4692190,4692192,4692191 ``` Successful response is an array of project_users. @@ -187,15 +195,15 @@ Successful response is an array of project_users. } ``` -###Delete multiple project users### +### Delete multiple project users By supplying multiple project user ids, you can mass delete project users. -`DELETE https://www.toggl.com/api/v8/project_users/{project_user_ids}` +`DELETE https://api.track.toggl.com/api/v8/project_users/{project_user_ids}` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X DELETE https://www.toggl.com/api/v8/project_users/4692190,4692192,4692193 + -X DELETE https://api.track.toggl.com/api/v8/project_users/4692190,4692192,4692193 ``` Successful request will return `200 OK`. If the user has no access to delete, you'll get a status code `4xx` diff --git a/chapters/projects.md b/chapters/projects.md index 222ba36..e12fc36 100644 --- a/chapters/projects.md +++ b/chapters/projects.md @@ -10,7 +10,7 @@ Project has the following properties * template: whether the project can be used as a template (boolean, not required) * template_id: id of the template project used on current project's creation * billable: whether the project is billable or not (boolean, default true, available only for pro workspaces) -* auto_estimates: whether the estimated hours is calculated based on task estimations or is fixed manually (boolean, default false, not required, premium functionality) +* auto_estimates: whether the estimated hours are automatically calculated based on task estimations or manually fixed based on the value of 'estimated_hours' (boolean, default false, not required, premium functionality) * estimated_hours: if auto_estimates is true then the sum of task estimations is returned, otherwise user inserted hours (integer, not required, premium functionality) * at: timestamp that is sent in the response for PUT, indicates the time task was last updated (read-only) * color: id of the color selected for the project @@ -18,9 +18,9 @@ Project has the following properties * created_at: timestamp indicating when the project was created (UTC time), read-only -##Create project## +## Create project -`POST https://www.toggl.com/api/v8/projects` +`POST https://api.track.toggl.com/api/v8/projects` Example request @@ -28,7 +28,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"project":{"name":"An awesome project","wid":777,"template_id":10237,"is_private":true,"cid":123397}}' \ - -X POST https://www.toggl.com/api/v8/projects + -X POST https://api.track.toggl.com/api/v8/projects ``` Successful response @@ -43,21 +43,21 @@ Successful response "is_private":true, "active":true, "at":"2013-03-06T12:15:37+00:00", - "template_id":10237 + "template_id":10237, "color": "5" } } ``` -##Get project data## +## Get project data -`GET https://www.toggl.com/api/v8/projects/{project_id}` +`GET https://api.track.toggl.com/api/v8/projects/{project_id}` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X GET https://www.toggl.com/api/v8/projects/193838628 + -X GET https://api.track.toggl.com/api/v8/projects/193838628 ``` @@ -73,15 +73,15 @@ Successful response "is_private":true, "active":true, "at":"2013-03-06T12:15:37+00:00", - "template":true + "template":true, "color": "5" } } ``` -##Update project data## +## Update project data -`PUT https://www.toggl.com/api/v8/projects/{project_id}` +`PUT https://api.track.toggl.com/api/v8/projects/{project_id}` Example request @@ -89,7 +89,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"project":{"name":"Changed the name","is_private":false,"cid":123398, "color": "6"}}' \ - -X PUT https://www.toggl.com/api/v8/projects/193838628 + -X PUT https://api.track.toggl.com/api/v8/projects/193838628 ``` @@ -110,26 +110,26 @@ Successful response } ``` -##Delete a project## +## Delete a project -`DELETE https://www.toggl.com/api/v8/projects/{project_id}` +`DELETE https://api.track.toggl.com/api/v8/projects/{project_id}` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X DELETE https://www.toggl.com/api/v8/projects/4692190 + -X DELETE https://api.track.toggl.com/api/v8/projects/4692190 ``` -##Get project users## +## Get project users -`GET https://www.toggl.com/api/v8/projects/{project_id}/project_users` +`GET https://api.track.toggl.com/api/v8/projects/{project_id}/project_users` Read more about project user fields from [here](project_users.md). Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X GET https://www.toggl.com/api/v8/projects/193838628/project_users + -X GET https://api.track.toggl.com/api/v8/projects/193838628/project_users ``` @@ -155,16 +155,17 @@ Successful response is an array of the project's users ] ``` -##Get project tasks## +## Get project tasks +Available for Starter, Premium and Enterprise workspaces -`GET https://www.toggl.com/api/v8/projects/{project_id}/tasks` +`GET https://api.track.toggl.com/api/v8/projects/{project_id}/tasks` Read more about task fields from [here](tasks.md). Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X GET https://www.toggl.com/api/v8/projects/777/tasks + -X GET https://api.track.toggl.com/api/v8/projects/777/tasks ``` @@ -178,7 +179,7 @@ Successful response is an array of the project's tasks "pid":777, "active":false, "at":"2013-02-26T15:09:52+00:00", - "estimated_seconds":3600, + "estimated_seconds":3600 }, { "name":"Another task", "id":1335076911, @@ -186,25 +187,25 @@ Successful response is an array of the project's tasks "wid":888, "pid":777, "active":false, - "at":"2013-02-26T15:09:52+00:00", + "at":"2013-02-26T15:09:52+00:00" } ] ``` -##Get workspace projects## +## Get workspace projects Retrieving workspace projects is documented [here](workspaces.md#get-workspace-projects). -##Mass Actions## +## Mass Actions -###Delete multiple projects### +### Delete multiple projects By supplying multiple projectuser ids, you can mass delete projects. -`DELETE https://www.toggl.com/api/v8/projects/{project_ids}` +`DELETE https://api.track.toggl.com/api/v8/projects/{project_ids}` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X DELETE https://www.toggl.com/api/v8/projects/4692190,4692192,4692193 + -X DELETE https://api.track.toggl.com/api/v8/projects/4692190,4692192,4692193 ``` diff --git a/chapters/tags.md b/chapters/tags.md index f95bc53..e8013ed 100644 --- a/chapters/tags.md +++ b/chapters/tags.md @@ -5,9 +5,9 @@ Tag has the following properties * name: The name of the tag (string, required, unique in workspace) * wid: workspace ID, where the tag will be used (integer, required) -##Create tag## +## Create tag -`POST https://www.toggl.com/api/v8/tags` +`POST https://api.track.toggl.com/api/v8/tags` Example request @@ -15,7 +15,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"tag":{"name":"billed","wid":777}}' \ - -X POST https://www.toggl.com/api/v8/tags + -X POST https://api.track.toggl.com/api/v8/tags ``` @@ -30,8 +30,8 @@ Successful response } ``` -##Update a tag## -`PUT https://www.toggl.com/api/v8/tags/{tag_id}` +## Update a tag +`PUT https://api.track.toggl.com/api/v8/tags/{tag_id}` Workspace id (wid) can't be changed. @@ -40,7 +40,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"tag":{"name":"not billed"}}' \ - -X PUT https://www.toggl.com/api/v8/tags/1239455 + -X PUT https://api.track.toggl.com/api/v8/tags/1239455 ``` Successful response @@ -54,14 +54,14 @@ Successful response } ``` -##Delete a tag## +## Delete a tag -`DELETE https://www.toggl.com/api/v8/tags/{tag_id}` +`DELETE https://api.track.toggl.com/api/v8/tags/{tag_id}` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X DELETE https://www.toggl.com/api/v8/tags/1239455 + -X DELETE https://api.track.toggl.com/api/v8/tags/1239455 ``` Successful request will return `200 OK`. If the user has no access to delete, you'll get a status code `4xx` \ No newline at end of file diff --git a/chapters/tasks.md b/chapters/tasks.md index d210e34..e56d330 100644 --- a/chapters/tasks.md +++ b/chapters/tasks.md @@ -1,6 +1,6 @@ Tasks ==================== -Tasks are available only for pro workspaces. +Tasks are available only for starter and other paid workspaces. Task has the following properties * name: The name of the task (string, required, unique in project) @@ -14,10 +14,10 @@ Task has the following properties Workspace id (wid) and project id (pid) can't be changed on update. -##Actions for single project user## -###Create a task### +## Actions for single project user +### Create a task -`POST https://www.toggl.com/api/v8/tasks` +`POST https://api.track.toggl.com/api/v8/tasks` Example request @@ -25,7 +25,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"task":{"name":"A new task","pid":777}}' \ - -X POST https://www.toggl.com/api/v8/tasks + -X POST https://api.track.toggl.com/api/v8/tasks ``` @@ -43,15 +43,15 @@ Successful response } ``` -###Get task details### +### Get task details -`GET https://www.toggl.com/api/v8/tasks/{task_id}` +`GET https://api.track.toggl.com/api/v8/tasks/{task_id}` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X GET https://www.toggl.com/api/v8/tasks/1335076912 + -X GET https://api.track.toggl.com/api/v8/tasks/1335076912 ``` Successful response @@ -68,16 +68,16 @@ Successful response } ``` -###Update a task### +### Update a task -`PUT https://www.toggl.com/api/v8/tasks/{task_id}` +`PUT https://api.track.toggl.com/api/v8/tasks/{task_id}` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"task":{"active":false,"estimated_seconds":3600,"fields":"done_seconds,uname"}}' \ - -X PUT https://www.toggl.com/api/v8/tasks/1335076912 + -X PUT https://api.track.toggl.com/api/v8/tasks/1335076912 ``` Successful response @@ -97,32 +97,32 @@ Successful response } ``` -###Delete a task### +### Delete a task -`DELETE https://www.toggl.com/api/v8/tasks/{task_id}` +`DELETE https://api.track.toggl.com/api/v8/tasks/{task_id}` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X DELETE https://www.toggl.com/api/v8/tasks/1335076912 + -X DELETE https://api.track.toggl.com/api/v8/tasks/1335076912 ``` Successful request will return `200 OK`. If the user has no access to delete, you'll get a status code `4xx` -##Mass Actions## +## Mass Actions -###Update multiple tasks### +### Update multiple tasks By supplying multiple task ids, you can mass update tasks. This is good for marking tasks as done or not done (`active`). -`PUT https://www.toggl.com/api/v8/tasks/{task_ids}` +`PUT https://api.track.toggl.com/api/v8/tasks/{task_ids}` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"task":{"active":false,"fields":"done_seconds,uname"}}' \ - -X PUT https://www.toggl.com/api/v8/tasks/1335076912,1335076911 + -X PUT https://api.track.toggl.com/api/v8/tasks/1335076912,1335076911 ``` Successful response is an array of tasks. @@ -153,14 +153,14 @@ Successful response is an array of tasks. } ``` -###Delete multiple tasks### +### Delete multiple tasks By supplying multiple task ids, you can mass delete tasks. -`DELETE https://www.toggl.com/api/v8/tasks/{task_ids}` +`DELETE https://api.track.toggl.com/api/v8/tasks/{task_ids}` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X DELETE https://www.toggl.com/api/v8/tasks/1335076912,1335076911,1335076910 + -X DELETE https://api.track.toggl.com/api/v8/tasks/1335076912,1335076911,1335076910 ``` Successful request will return `200 OK`. If the user has no access to delete, you'll get a status code `4xx` diff --git a/chapters/time_entries.md b/chapters/time_entries.md index c3b0a88..a538042 100644 --- a/chapters/time_entries.md +++ b/chapters/time_entries.md @@ -1,7 +1,7 @@ Time Entries ==================== -The requests are scoped with the user whose API token is used. Only his/her time entries are updated, retrieved and created. +The requests are scoped with the user whose API token is used. Only his/her time entries and time entries in a workspace where the user is an admin are updated, retrieved and created. Time entry has the following properties * description: (string, strongly suggested to be used) @@ -17,17 +17,17 @@ Time entry has the following properties * duronly: should Toggl show the start and stop time of this time entry? (boolean, not required) * at: timestamp that is sent in the response, indicates the time item was last updated -##Create a time entry## +## Create a time entry -`POST https://www.toggl.com/api/v8/time_entries` +`POST https://api.track.toggl.com/api/v8/time_entries` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ - -d '{"time_entry":{"description":"Meeting with possible clients","tags":["billed"],"duration":1200,"start":"2013-03-05T07:58:58.000Z","pid":123}}' \ - -X POST https://www.toggl.com/api/v8/time_entries + -d '{"time_entry":{"description":"Meeting with possible clients","tags":["billed"],"duration":1200,"start":"2013-03-05T07:58:58.000Z","pid":123,"created_with":"curl"}}' \ + -X POST https://api.track.toggl.com/api/v8/time_entries ``` @@ -48,17 +48,17 @@ Successful response } ``` -##Start a time entry## +## Start a time entry -`POST https://www.toggl.com/api/v8/time_entries/start` +`POST https://api.track.toggl.com/api/v8/time_entries/start` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ - -d '{"time_entry":{"description":"Meeting with possible clients","tags":["billed"],"pid":123}}' \ - -X POST https://www.toggl.com/api/v8/time_entries/start + -d '{"time_entry":{"description":"Meeting with possible clients","tags":["billed"],"pid":123,"created_with":"curl"}}' \ + -X POST https://api.track.toggl.com/api/v8/time_entries/start ``` @@ -79,15 +79,15 @@ Successful response } ``` -##Stop a time entry## +## Stop a time entry -`PUT https://www.toggl.com/api/v8/time_entries/{time_entry_id}/stop` +`PUT https://api.track.toggl.com/api/v8/time_entries/{time_entry_id}/stop` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ - -X PUT https://www.toggl.com/api/v8/time_entries/436694100/stop + -X PUT https://api.track.toggl.com/api/v8/time_entries/436694100/stop ``` Successful response @@ -107,15 +107,15 @@ Successful response } ``` -##Get time entry details## +## Get time entry details -`GET https://www.toggl.com/api/v8/time_entries/{time_entry_id}` +`GET https://api.track.toggl.com/api/v8/time_entries/{time_entry_id}` Example request: ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ --X GET https://www.toggl.com/api/v8/time_entries/436694100 +-X GET https://api.track.toggl.com/api/v8/time_entries/436694100 ``` Successful response @@ -138,15 +138,15 @@ Successful response ``` -##Get running time entry## +## Get running time entry -`GET https://www.toggl.com/api/v8/time_entries/current` +`GET https://api.track.toggl.com/api/v8/time_entries/current` Example request: ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ --X GET https://www.toggl.com/api/v8/time_entries/current +-X GET https://api.track.toggl.com/api/v8/time_entries/current ``` Successful response @@ -166,8 +166,8 @@ Successful response ``` -##Update a time entry## -`PUT https://www.toggl.com/api/v8/time_entries/{time_entry_id}` +## Update a time entry +`PUT https://api.track.toggl.com/api/v8/time_entries/{time_entry_id}` Example request @@ -175,7 +175,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"time_entry":{"description":"Meeting with possible clients","tags":[""],"duration":1240,"start":"2013-03-05T07:58:58.000Z","stop":"2013-03-05T08:58:58.000Z","duronly":true,"pid":123,"billable":true}}' \ - -X PUT https://www.toggl.com/api/v8/time_entries/436694100 + -X PUT https://api.track.toggl.com/api/v8/time_entries/436694100 ``` @@ -198,23 +198,23 @@ Successful response } ``` -##Delete a time entry## +## Delete a time entry -`DELETE https://www.toggl.com/api/v8/time_entries/{time_entry_id}` +`DELETE https://api.track.toggl.com/api/v8/time_entries/{time_entry_id}` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X DELETE https://www.toggl.com/api/v8/time_entries/1239455 + -X DELETE https://api.track.toggl.com/api/v8/time_entries/1239455 ``` Successful request will return `200 OK` -##Get time entries started in a specific time range## +## Get time entries started in a specific time range -`GET https://www.toggl.com/api/v8/time_entries` +`GET https://api.track.toggl.com/api/v8/time_entries` With `start_date` and `end_date` parameters you can specify the date range of the time entries returned. If `start_date` and `end_date` are not specified, time entries started during the last 9 days are returned. **The limit of returned time entries is 1000.** So only the first 1000 found time entries are returned. To get all time entries for a specific time span, you should consider using the [detailed report](../reports/detailed.md) request, which returns paginated results, but enables you to get all the asked time entries with multiple requests. @@ -224,7 +224,7 @@ Example request with start date 2013-03-10T15:42:46+02:00 and end_date 2013-03-1 ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X GET "https://www.toggl.com/api/v8/time_entries?start_date=2013-03-10T15%3A42%3A46%2B02%3A00&end_date=2013-03-12T15%3A42%3A46%2B02%3A00" + -X GET "https://api.track.toggl.com/api/v8/time_entries?start_date=2013-03-10T15%3A42%3A46%2B02%3A00&end_date=2013-03-12T15%3A42%3A46%2B02%3A00" ``` Successful response @@ -257,7 +257,7 @@ Successful response ## Bulk update time entries tags ## -`PUT https://www.toggl.com/api/v8/time_entries/{time_entry_ids_separated_by_a_comma}` +`PUT https://api.track.toggl.com/api/v8/time_entries/{time_entry_ids_separated_by_a_comma}` You can mass assign and remove tags from time entries. Just instead of one `time_entry_id`, you need to send all the time entry ids, which you want to update, separated by a comma in the request url. The request is similar to regular time entry update. @@ -274,7 +274,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"time_entry":{"tags":["billed","productive"], "tag_action": "add"}}' \ - -X PUT https://www.toggl.com/api/v8/time_entries/436694100,436694101 + -X PUT https://api.track.toggl.com/api/v8/time_entries/436694100,436694101 ``` Successful response diff --git a/chapters/users.md b/chapters/users.md index e32d25b..fc0571d 100644 --- a/chapters/users.md +++ b/chapters/users.md @@ -5,14 +5,15 @@ User has the following properties * api_token: (string) * default_wid: default workspace id (integer) * email: (string) +* fullname: (string) * jquery_timeofday_format: (string) -* jquery_date_format:(string) +* jquery_date_format: (string) * timeofday_format: (string) * date_format: (string) * store_start_and_stop_time: whether start and stop time are saved on time entry (boolean) * beginning_of_week: (integer 0-6, Sunday=0) * language: user's language (string) -* image_url: url with the user's profile picture(string) +* image_url: url with the user's profile picture (string) * sidebar_piechart: should a piechart be shown on the sidebar (boolean) * at: timestamp of last changes * new_blog_post: an object with toggl blog post title and link @@ -23,7 +24,7 @@ User has the following properties * timezone: (string) timezone user has set on the "My profile" page ( [IANA TZ timezones](http://en.wikipedia.org/wiki/List_of_tz_database_time_zones) ) ## Get current user data ## -`GET https://www.toggl.com/api/v8/me` +`GET https://api.track.toggl.com/api/v8/me` By default the request responds with user properties. To get all the workspaces, clients, projects, tasks, time entries and tags which the user can see, add the parameter `with_related_data=true` @@ -32,7 +33,7 @@ If you want to retrieve objects which have changed after certain time, add `sinc Example request *without* related data ```shell -curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token -X GET https://www.toggl.com/api/v8/me +curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token -X GET https://api.track.toggl.com/api/v8/me ``` Successful response @@ -69,7 +70,7 @@ Successful response Example request with all the connected data ```shell -curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token -X GET https://www.toggl.com/api/v8/me?with_related_data=true +curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token -X GET https://api.track.toggl.com/api/v8/me?with_related_data=true ``` Successful response @@ -122,7 +123,7 @@ Successful response "name":"Important project", "billable":false, "active":false, - "at":"2013-03-06T09:13:31+00:00" + "at":"2013-03-06T09:13:31+00:00", "color":"5" } ], @@ -161,9 +162,9 @@ Successful response } ``` -##Update user data## +## Update user data ## -`PUT https://www.toggl.com/api/v8/me` +`PUT https://api.track.toggl.com/api/v8/me` You can update the following user fields: * fullname: string @@ -189,7 +190,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"user":{"fullname":"John Smith"}}' \ - -X PUT https://www.toggl.com/api/v8/me + -X PUT https://api.track.toggl.com/api/v8/me ``` Successful response @@ -228,14 +229,14 @@ Successful response } ``` -##Reset API token## -`POST https://www.toggl.com/api/v8/reset_token` +## Reset API token ## +`POST https://api.track.toggl.com/api/v8/reset_token` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X POST https://www.toggl.com/api/v8/reset_token + -X POST https://api.track.toggl.com/api/v8/reset_token ``` Successful response is a string with the new API token: @@ -244,11 +245,11 @@ Successful response is a string with the new API token: ``` -##Get workspace users## +## Get workspace users ## Retrieving workspace users is documented [here](workspaces.md#get-workspace-users). -##Sign up new user## +## Sign up new user ## To create a user you must provide these parameters for the user: * email: a valid email for the user whose account is created (string, required) @@ -256,13 +257,13 @@ To create a user you must provide these parameters for the user: * timezone: for example "Etc/UTC" (string, required) * created_with: in free form, name of the app that signed the user app (string, required) -`POST https://www.toggl.com/api/v8/signups` +`POST https://api.track.toggl.com/api/v8/signups` Example request ```shell curl -H "Content-Type: application/json" \ -d '{"user":{"email":"test.user@toggl.com","password":"StrongPassword"}}' \ --X POST https://www.toggl.com/api/v8/signups +-X POST https://api.track.toggl.com/api/v8/signups ``` Successful response includes created user's data and API token @@ -270,7 +271,6 @@ Successful response includes created user's data and API token { "data":{ "id":599978901, - "api_token":"808lolae4eab897cce9729a53642124effe", "default_wid":983493, "email":"test.user@toggl.com", "fullname":"Test User", diff --git a/chapters/workspace_users.md b/chapters/workspace_users.md index 0ea5bf6..44355a9 100644 --- a/chapters/workspace_users.md +++ b/chapters/workspace_users.md @@ -8,11 +8,11 @@ Workspace user has the following properties: * active: if the workspace user has accepted the invitation to this workspace (boolean) * invite_url: if user has not accepted the invitation the url for accepting his/her invitation is sent when the request is made by workspace_admin -##Invite users to workspace## +## Invite users to workspace You can add users to workspace by email addresses. A letter inviting the user to your workspace is sent to the user's email. -`POST https://www.toggl.com/api/v8/workspaces/{workspace_id}/invite` +`POST https://api.track.toggl.com/api/v8/workspaces/{workspace_id}/invite` Request has the following properties: * emails: array of emails @@ -28,7 +28,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"emails":["john.doe@toggl.com", "Jane.Swift@toggl.com"]}' \ - -X POST https://www.toggl.com/api/v8/workspaces/777/invite + -X POST https://api.track.toggl.com/api/v8/workspaces/777/invite ``` Successful response @@ -48,11 +48,11 @@ Successful response ``` -##Update workspace user## +## Update workspace user Only the admin flag can be changed. -`PUT https://www.toggl.com/api/v8/workspace_users/{workspace_user_id}` +`PUT https://api.track.toggl.com/api/v8/workspace_users/{workspace_user_id}` Example request @@ -60,7 +60,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"workspace_user":{"admin":false}}' \ - -X PUT https://www.toggl.com/api/v8/workspace_users/19012628 + -X PUT https://api.track.toggl.com/api/v8/workspace_users/19012628 ``` @@ -77,27 +77,27 @@ Successful response } ``` -##Delete workspace user## +## Delete workspace user -`DELETE https://www.toggl.com/api/v8/workspace_users/{workspace_user_id}` +`DELETE https://api.track.toggl.com/api/v8/workspace_users/{workspace_user_id}` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ - -X DELETE https://www.toggl.com/api/v8/workspace_users/19012628 + -X DELETE https://api.track.toggl.com/api/v8/workspace_users/19012628 ``` Successful request will return `200 OK`. If the user has no access to delete, you'll get a status code `4xx` -##Get workspace users## +## Get workspace users This request returns not the user objects, but the `workspace_user` objects (the connection between user and workspace) -`GET https://www.toggl.com/api/v8/workspaces/{workspace_id}/workspace_users` +`GET https://api.track.toggl.com/api/v8/workspaces/{workspace_id}/workspace_users` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ --X GET https://www.toggl.com/api/v8/workspaces/777/workspace_users +-X GET https://api.track.toggl.com/api/v8/workspaces/777/workspace_users ``` Successful response is an array of workspace's workspace users diff --git a/chapters/workspaces.md b/chapters/workspaces.md index c8e35f9..3b97dc0 100644 --- a/chapters/workspaces.md +++ b/chapters/workspaces.md @@ -14,16 +14,23 @@ Workspace has the following properties * at: timestamp that indicates the time workspace was last updated * logo_url: URL pointing to the logo (if set, otherwise omited) (string) +### Rounding type +| Type | Integer | +| ---------- | :-----: | +| round down | -1 | +| nearest | 0 | +| round up | 1 | -##Get workspaces## -`GET https://www.toggl.com/api/v8/workspaces` +## Get workspaces + +`GET https://api.track.toggl.com/api/v8/workspaces` Get data about all the workspaces where the token owner belongs to. Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ --X GET https://www.toggl.com/api/v8/workspaces +-X GET https://api.track.toggl.com/api/v8/workspaces ``` Successful response is an array of workspaces @@ -58,13 +65,13 @@ Successful response is an array of workspaces ] ``` -##Get single workspace## -`GET https://www.toggl.com/api/v8/workspaces/{workspace_id}` +## Get single workspace +`GET https://api.track.toggl.com/api/v8/workspaces/{workspace_id}` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ --X GET https://www.toggl.com/api/v8/workspaces/3134975 +-X GET https://api.track.toggl.com/api/v8/workspaces/3134975 ``` Successful response @@ -87,9 +94,9 @@ Successful response } ``` -##Update workspace## +## Update workspace -`PUT https://www.toggl.com/api/v8/workspaces/{workspace_id}` +`PUT https://api.track.toggl.com/api/v8/workspaces/{workspace_id}` Example request @@ -98,7 +105,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"workspace":{"default_currency": "EUR", "default_hourly_rate": 50, "name": "John's ws", "only_admins_may_create_projects": false, "only_admins_see_billable_rates": true, "rounding": 1, "rounding_minutes": 60}}' \ - -X PUT https://www.toggl.com/api/v8/workspaces/3134975 + -X PUT https://api.track.toggl.com/api/v8/workspaces/3134975 ``` @@ -122,15 +129,15 @@ Successful response } ``` -##Get workspace users## +## Get workspace users To get a successful response, the token owner must be workspace admin. -`GET https://www.toggl.com/api/v8/workspaces/{workspace_id}/users` +`GET https://api.track.toggl.com/api/v8/workspaces/{workspace_id}/users` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ --X GET https://www.toggl.com/api/v8/workspaces/777/users +-X GET https://api.track.toggl.com/api/v8/workspaces/777/users ``` Successful response is an array of workspace users @@ -184,15 +191,15 @@ Successful response is an array of workspace users ] ``` -##Get workspace clients## +## Get workspace clients To get a successful response, the token owner must be workspace admin. -`GET https://www.toggl.com/api/v8/workspaces/{workspace_id}/clients` +`GET https://api.track.toggl.com/api/v8/workspaces/{workspace_id}/clients` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ --X GET https://www.toggl.com/api/v8/workspaces/777/clients +-X GET https://api.track.toggl.com/api/v8/workspaces/777/clients ``` Successful response is an array of workspace clients @@ -218,10 +225,38 @@ Successful response is an array of workspace clients ] ``` -##Get workspace projects## +## Get workspace groups + +To get a successful response, the token owner must be workspace admin. +`GET https://api.track.toggl.com/api/v8/workspaces/{workspace_id}/groups` + +Example request +```shell +curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ +-X GET https://api.track.toggl.com/api/v8/workspaces/777/groups +``` + +Successful response is an array of workspace groups +```json +[ + { + "id":123, + "wid":777, + "name":"Management", + "at":"2013-03-06T09:06:13+00:00" + },{ + "id":987, + "wid":777, + "name":"Developers", + "at":"2013-03-06T09:05:40+00:00" + } +] +``` + +## Get workspace projects To get a successful response, the token owner must be workspace admin. -`GET https://www.toggl.com/api/v8/workspaces/{workspace_id}/projects` +`GET https://api.track.toggl.com/api/v8/workspaces/{workspace_id}/projects` To filter projects by their state you can add the additional param to the request url: * active: possible values `true`/`false`/`both`. By default true. If false, only archived projects are returned. @@ -235,7 +270,7 @@ To get only project templates add the additional param to the request url: Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ --X GET https://www.toggl.com/api/v8/workspaces/777/projects +-X GET https://api.track.toggl.com/api/v8/workspaces/777/projects ``` Successful response is an array of active workspace projects @@ -263,12 +298,12 @@ Successful response is an array of active workspace projects ] ``` -##Get workspace tasks## +## Get workspace tasks Available only for pro workspaces To get a successful response, the token owner must be workspace admin. Get all not done tasks in this workspace. -`GET https://www.toggl.com/api/v8/workspaces/{workspace_id}/tasks` +`GET https://api.track.toggl.com/api/v8/workspaces/{workspace_id}/tasks` To filter tasks by their state you can add the additional param to the request url: * active: possible values `true`/`false`/`both`. By default true. If false, only done tasks are returned. @@ -277,7 +312,7 @@ To filter tasks by their state you can add the additional param to the request u Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ --X GET https://www.toggl.com/api/v8/workspaces/777/tasks +-X GET https://api.track.toggl.com/api/v8/workspaces/777/tasks ``` Successful response is an array of workspace tasks @@ -313,14 +348,14 @@ Successful response is an array of workspace tasks ] ``` -##Get workspace tags## +## Get workspace tags -`GET https://www.toggl.com/api/v8/workspaces/{workspace_id}/tags` +`GET https://api.track.toggl.com/api/v8/workspaces/{workspace_id}/tags` Example request ```shell curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ --X GET https://www.toggl.com/api/v8/workspaces/777/tags +-X GET https://api.track.toggl.com/api/v8/workspaces/777/tags ``` Successful response is an array of active workspace tags diff --git a/reports.md b/reports.md index 8f4d233..64fa08a 100644 --- a/reports.md +++ b/reports.md @@ -1,60 +1,69 @@ Toggl Reports API v2 ================= -Here you can get the general information about how to use Toggl reports API, from how to authenticate, what filters to use and how the response is structured. The available reports are similar to the reports available in [Toggl reports page](https://www.toggl.com/report/show). +Here you can get the general information about how to use Toggl reports API, from how to authenticate, what filters to use and how the response is structured. The available reports are similar to the reports available in [Toggl reports page](https://track.toggl.com/reports). More detailed information for the reports. * [Weekly report](reports/weekly.md) * [Detailed report](reports/detailed.md) * [Summary report](reports/summary.md) +* [Project dashboard](reports/project.md) -##URLs## +## URLs -The reports API base URL is `https://toggl.com/reports/api/v2` +The reports API base URL is `https://api.track.toggl.com/reports/api/v2` -Weekly report URL `GET https://toggl.com/reports/api/v2/weekly` +Weekly report URL `GET https://api.track.toggl.com/reports/api/v2/weekly` -Detailed report URL: `GET https://toggl.com/reports/api/v2/details` +Detailed report URL: `GET https://api.track.toggl.com/reports/api/v2/details` -Summary report URL: `GET https://toggl.com/reports/api/v2/summary` +Summary report URL: `GET https://api.track.toggl.com/reports/api/v2/summary` -For PDF response add .pdf to the end of the URL. +For PDF response add .pdf to the end of the URL. For CSV response add .csv as well. +## Rate limiting -##Authentication## +There is rate limiting of 1 request per second (per IP per API token), this +limit may change in future. In case client application exceeds rate limit +HTTP status 429 will be returned. Excessive requests may yield in stricter +limits set upon token/IP combination. + +## Authentication You can authenticate in the reports API **only** with your API token. For HTTP Basic Auth you have to add the Authorization header with the request. -The token is sent as user name and the string 'api_token' as the password. +The API token is the user name and the string 'api_token' is the password. Whenever possible please use the tools and interfaces provided by your http library to do Basic Auth (for example, curl uses the -u switch for that). -##Request Parameters## +## Request Parameters The API expects the request parameters as the query string of the URL. The following parameters and filters can be used in all of the reports -* user_agent: string, **required**, the name of your application or your email address so we can get in touch in case you're doing something wrong. -* workspace_id: integer, **required**. The workspace which data you want to access. -* since: string, ISO 8601 date (YYYY-MM-DD), by default until - 6 days. -* until: string, ISO 8601 date (YYYY-MM-DD), by default today -* billable: possible values: yes/no/both, default both -* client_ids: client ids separated by a comma, **0** if you want to filter out time entries without a client -* project_ids: project ids separated by a comma, **0** if you want to filter out time entries without a project -* user_ids: user ids separated by a comma -* tag_ids: tag ids separated by a comma, **0** if you want to filter out time entries without a tag -* task_ids: task ids separated by a comma, **0** if you want to filter out time entries without a task -* time_entry_ids: time entry ids separated by a comma -* description: string, time entry description -* without_description: true/false, filters out the time entries which do not have a description ('(no description)') -* order_field: - * date/description/duration/user in detailed reports - * title/duration/amount in summary reports - * title/day1/day2/day3/day4/day5/day6/day7/week_total in weekly report -* order_desc: on/off, `on` for descending and `off` for ascending order -* distinct_rates: on/off, default off -* rounding: on/off, default off, rounds time according to workspace settings -* display_hours: decimal/minutes, display hours with minutes or as a decimal number, default minutes - -##Successful response## +* `user_agent`: **Required**. The name of your application or your email address so we can get in touch in case you're doing something wrong. +* `workspace_id`: **Required**. The workspace whose data you want to access. +* `since`: ISO 8601 date (YYYY-MM-DD) format. Defaults to today - 6 days. +* `until`: ISO 8601 date (YYYY-MM-DD) format. Note: Maximum date span (`until - since`) is one year. Defaults to today, unless since is in future or more than year ago, in this case until is since + 6 days. +* `billable`: "yes", "no", or "both". Defaults to "both". +* `client_ids`: A list of client IDs separated by a comma. Use "0" if you want to filter out time entries without a client. +* `project_ids`: A list of project IDs separated by a comma. Use "0" if you want to filter out time entries without a project. +* `user_ids`: A list of user IDs separated by a comma. +* `members_of_group_ids`: A list of group IDs separated by a comma. This limits provided `user_ids` to the members of the given groups. +* `or_members_of_group_ids`: A list of group IDs separated by a comma. This extends provided `user_ids` with the members of the given groups. +* `tag_ids`: A list of tag IDs separated by a comma. Use "0" if you want to filter out time entries without a tag. +* `task_ids`: A list of task IDs separated by a comma. Use "0" if you want to filter out time entries without a task. +* `time_entry_ids`: A list of time entry IDs separated by a comma. +* `description`: Matches against time entry descriptions. +* `without_description`: "true" or "false". Filters out the time entries which do not have a description (literally "(no description)"). +* `order_field`: + * For detailed reports: "date", "description", "duration", or "user" + * For summary reports: "title", "duration", or "amount" + * For weekly reports: "title", "day1", "day2", "day3", "day4", "day5", "day6", "day7", or "week_total" +* `order_desc`: "on" for descending, or "off" for ascending order. +* `distinct_rates`: "on" or "off". Defaults to "off". +* `rounding`: "on" or "off". Defaults to "off". Rounds time according to workspace settings. +* `display_hours`: "decimal" or "minutes". Defaults to "minutes". Determines whether to display hours as a decimal number or with minutes. + +## Successful response The general structure of the successful response ```json @@ -72,7 +81,7 @@ The response may include some additional attributes depending on the report type * total_currencies: an array with amounts and currencies for the selected report * data: an array with detailed information of the requested report. The structure of the data in the array depends on the report. -##Failed requests## +## Failed requests In case of unsuccessful request the API returns the error in JSON and corresponding HTTP status code * message: the general message of the occurred error @@ -90,3 +99,25 @@ Example error } ``` + +Notable error codes: + + 402 Payment Required - feature is not included in current subscription level of + workspace + 410 Gone - this api version is deprecated. Update your client. + 429 Too Many Requests - add delay between requests. + + +To provide third-party developers with important information, we will use +[Warning](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.46) HTTP +header in api responses. We recommend to set up automated notifications for +Warning headers in all responses, in addition to notifying you about failed requests. + +Example warning + + Warning:Human readable warning message + +There are two test endpoints, that return error so you can test client side +error handling: [Error 400](https://api.track.toggl.com/reports/api/v2/error400) and +[Error 500](https://api.track.toggl.com/reports/api/v2/error500) both of them set +Warning header to test value. diff --git a/reports/detailed.md b/reports/detailed.md index b23e834..8c814c6 100644 --- a/reports/detailed.md +++ b/reports/detailed.md @@ -1,17 +1,19 @@ -#Detailed report# +# Detailed report The detailed report returns the time entries for the requested parameters/filters. -There is one additional parameter in detailed reports. As the returned data is paginated you have to add the page parameter. -* page: integer, default 1 -##Response## +## Request -General data -* total_count: total number of time entries that were found for the request. Pay attention to the fact that the amount of time entries returned is max the number which is returned with the `per_page` field (currently 50). To get the next batch of time entries you need to do a new request with same parameters and the incremented `page` parameter. It is not possible to get all the time entries with one request. -* per_page: how many time entries are displayed in one request +In addition to the [standard request parameters](../reports.md#request-parameters), there is one additional parameter in detailed reports. As the returned data is paginated you have to add the page parameter. +* `page`: integer, default 1 +## Response -###Data array### +The response will include the [standard response parameters](../reports.md#successful-response), as well as: +* `total_count`: total number of time entries that were found for the request. Pay attention to the fact that the amount of time entries returned is max the number which is returned with the `per_page` field (currently 50). To get the next batch of time entries you need to do a new request with same parameters and the incremented `page` parameter. It is not possible to get all the time entries with one request. +* `per_page`: how many time entries are displayed in one request + +### Data array Time entry data * id: time entry id @@ -33,11 +35,11 @@ Time entry data * cur: billable amount currency * tags: array of tag names, which assigned for the time entry -##Example## +## Example Example request ```shell -curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token -X GET "https://toggl.com/reports/api/v2/details?workspace_id=123&since=2013-05-19&until=2013-05-20&user_agent=api_test" +curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token -X GET "https://api.track.toggl.com/reports/api/v2/details?workspace_id=123&since=2013-05-19&until=2013-05-20&user_agent=api_test" ``` diff --git a/reports/project.md b/reports/project.md new file mode 100644 index 0000000..d11aea9 --- /dev/null +++ b/reports/project.md @@ -0,0 +1,158 @@ +# Project dashboard + +[Project dashboard](https://support.toggl.com/en/articles/3167701-project-dashboard) returns at-a glance information for a single project. This feature is only available with paid Toggl plans. + +## Request + +`GET /reports/api/v2/project` + +Parameters are: + +* `user_agent` string, **required**, email, or other way to contact client + application developer +* `workspace_id` integer, **required**. The workspace whose data you want to + access +* `project_id` integer, **required**. The project whose data you want to + access +* `page` integer, optional. number of 'tasks_page' you want to fetch +* `order_field` string: name/assignee/duration/billable_amount/estimated_seconds +* `order_desc` string: on/off, `on` for descending and `off` for ascending +order + +## Response + +Project dashboard response has following strucure: ([json schema] +(project_dashboard_schema.json)) + +```json +{ + "name": "string, name of project", + "duration": "integer, total time tracked for this project (ms)", + "billable_duration": "integer, billable time tracked for this project (ms)", + "billable_amount": "number, sum of earnings", + "tasks_count": "integer, total number of tasks in this project", + "currency": "string, currency of billable_amount", + "estimated_seconds": "integer, estimate of how long project would take in seconds", + "task_estimated_seconds": "integer, total of each task time estimations in seconds", + "use_task_estimated_seconds": "boolean, flag indicating if total of task time estimations (true) should be used as grand-estimate, for false value estimated_seconds should be used instead", + "tasks_per_page": "integer, number of tasks per page in #tasks_page, use together with #tasks_count to build pagination links", + "users": [{ + "name": "string, toggl user name", + "duration": "integer, time tracked for this project by given user (ms)", + "billable_duration": "integer, billable time tracked for this project by given user (ms)", + "billable_amount": "number, billable amount contributed by given user" + }], + "top_tasks": [{ + "duration": "integer, time tracked for this project (ms)", + "billable_amount": "number, billable amount contributed by this task", + "name": "string, name of task, null value for name has special meaning - 'Sum of Others'", + "estimated_seconds": "integer, estimate of how long task should take in seconds", + "asignee": "string, toggl user assigned to this task" + }], + "tasks_page": [{ + "name": "string, name of task", + "assignee": "string, toggl user assigned to this task", + "estimated_seconds": "integer, estimate of how long task should take in seconds", + "duration": "integer, time tracked for this project (ms)", + "billable_amount": "number, billable amount contributed by this task" +}] +} +``` + +* `users` array holds all users who contributed time to project +* `top_tasks` is array of tasks that contributed more than 10% of total time + to project +* `tasks_page` is array holding all tasks of given project, one page + at a time + +## Example + +request: +```shell +curl -u my-secret-toggl-api-token:api_token -X GET "https://api.track.toggl.com/reports/api/v2/project/?page=1&user_agent=devteam@example.com&workspace_id=1&project_id=2" +``` + +response (formatted for readability): +```json +{ + "name": "Accounting", + "duration": 74417000, + "duration_without_task": 21137000, + "billable_duration": 43097000, + "billable_amount": 838, + "tasks_count": 4, + "currency": "USD", + "estimated_seconds": 25200, + "task_estimated_seconds": 72000, + "use_task_estimated_seconds": true, + "tasks_per_page": 10, + "users": [ + { + "name": "Paul McMurdoh", + "duration": 74417000, + "billable_duration": 43097000, + "billable_amount": 838 + } + ], + "top_tasks": [ + { + "duration": 25200000, + "billable_amount": 371, + "name": "Invoices", + "estimated_seconds": 18000, + "asignee": null + }, + { + "duration": 10800000, + "billable_amount": null, + "name": "Writing", + "estimated_seconds": 21600, + "asignee": null + }, + { + "duration": 10080000, + "billable_amount": 196, + "name": "Planning", + "estimated_seconds": 14400, + "asignee": null + }, + { + "duration": 7200000, + "billable_amount": 140, + "name": "Billing", + "estimated_seconds": 18000, + "asignee": null + } + ], + "tasks_page": [ + { + "name": "Billing", + "assignee": null, + "estimated_seconds": 18000, + "duration": 7200000, + "billable_amount": 140 + }, + { + "name": "Invoices", + "assignee": null, + "estimated_seconds": 18000, + "duration": 25200000, + "billable_amount": 371 + }, + { + "name": "Planning", + "assignee": null, + "estimated_seconds": 14400, + "duration": 10080000, + "billable_amount": 196 + }, + { + "name": "Writing", + "assignee": null, + "estimated_seconds": 21600, + "duration": 10800000, + "billable_amount": null + } + ] +} +``` diff --git a/reports/project_dashboard_schema.json b/reports/project_dashboard_schema.json new file mode 100644 index 0000000..1177278 --- /dev/null +++ b/reports/project_dashboard_schema.json @@ -0,0 +1,171 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Toggl Project dashboard", + "type": "object", + "required": [ + "name", + "duration", + "duration_without_task", + "billable_duration", + "billable_amount", + "tasks_count", + "currency", + "estimated_seconds", + "task_estimated_seconds", + "use_task_estimated_seconds", + "tasks_per_page", + "users", + "top_tasks", + "tasks_page" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of project" + }, + "duration": { + "type": "integer", + "description": "Total time tracked for this project (ms)" + }, + "duration_without_task": { + "type": "integer", + "description": "Time that was tracked without task" + }, + "billable_duration": { + "type": ["integer", "null"], + "description": "Billable time tracked for this project (ms) " + }, + "billable_amount": { + "type": ["number", "null"], + "description": "Billable amount sum " + }, + "tasks_count": { + "type": "integer", + "description": "Total number of tasks in this project" + }, + "currency": { + "type": "string", + "description": "Currency of billable_amount " + }, + "estimated_seconds": { + "type": ["integer", "null"], + "description": "Estimate of how long project would take in seconds" + }, + "task_estimated_seconds": { + "type": ["integer", "null"], + "description": "Total of each task time estimations in seconds" + }, + "use_task_estimated_seconds": { + "type": "boolean", + "description": "Flag indicating if total of task time estimations (true) should be used as grand-estimate, for false value estimated_seconds should be used instead" + }, + "tasks_per_page": { + "type": "integer", + "description": "Number of tasks per page in #tasks_page, use together with #tasks_count to display user with pagination links" + }, + "users": { + "type": "array", + "description": "All users who contributed time to project", + "minItems": 0, + "uniqueItems": true, + "items": { + "type": "object", + "required": [ + "name", + "duration", + "billable_duration", + "billable_amount" + ], + "properties": { + "name": { + "type": "string", + "description": "Toggl user name" + }, + "duration": { + "type": "integer", + "description": "Time tracked for this project by given user (ms)" + }, + "billable_duration": { + "type": "integer", + "description": "Billable time tracked for this project by given user (ms) " + }, + "billable_amount": { + "type": "number", + "description": "Billable amount contributed by given user " + } + } + } + }, + "top_tasks": { + "type": ["array", "null"], + "description": "Tasks that contributed more than 10% of total time to project", + "minItems": 0, + "uniqueItems": true, + "items": { + "type": "object", + "required": [ + "duration", + "billable_amount" + ], + "properties": { + "duration": { + "type": "integer", + "description": "Time tracked for this project (ms)" + }, + "billable_amount": { + "type": "number", + "description": "Billable amount contributed by this task " + }, + "name": { + "type": ["string", "null"], + "description": "Name of task, null value for name has special meaning - 'Sum of Others'" + }, + "estimated_seconds": { + "type": ["integer", "null"], + "description": "Estimate of how long task should take in seconds" + }, + "asignee": { + "type":["string", "null"], + "description": "Toggl user assigned to this task" + } + } + } + }, + "tasks_page": { + "type": ["array", "null"], + "description": "Paginated list of tasks", + "minItems": 0, + "uniqueItems": true, + "items": { + "type": "object", + "required": [ + "name", + "duration", + "billable_amount" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of task" + }, + "assignee": { + "type": "string", + "description": "Toggl user assigned to this task" + }, + "estimated_seconds": { + "type": "integer", + "description": "Estimate of how long task should take in seconds" + }, + "duration": { + "type": "integer", + "description": "Time tracked for this project (ms)" + }, + "billable_amount": { + "type": "number", + "description": "Billable amount contributed by this task " + } + } + } + } + } +} diff --git a/reports/summary.md b/reports/summary.md index 009166b..0081c2f 100644 --- a/reports/summary.md +++ b/reports/summary.md @@ -1,11 +1,14 @@ -#Summary report# +# Summary report Summary report returns the aggregated time entries data. -Additional parameters for this report -* grouping -* subgrouping -* subgrouping_ids (boolean) - whether returned items will contain 'ids' key containing coma separated group item ID values -* grouped_time_entry_ids (boolean) - whether returned items will contain 'time_entry_ids' key containing coma separated time entries ID values for given item + +## Request + +In addition to the [standard request parameters](../reports.md#request-parameters), summaries accept the following additional parameters: +* `grouping` +* `subgrouping` +* `subgrouping_ids` (boolean) - whether returned items will contain 'ids' key containing comma separated group item ID values +* `grouped_time_entry_ids` (boolean) - whether returned items will contain 'time_entry_ids' key containing comma separated time entries ID values for given item Use the grouping and subgrouping params to organize the data as needed. By default `grouping:projects` and `subgrouping:time_entries` @@ -25,9 +28,11 @@ Following groupings with subgroupings are available in the summary report * projects * clients -##Response## +## Response -###Data array### +The response will include the [standard response parameters](../reports.md#successful-response). + +### Data array General structure of the item in the data array * id: the id of the grouping object @@ -65,11 +70,14 @@ General structure of the item in the data array } ``` -##Example## +## Project colors +When grouped by project the title part of the return will contain color and color_hex fields. First one contains the color id (returned also by APIv8), second one will return the corresponding HEX value. (Please note: color return is a subject of change). + +## Example Example request ```shell -curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token -X GET "https://toggl.com/reports/api/v2/summary?workspace_id=123&since=2013-05-19&until=2013-05-20&user_agent=api_test" +curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token -X GET "https://api.track.toggl.com/reports/api/v2/summary?workspace_id=123&since=2013-05-19&until=2013-05-20&user_agent=api_test" ``` diff --git a/reports/weekly.md b/reports/weekly.md index ac430f8..70c8141 100644 --- a/reports/weekly.md +++ b/reports/weekly.md @@ -1,18 +1,21 @@ -#Weekly report# +# Weekly report -The weekly report gives aggregated 7 day durations or earnings grouped by users and projects. The `until` parameter is ignored for weekly report, 7 days starting from since are shown. +The weekly report gives aggregated 7 day durations or earnings grouped by users and projects. -Additional parameters for this report are: -* grouping: users/projects, default projects. If one grouping is selected, the other acts as subgrouping. -* calculate: time/earnings, default time +## Request +The weekly report accepts all of the [standard request parameters](../reports.md#request-parameters), with the exception of the `until` parameter. Instead, 7 days starting from `since` are shown. -##Response## +Additional request parameters for this report are: +* `grouping`: `users`/`projects`, default projects. If one grouping is selected, the other acts as subgrouping. +* `calculate`: `time`/`earnings`, default time -General data -* week_totals: array of total amounts/hours for every day (null if there's no work on a certain day) +## Response -###Data array### +The response will include the [standard response parameters](../reports.md#successful-response), as well as: +* `week_totals`: array of total amounts/hours for every day (null if there's no work on a certain day) + +### Data array Grouping is `projects` the main grouping looks like this * title: object containing project and client name @@ -84,11 +87,11 @@ If `calculate=earnings`, it is an array of objects with currency string and the ] ``` -##Example## +## Example Example request ```shell -curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token -X GET "https://toggl.com/reports/api/v2/weekly?workspace_id=123&since=2013-05-19&until=2013-05-20&user_agent=api_test" +curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token -X GET "https://api.track.toggl.com/reports/api/v2/weekly?workspace_id=123&since=2013-05-19&until=2013-05-20&user_agent=api_test" ``` Successful response @@ -145,7 +148,7 @@ require 'JSON' wsid = # your workspace id api_token = #your api token -uri = URI("https://toggl.com/reports/api/v2/weekly?workspace_id=#{wsid}&since=2014-03-01&until=2014-03-05&user_agent=api_example_test") +uri = URI("https://api.track.toggl.com/reports/api/v2/weekly?workspace_id=#{wsid}&since=2014-03-01&until=2014-03-05&user_agent=api_example_test") req = Net::HTTP::Get.new(uri) req.basic_auth api_token, 'api_token' @@ -155,4 +158,4 @@ resp = http.request(req) puts resp.body puts JSON.parse(resp.body) -``` \ No newline at end of file +``` diff --git a/toggl_api.md b/toggl_api.md index 5abb902..dd9ceb4 100644 --- a/toggl_api.md +++ b/toggl_api.md @@ -1,16 +1,22 @@ Toggl API v8 ==================== +### Important + +Toggl API **v9** is our current supported version which is documented at https://developers.track.toggl.com/docs + +---- + The API accepts only JSON requests. Please make sure you're setting `Content-Type: application/json`in your request header. Each request returns a **JSON-encoded** body. If the time entry is currently running, the *duration* attribute contains a negative value, denoting the start of the time entry in seconds since epoch (Jan 1 1970). The correct duration can be calculated as current_time + duration, where current_time is the current time in seconds since epoch. The result of each action is communicated via standard HTTP response codes. -###CORS### +### CORS -If you wish to use the API using CORS, we'll need to whitelist you first. Please send us a note at support@toggl.com to whitelist your domain(s). +If you wish to use the API using CORS, we'll need to whitelist you first. Please refer to the [CORS documentation](https://github.com/toggl/toggl_api_docs/blob/master/chapters/cors.md) -###Successful requests### +### Successful requests When request is successful (2xx), a nested response object is returned. Fields which value is NULL are not in the response. @@ -20,7 +26,7 @@ Example request curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H "Content-Type: application/json" \ -d '{"time_entry":{"description":"New time entry","created_with":"API example code","start":"2012-02-12T15:35:47+02:00","duration":1200,"wid":31366}}' \ - -X POST https://www.toggl.com/api/v8/time_entries + -X POST https://api.track.toggl.com/api/v8/time_entries ``` Response @@ -43,7 +49,7 @@ Response } ``` -###Failed requests### +### Failed requests If a create or update action failed, HTTP status code 404 and an array of localized error messages will be returned. @@ -51,7 +57,7 @@ If a create or update action failed, HTTP status code 404 and an array of locali curl -v -u 1971800d4d82861d8f2c1651fea4d212:api_token \ -H 'Content-Type: application/json' \ -d '{"time_entry":{"description":"New time entry","created_with":"API example code"}}' \ - -X POST https://www.toggl.com/api/v8/time_entries + -X POST https://api.track.toggl.com/api/v8/time_entries ``` Response @@ -59,74 +65,82 @@ Response `["Start can't be blank"]` -##Authentication## +## Authentication To use the API, you need to authenticate yourself. This can be done via HTTP POST or HTTP Basic Auth. After successful authentication a session is created using a cookie. If authentication fails, HTTP status code 403 is returned. You can read more about authentication and see sample requests [here](chapters/authentication.md). -##Supported API requests## +## Supported API requests * [Authenticate and get user data](chapters/authentication.md) - - HTTP Basic Auth with e-mail and password - - HTTP Basic Auth with API token - - Authentication with a session cookie - - Destroy the session + - HTTP Basic Auth with e-mail and password + - HTTP Basic Auth with API token + - Authentication with a session cookie + - Destroy the session * [Clients](chapters/clients.md) - - create a client - - get client details - - update a client - - delete a client - - get clients visible to user - - get client projects + - create a client + - get client details + - update a client + - delete a client + - get clients visible to user + - get client projects +* [Groups](chapters/groups.md) + - create a group + - update a group + - delete a group * [Projects](chapters/projects.md) - - create a project - - get project data - - update project data - - get project users - - get project tasks + - create a project + - get project data + - update project data + - delete a project + - get project users + - get project tasks + - delete multiple projects * [Project users](chapters/project_users.md) - - create a project user - - update a project user - - delete a project user - - add multiple users to a project - - update multiple project users - - delete multiple project users + - create a project user + - update a project user + - delete a project user + - add multiple users to a project + - update multiple project users + - delete multiple project users * [Tags](chapters/tags.md) - - create a tag - - update a tag - - delete a tag + - create a tag + - update a tag + - delete a tag * [Tasks](chapters/tasks.md) *(available only for pro workspaces)* - - create a task - - get task details - - update a task - - delete a task - - update multiple tasks - - delete multiple tasks + - create a task + - get task details + - update a task + - delete a task + - update multiple tasks + - delete multiple tasks * [Time entries](chapters/time_entries.md) - - create a time entry - - start a time entry - - stop a time entry - - get time entry details - - update time entry - - delete time entry - - get time entries started in a specific time range - - bulk update time entries tags + - create a time entry + - start a time entry + - stop a time entry + - get time entry details + - update time entry + - delete time entry + - get time entries started in a specific time range + - bulk update time entries tags * [Users](chapters/users.md) - - get current user data and time entries - - update current user data - - reset API token - - sign up new user + - get current user data and time entries + - update current user data + - reset API token + - sign up new user * [Workspaces](chapters/workspaces.md) - - get user workspaces - - get workspace users - - get workspace clients - - get workspace projects - - get workspace tasks - - get workspace tags + - get user workspaces + - get workspace users + - get workspace clients + - get workspace groups + - get workspace projects + - get workspace tasks + - get workspace tags * [Workspace users](chapters/workspace_users.md) - - invite users to workspace - - update workspace user - - delete workspace user - - get workspace users for a workspace - + - invite users to workspace + - update workspace user + - delete workspace user + - get workspace users for a workspace +* [Dashboard](chapters/dashboard.md) + - Get a generic overview of your team diff --git a/webhooks.md b/webhooks.md new file mode 100644 index 0000000..8454745 --- /dev/null +++ b/webhooks.md @@ -0,0 +1,254 @@ +Toggl Webhooks API v1 +===================== + +### Important + +This document has been migrated to https://developers.track.toggl.com/docs/webhooks_start + +---- + +Here you can get the general information about how to use Toggl Webhooks API: how to authenticate, create and list webhooks subscription, validate their URL endpoints and validate the received payloads. + +## Authentication +
+ +You can authenticate to the Webhooks API **only** with your API token. For HTTP Basic Auth you have to add the Authorization header with the request. +The API token is the user name and the string `api_token` is the password. +Whenever possible, please use the tools and interfaces provided by your http library to do Basic Auth (for example, curl uses the -u switch to allow for it). +
+ +## Interacting with the API +
+ +**Notes**: + * the Webhooks API base URL is `https://track.toggl.com/webhooks/api/v1`, + * we provide example requests using [curl](https://curl.se/), + * we parse request responses using [jq](https://stedolan.github.io/jq/), + * in the examples you should replace `{}` with the corresponding value. + +### Request Parameters + +The API expects the following parameters: +* `workspace_id`: **Required**. The workspace ID for your webhooks subscription/s, to be provided in the URL path. +* `User-Agent`: **Suggested**. The name of your application or your email address so we can get in touch in case you're doing something wrong. To be provided as a HTTP header. + + +### List available subscriptions for a given workspace +``` +curl -u {api_token}:api_token \ + -H 'User-Agent: {user_agent}' \ + https://track.toggl.com/webhooks/api/v1/subscriptions/{workspace_id} | jq . +``` + +### Create a subscription +``` +curl -u {api_token}:api_token \ + -d '{ + "url_callback": "{url_callback}", + "event_filters": [ + {"entity": "project", "action": "created"}, + {"entity": "tag", "action": "*"} + ], + "enabled": true, + "description": "My first Webhooks subscription" + }' \ + -H 'User-Agent: {user_agent}' \ + https://track.toggl.com/webhooks/api/v1/subscriptions/{workspace_id} | jq . +``` +Response example: +```json +{ + "subscription_id": 1, + "workspace_id": {workspace_id}, + "user_id": ..., + "enabled": true, + "description": "My first Webhooks subscription", + "event_filters": [ + { + "entity": "project", + "action": "created" + }, + { + "entity": "tag", + "action": "*" + } + ], + "url_callback": {url_callback}, + "secret": ..., + "validated_at": null, + "has_pending_events": false, + "created_at": "2022-05-31T02:50:45.984607Z" +} +``` + +**Notes**: + * replace `{url_callback}` with the URL endpoint that will receive request for this webhooks subscription, + * after creating the subscription you still need to [validate](#validating-a-url-endpoint) its `url_callback`. + +#### About Event Filters +Event Filters allow you to reduce the scope of received events. They currently provide filtering capabilities by entity type and HTTP action applied over them. + +Some possible event filters that you can build would be: +1. All events for created projects: +```js + event_filters": [ + {"entity": "project", "action": "created"} + ] +``` +2. All events for tags: +```js + event_filters": [ + {"entity": "tag", "action": "*"} + ] +``` +3. All events that occurred in a workspace: +```js + event_filters": [ + {"entity": "*", "action": "*"} + ] +``` +4. All updated time entries and clients: +```js + event_filters": [ + {"entity": "time_entry", "action": "updated"}, + {"entity": "client", "action": "updated"} + ] +``` +In any case, there would be authorization checks in place to also filter out the events that the creator of the subscription does not have permission to see. + +You can get a list of supported entities and actions by using the endpoint `https://track.toggl.com/webhooks/api/v1/event_filters` +``` +curl -u {api_token}:api_token \ + -H 'User-Agent: {user_agent}' \ + https://track.toggl.com/webhooks/api/v1/event_filters | jq . +``` + +### Update a subscription +``` +curl -u {api_token}:api_token \ + -X PUT \ + -d '{ + "url_callback": "{url_callback}", + "event_filters": [ + {"entity": "*", "action": "*"} + ], + "enabled": true, + "secret": "new secret string", + "description": "My first Webhooks subscription" + }' \ + -H 'User-Agent: {user_agent}' \ + https://track.toggl.com/webhooks/api/v1/subscriptions/{workspace_id}/{subscription_id} | jq . +``` + +### Change enabled flag in a subscription +``` +curl -u {api_token}:api_token \ + -X PATCH \ + -d '{"enabled": false}' \ + -H 'User-Agent: {user_agent}' \ + https://track.toggl.com/webhooks/api/v1/subscriptions/{workspace_id}/{subscription_id} | jq . +``` + +### Delete a subscription +``` +curl -u {api_token}:api_token \ + -X DELETE \ + -H 'User-Agent: {user_agent}' \ + https://track.toggl.com/webhooks/api/v1/subscriptions/{workspace_id}/{subscription_id} | jq . +``` + +### Ping a subscription to test the setup +You will receive a dummy event in the registered URL endpoint for `{subscription_id}`. +``` +curl -u {api_token}:api_token \ + -X POST \ + -H 'User-Agent: {user_agent}' \ + https://track.toggl.com/webhooks/api/v1/ping/{workspace_id}/{subscription_id} | jq . +``` + +### Get information about matching events for a subscription +We store events that we attempted to deliver to a subscription for a week, you can get information about them (creation date, number of failed delivery attempts, last delivery error, ...) by using the special endpoint `/subscriptions/{workspace_id}/{subscription_id}/events`. + +``` +curl -u {api_token}:api_token \ + -H 'User-Agent: {user_agent}' \ + https://track.toggl.com/webhooks/api/v1/subscriptions/{workspace_id}/{subscription_id}/events` | jq . +``` +Response example: +```json +{ + "total": 2, + "events": [ + { + "event_id": ..., + "created_at": "2022-05-31T02:56:52.493Z", + "creator_id": ..., + "metadata": { + "path": "/api/v9/workspaces/{workspace_id}/projects", + "model": "project", + "action": "created", + "project_id": ..., + "request_type": "POST", + "workspace_id": "{workspace_id}", + "event_user_id": ... + }, + "payload": { + ... + }, + "consumer_id": ..., + "last_delivery_attempt": "2022-05-31T02:56:54.205984Z", + "last_delivery_error": null, + "failed_delivery_attempts": 3 + }, + ... + ] +} +``` +
+ +## Validating a URL endpoint + +
+For a subscription to receive events it has to be both enabled and validated. +The objective of the validation is for the end user to prove that they have access to the events we will send to the URL endpoint. Otherwise, a malicious user could provide us with a valid URL endpoint, that accepts POST requests and returns the expected 2xx status to our requests but that is not associated with the user who created the subscription. In such a scenario we would be sending unsolicited requests to this URL, potentially creating a denial of service. +The validation part can take any of two forms: one synchronous and one asynchronous. + +#### Synchronous Validation +In our special PING events the system will include the `validation_code` field for non-validated subscriptions and we will read the response body trying to parse this structure: +```json + {"validation_code": ""} +``` +Where `` must be the code we included in our PING event. + +#### Asynchronous Validation +Requiring users to implement this behavior in their endpoints could be too much of a burden or they could not even be able to accomplish it if the endpoint service is provided by a third party. In such scenarios we also provide an alternative asynchronous validation scheme where end users need to perform a GET request to `/webhooks/api/v1/validate/{workspace_id}/{subscription_id}/{validation_code}`. If everything is fine, then an OK response will be returned and the subscription will be set as validated. +
+ +## Validating received events + +
+ +In order to be sure that Toggl is the one sending events to your URL endpoint we include a special HTTP header `X-Webhook-Signature-256` that you can use to validate that no one else is sending those requests. + +In order to perform this validation you should: +- Set the field `secret` while creating a new subscription. If omitted, the system will assign one automatically. +- When delivering events to your subscription's URL endpoint the system will add the `X-Webhook-Signature-256` header. +- Signature has the form of `sha256={value}` where value is a HMAC hash based on SHA256 algorithm + secret + body. +- Example: `sha256=6d011bcd0b5bfb7e45372af01bc18f30cc04599df72eca189cdac1094008b095`. +
+ + +## Glossary + +
+ +Common used terms in this document + + +* **Event Filter**: allows you to specify which events a given subscription should receive in its configured URL callback. A subscription may have multiple event filters, but must have at least one. +* **Subscription**: a Webhooks subscription is an entity tied to a single workspace and user creator that has a description, a secret, a set of event filters, a url callback and a enabled and validation status. A user may have multiple subscriptions and a workspace may have multiple subscriptions from different users, but there's a limit of subscriptions per user and workspace. +* **URL callback**: is the URL destination endpoint for a subscription. The system will validate that it's both reachable and returns a 2xx status before starting to forward events to it. +* **User Creator**: given a subscription, the user creator is the one who set it up. Any event sent to the configured url callback will be validated using the permissions of this user. If the user creator doesn't have permission to see some entity, then events related to that entity won't be forwarded to the URL callback. A workspace administrator may list and edit subscriptions from other users in that workspace. +* **Validation Status**: each created subscription must be validated before it can start receiving events. This validation step is to ensure that the creator has access to the provided URL callback. Otherwise, it would mean that Toggl is sending unsolicited events to the configured URL. A non-validated and not enabled subscription may still receive the special PING event which is useful to test that you can receive events from Toggl. + +