Introduction
Welcome to the Timing API reference.
If you prefer a more interactive presentation of the API, you can download our Postman Collection and open it in a tool like Postman or Paw.
We also offer three Siri shortcuts that demonstrate starting and stopping timers via the API:
- Start Timing Timer
- Start Timing Timer (letting you select a project for the timer first)
- Start Fixed Timing Timer (letting you enter timer title and project name once)
- Stop Timing Timer
The "Start Fixed Timing Timer" shortcut will ask you once for a combination of timer title and project name. From then on, it will always launch a shortcut with that combination of title and project. You can create several copies of this shortcut (e.g. by duplicating it), each with a different title/project combination.
Use Cases
Siri Shortcuts and Automation
Using the Timing API, you can quickly create Siri shortcuts to e.g. start and stop timers. During installation, the shortcuts will ask you for an API which you can generate in the 'API Keys' section of the web app. Once installed, simply run the corresponding shortcut to start or stop a timer.
- Start Timing Timer
- Start Timing Timer (letting you select a project for the timer first)
- Start Fixed Timing Timer (letting you enter timer title and project name once)
- Stop Timing Timer
The "Start Fixed Timing Timer" shortcut will ask you once for a combination of timer title and project name. From then on, it will always launch a shortcut with that combination of title and project. You can create several copies of this shortcut (e.g. by duplicating it), each with a different title/project combination.
Feel free to customize these shortcuts to your liking, e.g. by changing the "Start Timer" shortcut to let you select from a couple of preset titles instead. We are also interested in the shortcuts you create, so please let us know what you build with this!
You could also create scripts that start or stop a timer whenever you perform a specific action; see Start a new timer. and Stop the currently running timer. for the corresponding API calls.
Integrating with your billing system
The API also makes it possible to integrate with whatever billing system you are currently using. Simply retrieve your most recent time entries, then send them to your billing system in the desired format. You can also create a script to create a custom report in exactly the format you need, of course.
Make sure to have a look at the ?include_project_data=true
query parameter to include the corresponding project's attributes in the response. This lets you retrieve project titles without having to do a second API call to the "Projects" collection.
GrandTotal integration
The GrandTotal plugin for Timing already uses the Timing Web API to import your team members' time entries. To use that functionality, please refer the corresponding section in the documentation.
Zapier integration
We also offer a Zapier integration. This lets you connect the API to thousands of other services with just a few clicks, solving the problems mentioned above without having to write any code. To start using this integration, see the Zapier section in the web app.
Example use cases include:
- Creating projects for your team members whenever a new project is created in your project management system (e.g. Trello, Asana)
- Importing a list of projects for each team member from a Google Spreadsheet
- Automatically sending finished time entries to your billing system
- Automatically exporting your team members' time entries to a Google Spreadsheet
- Sending a message to a Slack channel whenever you start or stop a task
- Emailing you weekly reports of your team members' logged hours
- And much more...
Contact us
We also recommend for you to reach out and let us know your desired use cases! This helps us prioritize which API features to build first.
API Usage
The API root is https://web.timingapp.com/api/v1
. All endpoint URLs share this prefix. Sample code for each available API call can be found in the right-hand column. Note that query parameters need to be URL-encoded, as shown in the Bash example for the Return a list of time entries. call.
Authentication
The Timing API requires authentication with an API key. You can generate a key in the 'API Keys' section of the web app. Once generated, add an Authorization
header to each request with value Bearer {{token}}
, where {{token}}
is your key.
Rate limiting
The API enforces a rate limit of 500 requests per hour. You can retrieve your current quota via the x-ratelimit-remaining
header attached to every request. In addition, sending more than 200 requests per minute will also trigger a temporary rate limit.
Request and response data
The API expects requests and returns responses in the JSON format. The actual response payload can be found in the data
field. Additional data might be provided in the links
and meta
fields described below. Refer to the descriptions of individual API calls for concrete examples.
Repeated fields
Query parameters ending with a []
can be passed repeatedly. For example, passing ?columns[]=title&columns[]=notes
will show both the "Title" and the "Notes" columns. Optionally, ascending indices can be provided (e.g. ?columns[0]=title&columns[1]=notes
), which makes it easier to build queries in e.g. PHP.
Date format
As Timing is a time-tracking application, its API has to work with many dates. Dates returned by the API will always be formatted as an ISO8601 string including microseconds as well as the time zone, for example 2019-01-01T00:00:00.000000+00:00
.
When sending dates in your requests, we recommend providing dates in a format appropriate to the type of request:
- For time entries, and other requests where the exact time is important, use an ISO8601 format without microseconds but including the time zone, for example
2019-01-01T00:00:00+00:00
or2019-01-01 00:00:00+00
. - For requests where the exact time is not important, such as on a report, use a date-only ISO8601 format, for example
2019-01-01
. In this case, the beginning of a date range (e.g.start_date_min
) will be interpreted as the start of the day in the user's time zone, and the end of a date range (e.g.start_date_max
), will be interpreted as the end of the day in the user's time zone.
Timezone
When a timezone is not provided, the default timezone for an unqualified date is assumed to be UTC. For example, 2019-01-01T00:00:00
would be interpreted as 2019-01-01T00:00:00+0000
. This may be subject to change, however, so try to provide a timezone with your request whenever possible.
A default timezone may be provided, using the X-Time-Zone
header. When this header is set to a valid timezone, any unqualified date is assumed to be in this timezone instead of UTC.
The header only affects input parameters, and all dates are currently returned in UTC. This however may change in the future, so your code should not make any assumptions about this, and always account for the timezone specified in the results.
References
The Timing API identifies entities via the self
field, which contains a link relative to the API root, for example /projects/1
. This avoids any ambiguity about the type of the linked resource and provides you with a convenient way of looking it up, without having to look up the correct API call in this documentation: Simply append the link's value to the API root, resulting in e.g. https://web.timingapp.com/api/v1/projects/1
.
References should be treated as opaque strings; your code should not assumptions about their structure.
Shallow references
For API responses that contain related entities, these entities are usually referenced in a "shallow" fashion. Instead of including the full object, a placeholder containing only the self
field is provided, e.g. as "parent": {"self": "/projects/1"}
. For the Return a list of time entries. call, you can append the ?include_project_data=true
query parameter to include the corresponding project's attributes in the response. This lets you retrieve project titles without having to do a second API call to the "Projects" collection.
Links
Some responses include links to related queries or entities. This includes pagination and queries for related entries.
Pagination
By default, collection responses are paginated to 100 items per page. The links to retrieve the first, last, next and previous pages are part of the response's links
field. Additional information about the paginated data can be found in the meta
field.
Custom fields
Some entities (namely projects and time entries) can have custom fields. These are returned as the custom_fields
collection, with an entry for each custom field on the entity. Custom fields are intended only for scripting purposes. They are exposed only via the API and are not visible anywhere in the Timing app on your Mac nor the web app.
Naming
Custom field names must be a non-empty string, and may only contain alphanumeric characters, dashes and underscores. Additionally, they must not start with an underscore or contain only digits.
Values
Custom field values may only be strings. The only exception to this is providing null
, which can be provided to remove a custom field.
Usage
Custom fields may be added when creating or updating an entity. When updating an entity, any custom fields not provided will be left untouched. If you want to remove a custom field, you must explicitly set it to null
.
Projects
List projects hierarchically.
requires authentication
Return the complete project hierarchy.
See Display the specified project. for the returned attributes.
Example request:
curl --request GET \
--get "https://web.timingapp.com/api/v1/projects/hierarchy" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const url = new URL(
"https://web.timingapp.com/api/v1/projects/hierarchy"
);
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/projects/hierarchy';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/projects/hierarchy'
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()
Example response (200):
Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 500
x-ratelimit-remaining: 499
access-control-allow-origin: *
{
"data": [
{
"self": "/projects/1",
"team_id": null,
"title": "Project at root level",
"title_chain": [
"Project at root level"
],
"color": "#FF0000",
"productivity_score": 1,
"is_archived": false,
"notes": null,
"children": [
{
"self": "/projects/2",
"team_id": null,
"title": "Unproductive child project",
"title_chain": [
"Project at root level",
"Unproductive child project"
],
"color": "#00FF00",
"productivity_score": -1,
"is_archived": false,
"notes": null,
"children": [],
"parent": {
"self": "/projects/1"
},
"custom_fields": {}
}
],
"parent": null,
"custom_fields": {}
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List projects.
requires authentication
Return a list containing all projects.
See Display the specified project. for the returned attributes.
Example request:
curl --request GET \
--get "https://web.timingapp.com/api/v1/projects?title=root&hide_archived=1" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const url = new URL(
"https://web.timingapp.com/api/v1/projects"
);
const params = {
"title": "root",
"hide_archived": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/projects';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'title' => 'root',
'hide_archived' => '1',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/projects'
params = {
'title': 'root',
'hide_archived': '1',
}
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()
Example response (200):
Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 500
x-ratelimit-remaining: 498
access-control-allow-origin: *
{
"data": [
{
"self": "/projects/1",
"team_id": null,
"title": "Project at root level",
"title_chain": [
"Project at root level"
],
"color": "#FF0000",
"productivity_score": 1,
"is_archived": false,
"notes": null,
"children": [
{
"self": "/projects/2"
}
],
"parent": null,
"custom_fields": {}
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create project.
requires authentication
Create a new project.
See Display the specified project. for the returned attributes.
Example request:
curl --request POST \
"https://web.timingapp.com/api/v1/projects" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"title\": \"Acme Inc.\",
\"parent\": \"\\/projects\\/1\",
\"color\": \"#FF0000\",
\"productivity_score\": 1,
\"is_archived\": false,
\"notes\": \"Some more detailed notes\",
\"custom_fields\": {
\"field_name\": \"field_value\"
}
}"
const url = new URL(
"https://web.timingapp.com/api/v1/projects"
);
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"title": "Acme Inc.",
"parent": "\/projects\/1",
"color": "#FF0000",
"productivity_score": 1,
"is_archived": false,
"notes": "Some more detailed notes",
"custom_fields": {
"field_name": "field_value"
}
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/projects';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'title' => 'Acme Inc.',
'parent' => '/projects/1',
'color' => '#FF0000',
'productivity_score' => 1.0,
'is_archived' => false,
'notes' => 'Some more detailed notes',
'custom_fields' => [
'field_name' => 'field_value',
],
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/projects'
payload = {
"title": "Acme Inc.",
"parent": "\/projects\/1",
"color": "#FF0000",
"productivity_score": 1,
"is_archived": false,
"notes": "Some more detailed notes",
"custom_fields": {
"field_name": "field_value"
}
}
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()
Example response (201):
Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 500
x-ratelimit-remaining: 497
access-control-allow-origin: *
{
"data": {
"self": "/projects/2",
"team_id": null,
"title": "Acme Inc.",
"title_chain": [
"Project at root level",
"Acme Inc."
],
"color": "#FF0000",
"productivity_score": 1,
"is_archived": false,
"notes": "Some more detailed notes",
"children": [],
"parent": {
"self": "/projects/1"
},
"custom_fields": {
"field_name": "field_value"
}
},
"links": {
"time-entries": "https://web.timingapp.com/api/v1/time-entries?project[]=/projects/2"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Show project.
requires authentication
Display the specified project.
The following attributes will be returned:
self
: A reference to the entity itself, relative to the API root.title
: The project's title.title_chain
: An array containing the title of the project and all its ancestors. Example:["Parent", "Child"]
color
: The project's color, in hexadecimal format (#RRGGBB
). Example:#FF0000
productivity_score
: The project's productivity rating, between -1 (very unproductive) and 1 (very productive). Example:1
is_archived
: Whether the project has been archived. Defaults to false. Example:false
parent
: A reference to the enclosing project.children
: The project's children.team_id
: The ID of the team that this project belongs to, if applicable.
Example request:
curl --request GET \
--get "https://web.timingapp.com/api/v1/projects/1" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const url = new URL(
"https://web.timingapp.com/api/v1/projects/1"
);
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/projects/1';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/projects/1'
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()
Example response (200):
Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 500
x-ratelimit-remaining: 496
access-control-allow-origin: *
{
"data": {
"self": "/projects/1",
"team_id": null,
"title": "Project at root level",
"title_chain": [
"Project at root level"
],
"color": "#FF0000",
"productivity_score": 1,
"is_archived": false,
"notes": null,
"children": [
{
"self": "/projects/2"
}
],
"parent": null,
"custom_fields": {}
},
"links": {
"time-entries": "https://web.timingapp.com/api/v1/time-entries?project[]=/projects/1"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update project.
requires authentication
Update the specified project.
See Display the specified project. for the returned attributes.
Example request:
curl --request PUT \
"https://web.timingapp.com/api/v1/projects/1" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"title\": \"Acme Inc.\",
\"color\": \"#FF0000\",
\"productivity_score\": 1,
\"is_archived\": false,
\"notes\": \"Some more detailed notes\",
\"custom_fields\": {
\"field_name\": \"field_value\"
}
}"
const url = new URL(
"https://web.timingapp.com/api/v1/projects/1"
);
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"title": "Acme Inc.",
"color": "#FF0000",
"productivity_score": 1,
"is_archived": false,
"notes": "Some more detailed notes",
"custom_fields": {
"field_name": "field_value"
}
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/projects/1';
$response = $client->put(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'title' => 'Acme Inc.',
'color' => '#FF0000',
'productivity_score' => 1.0,
'is_archived' => false,
'notes' => 'Some more detailed notes',
'custom_fields' => [
'field_name' => 'field_value',
],
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/projects/1'
payload = {
"title": "Acme Inc.",
"color": "#FF0000",
"productivity_score": 1,
"is_archived": false,
"notes": "Some more detailed notes",
"custom_fields": {
"field_name": "field_value"
}
}
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('PUT', url, headers=headers, json=payload)
response.json()
Example response (200):
Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 500
x-ratelimit-remaining: 495
access-control-allow-origin: *
{
"data": {
"self": "/projects/1",
"team_id": null,
"title": "Acme Inc.",
"title_chain": [
"Acme Inc."
],
"color": "#FF0000",
"productivity_score": 1,
"is_archived": false,
"notes": "Some more detailed notes",
"children": [
{
"self": "/projects/2"
}
],
"parent": null,
"custom_fields": {
"field_name": "field_value"
}
},
"links": {
"time-entries": "https://web.timingapp.com/api/v1/time-entries?project[]=/projects/1"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete project.
requires authentication
Delete the specified project and all of its children.
Example request:
curl --request DELETE \
"https://web.timingapp.com/api/v1/projects/1" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const url = new URL(
"https://web.timingapp.com/api/v1/projects/1"
);
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/projects/1';
$response = $client->delete(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/projects/1'
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('DELETE', url, headers=headers)
response.json()
Example response (204):
Show headers
cache-control: no-cache, private
x-ratelimit-limit: 500
x-ratelimit-remaining: 494
access-control-allow-origin: *
Empty response
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Reports
Generate report.
requires authentication
Generate a report that can contain both time entries and app usage.
Returns a JSON array with several rows; each row includes the total duration (in seconds) belonging to the corresponding other (configurable) columns.
The include_app_usage
and include_team_members
parameters govern whether to include app usage (otherwise, only time entries are returned) as well as data for other team members.
The start_date_min
, start_date_max
, projects
(also see include_child_projects
) and search_query
parameters allow filtering the returned data.
The columns
, project_grouping_level
, include_project_data
, timespan_grouping_mode
, and sort
parameters govern the presentation of the returned data.
Example request:
curl --request GET \
--get "https://web.timingapp.com/api/v1/report?include_app_usage=0&include_team_members=0&team_members[]=%2Fusers%2F1&start_date_min=2019-01-01&start_date_max=2019-01-01&projects[]=%2Fprojects%2F1&include_child_projects=1&search_query=meeting&columns[]=project&project_grouping_level=0&include_project_data=1×pan_grouping_mode=day&sort[]=-duration" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const url = new URL(
"https://web.timingapp.com/api/v1/report"
);
const params = {
"include_app_usage": "0",
"include_team_members": "0",
"team_members[0]": "/users/1",
"start_date_min": "2019-01-01",
"start_date_max": "2019-01-01",
"projects[0]": "/projects/1",
"include_child_projects": "1",
"search_query": "meeting",
"columns[0]": "project",
"project_grouping_level": "0",
"include_project_data": "1",
"timespan_grouping_mode": "day",
"sort[0]": "-duration",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/report';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'include_app_usage' => '0',
'include_team_members' => '0',
'team_members[0]' => '/users/1',
'start_date_min' => '2019-01-01',
'start_date_max' => '2019-01-01',
'projects[0]' => '/projects/1',
'include_child_projects' => '1',
'search_query' => 'meeting',
'columns[0]' => 'project',
'project_grouping_level' => '0',
'include_project_data' => '1',
'timespan_grouping_mode' => 'day',
'sort[0]' => '-duration',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/report'
params = {
'include_app_usage': '0',
'include_team_members': '0',
'team_members[0]': '/users/1',
'start_date_min': '2019-01-01',
'start_date_max': '2019-01-01',
'projects[0]': '/projects/1',
'include_child_projects': '1',
'search_query': 'meeting',
'columns[0]': 'project',
'project_grouping_level': '0',
'include_project_data': '1',
'timespan_grouping_mode': 'day',
'sort[0]': '-duration',
}
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()
Example response (200):
Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 500
x-ratelimit-remaining: 489
access-control-allow-origin: *
{
"data": [
{
"duration": 3600,
"project": {
"self": "/projects/1",
"team_id": null,
"title": "Project at root level",
"title_chain": [
"Project at root level"
],
"color": "#FF0000",
"productivity_score": 1,
"is_archived": false,
"notes": null,
"parent": null,
"custom_fields": {}
}
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Teams
List team members.
requires authentication
Return a list containing all active members of the given team.
Members with pending invitations will be excluded.
The following attributes will be returned:
self
: A reference to the entity itself, relative to the API root.email
: The team member's email address.name
: The team member's name. May be null if the team member has not entered a name in their account profile.
Example request:
curl --request GET \
--get "https://web.timingapp.com/api/v1/teams/1/members" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const url = new URL(
"https://web.timingapp.com/api/v1/teams/1/members"
);
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/teams/1/members';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/teams/1/members'
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()
Example response (200):
Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 500
x-ratelimit-remaining: 491
access-control-allow-origin: *
{
"data": [
{
"self": "/users/1",
"email": "johnny@appleseed.net",
"name": "Johnny Appleseed"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List teams.
requires authentication
Return a list containing all the teams you are a member of.
Example request:
curl --request GET \
--get "https://web.timingapp.com/api/v1/teams" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const url = new URL(
"https://web.timingapp.com/api/v1/teams"
);
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/teams';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/teams'
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()
Example response (200):
Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 500
x-ratelimit-remaining: 490
access-control-allow-origin: *
{
"data": [
{
"id": "/teams/1",
"name": "Demo Team"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Time Entries
Start timer.
requires authentication
Start a new timer.
This also stops the currently running timer if there is one.
See Display the specified time entry. for the returned attributes.
Example request:
curl --request POST \
"https://web.timingapp.com/api/v1/time-entries/start" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"start_date\": \"2019-01-01T00:00:00+00:00\",
\"project\": \"Unproductive child project\",
\"title\": \"Client Meeting\",
\"notes\": \"Some more detailed notes\",
\"replace_existing\": false,
\"custom_fields\": {
\"field_name\": \"field_value\"
}
}"
const url = new URL(
"https://web.timingapp.com/api/v1/time-entries/start"
);
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"start_date": "2019-01-01T00:00:00+00:00",
"project": "Unproductive child project",
"title": "Client Meeting",
"notes": "Some more detailed notes",
"replace_existing": false,
"custom_fields": {
"field_name": "field_value"
}
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/time-entries/start';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'start_date' => '2019-01-01T00:00:00+00:00',
'project' => 'Unproductive child project',
'title' => 'Client Meeting',
'notes' => 'Some more detailed notes',
'replace_existing' => false,
'custom_fields' => [
'field_name' => 'field_value',
],
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/time-entries/start'
payload = {
"start_date": "2019-01-01T00:00:00+00:00",
"project": "Unproductive child project",
"title": "Client Meeting",
"notes": "Some more detailed notes",
"replace_existing": false,
"custom_fields": {
"field_name": "field_value"
}
}
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()
Example response (201):
Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 500
x-ratelimit-remaining: 493
access-control-allow-origin: *
{
"data": {
"self": "/time-entries/2",
"start_date": "2019-01-01T00:00:00.000000+00:00",
"end_date": "2019-01-01T00:00:00.000000+00:00",
"duration": 0,
"project": {
"self": "/projects/2"
},
"title": "Client Meeting",
"notes": "Some more detailed notes",
"is_running": true,
"creator_name": "Johnny Appleseed",
"custom_fields": {
"field_name": "field_value"
}
},
"message": "Timer 'Client Meeting' started."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Stop timer.
requires authentication
Stop the currently running timer.
Returns the stopped timer's attributes as listed under Display the specified time entry..
Example request:
curl --request PUT \
"https://web.timingapp.com/api/v1/time-entries/stop" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const url = new URL(
"https://web.timingapp.com/api/v1/time-entries/stop"
);
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "PUT",
headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/time-entries/stop';
$response = $client->put(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/time-entries/stop'
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('PUT', url, headers=headers)
response.json()
Example response (200):
Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 500
x-ratelimit-remaining: 499
access-control-allow-origin: *
{
"data": {
"self": "/time-entries/1",
"start_date": "2019-01-01T00:00:00.000000+00:00",
"end_date": "2019-01-01T01:00:00.000000+00:00",
"duration": 3600,
"project": {
"self": "/projects/1"
},
"title": "Client Meeting",
"notes": "Some more detailed notes",
"is_running": false,
"creator_name": "Johnny Appleseed",
"custom_fields": {}
},
"message": "Timer 'Client Meeting' stopped."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Show latest time entry.
requires authentication
Redirect to the latest time entry.
See Display the specified time entry. for the route the redirect points to.
Example request:
curl --request GET \
--get "https://web.timingapp.com/api/v1/time-entries/latest" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const url = new URL(
"https://web.timingapp.com/api/v1/time-entries/latest"
);
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/time-entries/latest';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/time-entries/latest'
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()
Example response (302):
Show headers
cache-control: no-cache, private
location: https://web.timingapp.com/api/v1/time-entries/1
content-type: text/html; charset=utf-8
x-ratelimit-limit: 500
x-ratelimit-remaining: 498
access-control-allow-origin: *
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="refresh" content="0;url='https://web.timingapp.com/api/v1/time-entries/1'" />
<title>Redirecting to https://web.timingapp.com/api/v1/time-entries/1</title>
</head>
<body>
Redirecting to <a href="https://web.timingapp.com/api/v1/time-entries/1">https://web.timingapp.com/api/v1/time-entries/1</a>.
</body>
</html>
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Show running timer.
Redirect to the currently running timer.
See Display the specified time entry. for the route the redirect points to.
Example request:
curl --request GET \
--get "https://web.timingapp.com/api/v1/time-entries/running" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const url = new URL(
"https://web.timingapp.com/api/v1/time-entries/running"
);
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/time-entries/running';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/time-entries/running'
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()
Example response (404):
Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 500
x-ratelimit-remaining: 497
access-control-allow-origin: *
{
"message": "No running timer found."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List time entries.
requires authentication
Return a list of time entries.
See Display the specified time entry. for the returned attributes.
Items are ordered descending by their start_date
field.
Example request:
curl --request GET \
--get "https://web.timingapp.com/api/v1/time-entries?start_date_min=2019-01-01&start_date_max=2019-01-01&projects[]=%2Fprojects%2F1&include_child_projects=1&search_query=meeting&is_running=0&include_project_data=1&include_team_members=0&team_members[]=%2Fusers%2F1" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const url = new URL(
"https://web.timingapp.com/api/v1/time-entries"
);
const params = {
"start_date_min": "2019-01-01",
"start_date_max": "2019-01-01",
"projects[0]": "/projects/1",
"include_child_projects": "1",
"search_query": "meeting",
"is_running": "0",
"include_project_data": "1",
"include_team_members": "0",
"team_members[0]": "/users/1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/time-entries';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'start_date_min' => '2019-01-01',
'start_date_max' => '2019-01-01',
'projects[0]' => '/projects/1',
'include_child_projects' => '1',
'search_query' => 'meeting',
'is_running' => '0',
'include_project_data' => '1',
'include_team_members' => '0',
'team_members[0]' => '/users/1',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/time-entries'
params = {
'start_date_min': '2019-01-01',
'start_date_max': '2019-01-01',
'projects[0]': '/projects/1',
'include_child_projects': '1',
'search_query': 'meeting',
'is_running': '0',
'include_project_data': '1',
'include_team_members': '0',
'team_members[0]': '/users/1',
}
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()
Example response (200):
Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 500
x-ratelimit-remaining: 496
access-control-allow-origin: *
{
"data": [
{
"self": "/time-entries/1",
"start_date": "2019-01-01T00:00:00.000000+00:00",
"end_date": "2019-01-01T01:00:00.000000+00:00",
"duration": 3600,
"project": {
"self": "/projects/1",
"team_id": null,
"title": "Project at root level",
"title_chain": [
"Project at root level"
],
"color": "#FF0000",
"productivity_score": 1,
"is_archived": false,
"notes": null,
"parent": null,
"custom_fields": {}
},
"title": "Client Meeting",
"notes": "Some more detailed notes",
"is_running": false,
"creator_name": "Johnny Appleseed",
"custom_fields": {}
}
],
"links": {
"first": "http://timing-web.test/api/v1/time-entries?start_date_min=2019-01-01&start_date_max=2019-01-01&projects%5B0%5D=%2Fprojects%2F1&include_child_projects=1&search_query=meeting&is_running=0&include_project_data=1&include_team_members=0&team_members%5B0%5D=%2Fusers%2F1&page=1",
"last": "http://timing-web.test/api/v1/time-entries?start_date_min=2019-01-01&start_date_max=2019-01-01&projects%5B0%5D=%2Fprojects%2F1&include_child_projects=1&search_query=meeting&is_running=0&include_project_data=1&include_team_members=0&team_members%5B0%5D=%2Fusers%2F1&page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"links": [
{
"url": null,
"label": "« Previous",
"active": false
},
{
"url": "http://timing-web.test/api/v1/time-entries?start_date_min=2019-01-01&start_date_max=2019-01-01&projects%5B0%5D=%2Fprojects%2F1&include_child_projects=1&search_query=meeting&is_running=0&include_project_data=1&include_team_members=0&team_members%5B0%5D=%2Fusers%2F1&page=1",
"label": "1",
"active": true
},
{
"url": null,
"label": "Next »",
"active": false
}
],
"path": "http://timing-web.test/api/v1/time-entries",
"per_page": 1000,
"to": 1,
"total": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create time entry.
requires authentication
Create a new time entry.
See Display the specified time entry. for the returned attributes.
Example request:
curl --request POST \
"https://web.timingapp.com/api/v1/time-entries" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"start_date\": \"2019-01-01T00:00:00+00:00\",
\"end_date\": \"2019-01-01T01:00:00+00:00\",
\"project\": \"Unproductive child project\",
\"title\": \"Client Meeting\",
\"notes\": \"Some more detailed notes\",
\"replace_existing\": false,
\"custom_fields\": {
\"field_name\": \"field_value\"
}
}"
const url = new URL(
"https://web.timingapp.com/api/v1/time-entries"
);
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"start_date": "2019-01-01T00:00:00+00:00",
"end_date": "2019-01-01T01:00:00+00:00",
"project": "Unproductive child project",
"title": "Client Meeting",
"notes": "Some more detailed notes",
"replace_existing": false,
"custom_fields": {
"field_name": "field_value"
}
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/time-entries';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'start_date' => '2019-01-01T00:00:00+00:00',
'end_date' => '2019-01-01T01:00:00+00:00',
'project' => 'Unproductive child project',
'title' => 'Client Meeting',
'notes' => 'Some more detailed notes',
'replace_existing' => false,
'custom_fields' => [
'field_name' => 'field_value',
],
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/time-entries'
payload = {
"start_date": "2019-01-01T00:00:00+00:00",
"end_date": "2019-01-01T01:00:00+00:00",
"project": "Unproductive child project",
"title": "Client Meeting",
"notes": "Some more detailed notes",
"replace_existing": false,
"custom_fields": {
"field_name": "field_value"
}
}
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()
Example response (201):
Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 500
x-ratelimit-remaining: 495
access-control-allow-origin: *
{
"data": {
"self": "/time-entries/2",
"start_date": "2019-01-01T00:00:00.000000+00:00",
"end_date": "2019-01-01T01:00:00.000000+00:00",
"duration": 3600,
"project": {
"self": "/projects/2"
},
"title": "Client Meeting",
"notes": "Some more detailed notes",
"is_running": false,
"creator_name": "Johnny Appleseed",
"custom_fields": {
"field_name": "field_value"
}
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Show time entry.
requires authentication
Display the specified time entry.
The following attributes will be returned:
self
: A link to the entity itself, relative to the API root.start_date
: The time entry's start date and time.end_date
: The time entry's end date and time.duration
: The time entry's total duration, in seconds.project
: The project this time entry is associated with.title
: The time entry's title.notes
: The time entry's notes.is_running
: Whether the time entry is currently running. Only one time entry can be running at any given time.
Example request:
curl --request GET \
--get "https://web.timingapp.com/api/v1/time-entries/1" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const url = new URL(
"https://web.timingapp.com/api/v1/time-entries/1"
);
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/time-entries/1';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/time-entries/1'
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()
Example response (200):
Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 500
x-ratelimit-remaining: 494
access-control-allow-origin: *
{
"data": {
"self": "/time-entries/1",
"start_date": "2019-01-01T00:00:00.000000+00:00",
"end_date": "2019-01-01T01:00:00.000000+00:00",
"duration": 3600,
"project": {
"self": "/projects/1"
},
"title": "Client Meeting",
"notes": "Some more detailed notes",
"is_running": false,
"creator_name": "Johnny Appleseed",
"custom_fields": {}
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update time entry.
requires authentication
Update the specified time entry.
See Display the specified time entry. for the returned attributes.
Example request:
curl --request PUT \
"https://web.timingapp.com/api/v1/time-entries/1" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"start_date\": \"2019-01-01T00:00:00+00:00\",
\"end_date\": \"2019-01-01T01:00:00+00:00\",
\"project\": \"Unproductive child project\",
\"title\": \"Client Meeting\",
\"notes\": \"Some more detailed notes\",
\"replace_existing\": false,
\"custom_fields\": {
\"field_name\": \"field_value\"
}
}"
const url = new URL(
"https://web.timingapp.com/api/v1/time-entries/1"
);
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"start_date": "2019-01-01T00:00:00+00:00",
"end_date": "2019-01-01T01:00:00+00:00",
"project": "Unproductive child project",
"title": "Client Meeting",
"notes": "Some more detailed notes",
"replace_existing": false,
"custom_fields": {
"field_name": "field_value"
}
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/time-entries/1';
$response = $client->put(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'start_date' => '2019-01-01T00:00:00+00:00',
'end_date' => '2019-01-01T01:00:00+00:00',
'project' => 'Unproductive child project',
'title' => 'Client Meeting',
'notes' => 'Some more detailed notes',
'replace_existing' => false,
'custom_fields' => [
'field_name' => 'field_value',
],
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/time-entries/1'
payload = {
"start_date": "2019-01-01T00:00:00+00:00",
"end_date": "2019-01-01T01:00:00+00:00",
"project": "Unproductive child project",
"title": "Client Meeting",
"notes": "Some more detailed notes",
"replace_existing": false,
"custom_fields": {
"field_name": "field_value"
}
}
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('PUT', url, headers=headers, json=payload)
response.json()
Example response (200):
Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 500
x-ratelimit-remaining: 493
access-control-allow-origin: *
{
"data": {
"self": "/time-entries/1",
"start_date": "2019-01-01T00:00:00.000000+00:00",
"end_date": "2019-01-01T01:00:00.000000+00:00",
"duration": 3600,
"project": {
"self": "/projects/2"
},
"title": "Client Meeting",
"notes": "Some more detailed notes",
"is_running": false,
"creator_name": "Johnny Appleseed",
"custom_fields": {
"field_name": "field_value"
}
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete time entry.
requires authentication
Delete the specified time entry.
Example request:
curl --request DELETE \
"https://web.timingapp.com/api/v1/time-entries/1" \
--header "Authorization: Bearer {{token}}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const url = new URL(
"https://web.timingapp.com/api/v1/time-entries/1"
);
const headers = {
"Authorization": "Bearer {{token}}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://web.timingapp.com/api/v1/time-entries/1';
$response = $client->delete(
$url,
[
'headers' => [
'Authorization' => 'Bearer {{token}}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://web.timingapp.com/api/v1/time-entries/1'
headers = {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('DELETE', url, headers=headers)
response.json()
Example response (204):
Show headers
cache-control: no-cache, private
x-ratelimit-limit: 500
x-ratelimit-remaining: 492
access-control-allow-origin: *
Empty response
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.