GET List tasks
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks
Returns a list of tasks based on the workspace ID.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks \
-H "Content-Type: application/json" \
-u <email>:<password>
req, err := http.NewRequest(http.MethodGet,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks")
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks')
req = Net::HTTP::Get.new(uri)
req['Content-Type'] = "application/json"
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks", {
method: "GET",
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.get('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks', headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::GET, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks".to_string())
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
Query
| name | type | required | description |
|---|
| page | integer | false | page number |
| per_page | integer | false | results per page |
| with_entries | boolean | false | include time entries |
| pinned | boolean | false | filter by tasks the current user has pinned |
| order_by | []string | false | order by. tag_ids and assignees order by the canonicalized (sorted) array, so tasks with the same set of tags or assignees cluster together regardless of storage order. Also accepts pcf_<id> / -pcf_<id> to sort tasks by the named custom field on the task's parent project, and cf_<id> / -cf_<id> to sort by the task's own custom field. Multi_select and users CF types use the same canonicalized-array semantics. project_name orders by project name (case-insensitive), then project ID, so same-named projects stay separate groups; tasks without a project sort last ascending and first descending. sub_tasks_grouped orders top-level tasks by name (direction applies) with each task's subtasks directly after it in position order; it cannot be combined with other order_by values. |
| status_id | []integer | false | filter in tasks by status' IDs |
| toggl_user_id | integer | false | filter in tasks by user |
| name | string | false | filter tasks by task name, project name, or client name |
| has_time_entries | boolean | false | filter tasks if it has time entries |
| has_dates | boolean | false | filter tasks by date presence: true returns tasks with start_date or end_date, false returns tasks with both dates NULL |
| private | boolean | false | filter tasks by private state |
| archived | boolean | false | filter in/out archived tasks |
| active_project | boolean | false | Only tasks without a project or in a live, non-archived, non-completed, non-template, non-draft project. |
| include_project_completed | boolean | false | include tasks whose parent project is completed (default false hides them; tasks without a project are always returned) |
| include_drafts | boolean | false | include tasks belonging to draft projects (default false hides them; requires view_draft_projects permission; tasks without a project are always returned) |
| project_id | []integer | false | filter by project ids. ?project_id= will include tasks with no project. |
| parent_task_id | []integer | false | filter by parent task ids. ?parent_task_id= will include tasks with no parent. |
| start_date | string | false | filter tasks overlapping date range (start). Used with end_date to find tasks where task.start_date <= end_date AND task.end_date >= start_date |
| end_date | string | false | filter tasks overlapping date range (end). Used with start_date to find tasks where task.start_date <= end_date AND task.end_date >= start_date |
| active_by_date | string | false | filter tasks active by a date (today_and_overdue preset): returns tasks that have at least one date and whose start_date is null or on or before the date; end_date is not upper-bounded so overdue tasks remain included |
| start_date_from | string | false | [LEGACY] use start_date instead |
| start_date_to | string | false | [LEGACY] use start_date instead |
| end_date_from | string | false | [LEGACY] use end_date instead |
| end_date_to | string | false | [LEGACY] use end_date instead |
| dates_overlap_start | string | false | [LEGACY] use start_date instead |
| dates_overlap_end | string | false | [LEGACY] use end_date instead |
| occurrence_window_date | string | false | Repeats of a recurring task dated after this date + occurrence_window_days are hidden; earlier ones show. Default: today (UTC). |
| occurrence_window_days | integer | false | Days after occurrence_window_date, 0–31. Default: 7. Ignored with end_date or active_by_date. |
| estimated_mins_min | integer | false | filter by estimated mins min |
| estimated_mins_max | integer | false | filter by estimated mins max |
| source | []string | false | filter by sources |
| priority | []string | false | filter by priority |
| is_priority | boolean | false | filter by whether task is a user priority |
| state | []string | false | filter by state |
| team_id | []integer | false | filter tasks by team IDs |
| assignee_team_id | []integer | false | filter in tasks assigned to these teams, without expanding the teams to their members |
| assignee_user_id | []integer | false | filter in tasks by assignee's user IDs |
| tag_id | []integer | false | filter in tasks by tag IDs |
| recurring | boolean | false | filter by recurring tasks |
| recurring_task_ids | []integer | false | filter by recurring task ids |
| ids | []integer | false | only these tasks, up to 100; the list is still paged (default 20), so set per_page to the id count. Without occurrence_window_date or occurrence_window_days the occurrence window is off; templates and draft-project tasks the caller may see are included. Other filters and the caller's visibility still apply. |
| client_id | []integer | false | filter by client ids. ?client_id= will include tasks with no client. |
| include_rates | boolean | false | includes the parent projects' rate data |
| include_assignees | boolean | false | includes the unified user and team assignees |
| include_parent_matches | boolean | false | when true, the name filter also matches the parent task's name, returning subtasks whose parent matches |
| disable_aggregations | boolean | false | when true, skips computing aggregations and parent task hydration for faster response |
| cf_filter | []string | false | filter by the task's own custom field values. Repeatable; each entry is 'fieldID:value1,value2' (values within an entry are OR, separate entries AND). Trailing colon 'fieldID:' selects the no-value bucket (select/multi_select only). Predicate vocabulary mirrors the project list cf_filter. |
Response
200
| Name | Type | Description |
|---|
| data | Array of object | - |
| page | integer | - |
| per_page | integer | - |
| total | integer | - |
data
| Name | Type | Description |
|---|
| allocation_unit | string | Valid values: percent, flat. |
| archived_at | string | - |
| assignee_user_ids | Array of integer | - |
| assignees | Array of object | A unified column for all task entity assignments |
| auto_log_time | boolean | - |
| billable | boolean | null |
| client | object | - |
| color | string | - |
| created_at | string | - |
| custom_field_values | Array of object | - |
| deleted_at | string | - |
| description | string | - |
| end_date | string | - |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | - |
| id | integer | - |
| is_recurring_series | boolean | IsRecurringSeries marks a canonical series root (S). Server-owned and read-only: no current API path can set it, and the response only exposes the marker while series behavior stays disabled. |
| is_template | boolean | - |
| metadata | object | - |
| name | string | - |
| notes | string | - |
| parent | object | - |
| parent_task_id | integer | - |
| parent_task_name | string | - |
| pinned | boolean | - |
| position | integer | - |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | - |
| private | boolean | - |
| project | object | - |
| project_id | integer | - |
| recurrence_date | string | - |
| recurring_rule | string | The rule of the task's series (RRULE with DTSTART); omitted for a normal task and once the series has stopped. |
| recurring_series_id | integer | The series this task is an occurrence of; omitted for a normal task. Only the server sets it. |
| recurring_task_id | integer | - |
| rollup_enabled | boolean | - |
| rrule | string | - |
| source | string | - |
| source_template_task_id | integer | - |
| start_date | string | - |
| status | object | - |
| status_id | integer | - |
| status_updated_at | string | - |
| sub_task_done_count | integer | - |
| sub_task_total_count | integer | - |
| tag_ids | Array of integer | - |
| tags | Array of object | - |
| time_entry_total_count | integer | - |
| toggl_user_id | integer | - |
| total_tracked_time | integer | - |
| updated_at | string | - |
| workspace_id | integer | - |
assignees
| Name | Type | Description |
|---|
| id | integer | - |
| type | string | Valid values: user, team. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
| Name | Type | Description |
|---|
| all_day | boolean | - |
| calendar_event_id | integer | - |
| calendar_id | integer | - |
| event_classification | string | EventClassification is the calendar provider's own classification of the event behind this task, normalised by the calendar service — see calmodels.EventClassification for the values. Absent when the provider reported no classification. |
| extension_source | string | Browser-extension provenance: the source/config that produced the task and the page URL it was tracked from. Written by the extension's start-from-description flow; ExtensionURL is queryable via FindByURL. |
| extension_url | string | - |
| external_id | string | - |
| ical_uid | string | - |
| last_asserted_track_project_id | integer | LastAssertedTrackProjectID is the Track planned_task.project_id that the Focus→Track mirror last successfully wrote for this task. Track→Focus uses it to distinguish a stale echo (Track still holds this value after a Focus-side project move) from an intentional Track-side project move. Internal mirror state, written by toggl_api focus_sync_worker; not user-facing. |
| last_integration_dates | object | LastIntegrationDates are the start and end dates the task's integration last sent. Integration sync overwrites the task's dates only when the source's dates differ from these, so dates set in Focus survive unrelated source edits. Internal sync state; not user-facing. |
| meeting_link | string | - |
| project_assignment | object | - |
| updated_at | string | - |
last_integration_dates
| Name | Type | Description |
|---|
| end | string | - |
| start | string | - |
project_assignment
| Name | Type | Description |
|---|
| accuracy | number | - |
| confirmed_at | string | - |
| match_tier | string | Valid values: exact_name, similar_name. |
| matched_name | string | - |
| normalized_name | string | - |
| origin | string | Valid values: manual, auto_suggestion, confirmed_suggestion, integration, legacy, explicit_mapping. |
| suggested_at | string | - |
parent
| Name | Type | Description |
|---|
| allocation_unit | string | Valid values: percent, flat. |
| archived_at | string | - |
| assignee_user_ids | Array of integer | - |
| assignees | Array of object | A unified column for all task entity assignments |
| auto_log_time | boolean | - |
| billable | boolean | null |
| client | object | - |
| color | string | - |
| created_at | string | - |
| custom_field_values | Array of object | - |
| deleted_at | string | - |
| description | string | - |
| end_date | string | - |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | - |
| id | integer | - |
| is_recurring_series | boolean | IsRecurringSeries marks a canonical series root (S). Server-owned and read-only: no current API path can set it, and the response only exposes the marker while series behavior stays disabled. |
| is_template | boolean | - |
| metadata | object | - |
| name | string | - |
| notes | string | - |
| parent_task_id | integer | - |
| parent_task_name | string | - |
| pinned | boolean | - |
| position | integer | - |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | - |
| private | boolean | - |
| project | object | - |
| project_id | integer | - |
| recurrence_date | string | - |
| recurring_rule | string | The rule of the task's series (RRULE with DTSTART); omitted for a normal task and once the series has stopped. |
| recurring_series_id | integer | The series this task is an occurrence of; omitted for a normal task. Only the server sets it. |
| recurring_task_id | integer | - |
| rollup_enabled | boolean | - |
| rrule | string | - |
| source | string | - |
| source_template_task_id | integer | - |
| start_date | string | - |
| status | object | - |
| status_id | integer | - |
| status_updated_at | string | - |
| tag_ids | Array of integer | - |
| tags | Array of object | - |
| toggl_user_id | integer | - |
| updated_at | string | - |
| workspace_id | integer | - |
assignees
| Name | Type | Description |
|---|
| id | integer | - |
| type | string | Valid values: user, team. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
| Name | Type | Description |
|---|
| all_day | boolean | - |
| calendar_event_id | integer | - |
| calendar_id | integer | - |
| event_classification | string | EventClassification is the calendar provider's own classification of the event behind this task, normalised by the calendar service — see calmodels.EventClassification for the values. Absent when the provider reported no classification. |
| extension_source | string | Browser-extension provenance: the source/config that produced the task and the page URL it was tracked from. Written by the extension's start-from-description flow; ExtensionURL is queryable via FindByURL. |
| extension_url | string | - |
| external_id | string | - |
| ical_uid | string | - |
| last_asserted_track_project_id | integer | LastAssertedTrackProjectID is the Track planned_task.project_id that the Focus→Track mirror last successfully wrote for this task. Track→Focus uses it to distinguish a stale echo (Track still holds this value after a Focus-side project move) from an intentional Track-side project move. Internal mirror state, written by toggl_api focus_sync_worker; not user-facing. |
| last_integration_dates | object | LastIntegrationDates are the start and end dates the task's integration last sent. Integration sync overwrites the task's dates only when the source's dates differ from these, so dates set in Focus survive unrelated source edits. Internal sync state; not user-facing. |
| meeting_link | string | - |
| project_assignment | object | - |
| updated_at | string | - |
last_integration_dates
| Name | Type | Description |
|---|
| end | string | - |
| start | string | - |
project_assignment
| Name | Type | Description |
|---|
| accuracy | number | - |
| confirmed_at | string | - |
| match_tier | string | Valid values: exact_name, similar_name. |
| matched_name | string | - |
| normalized_name | string | - |
| origin | string | Valid values: manual, auto_suggestion, confirmed_suggestion, integration, legacy, explicit_mapping. |
| suggested_at | string | - |
project
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| client | object | - |
| color | string | - |
| custom_field_values | Array of object | CustomFieldValues are the parent project's CF values, hydrated by callers that surface them (currently the task list, via task.service.hydrateTaskProjectCustomFieldValues which routes through customfield.Service.GetFieldsByIDs and respects the PermissionViewWorkspaceProjectCustomFields gate). Producers that don't hydrate (e.g. timeentry) leave the slice empty; omitempty hides it on those responses. |
| draft | boolean | - |
| estimate_source | string | Valid values: manual, tasks, designation. |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
| recurring_project_id | integer | RecurringProjectID links an instance to its recurring template, so clients can lane an entry under a collapsed series. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
rate
| Name | Type | Description |
|---|
| billable | boolean | - |
| currency | string | - |
| end_at | string | - |
| has_more_rates | boolean | - |
| hourly_rate | number | - |
| project_color | string | - |
| project_created_at | string | - |
| project_id | integer | - |
| project_name | string | - |
| project_rate_id | integer | - |
| start_at | string | - |
| workspace_rate_id | integer | - |
status
| Name | Type | Description |
|---|
| emoji | string | - |
| id | integer | - |
| name | string | - |
| type | string | Valid values: todo, done, in_progress, blocked. |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
project
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| client | object | - |
| color | string | - |
| custom_field_values | Array of object | CustomFieldValues are the parent project's CF values, hydrated by callers that surface them (currently the task list, via task.service.hydrateTaskProjectCustomFieldValues which routes through customfield.Service.GetFieldsByIDs and respects the PermissionViewWorkspaceProjectCustomFields gate). Producers that don't hydrate (e.g. timeentry) leave the slice empty; omitempty hides it on those responses. |
| draft | boolean | - |
| estimate_source | string | Valid values: manual, tasks, designation. |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
| recurring_project_id | integer | RecurringProjectID links an instance to its recurring template, so clients can lane an entry under a collapsed series. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
rate
| Name | Type | Description |
|---|
| billable | boolean | - |
| currency | string | - |
| end_at | string | - |
| has_more_rates | boolean | - |
| hourly_rate | number | - |
| project_color | string | - |
| project_created_at | string | - |
| project_id | integer | - |
| project_name | string | - |
| project_rate_id | integer | - |
| start_at | string | - |
| workspace_rate_id | integer | - |
status
| Name | Type | Description |
|---|
| emoji | string | - |
| id | integer | - |
| name | string | - |
| type | string | Valid values: todo, done, in_progress, blocked. |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
400
Invalid request
500
Internal Server Error
POST Create a new task
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks
Creates a new task with the provided details. Omitted private inherits the parent task, then project visibility, then the effective workspace default, gated by private-feature access. Project-less tasks default to private when the role requires it and the plan permits it. With the recurring_create_paths beta flag on (and repeating tasks enabled), rrule makes a repeating task the way recurring_rule does; a start date that is not one of the rule's dates moves to the rule's next date, and the task keeps its length.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X POST https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks \
-H "Content-Type: application/json" \
-d '\{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_rule":"string","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}' \
-u <email>:<password>
bytes, err := json.Marshal('\{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_rule":"string","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}')
if err != nil {
print(err)
}
req, err := http.NewRequest(http.MethodPost,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks", bytes.NewBuffer(bytes))
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "application/json"
req.body = \{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_rule":"string","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}.to_json
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks", {
method: "POST",
body: \{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_rule":"string","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\},
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.post('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks', json=\{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_rule":"string","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}, headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::POST, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks".to_string())
.json(&serde_json::json!(\{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_rule":"string","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}))
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
Body
| Name | Type | Description |
|---|
| allocation_unit | string | Valid values: percent, flat. |
| assignee_user_ids | Array of integer | - |
| auto_log_time | boolean | - |
| billable | boolean | - |
| color | string | - |
| custom_fields | object | - |
| description | string | - |
| end_date | string | Send together with start_date; must be on or after start_date. |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | - |
| name | string | - |
| notes | string | - |
| parent_task_id | integer | - |
| pinned | boolean | - |
| position | integer | null |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | - |
| private | boolean | - |
| project_id | integer | - |
| recurring_rule | string | null |
| rollup_enabled | boolean | - |
| rrule | string | null |
| start_date | string | Send together with end_date; a date without the other is rejected. |
| status_id | integer | - |
| tag_ids | Array of integer | - |
| team_assignee_ids | Array of integer | - |
custom_fields
Response
201
Task created successfully
400
Invalid request; for a repeating task (recurring_rule, or rrule with the recurring_create_paths beta flag on): a rule that is not supported (error=recurring_rule_not_supported) or repeats more often than the task lasts (error=recurring_rule_too_frequent); a subtask (error=recurring_subtask), a task in a template project (error=recurring_on_template), a rolled-up task (error=task_rollup_cannot_recur) or a task in an archived project (error=recurring_archived_project)
402
Not available on the current plan
403
Insufficient permissions, or repeating tasks are not enabled (error=feature_not_enabled)
500
Internal Server Error
503
Beta features service unavailable (error=beta_features_unavailable)
POST Creates tasks in bulk
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk
Creates tasks in bulk with the provided details. Omitted private uses the same context, workspace default, and role rules as single-task creation.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X POST https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk \
-H "Content-Type: application/json" \
-d '\{"tasks":[\{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}]\}' \
-u <email>:<password>
bytes, err := json.Marshal('\{"tasks":[\{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}]\}')
if err != nil {
print(err)
}
req, err := http.NewRequest(http.MethodPost,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk", bytes.NewBuffer(bytes))
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "application/json"
req.body = \{"tasks":[\{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}]\}.to_json
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk", {
method: "POST",
body: \{"tasks":[\{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}]\},
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.post('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk', json=\{"tasks":[\{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}]\}, headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::POST, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk".to_string())
.json(&serde_json::json!(\{"tasks":[\{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}]\}))
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
Body
| Name | Type | Description |
|---|
| tasks | Array of object | - |
tasks
| Name | Type | Description |
|---|
| allocation_unit | string | Valid values: percent, flat. |
| assignee_user_ids | Array of integer | - |
| auto_log_time | boolean | - |
| billable | boolean | - |
| color | string | - |
| custom_fields | object | - |
| description | string | - |
| end_date | string | Send together with start_date; must be on or after start_date. |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | - |
| name | string | - |
| notes | string | - |
| parent_task_id | integer | - |
| pinned | boolean | - |
| position | integer | null |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | - |
| private | boolean | - |
| project_id | integer | - |
| rollup_enabled | boolean | - |
| rrule | string | null |
| start_date | string | Send together with end_date; a date without the other is rejected. |
| status_id | integer | - |
| tag_ids | Array of integer | - |
| team_assignee_ids | Array of integer | - |
custom_fields
Response
201
Tasks created successfully
400
Invalid request
402
Not available on the current plan
403
Insufficient permissions
500
Internal Server Error
DELETE Delete tasks by ID
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk
Deletes tasks by the provided IDs. An occurrence of a series made with recurring_rule is deleted alone (there is no scope).
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X DELETE https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk \
-H "Content-Type: application/json" \
-u <email>:<password>
req, err := http.NewRequest(http.MethodPut,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk")
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk')
req = Net::HTTP::Delete.new(uri)
req['Content-Type'] = "application/json"
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk", {
method: "DELETE",
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.delete('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk', headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::DELETE, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk".to_string())
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
Query
| name | type | required | description |
|---|
| ids | []integer | true | task IDs |
| outbound_sync | boolean | false | Conduct outbound sync or not |
| move_time_to_task_id | integer | false | Move the logged time the caller may edit to this task (in the project of every deleted task, live, not being deleted) instead of leaving it taskless; locked entries stay taskless |
Response
204
No Content
400
Invalid request, or move_time_to_task_id is in another project (error=move_time_target_project_mismatch) or is being deleted (error=move_time_target_deleted)
402
Not available on the current plan
403
Insufficient permissions
404
The task in move_time_to_task_id does not exist
409
A task's series changed while its next date was being added, try again (error=recurring_series_changed)
500
Internal Server Error
PATCH Partially update tasks in bulk
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk
Partially update existing tasks in bulk. position and after_task_id are mutually exclusive, and after_task_id may not name another task updated in the same request: items are applied in ascending task id and each anchor resolves against committed state. On an occurrence of a series made with recurring_rule, an item changes only that occurrence (there is no scope).
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X PATCH https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk \
-H "Content-Type: application/json" \
-d '[\{"after_task_id":"integer","allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","id":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_task_id":"integer","repeat_planned_time_entry_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}]'
bytes, err := json.Marshal('[\{"after_task_id":"integer","allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","id":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_task_id":"integer","repeat_planned_time_entry_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}]')
if err != nil {
print(err)
}
req, err := http.NewRequest(http.MethodGet,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk", bytes.NewBuffer(bytes))
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk')
req = Net::HTTP::Patch.new(uri)
req['Content-Type'] = "application/json"
req.body = [\{"after_task_id":"integer","allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","id":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_task_id":"integer","repeat_planned_time_entry_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}].to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk", {
method: "PATCH",
body: [\{"after_task_id":"integer","allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","id":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_task_id":"integer","repeat_planned_time_entry_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}],
headers: {
"Content-Type": "application/json"
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.patch('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk', json=[\{"after_task_id":"integer","allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","id":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_task_id":"integer","repeat_planned_time_entry_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}], headers={'content-type': 'application/json'})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new();
let json = client.request(Method::PATCH, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk".to_string())
.json(&serde_json::json!([\{"after_task_id":"integer","allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","id":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_task_id":"integer","repeat_planned_time_entry_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}]))
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
Body
| Name | Type | Description |
|---|
| items | Array of object | - |
items
| Name | Type | Description |
|---|
| after_task_id | integer | null |
| allocation_unit | string | Valid values: percent, flat. |
| assignee_user_ids | Array of integer | - |
| auto_log_time | boolean | null |
| billable | boolean | null |
| color | string | null |
| custom_fields | object | - |
| description | string | null |
| end_date | string | null |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | null |
| id | integer | - |
| name | string | - |
| notes | string | null |
| outbound_sync | boolean | - |
| parent_task_id | integer | null |
| pinned | boolean | Deprecated: use POST or DELETE .../tasks/{task_id}/pinned. Sets the current user's own pin only. |
| position | integer | null |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | null |
| private | boolean | - |
| project_id | integer | null |
| recurring_task_id | integer | null |
| repeat_planned_time_entry_id | integer | null |
| rollup_enabled | boolean | - |
| rrule | string | null |
| start_date | string | null |
| status_id | integer | - |
| tag_ids | Array of integer | - |
| team_assignee_ids | Array of integer | - |
custom_fields
Response
204
No Content
400
Invalid request
402
Not available on the current plan
403
Insufficient permissions
409
Tags are required, and removing the tags would leave time entries without tags (error=would_leave_time_entries_without_tags); a task's series changed while its next date was being added, try again (error=recurring_series_changed); rrule or recurring_task_id sent for an occurrence of a series made with recurring_rule, from an app that needs an update or a reload (error=recurring_client_outdated)
500
Internal Server Error
POST Bulk archives tasks given their IDs
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk/archive
Bulk archives tasks, and their children given their IDs. An ID
with no task behind it is skipped rather than failing the batch;
archive a single task if you need a missing one reported. An
occurrence of a series made with recurring_rule is archived alone
(there is no scope).
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X POST https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk/archive \
-H "Content-Type: application/json" \
-d '\{"task_ids":[\{\}]\}' \
-u <email>:<password>
bytes, err := json.Marshal('\{"task_ids":[\{\}]\}')
if err != nil {
print(err)
}
req, err := http.NewRequest(http.MethodPost,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk/archive", bytes.NewBuffer(bytes))
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk/archive')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "application/json"
req.body = \{"task_ids":[\{\}]\}.to_json
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk/archive", {
method: "POST",
body: \{"task_ids":[\{\}]\},
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.post('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk/archive', json=\{"task_ids":[\{\}]\}, headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::POST, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/bulk/archive".to_string())
.json(&serde_json::json!(\{"task_ids":[\{\}]\}))
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
Body
| Name | Type | Description |
|---|
| task_ids | Array of integer | - |
Response
204
No Content
400
Invalid request
403
Insufficient permissions
500
Internal Server Error
PUT Sync tasks by calendar range
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/calendar
Deprecated: use POST /organizations/\{organization_id\}/workspaces/\{workspace_id\}/calendar/sync, which is identical. This path is retained only for clients that cannot be updated, and will be removed once its traffic reaches zero. Sync a list of tasks based on calendar events.
Pass skip_provider_refresh=true to skip the live calendar provider refresh before syncing (e.g. for a caller that knows the CalendarsEvents cache already has current provider data).
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X PUT https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/calendar \
-H "Content-Type: application/json" \
-u <email>:<password>
req, err := http.NewRequest(http.MethodPut,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/calendar")
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/calendar')
req = Net::HTTP::Put.new(uri)
req['Content-Type'] = "application/json"
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/calendar", {
method: "PUT",
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.put('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/calendar', headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::PUT, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/calendar".to_string())
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
Query
| name | type | required | description |
|---|
| date_from | string | true | from timestamp |
| date_to | string | true | to timestamp |
| skip_provider_refresh | boolean | false | skip the live calendar provider refresh before syncing (default false: refresh happens) |
Response
200
| Name | Type | Description |
|---|
| changed | integer | - |
| degraded_integrations | Array of integer | - |
| time_entries_created | integer | - |
| time_entries_materialized | integer | - |
| time_entries_relinked | integer | - |
400
Invalid request
403
Insufficient permissions
500
Internal Server Error
GET List recurring task instances
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/recurring
Returns a list of tasks based on the workspace ID.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/recurring \
-H "Content-Type: application/json" \
-u <email>:<password>
req, err := http.NewRequest(http.MethodGet,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/recurring")
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/recurring')
req = Net::HTTP::Get.new(uri)
req['Content-Type'] = "application/json"
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/recurring", {
method: "GET",
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.get('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/recurring', headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::GET, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/recurring".to_string())
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
Query
| name | type | required | description |
|---|
| page | integer | false | page number |
| per_page | integer | false | results per page |
| archived | boolean | false | filter in/out archived tasks |
| start_date | string | false | filter tasks overlapping date range (start). Used with end_date to find tasks where task.start_date <= end_date AND task.end_date >= start_date |
| end_date | string | false | filter tasks overlapping date range (end). Used with start_date to find tasks where task.start_date <= end_date AND task.end_date >= start_date |
| dates_overlap_start | string | false | [LEGACY] use start_date instead |
| dates_overlap_end | string | false | [LEGACY] use end_date instead |
| recurring_task_ids | []integer | false | filter by recurring task ids |
| team_id | []integer | false | filter recurring task instances by team IDs |
| assignee_team_id | []integer | false | filter in recurring task instances assigned to these teams, without expanding the teams to their members |
| assignee_user_id | []integer | false | filter recurring task instances by assignee's user IDs |
| tag_id | []integer | false | filter in tasks by tag IDs |
| include_assignees | boolean | false | includes the unified user and team assignees |
Response
200
| Name | Type | Description |
|---|
| data | Array of object | - |
| page | integer | - |
| per_page | integer | - |
data
| Name | Type | Description |
|---|
| allocation_unit | string | Valid values: percent, flat. |
| archived_at | string | - |
| assignee_user_ids | Array of integer | - |
| assignees | Array of object | A unified column for all task entity assignments |
| auto_log_time | boolean | - |
| billable | boolean | null |
| client | object | - |
| color | string | - |
| created_at | string | - |
| custom_field_values | Array of object | - |
| deleted_at | string | - |
| description | string | - |
| end_date | string | - |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | - |
| id | integer | - |
| is_recurring_series | boolean | IsRecurringSeries marks a canonical series root (S). Server-owned and read-only: no current API path can set it, and the response only exposes the marker while series behavior stays disabled. |
| is_template | boolean | - |
| metadata | object | - |
| name | string | - |
| notes | string | - |
| parent_task_id | integer | - |
| parent_task_name | string | - |
| pinned | boolean | - |
| position | integer | - |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | - |
| private | boolean | - |
| project | object | - |
| project_id | integer | - |
| recurrence_date | string | - |
| recurring_rule | string | The rule of the task's series (RRULE with DTSTART); omitted for a normal task and once the series has stopped. |
| recurring_series_id | integer | The series this task is an occurrence of; omitted for a normal task. Only the server sets it. |
| recurring_task_id | integer | - |
| rollup_enabled | boolean | - |
| rrule | string | - |
| source | string | - |
| source_template_task_id | integer | - |
| start_date | string | - |
| status | object | - |
| status_id | integer | - |
| status_updated_at | string | - |
| tag_ids | Array of integer | - |
| tags | Array of object | - |
| toggl_user_id | integer | - |
| updated_at | string | - |
| workspace_id | integer | - |
assignees
| Name | Type | Description |
|---|
| id | integer | - |
| type | string | Valid values: user, team. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
| Name | Type | Description |
|---|
| all_day | boolean | - |
| calendar_event_id | integer | - |
| calendar_id | integer | - |
| event_classification | string | EventClassification is the calendar provider's own classification of the event behind this task, normalised by the calendar service — see calmodels.EventClassification for the values. Absent when the provider reported no classification. |
| extension_source | string | Browser-extension provenance: the source/config that produced the task and the page URL it was tracked from. Written by the extension's start-from-description flow; ExtensionURL is queryable via FindByURL. |
| extension_url | string | - |
| external_id | string | - |
| ical_uid | string | - |
| last_asserted_track_project_id | integer | LastAssertedTrackProjectID is the Track planned_task.project_id that the Focus→Track mirror last successfully wrote for this task. Track→Focus uses it to distinguish a stale echo (Track still holds this value after a Focus-side project move) from an intentional Track-side project move. Internal mirror state, written by toggl_api focus_sync_worker; not user-facing. |
| last_integration_dates | object | LastIntegrationDates are the start and end dates the task's integration last sent. Integration sync overwrites the task's dates only when the source's dates differ from these, so dates set in Focus survive unrelated source edits. Internal sync state; not user-facing. |
| meeting_link | string | - |
| project_assignment | object | - |
| updated_at | string | - |
last_integration_dates
| Name | Type | Description |
|---|
| end | string | - |
| start | string | - |
project_assignment
| Name | Type | Description |
|---|
| accuracy | number | - |
| confirmed_at | string | - |
| match_tier | string | Valid values: exact_name, similar_name. |
| matched_name | string | - |
| normalized_name | string | - |
| origin | string | Valid values: manual, auto_suggestion, confirmed_suggestion, integration, legacy, explicit_mapping. |
| suggested_at | string | - |
project
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| client | object | - |
| color | string | - |
| custom_field_values | Array of object | CustomFieldValues are the parent project's CF values, hydrated by callers that surface them (currently the task list, via task.service.hydrateTaskProjectCustomFieldValues which routes through customfield.Service.GetFieldsByIDs and respects the PermissionViewWorkspaceProjectCustomFields gate). Producers that don't hydrate (e.g. timeentry) leave the slice empty; omitempty hides it on those responses. |
| draft | boolean | - |
| estimate_source | string | Valid values: manual, tasks, designation. |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
| recurring_project_id | integer | RecurringProjectID links an instance to its recurring template, so clients can lane an entry under a collapsed series. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
rate
| Name | Type | Description |
|---|
| billable | boolean | - |
| currency | string | - |
| end_at | string | - |
| has_more_rates | boolean | - |
| hourly_rate | number | - |
| project_color | string | - |
| project_created_at | string | - |
| project_id | integer | - |
| project_name | string | - |
| project_rate_id | integer | - |
| start_at | string | - |
| workspace_rate_id | integer | - |
status
| Name | Type | Description |
|---|
| emoji | string | - |
| id | integer | - |
| name | string | - |
| type | string | Valid values: todo, done, in_progress, blocked. |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
400
Invalid request
500
Internal Server Error
GET List tasks, streaming the response
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/stream
Returns a list of tasks based on the workspace ID.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/stream \
-H "Content-Type: application/json" \
-u <email>:<password>
req, err := http.NewRequest(http.MethodGet,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/stream")
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/stream')
req = Net::HTTP::Get.new(uri)
req['Content-Type'] = "application/json"
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/stream", {
method: "GET",
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.get('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/stream', headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::GET, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/stream".to_string())
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
Query
| name | type | required | description |
|---|
| with_entries | boolean | false | include time entries |
| pinned | boolean | false | filter by tasks the current user has pinned |
| order_by | []string | false | order by. tag_ids and assignees order by the canonicalized (sorted) array, so tasks with the same set of tags or assignees cluster together regardless of storage order. Also accepts pcf_<id> / -pcf_<id> to sort tasks by the named custom field on the task's parent project, and cf_<id> / -cf_<id> to sort by the task's own custom field. Multi_select and users CF types use the same canonicalized-array semantics. project_name orders by project name (case-insensitive), then project ID, so same-named projects stay separate groups; tasks without a project sort last ascending and first descending. sub_tasks_grouped orders top-level tasks by name (direction applies) with each task's subtasks directly after it in position order; it cannot be combined with other order_by values. |
| status_id | []integer | false | filter in tasks by their status' ID |
| toggl_user_id | integer | false | filter in tasks by user |
| name | string | false | filter tasks by task name, project name, or client name |
| include_parent_matches | boolean | false | when true, the name filter also matches the parent task's name, returning subtasks whose parent matches |
| has_time_entries | boolean | false | filter tasks if it has time entries |
| has_dates | boolean | false | filter tasks by date presence: true returns tasks with start_date or end_date, false returns tasks with both dates NULL |
| private | boolean | false | filter tasks by private state |
| archived | boolean | false | filter in/out archived tasks |
| active_project | boolean | false | Only tasks without a project or in a live, non-archived, non-completed, non-template, non-draft project. |
| include_project_completed | boolean | false | include tasks whose parent project is completed (default false hides them; tasks without a project are always returned) |
| include_drafts | boolean | false | include tasks belonging to draft projects (default false hides them; requires view_draft_projects permission; tasks without a project are always returned) |
| project_id | []integer | false | filter by project ids. ?project_id= will include tasks with no project. |
| parent_task_id | []integer | false | filter by parent task ids. ?parent_task_id= will include tasks with no parent. |
| start_date | string | false | filter tasks overlapping date range (start). Used with end_date to find tasks where task.start_date <= end_date AND task.end_date >= start_date |
| end_date | string | false | filter tasks overlapping date range (end). Used with start_date to find tasks where task.start_date <= end_date AND task.end_date >= start_date |
| active_by_date | string | false | filter tasks active by a date (today_and_overdue preset): returns tasks that have at least one date and whose start_date is null or on or before the date; end_date is not upper-bounded so overdue tasks remain included |
| start_date_from | string | false | [LEGACY] use start_date instead |
| start_date_to | string | false | [LEGACY] use start_date instead |
| end_date_from | string | false | [LEGACY] use end_date instead |
| end_date_to | string | false | [LEGACY] use end_date instead |
| dates_overlap_start | string | false | [LEGACY] use start_date instead |
| dates_overlap_end | string | false | [LEGACY] use end_date instead |
| occurrence_window_date | string | false | Repeats of a recurring task dated after this date + occurrence_window_days are hidden; earlier ones show. Default: today (UTC). |
| occurrence_window_days | integer | false | Days after occurrence_window_date, 0–31. Default: 7. Ignored with end_date or active_by_date. |
| estimated_mins_min | integer | false | filter by estimated mins min |
| estimated_mins_max | integer | false | filter by estimated mins max |
| source | []string | false | filter by sources |
| priority | []string | false | filter by priority |
| is_priority | boolean | false | filter by whether task is a user priority |
| state | []string | false | filter by state |
| team_id | []integer | false | filter tasks by team IDs |
| assignee_team_id | []integer | false | filter in tasks assigned to these teams, without expanding the teams to their members |
| assignee_user_id | []integer | false | filter in tasks by assignee's user IDs |
| tag_id | []integer | false | filter in tasks by tag IDs |
| recurring | boolean | false | filter by recurring tasks |
| recurring_task_ids | []integer | false | filter by recurring task ids |
| ids | []integer | false | only these tasks, up to 100. Without occurrence_window_date or occurrence_window_days the occurrence window is off; templates and draft-project tasks the caller may see are included. Other filters and the caller's visibility still apply. |
| client_id | []integer | false | filter by client ids. ?client_id= will include tasks with no client. |
| include_assignees | boolean | false | includes the unified user and team assignees |
| cf_filter | []string | false | filter by the task's own custom field values. Repeatable; each entry is 'fieldID:value1,value2' (values within an entry are OR, separate entries AND). Trailing colon 'fieldID:' selects the no-value bucket (select/multi_select only). Predicate vocabulary mirrors the project list cf_filter. |
Response
200
| Name | Type | Description |
|---|
| items | Array of object | - |
items
| Name | Type | Description |
|---|
| allocation_unit | string | Valid values: percent, flat. |
| archived_at | string | - |
| assignee_user_ids | Array of integer | - |
| assignees | Array of object | A unified column for all task entity assignments |
| auto_log_time | boolean | - |
| billable | boolean | null |
| client | object | - |
| color | string | - |
| created_at | string | - |
| custom_field_values | Array of object | - |
| deleted_at | string | - |
| description | string | - |
| end_date | string | - |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | - |
| id | integer | - |
| is_recurring_series | boolean | IsRecurringSeries marks a canonical series root (S). Server-owned and read-only: no current API path can set it, and the response only exposes the marker while series behavior stays disabled. |
| is_template | boolean | - |
| metadata | object | - |
| name | string | - |
| notes | string | - |
| parent | object | - |
| parent_task_id | integer | - |
| parent_task_name | string | - |
| pinned | boolean | - |
| position | integer | - |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | - |
| private | boolean | - |
| project | object | - |
| project_id | integer | - |
| recurrence_date | string | - |
| recurring_rule | string | The rule of the task's series (RRULE with DTSTART); omitted for a normal task and once the series has stopped. |
| recurring_series_id | integer | The series this task is an occurrence of; omitted for a normal task. Only the server sets it. |
| recurring_task_id | integer | - |
| rollup_enabled | boolean | - |
| rrule | string | - |
| source | string | - |
| source_template_task_id | integer | - |
| start_date | string | - |
| status | object | - |
| status_id | integer | - |
| status_updated_at | string | - |
| sub_task_done_count | integer | - |
| sub_task_total_count | integer | - |
| tag_ids | Array of integer | - |
| tags | Array of object | - |
| time_entry_total_count | integer | - |
| toggl_user_id | integer | - |
| total_tracked_time | integer | - |
| updated_at | string | - |
| workspace_id | integer | - |
assignees
| Name | Type | Description |
|---|
| id | integer | - |
| type | string | Valid values: user, team. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
| Name | Type | Description |
|---|
| all_day | boolean | - |
| calendar_event_id | integer | - |
| calendar_id | integer | - |
| event_classification | string | EventClassification is the calendar provider's own classification of the event behind this task, normalised by the calendar service — see calmodels.EventClassification for the values. Absent when the provider reported no classification. |
| extension_source | string | Browser-extension provenance: the source/config that produced the task and the page URL it was tracked from. Written by the extension's start-from-description flow; ExtensionURL is queryable via FindByURL. |
| extension_url | string | - |
| external_id | string | - |
| ical_uid | string | - |
| last_asserted_track_project_id | integer | LastAssertedTrackProjectID is the Track planned_task.project_id that the Focus→Track mirror last successfully wrote for this task. Track→Focus uses it to distinguish a stale echo (Track still holds this value after a Focus-side project move) from an intentional Track-side project move. Internal mirror state, written by toggl_api focus_sync_worker; not user-facing. |
| last_integration_dates | object | LastIntegrationDates are the start and end dates the task's integration last sent. Integration sync overwrites the task's dates only when the source's dates differ from these, so dates set in Focus survive unrelated source edits. Internal sync state; not user-facing. |
| meeting_link | string | - |
| project_assignment | object | - |
| updated_at | string | - |
last_integration_dates
| Name | Type | Description |
|---|
| end | string | - |
| start | string | - |
project_assignment
| Name | Type | Description |
|---|
| accuracy | number | - |
| confirmed_at | string | - |
| match_tier | string | Valid values: exact_name, similar_name. |
| matched_name | string | - |
| normalized_name | string | - |
| origin | string | Valid values: manual, auto_suggestion, confirmed_suggestion, integration, legacy, explicit_mapping. |
| suggested_at | string | - |
parent
| Name | Type | Description |
|---|
| allocation_unit | string | Valid values: percent, flat. |
| archived_at | string | - |
| assignee_user_ids | Array of integer | - |
| assignees | Array of object | A unified column for all task entity assignments |
| auto_log_time | boolean | - |
| billable | boolean | null |
| client | object | - |
| color | string | - |
| created_at | string | - |
| custom_field_values | Array of object | - |
| deleted_at | string | - |
| description | string | - |
| end_date | string | - |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | - |
| id | integer | - |
| is_recurring_series | boolean | IsRecurringSeries marks a canonical series root (S). Server-owned and read-only: no current API path can set it, and the response only exposes the marker while series behavior stays disabled. |
| is_template | boolean | - |
| metadata | object | - |
| name | string | - |
| notes | string | - |
| parent_task_id | integer | - |
| parent_task_name | string | - |
| pinned | boolean | - |
| position | integer | - |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | - |
| private | boolean | - |
| project | object | - |
| project_id | integer | - |
| recurrence_date | string | - |
| recurring_rule | string | The rule of the task's series (RRULE with DTSTART); omitted for a normal task and once the series has stopped. |
| recurring_series_id | integer | The series this task is an occurrence of; omitted for a normal task. Only the server sets it. |
| recurring_task_id | integer | - |
| rollup_enabled | boolean | - |
| rrule | string | - |
| source | string | - |
| source_template_task_id | integer | - |
| start_date | string | - |
| status | object | - |
| status_id | integer | - |
| status_updated_at | string | - |
| tag_ids | Array of integer | - |
| tags | Array of object | - |
| toggl_user_id | integer | - |
| updated_at | string | - |
| workspace_id | integer | - |
assignees
| Name | Type | Description |
|---|
| id | integer | - |
| type | string | Valid values: user, team. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
| Name | Type | Description |
|---|
| all_day | boolean | - |
| calendar_event_id | integer | - |
| calendar_id | integer | - |
| event_classification | string | EventClassification is the calendar provider's own classification of the event behind this task, normalised by the calendar service — see calmodels.EventClassification for the values. Absent when the provider reported no classification. |
| extension_source | string | Browser-extension provenance: the source/config that produced the task and the page URL it was tracked from. Written by the extension's start-from-description flow; ExtensionURL is queryable via FindByURL. |
| extension_url | string | - |
| external_id | string | - |
| ical_uid | string | - |
| last_asserted_track_project_id | integer | LastAssertedTrackProjectID is the Track planned_task.project_id that the Focus→Track mirror last successfully wrote for this task. Track→Focus uses it to distinguish a stale echo (Track still holds this value after a Focus-side project move) from an intentional Track-side project move. Internal mirror state, written by toggl_api focus_sync_worker; not user-facing. |
| last_integration_dates | object | LastIntegrationDates are the start and end dates the task's integration last sent. Integration sync overwrites the task's dates only when the source's dates differ from these, so dates set in Focus survive unrelated source edits. Internal sync state; not user-facing. |
| meeting_link | string | - |
| project_assignment | object | - |
| updated_at | string | - |
last_integration_dates
| Name | Type | Description |
|---|
| end | string | - |
| start | string | - |
project_assignment
| Name | Type | Description |
|---|
| accuracy | number | - |
| confirmed_at | string | - |
| match_tier | string | Valid values: exact_name, similar_name. |
| matched_name | string | - |
| normalized_name | string | - |
| origin | string | Valid values: manual, auto_suggestion, confirmed_suggestion, integration, legacy, explicit_mapping. |
| suggested_at | string | - |
project
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| client | object | - |
| color | string | - |
| custom_field_values | Array of object | CustomFieldValues are the parent project's CF values, hydrated by callers that surface them (currently the task list, via task.service.hydrateTaskProjectCustomFieldValues which routes through customfield.Service.GetFieldsByIDs and respects the PermissionViewWorkspaceProjectCustomFields gate). Producers that don't hydrate (e.g. timeentry) leave the slice empty; omitempty hides it on those responses. |
| draft | boolean | - |
| estimate_source | string | Valid values: manual, tasks, designation. |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
| recurring_project_id | integer | RecurringProjectID links an instance to its recurring template, so clients can lane an entry under a collapsed series. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
rate
| Name | Type | Description |
|---|
| billable | boolean | - |
| currency | string | - |
| end_at | string | - |
| has_more_rates | boolean | - |
| hourly_rate | number | - |
| project_color | string | - |
| project_created_at | string | - |
| project_id | integer | - |
| project_name | string | - |
| project_rate_id | integer | - |
| start_at | string | - |
| workspace_rate_id | integer | - |
status
| Name | Type | Description |
|---|
| emoji | string | - |
| id | integer | - |
| name | string | - |
| type | string | Valid values: todo, done, in_progress, blocked. |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
project
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| client | object | - |
| color | string | - |
| custom_field_values | Array of object | CustomFieldValues are the parent project's CF values, hydrated by callers that surface them (currently the task list, via task.service.hydrateTaskProjectCustomFieldValues which routes through customfield.Service.GetFieldsByIDs and respects the PermissionViewWorkspaceProjectCustomFields gate). Producers that don't hydrate (e.g. timeentry) leave the slice empty; omitempty hides it on those responses. |
| draft | boolean | - |
| estimate_source | string | Valid values: manual, tasks, designation. |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
| recurring_project_id | integer | RecurringProjectID links an instance to its recurring template, so clients can lane an entry under a collapsed series. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
rate
| Name | Type | Description |
|---|
| billable | boolean | - |
| currency | string | - |
| end_at | string | - |
| has_more_rates | boolean | - |
| hourly_rate | number | - |
| project_color | string | - |
| project_created_at | string | - |
| project_id | integer | - |
| project_name | string | - |
| project_rate_id | integer | - |
| start_at | string | - |
| workspace_rate_id | integer | - |
status
| Name | Type | Description |
|---|
| emoji | string | - |
| id | integer | - |
| name | string | - |
| type | string | Valid values: todo, done, in_progress, blocked. |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
400
Invalid request
500
Internal Server Error
GET Get a task by ID
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}
Returns a task by the provided ID.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id} \
-H "Content-Type: application/json" \
-u <email>:<password>
req, err := http.NewRequest(http.MethodGet,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}")
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}')
req = Net::HTTP::Get.new(uri)
req['Content-Type'] = "application/json"
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}", {
method: "GET",
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.get('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}', headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::GET, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}".to_string())
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
| task_id | integer | true | task ID |
Query
| name | type | required | description |
|---|
| include_assignees | boolean | false | includes the unified user and team assignees |
Response
200
| Name | Type | Description |
|---|
| allocation_unit | string | Valid values: percent, flat. |
| archived_at | string | - |
| assignee_user_ids | Array of integer | - |
| assignees | Array of object | A unified column for all task entity assignments |
| auto_log_time | boolean | - |
| billable | boolean | null |
| client | object | - |
| color | string | - |
| created_at | string | - |
| custom_field_values | Array of object | - |
| deleted_at | string | - |
| description | string | - |
| end_date | string | - |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | - |
| id | integer | - |
| is_recurring_series | boolean | IsRecurringSeries marks a canonical series root (S). Server-owned and read-only: no current API path can set it, and the response only exposes the marker while series behavior stays disabled. |
| is_template | boolean | - |
| metadata | object | - |
| name | string | - |
| notes | string | - |
| parent | object | - |
| parent_task_id | integer | - |
| parent_task_name | string | - |
| pinned | boolean | - |
| position | integer | - |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | - |
| private | boolean | - |
| project | object | - |
| project_id | integer | - |
| recurrence_date | string | - |
| recurring_rule | string | The rule of the task's series (RRULE with DTSTART); omitted for a normal task and once the series has stopped. |
| recurring_series_id | integer | The series this task is an occurrence of; omitted for a normal task. Only the server sets it. |
| recurring_task_id | integer | - |
| rollup_enabled | boolean | - |
| rrule | string | - |
| source | string | - |
| source_template_task_id | integer | - |
| start_date | string | - |
| status | object | - |
| status_id | integer | - |
| status_updated_at | string | - |
| sub_task_done_count | integer | - |
| sub_task_total_count | integer | - |
| tag_ids | Array of integer | - |
| tags | Array of object | - |
| time_entry_total_count | integer | - |
| toggl_user_id | integer | - |
| total_tracked_time | integer | - |
| updated_at | string | - |
| workspace_id | integer | - |
assignees
| Name | Type | Description |
|---|
| id | integer | - |
| type | string | Valid values: user, team. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
| Name | Type | Description |
|---|
| all_day | boolean | - |
| calendar_event_id | integer | - |
| calendar_id | integer | - |
| event_classification | string | EventClassification is the calendar provider's own classification of the event behind this task, normalised by the calendar service — see calmodels.EventClassification for the values. Absent when the provider reported no classification. |
| extension_source | string | Browser-extension provenance: the source/config that produced the task and the page URL it was tracked from. Written by the extension's start-from-description flow; ExtensionURL is queryable via FindByURL. |
| extension_url | string | - |
| external_id | string | - |
| ical_uid | string | - |
| last_asserted_track_project_id | integer | LastAssertedTrackProjectID is the Track planned_task.project_id that the Focus→Track mirror last successfully wrote for this task. Track→Focus uses it to distinguish a stale echo (Track still holds this value after a Focus-side project move) from an intentional Track-side project move. Internal mirror state, written by toggl_api focus_sync_worker; not user-facing. |
| last_integration_dates | object | LastIntegrationDates are the start and end dates the task's integration last sent. Integration sync overwrites the task's dates only when the source's dates differ from these, so dates set in Focus survive unrelated source edits. Internal sync state; not user-facing. |
| meeting_link | string | - |
| project_assignment | object | - |
| updated_at | string | - |
last_integration_dates
| Name | Type | Description |
|---|
| end | string | - |
| start | string | - |
project_assignment
| Name | Type | Description |
|---|
| accuracy | number | - |
| confirmed_at | string | - |
| match_tier | string | Valid values: exact_name, similar_name. |
| matched_name | string | - |
| normalized_name | string | - |
| origin | string | Valid values: manual, auto_suggestion, confirmed_suggestion, integration, legacy, explicit_mapping. |
| suggested_at | string | - |
parent
| Name | Type | Description |
|---|
| allocation_unit | string | Valid values: percent, flat. |
| archived_at | string | - |
| assignee_user_ids | Array of integer | - |
| assignees | Array of object | A unified column for all task entity assignments |
| auto_log_time | boolean | - |
| billable | boolean | null |
| client | object | - |
| color | string | - |
| created_at | string | - |
| custom_field_values | Array of object | - |
| deleted_at | string | - |
| description | string | - |
| end_date | string | - |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | - |
| id | integer | - |
| is_recurring_series | boolean | IsRecurringSeries marks a canonical series root (S). Server-owned and read-only: no current API path can set it, and the response only exposes the marker while series behavior stays disabled. |
| is_template | boolean | - |
| metadata | object | - |
| name | string | - |
| notes | string | - |
| parent_task_id | integer | - |
| parent_task_name | string | - |
| pinned | boolean | - |
| position | integer | - |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | - |
| private | boolean | - |
| project | object | - |
| project_id | integer | - |
| recurrence_date | string | - |
| recurring_rule | string | The rule of the task's series (RRULE with DTSTART); omitted for a normal task and once the series has stopped. |
| recurring_series_id | integer | The series this task is an occurrence of; omitted for a normal task. Only the server sets it. |
| recurring_task_id | integer | - |
| rollup_enabled | boolean | - |
| rrule | string | - |
| source | string | - |
| source_template_task_id | integer | - |
| start_date | string | - |
| status | object | - |
| status_id | integer | - |
| status_updated_at | string | - |
| tag_ids | Array of integer | - |
| tags | Array of object | - |
| toggl_user_id | integer | - |
| updated_at | string | - |
| workspace_id | integer | - |
assignees
| Name | Type | Description |
|---|
| id | integer | - |
| type | string | Valid values: user, team. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
| Name | Type | Description |
|---|
| all_day | boolean | - |
| calendar_event_id | integer | - |
| calendar_id | integer | - |
| event_classification | string | EventClassification is the calendar provider's own classification of the event behind this task, normalised by the calendar service — see calmodels.EventClassification for the values. Absent when the provider reported no classification. |
| extension_source | string | Browser-extension provenance: the source/config that produced the task and the page URL it was tracked from. Written by the extension's start-from-description flow; ExtensionURL is queryable via FindByURL. |
| extension_url | string | - |
| external_id | string | - |
| ical_uid | string | - |
| last_asserted_track_project_id | integer | LastAssertedTrackProjectID is the Track planned_task.project_id that the Focus→Track mirror last successfully wrote for this task. Track→Focus uses it to distinguish a stale echo (Track still holds this value after a Focus-side project move) from an intentional Track-side project move. Internal mirror state, written by toggl_api focus_sync_worker; not user-facing. |
| last_integration_dates | object | LastIntegrationDates are the start and end dates the task's integration last sent. Integration sync overwrites the task's dates only when the source's dates differ from these, so dates set in Focus survive unrelated source edits. Internal sync state; not user-facing. |
| meeting_link | string | - |
| project_assignment | object | - |
| updated_at | string | - |
last_integration_dates
| Name | Type | Description |
|---|
| end | string | - |
| start | string | - |
project_assignment
| Name | Type | Description |
|---|
| accuracy | number | - |
| confirmed_at | string | - |
| match_tier | string | Valid values: exact_name, similar_name. |
| matched_name | string | - |
| normalized_name | string | - |
| origin | string | Valid values: manual, auto_suggestion, confirmed_suggestion, integration, legacy, explicit_mapping. |
| suggested_at | string | - |
project
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| client | object | - |
| color | string | - |
| custom_field_values | Array of object | CustomFieldValues are the parent project's CF values, hydrated by callers that surface them (currently the task list, via task.service.hydrateTaskProjectCustomFieldValues which routes through customfield.Service.GetFieldsByIDs and respects the PermissionViewWorkspaceProjectCustomFields gate). Producers that don't hydrate (e.g. timeentry) leave the slice empty; omitempty hides it on those responses. |
| draft | boolean | - |
| estimate_source | string | Valid values: manual, tasks, designation. |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
| recurring_project_id | integer | RecurringProjectID links an instance to its recurring template, so clients can lane an entry under a collapsed series. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
rate
| Name | Type | Description |
|---|
| billable | boolean | - |
| currency | string | - |
| end_at | string | - |
| has_more_rates | boolean | - |
| hourly_rate | number | - |
| project_color | string | - |
| project_created_at | string | - |
| project_id | integer | - |
| project_name | string | - |
| project_rate_id | integer | - |
| start_at | string | - |
| workspace_rate_id | integer | - |
status
| Name | Type | Description |
|---|
| emoji | string | - |
| id | integer | - |
| name | string | - |
| type | string | Valid values: todo, done, in_progress, blocked. |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
project
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| client | object | - |
| color | string | - |
| custom_field_values | Array of object | CustomFieldValues are the parent project's CF values, hydrated by callers that surface them (currently the task list, via task.service.hydrateTaskProjectCustomFieldValues which routes through customfield.Service.GetFieldsByIDs and respects the PermissionViewWorkspaceProjectCustomFields gate). Producers that don't hydrate (e.g. timeentry) leave the slice empty; omitempty hides it on those responses. |
| draft | boolean | - |
| estimate_source | string | Valid values: manual, tasks, designation. |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
| recurring_project_id | integer | RecurringProjectID links an instance to its recurring template, so clients can lane an entry under a collapsed series. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
rate
| Name | Type | Description |
|---|
| billable | boolean | - |
| currency | string | - |
| end_at | string | - |
| has_more_rates | boolean | - |
| hourly_rate | number | - |
| project_color | string | - |
| project_created_at | string | - |
| project_id | integer | - |
| project_name | string | - |
| project_rate_id | integer | - |
| start_at | string | - |
| workspace_rate_id | integer | - |
status
| Name | Type | Description |
|---|
| emoji | string | - |
| id | integer | - |
| name | string | - |
| type | string | Valid values: todo, done, in_progress, blocked. |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
400
Invalid request
403
Insufficient permissions
500
Internal Server Error
PUT Update task
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}
Update an existing task. On an occurrence of a series made with recurring_rule, it changes only that occurrence (there is no scope).
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X PUT https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id} \
-H "Content-Type: application/json" \
-d '\{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","private":"boolean","project_id":"integer","recurring_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}'
bytes, err := json.Marshal('\{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","private":"boolean","project_id":"integer","recurring_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}')
if err != nil {
print(err)
}
req, err := http.NewRequest(http.MethodPut,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}", bytes.NewBuffer(bytes))
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}')
req = Net::HTTP::Put.new(uri)
req['Content-Type'] = "application/json"
req.body = \{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","private":"boolean","project_id":"integer","recurring_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}", {
method: "PUT",
body: \{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","private":"boolean","project_id":"integer","recurring_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\},
headers: {
"Content-Type": "application/json"
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.put('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}', json=\{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","private":"boolean","project_id":"integer","recurring_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}, headers={'content-type': 'application/json'})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new();
let json = client.request(Method::PUT, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}".to_string())
.json(&serde_json::json!(\{"allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","private":"boolean","project_id":"integer","recurring_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}))
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
| task_id | integer | true | Task ID |
Body
| Name | Type | Description |
|---|
| allocation_unit | string | null |
| assignee_user_ids | Array of integer | - |
| auto_log_time | boolean | - |
| billable | boolean | null |
| color | string | - |
| custom_fields | object | - |
| description | string | - |
| end_date | string | Send together with start_date; must be on or after start_date. |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | - |
| name | string | - |
| notes | string | - |
| outbound_sync | boolean | - |
| parent_task_id | integer | - |
| pinned | boolean | Deprecated: use POST or DELETE .../tasks/{task_id}/pinned. Sets the current user's own pin only. |
| position | integer | null |
| priority | string | Valid values: none, low, medium, high. |
| private | boolean | - |
| project_id | integer | - |
| recurring_task_id | integer | - |
| rollup_enabled | boolean | - |
| rrule | string | null |
| start_date | string | Send together with end_date; a date without the other is rejected. |
| status_id | integer | - |
| tag_ids | Array of integer | - |
| team_assignee_ids | Array of integer | - |
custom_fields
Response
204
Task updated successfully
400
Invalid request
402
Not available on the current plan
403
Insufficient permissions
409
Tags are required, and removing the tags would leave time entries without tags (error=would_leave_time_entries_without_tags); the task's series changed while its next date was being added, try again (error=recurring_series_changed); rrule or recurring_task_id sent for an occurrence of a series made with recurring_rule, from an app that needs an update or a reload (error=recurring_client_outdated)
500
Internal Server Error
DELETE Delete a task by ID
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}
Deletes a task by the provided ID. On an occurrence of a series made with recurring_rule, scope=following or all deletes this occurrence and the following ones, or all of them, with their time entries, except the ones someone worked on (done, with tracked or planned time, or with attachments), which stay; following ends the series' rule and all deletes the series. outbound_sync is ignored with following or all.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X DELETE https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id} \
-H "Content-Type: application/json" \
-u <email>:<password>
req, err := http.NewRequest(http.MethodPut,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}")
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}')
req = Net::HTTP::Delete.new(uri)
req['Content-Type'] = "application/json"
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}", {
method: "DELETE",
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.delete('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}', headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::DELETE, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}".to_string())
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
| task_id | integer | true | task ID |
Query
| name | type | required | description |
|---|
| from_recurring_task_id | integer | false | delete recurring tasks starting from this recurring task instance |
| scope | string | false | For a series made with recurring_rule: delete this occurrence (the default), this and the following ones, or all |
| outbound_sync | boolean | false | Conduct outbound sync or not |
| move_time_to_task_id | integer | false | Move the logged time the caller may edit to this task (same project, live, not being deleted) instead of leaving it taskless; locked entries stay taskless |
Response
204
No Content
400
Invalid request, or a scope of following or all, or from_recurring_task_id, for a task it doesn't apply to (error=recurring_scope_not_supported); a scope of following or all for an occurrence of a deleted series (error=recurring_series_deleted); a delete over the size limit for a series (error=recurring_series_too_large); move_time_to_task_id in another project (error=move_time_target_project_mismatch) or being deleted (error=move_time_target_deleted)
402
Not available on the current plan
403
Insufficient permissions
404
The task, or the task in move_time_to_task_id, does not exist
409
The task's series changed while its next date was being added, try again (error=recurring_series_changed)
500
Internal Server Error
PATCH Partially update a task
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}
Partially update an existing task. position (an ordinal rank) and after_task_id (the neighbour to land behind) are mutually exclusive. On an occurrence of a series made with recurring_rule, scope=following or all changes name, description, notes, estimated_mins, estimate_type, allocation_unit, auto_log_time, priority, color, tag_ids, custom_fields, assignee_user_ids, team_assignee_ids, private, project_id and billable on this occurrence and the following ones, or on all of them; deleted occurrences keep their values, except that a series move moves their dates too; send other fields with scope=this. start_date and end_date with scope=following or all and no other field (outbound_sync is taken and ignored) move or resize the series. N is the new start minus this occurrence's scheduled date (recurrence_date), and L the change in its length. This occurrence takes the dates sent. Every other occurrence from it (following) or from today (all), done and archived ones too, moves its start by N and its end by N + L; deleted ones move by N and keep their length. The rule and the dates still to come move by N, so a changed end alone on an occurrence on its scheduled date changes only the end dates. Occurrences before today never move, and time entries stay where they are. With following or all, assignees the user may not set are refused, not changed to the user, to none or to the first one as with scope=this. A project_id or billable change with following or all moves the occurrences' time entries as with scope=this, and is refused when an entry it changes belongs to another user whose time entries the user may not change, or is in a submitted or approved timesheet period, unless the user approves that timesheet. recurring_rule null, sent alone with scope=following or all, stops the series: the rule ends, and the occurrences from today (or from this one, if later, with following) that nobody worked on are deleted with their time entries. A recurring_rule sent alone with scope=following or all changes the series' rule from that day on, and starts a stopped series again: the occurrences on dates the new rule doesn't give that nobody worked on are deleted with their time entries, deleted occurrences on its dates come back, each as the same task with the values a new occurrence gets and without its time entries, and its other dates get new occurrences. New and brought-back occurrences take this occurrence's length. The rule is stored in the parser's normal form, and a DTSTART after that day moves back in whole periods, so the rule runs in step from that day; such a rule is refused when moving it would change its dates, or when it ends after a number of times. DTSTART must be one of the rule's dates, in UTC. The stored rule sent again changes nothing when its DTSTART is on or before that day.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X PATCH https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id} \
-H "Content-Type: application/json" \
-d '\{"after_task_id":"integer","allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_rule":"string","recurring_task_id":"integer","repeat_planned_time_entry_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}'
bytes, err := json.Marshal('\{"after_task_id":"integer","allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_rule":"string","recurring_task_id":"integer","repeat_planned_time_entry_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}')
if err != nil {
print(err)
}
req, err := http.NewRequest(http.MethodGet,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}", bytes.NewBuffer(bytes))
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}')
req = Net::HTTP::Patch.new(uri)
req['Content-Type'] = "application/json"
req.body = \{"after_task_id":"integer","allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_rule":"string","recurring_task_id":"integer","repeat_planned_time_entry_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}", {
method: "PATCH",
body: \{"after_task_id":"integer","allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_rule":"string","recurring_task_id":"integer","repeat_planned_time_entry_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\},
headers: {
"Content-Type": "application/json"
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.patch('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}', json=\{"after_task_id":"integer","allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_rule":"string","recurring_task_id":"integer","repeat_planned_time_entry_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}, headers={'content-type': 'application/json'})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new();
let json = client.request(Method::PATCH, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}".to_string())
.json(&serde_json::json!(\{"after_task_id":"integer","allocation_unit":"string","assignee_user_ids":[\{\}],"auto_log_time":"boolean","billable":"boolean","color":"string","custom_fields":\{\},"description":"string","end_date":"string","estimate_type":"string","estimated_mins":"integer","name":"string","notes":"string","outbound_sync":"boolean","parent_task_id":"integer","pinned":"boolean","position":"integer","priority":"string","priority_at":"string","private":"boolean","project_id":"integer","recurring_rule":"string","recurring_task_id":"integer","repeat_planned_time_entry_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\}))
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
| task_id | integer | true | Task ID |
Query
| name | type | required | description |
|---|
| from_recurring_task_id | integer | false | update recurring tasks starting from this recurring instance id |
| scope | string | false | For a series made with recurring_rule: change this occurrence (the default), this and the following ones, or all |
Body
| Name | Type | Description |
|---|
| after_task_id | integer | null |
| allocation_unit | string | Valid values: percent, flat. |
| assignee_user_ids | Array of integer | - |
| auto_log_time | boolean | null |
| billable | boolean | null |
| color | string | null |
| custom_fields | object | - |
| description | string | null |
| end_date | string | null |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | null |
| name | string | - |
| notes | string | null |
| outbound_sync | boolean | - |
| parent_task_id | integer | null |
| pinned | boolean | Deprecated: use POST or DELETE .../tasks/{task_id}/pinned. Sets the current user's own pin only. |
| position | integer | null |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | null |
| private | boolean | - |
| project_id | integer | null |
| recurring_rule | string | null |
| recurring_task_id | integer | null |
| repeat_planned_time_entry_id | integer | null |
| rollup_enabled | boolean | - |
| rrule | string | null |
| start_date | string | null |
| status_id | integer | - |
| tag_ids | Array of integer | - |
| team_assignee_ids | Array of integer | - |
custom_fields
Response
204
Task updated successfully
400
Invalid request; a scope of following or all for a task it doesn't apply to, or a recurring_rule, or start_date and end_date, with it for an occurrence of an archived series (error=recurring_scope_not_supported); a scope of following or all for an occurrence of a deleted series (error=recurring_series_deleted); a recurring_rule that is not supported, or with following or all has no date from the change's start, or has a DTSTART after that start and either COUNT or dates that moving it back would change (error=recurring_rule_not_supported); a recurring_rule that repeats more often than this task or occurrence lasts (error=recurring_rule_too_frequent); a recurring_rule with following or all while the series' farthest occurrence is in an archived project (error=recurring_archived_project) or a deleted one (error=invalid_task); a project_id with following or all for an archived project (error=recurring_archived_project), or one that is deleted or doesn't exist (error=invalid_task); a field that following and all don't change, to send with scope=this (error=recurring_scope_field_not_supported); start_date and end_date with following or all that can't move the series: sent with fields other than outbound_sync, or null, for an occurrence before today, for an ended series, by days the rule can't move by, with following for an occurrence past the dates the series has made so far, moving an occurrence before today or onto or before an earlier one (deleted ones count), making an occurrence end before it starts, or making the rule repeat more often than this occurrence lasts (error=recurring_series_move_not_supported); a change over the size limit for a series (error=recurring_series_too_large); recurring_rule null without scope=following or all (error=recurring_rule_null_not_supported)
402
Not available on the current plan
403
Insufficient permissions, or repeating tasks are not enabled (error=feature_not_enabled)
404
Task not found
409
Tags are required, and removing the tags would leave time entries without tags (error=would_leave_time_entries_without_tags); the task already repeats, also for recurring_rule on an occurrence without scope=following or all (error=task_already_repeats); the task's series changed while its next date was being added, or while following or all occurrences were being changed, try again (error=recurring_series_changed); a project_id or billable change with following or all would change a time entry in a submitted or approved timesheet period, unless the user approves that timesheet (error=time_entry_locked), or a time entry of another user whose time entries the user may not change (error=recurring_others_time_entries); rrule or recurring_task_id sent for an occurrence of a series made with recurring_rule, from an app that needs an update or a reload (error=recurring_client_outdated)
500
Internal Server Error
503
Beta features service unavailable (error=beta_features_unavailable)
POST Archive a task by ID
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/archive
Archives a task, and all its TEs with the provided task ID. On an occurrence of a series made with recurring_rule, scope=following or all archives this occurrence and the following ones, or all of them, done ones included, with their time entries, and archives the series, which then adds no new occurrences.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X POST https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/archive \
-H "Content-Type: application/json" \
-u <email>:<password>
req, err := http.NewRequest(http.MethodPost,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/archive")
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/archive')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "application/json"
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/archive", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.post('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/archive', headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::POST, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/archive".to_string())
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
| task_id | integer | true | task ID |
Query
| name | type | required | description |
|---|
| from_recurring_task_id | integer | false | archive recurring tasks starting from this recurring task instance |
| scope | string | false | For a series made with recurring_rule: archive this occurrence (the default), this and the following ones, or all |
Response
204
No Content
400
Invalid request, or a scope of following or all, or from_recurring_task_id, for a task it doesn't apply to (error=recurring_scope_not_supported); a scope of following or all for an occurrence of a deleted series (error=recurring_series_deleted); an archive over the size limit for a series (error=recurring_series_too_large)
403
Insufficient permissions
404
Task not found
500
Internal Server Error
GET Get a task with its children sub-tasks by ID
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/children
Returns a task and its children sub-tasks by the provided ID.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/children \
-H "Content-Type: application/json" \
-u <email>:<password>
req, err := http.NewRequest(http.MethodGet,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/children")
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/children')
req = Net::HTTP::Get.new(uri)
req['Content-Type'] = "application/json"
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/children", {
method: "GET",
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.get('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/children', headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::GET, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/children".to_string())
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
| task_id | integer | true | task ID |
Query
| name | type | required | description |
|---|
| page | integer | false | page number |
| per_page | integer | false | results per page |
| order_by | []string | false | order by. tag_ids and assignees order by the canonicalized (sorted) array, so tasks with the same set of tags or assignees cluster together regardless of storage order. |
| status_id | integer | false | filter children tasks by status ID |
| archived | boolean | false | filter in/out archived tasks |
| source | []string | false | filter by sources |
| team_id | []integer | false | filter children tasks by team IDs |
| assignee_user_id | []integer | false | filter in tasks by assignee's user IDs |
| tag_id | []integer | false | filter in tasks by tag IDs |
| include_assignees | boolean | false | includes the unified user and team assignees |
Response
200
| Name | Type | Description |
|---|
| data | Array of object | - |
| page | integer | - |
| per_page | integer | - |
data
| Name | Type | Description |
|---|
| allocation_unit | string | Valid values: percent, flat. |
| archived_at | string | - |
| assignee_user_ids | Array of integer | - |
| assignees | Array of object | A unified column for all task entity assignments |
| auto_log_time | boolean | - |
| billable | boolean | null |
| client | object | - |
| color | string | - |
| created_at | string | - |
| custom_field_values | Array of object | - |
| deleted_at | string | - |
| description | string | - |
| end_date | string | - |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | - |
| id | integer | - |
| is_recurring_series | boolean | IsRecurringSeries marks a canonical series root (S). Server-owned and read-only: no current API path can set it, and the response only exposes the marker while series behavior stays disabled. |
| is_template | boolean | - |
| metadata | object | - |
| name | string | - |
| notes | string | - |
| parent | object | - |
| parent_task_id | integer | - |
| parent_task_name | string | - |
| pinned | boolean | - |
| position | integer | - |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | - |
| private | boolean | - |
| project | object | - |
| project_id | integer | - |
| recurrence_date | string | - |
| recurring_rule | string | The rule of the task's series (RRULE with DTSTART); omitted for a normal task and once the series has stopped. |
| recurring_series_id | integer | The series this task is an occurrence of; omitted for a normal task. Only the server sets it. |
| recurring_task_id | integer | - |
| rollup_enabled | boolean | - |
| rrule | string | - |
| source | string | - |
| source_template_task_id | integer | - |
| start_date | string | - |
| status | object | - |
| status_id | integer | - |
| status_updated_at | string | - |
| sub_task_done_count | integer | - |
| sub_task_total_count | integer | - |
| tag_ids | Array of integer | - |
| tags | Array of object | - |
| time_entry_total_count | integer | - |
| toggl_user_id | integer | - |
| total_tracked_time | integer | - |
| updated_at | string | - |
| workspace_id | integer | - |
assignees
| Name | Type | Description |
|---|
| id | integer | - |
| type | string | Valid values: user, team. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
| Name | Type | Description |
|---|
| all_day | boolean | - |
| calendar_event_id | integer | - |
| calendar_id | integer | - |
| event_classification | string | EventClassification is the calendar provider's own classification of the event behind this task, normalised by the calendar service — see calmodels.EventClassification for the values. Absent when the provider reported no classification. |
| extension_source | string | Browser-extension provenance: the source/config that produced the task and the page URL it was tracked from. Written by the extension's start-from-description flow; ExtensionURL is queryable via FindByURL. |
| extension_url | string | - |
| external_id | string | - |
| ical_uid | string | - |
| last_asserted_track_project_id | integer | LastAssertedTrackProjectID is the Track planned_task.project_id that the Focus→Track mirror last successfully wrote for this task. Track→Focus uses it to distinguish a stale echo (Track still holds this value after a Focus-side project move) from an intentional Track-side project move. Internal mirror state, written by toggl_api focus_sync_worker; not user-facing. |
| last_integration_dates | object | LastIntegrationDates are the start and end dates the task's integration last sent. Integration sync overwrites the task's dates only when the source's dates differ from these, so dates set in Focus survive unrelated source edits. Internal sync state; not user-facing. |
| meeting_link | string | - |
| project_assignment | object | - |
| updated_at | string | - |
last_integration_dates
| Name | Type | Description |
|---|
| end | string | - |
| start | string | - |
project_assignment
| Name | Type | Description |
|---|
| accuracy | number | - |
| confirmed_at | string | - |
| match_tier | string | Valid values: exact_name, similar_name. |
| matched_name | string | - |
| normalized_name | string | - |
| origin | string | Valid values: manual, auto_suggestion, confirmed_suggestion, integration, legacy, explicit_mapping. |
| suggested_at | string | - |
parent
| Name | Type | Description |
|---|
| allocation_unit | string | Valid values: percent, flat. |
| archived_at | string | - |
| assignee_user_ids | Array of integer | - |
| assignees | Array of object | A unified column for all task entity assignments |
| auto_log_time | boolean | - |
| billable | boolean | null |
| client | object | - |
| color | string | - |
| created_at | string | - |
| custom_field_values | Array of object | - |
| deleted_at | string | - |
| description | string | - |
| end_date | string | - |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | - |
| id | integer | - |
| is_recurring_series | boolean | IsRecurringSeries marks a canonical series root (S). Server-owned and read-only: no current API path can set it, and the response only exposes the marker while series behavior stays disabled. |
| is_template | boolean | - |
| metadata | object | - |
| name | string | - |
| notes | string | - |
| parent_task_id | integer | - |
| parent_task_name | string | - |
| pinned | boolean | - |
| position | integer | - |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | - |
| private | boolean | - |
| project | object | - |
| project_id | integer | - |
| recurrence_date | string | - |
| recurring_rule | string | The rule of the task's series (RRULE with DTSTART); omitted for a normal task and once the series has stopped. |
| recurring_series_id | integer | The series this task is an occurrence of; omitted for a normal task. Only the server sets it. |
| recurring_task_id | integer | - |
| rollup_enabled | boolean | - |
| rrule | string | - |
| source | string | - |
| source_template_task_id | integer | - |
| start_date | string | - |
| status | object | - |
| status_id | integer | - |
| status_updated_at | string | - |
| tag_ids | Array of integer | - |
| tags | Array of object | - |
| toggl_user_id | integer | - |
| updated_at | string | - |
| workspace_id | integer | - |
assignees
| Name | Type | Description |
|---|
| id | integer | - |
| type | string | Valid values: user, team. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
| Name | Type | Description |
|---|
| all_day | boolean | - |
| calendar_event_id | integer | - |
| calendar_id | integer | - |
| event_classification | string | EventClassification is the calendar provider's own classification of the event behind this task, normalised by the calendar service — see calmodels.EventClassification for the values. Absent when the provider reported no classification. |
| extension_source | string | Browser-extension provenance: the source/config that produced the task and the page URL it was tracked from. Written by the extension's start-from-description flow; ExtensionURL is queryable via FindByURL. |
| extension_url | string | - |
| external_id | string | - |
| ical_uid | string | - |
| last_asserted_track_project_id | integer | LastAssertedTrackProjectID is the Track planned_task.project_id that the Focus→Track mirror last successfully wrote for this task. Track→Focus uses it to distinguish a stale echo (Track still holds this value after a Focus-side project move) from an intentional Track-side project move. Internal mirror state, written by toggl_api focus_sync_worker; not user-facing. |
| last_integration_dates | object | LastIntegrationDates are the start and end dates the task's integration last sent. Integration sync overwrites the task's dates only when the source's dates differ from these, so dates set in Focus survive unrelated source edits. Internal sync state; not user-facing. |
| meeting_link | string | - |
| project_assignment | object | - |
| updated_at | string | - |
last_integration_dates
| Name | Type | Description |
|---|
| end | string | - |
| start | string | - |
project_assignment
| Name | Type | Description |
|---|
| accuracy | number | - |
| confirmed_at | string | - |
| match_tier | string | Valid values: exact_name, similar_name. |
| matched_name | string | - |
| normalized_name | string | - |
| origin | string | Valid values: manual, auto_suggestion, confirmed_suggestion, integration, legacy, explicit_mapping. |
| suggested_at | string | - |
project
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| client | object | - |
| color | string | - |
| custom_field_values | Array of object | CustomFieldValues are the parent project's CF values, hydrated by callers that surface them (currently the task list, via task.service.hydrateTaskProjectCustomFieldValues which routes through customfield.Service.GetFieldsByIDs and respects the PermissionViewWorkspaceProjectCustomFields gate). Producers that don't hydrate (e.g. timeentry) leave the slice empty; omitempty hides it on those responses. |
| draft | boolean | - |
| estimate_source | string | Valid values: manual, tasks, designation. |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
| recurring_project_id | integer | RecurringProjectID links an instance to its recurring template, so clients can lane an entry under a collapsed series. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
rate
| Name | Type | Description |
|---|
| billable | boolean | - |
| currency | string | - |
| end_at | string | - |
| has_more_rates | boolean | - |
| hourly_rate | number | - |
| project_color | string | - |
| project_created_at | string | - |
| project_id | integer | - |
| project_name | string | - |
| project_rate_id | integer | - |
| start_at | string | - |
| workspace_rate_id | integer | - |
status
| Name | Type | Description |
|---|
| emoji | string | - |
| id | integer | - |
| name | string | - |
| type | string | Valid values: todo, done, in_progress, blocked. |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
project
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| client | object | - |
| color | string | - |
| custom_field_values | Array of object | CustomFieldValues are the parent project's CF values, hydrated by callers that surface them (currently the task list, via task.service.hydrateTaskProjectCustomFieldValues which routes through customfield.Service.GetFieldsByIDs and respects the PermissionViewWorkspaceProjectCustomFields gate). Producers that don't hydrate (e.g. timeentry) leave the slice empty; omitempty hides it on those responses. |
| draft | boolean | - |
| estimate_source | string | Valid values: manual, tasks, designation. |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
| recurring_project_id | integer | RecurringProjectID links an instance to its recurring template, so clients can lane an entry under a collapsed series. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
rate
| Name | Type | Description |
|---|
| billable | boolean | - |
| currency | string | - |
| end_at | string | - |
| has_more_rates | boolean | - |
| hourly_rate | number | - |
| project_color | string | - |
| project_created_at | string | - |
| project_id | integer | - |
| project_name | string | - |
| project_rate_id | integer | - |
| start_at | string | - |
| workspace_rate_id | integer | - |
status
| Name | Type | Description |
|---|
| emoji | string | - |
| id | integer | - |
| name | string | - |
| type | string | Valid values: todo, done, in_progress, blocked. |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
400
Invalid request
403
Insufficient permissions
500
Internal Server Error
GET Get a task with its parent tasks by ID
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/parents
Returns a task and its parent tasks by the provided ID.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/parents \
-H "Content-Type: application/json" \
-u <email>:<password>
req, err := http.NewRequest(http.MethodGet,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/parents")
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/parents')
req = Net::HTTP::Get.new(uri)
req['Content-Type'] = "application/json"
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/parents", {
method: "GET",
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.get('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/parents', headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::GET, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/parents".to_string())
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
| task_id | integer | true | task ID |
Query
| name | type | required | description |
|---|
| page | integer | false | page number |
| per_page | integer | false | results per page |
| order_by | []string | false | order by. tag_ids and assignees order by the canonicalized (sorted) array, so tasks with the same set of tags or assignees cluster together regardless of storage order. |
| status_id | integer | false | filter parent tasks by status ID |
| archived | boolean | false | filter in/out archived tasks |
| source | []string | false | filter by sources |
| team_id | []integer | false | filter parent tasks by team IDs |
| assignee_user_id | []integer | false | filter in tasks by assignee's user IDs |
| tag_id | []integer | false | filter in tasks by tag IDs |
| include_assignees | boolean | false | includes the unified user and team assignees |
Response
200
| Name | Type | Description |
|---|
| data | Array of object | - |
| page | integer | - |
| per_page | integer | - |
data
| Name | Type | Description |
|---|
| allocation_unit | string | Valid values: percent, flat. |
| archived_at | string | - |
| assignee_user_ids | Array of integer | - |
| assignees | Array of object | A unified column for all task entity assignments |
| auto_log_time | boolean | - |
| billable | boolean | null |
| client | object | - |
| color | string | - |
| created_at | string | - |
| custom_field_values | Array of object | - |
| deleted_at | string | - |
| description | string | - |
| end_date | string | - |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | - |
| id | integer | - |
| is_recurring_series | boolean | IsRecurringSeries marks a canonical series root (S). Server-owned and read-only: no current API path can set it, and the response only exposes the marker while series behavior stays disabled. |
| is_template | boolean | - |
| metadata | object | - |
| name | string | - |
| notes | string | - |
| parent | object | - |
| parent_task_id | integer | - |
| parent_task_name | string | - |
| pinned | boolean | - |
| position | integer | - |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | - |
| private | boolean | - |
| project | object | - |
| project_id | integer | - |
| recurrence_date | string | - |
| recurring_rule | string | The rule of the task's series (RRULE with DTSTART); omitted for a normal task and once the series has stopped. |
| recurring_series_id | integer | The series this task is an occurrence of; omitted for a normal task. Only the server sets it. |
| recurring_task_id | integer | - |
| rollup_enabled | boolean | - |
| rrule | string | - |
| source | string | - |
| source_template_task_id | integer | - |
| start_date | string | - |
| status | object | - |
| status_id | integer | - |
| status_updated_at | string | - |
| sub_task_done_count | integer | - |
| sub_task_total_count | integer | - |
| tag_ids | Array of integer | - |
| tags | Array of object | - |
| time_entry_total_count | integer | - |
| toggl_user_id | integer | - |
| total_tracked_time | integer | - |
| updated_at | string | - |
| workspace_id | integer | - |
assignees
| Name | Type | Description |
|---|
| id | integer | - |
| type | string | Valid values: user, team. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
| Name | Type | Description |
|---|
| all_day | boolean | - |
| calendar_event_id | integer | - |
| calendar_id | integer | - |
| event_classification | string | EventClassification is the calendar provider's own classification of the event behind this task, normalised by the calendar service — see calmodels.EventClassification for the values. Absent when the provider reported no classification. |
| extension_source | string | Browser-extension provenance: the source/config that produced the task and the page URL it was tracked from. Written by the extension's start-from-description flow; ExtensionURL is queryable via FindByURL. |
| extension_url | string | - |
| external_id | string | - |
| ical_uid | string | - |
| last_asserted_track_project_id | integer | LastAssertedTrackProjectID is the Track planned_task.project_id that the Focus→Track mirror last successfully wrote for this task. Track→Focus uses it to distinguish a stale echo (Track still holds this value after a Focus-side project move) from an intentional Track-side project move. Internal mirror state, written by toggl_api focus_sync_worker; not user-facing. |
| last_integration_dates | object | LastIntegrationDates are the start and end dates the task's integration last sent. Integration sync overwrites the task's dates only when the source's dates differ from these, so dates set in Focus survive unrelated source edits. Internal sync state; not user-facing. |
| meeting_link | string | - |
| project_assignment | object | - |
| updated_at | string | - |
last_integration_dates
| Name | Type | Description |
|---|
| end | string | - |
| start | string | - |
project_assignment
| Name | Type | Description |
|---|
| accuracy | number | - |
| confirmed_at | string | - |
| match_tier | string | Valid values: exact_name, similar_name. |
| matched_name | string | - |
| normalized_name | string | - |
| origin | string | Valid values: manual, auto_suggestion, confirmed_suggestion, integration, legacy, explicit_mapping. |
| suggested_at | string | - |
parent
| Name | Type | Description |
|---|
| allocation_unit | string | Valid values: percent, flat. |
| archived_at | string | - |
| assignee_user_ids | Array of integer | - |
| assignees | Array of object | A unified column for all task entity assignments |
| auto_log_time | boolean | - |
| billable | boolean | null |
| client | object | - |
| color | string | - |
| created_at | string | - |
| custom_field_values | Array of object | - |
| deleted_at | string | - |
| description | string | - |
| end_date | string | - |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | - |
| id | integer | - |
| is_recurring_series | boolean | IsRecurringSeries marks a canonical series root (S). Server-owned and read-only: no current API path can set it, and the response only exposes the marker while series behavior stays disabled. |
| is_template | boolean | - |
| metadata | object | - |
| name | string | - |
| notes | string | - |
| parent_task_id | integer | - |
| parent_task_name | string | - |
| pinned | boolean | - |
| position | integer | - |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | - |
| private | boolean | - |
| project | object | - |
| project_id | integer | - |
| recurrence_date | string | - |
| recurring_rule | string | The rule of the task's series (RRULE with DTSTART); omitted for a normal task and once the series has stopped. |
| recurring_series_id | integer | The series this task is an occurrence of; omitted for a normal task. Only the server sets it. |
| recurring_task_id | integer | - |
| rollup_enabled | boolean | - |
| rrule | string | - |
| source | string | - |
| source_template_task_id | integer | - |
| start_date | string | - |
| status | object | - |
| status_id | integer | - |
| status_updated_at | string | - |
| tag_ids | Array of integer | - |
| tags | Array of object | - |
| toggl_user_id | integer | - |
| updated_at | string | - |
| workspace_id | integer | - |
assignees
| Name | Type | Description |
|---|
| id | integer | - |
| type | string | Valid values: user, team. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
| Name | Type | Description |
|---|
| all_day | boolean | - |
| calendar_event_id | integer | - |
| calendar_id | integer | - |
| event_classification | string | EventClassification is the calendar provider's own classification of the event behind this task, normalised by the calendar service — see calmodels.EventClassification for the values. Absent when the provider reported no classification. |
| extension_source | string | Browser-extension provenance: the source/config that produced the task and the page URL it was tracked from. Written by the extension's start-from-description flow; ExtensionURL is queryable via FindByURL. |
| extension_url | string | - |
| external_id | string | - |
| ical_uid | string | - |
| last_asserted_track_project_id | integer | LastAssertedTrackProjectID is the Track planned_task.project_id that the Focus→Track mirror last successfully wrote for this task. Track→Focus uses it to distinguish a stale echo (Track still holds this value after a Focus-side project move) from an intentional Track-side project move. Internal mirror state, written by toggl_api focus_sync_worker; not user-facing. |
| last_integration_dates | object | LastIntegrationDates are the start and end dates the task's integration last sent. Integration sync overwrites the task's dates only when the source's dates differ from these, so dates set in Focus survive unrelated source edits. Internal sync state; not user-facing. |
| meeting_link | string | - |
| project_assignment | object | - |
| updated_at | string | - |
last_integration_dates
| Name | Type | Description |
|---|
| end | string | - |
| start | string | - |
project_assignment
| Name | Type | Description |
|---|
| accuracy | number | - |
| confirmed_at | string | - |
| match_tier | string | Valid values: exact_name, similar_name. |
| matched_name | string | - |
| normalized_name | string | - |
| origin | string | Valid values: manual, auto_suggestion, confirmed_suggestion, integration, legacy, explicit_mapping. |
| suggested_at | string | - |
project
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| client | object | - |
| color | string | - |
| custom_field_values | Array of object | CustomFieldValues are the parent project's CF values, hydrated by callers that surface them (currently the task list, via task.service.hydrateTaskProjectCustomFieldValues which routes through customfield.Service.GetFieldsByIDs and respects the PermissionViewWorkspaceProjectCustomFields gate). Producers that don't hydrate (e.g. timeentry) leave the slice empty; omitempty hides it on those responses. |
| draft | boolean | - |
| estimate_source | string | Valid values: manual, tasks, designation. |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
| recurring_project_id | integer | RecurringProjectID links an instance to its recurring template, so clients can lane an entry under a collapsed series. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
rate
| Name | Type | Description |
|---|
| billable | boolean | - |
| currency | string | - |
| end_at | string | - |
| has_more_rates | boolean | - |
| hourly_rate | number | - |
| project_color | string | - |
| project_created_at | string | - |
| project_id | integer | - |
| project_name | string | - |
| project_rate_id | integer | - |
| start_at | string | - |
| workspace_rate_id | integer | - |
status
| Name | Type | Description |
|---|
| emoji | string | - |
| id | integer | - |
| name | string | - |
| type | string | Valid values: todo, done, in_progress, blocked. |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
project
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| client | object | - |
| color | string | - |
| custom_field_values | Array of object | CustomFieldValues are the parent project's CF values, hydrated by callers that surface them (currently the task list, via task.service.hydrateTaskProjectCustomFieldValues which routes through customfield.Service.GetFieldsByIDs and respects the PermissionViewWorkspaceProjectCustomFields gate). Producers that don't hydrate (e.g. timeentry) leave the slice empty; omitempty hides it on those responses. |
| draft | boolean | - |
| estimate_source | string | Valid values: manual, tasks, designation. |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
| recurring_project_id | integer | RecurringProjectID links an instance to its recurring template, so clients can lane an entry under a collapsed series. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
rate
| Name | Type | Description |
|---|
| billable | boolean | - |
| currency | string | - |
| end_at | string | - |
| has_more_rates | boolean | - |
| hourly_rate | number | - |
| project_color | string | - |
| project_created_at | string | - |
| project_id | integer | - |
| project_name | string | - |
| project_rate_id | integer | - |
| start_at | string | - |
| workspace_rate_id | integer | - |
status
| Name | Type | Description |
|---|
| emoji | string | - |
| id | integer | - |
| name | string | - |
| type | string | Valid values: todo, done, in_progress, blocked. |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
400
Invalid request
403
Insufficient permissions
500
Internal Server Error
PATCH Restore a task by ID
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/restore
Restores a task by the provided ID. On a deleted occurrence of a series made with recurring_rule, scope=all restores every occurrence deleted when this one was or later, with their time entries, and the series if it was deleted then or later; the series adds its missing occurrences again from the next night. A series whose rule a following delete ended stays ended. Occurrences in a draft project come back without their time entries.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X PATCH https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/restore \
-H "Content-Type: application/json" \
-u <email>:<password>
req, err := http.NewRequest(http.MethodGet,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/restore")
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/restore')
req = Net::HTTP::Patch.new(uri)
req['Content-Type'] = "application/json"
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/restore", {
method: "PATCH",
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.patch('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/restore', headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::PATCH, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/restore".to_string())
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
| task_id | integer | true | task ID |
Query
| name | type | required | description |
|---|
| scope | string | false | For a series made with recurring_rule: restore this occurrence (the default) or all; following is refused |
Response
204
No Content
400
Invalid request, or a scope of following, or all for a task it doesn't apply to (error=recurring_scope_not_supported); a restore over the size limit for a series (error=recurring_series_too_large)
403
Insufficient permissions
404
Task not found
500
Internal Server Error
POST Unarchive a task by ID
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/unarchive
Unarchives a task, and all its TEs with the provided task ID. On an archived occurrence of a series made with recurring_rule, scope=all unarchives every occurrence archived when this one was or later, with their time entries, and the series if it was archived then or later; the series adds its missing occurrences again from the next night. Occurrences in a draft project come back without their time entries.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X POST https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/unarchive \
-H "Content-Type: application/json" \
-u <email>:<password>
req, err := http.NewRequest(http.MethodPost,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/unarchive")
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/unarchive')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "application/json"
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/unarchive", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.post('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/unarchive', headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::POST, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/unarchive".to_string())
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
| task_id | integer | true | task ID |
Query
| name | type | required | description |
|---|
| scope | string | false | For a series made with recurring_rule: unarchive this occurrence (the default) or all; following is refused |
Response
204
No Content
400
Invalid request, or a scope of following, or all for a task it doesn't apply to (error=recurring_scope_not_supported); all for an occurrence of a deleted series (error=recurring_series_deleted); an unarchive over the size limit for a series (error=recurring_series_too_large)
403
Insufficient permissions
404
Task not found
500
Internal Server Error
POST Parse image and retrieve tasks
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/extract
Parses the provided image and returns a list of tasks.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X POST https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/extract \
-H "Content-Type: application/json" \
-u <email>:<password>
req, err := http.NewRequest(http.MethodPost,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/extract")
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/extract')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "application/json"
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/extract", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.post('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/extract', headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::POST, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/extract".to_string())
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
Query
| name | type | required | description |
|---|
| file | file | true | attachment file |
Response
200
Image parsed successfully
| Name | Type | Description |
|---|
| items | Array of object | - |
items
| Name | Type | Description |
|---|
| allocation_unit | string | Valid values: percent, flat. |
| archived_at | string | - |
| assignee_user_ids | Array of integer | - |
| assignees | Array of object | A unified column for all task entity assignments |
| auto_log_time | boolean | - |
| billable | boolean | null |
| client | object | - |
| color | string | - |
| created_at | string | - |
| custom_field_values | Array of object | - |
| deleted_at | string | - |
| description | string | - |
| end_date | string | - |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | - |
| id | integer | - |
| is_recurring_series | boolean | IsRecurringSeries marks a canonical series root (S). Server-owned and read-only: no current API path can set it, and the response only exposes the marker while series behavior stays disabled. |
| is_template | boolean | - |
| metadata | object | - |
| name | string | - |
| notes | string | - |
| parent_task_id | integer | - |
| parent_task_name | string | - |
| pinned | boolean | - |
| position | integer | - |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | - |
| private | boolean | - |
| project | object | - |
| project_id | integer | - |
| recurrence_date | string | - |
| recurring_rule | string | The rule of the task's series (RRULE with DTSTART); omitted for a normal task and once the series has stopped. |
| recurring_series_id | integer | The series this task is an occurrence of; omitted for a normal task. Only the server sets it. |
| recurring_task_id | integer | - |
| rollup_enabled | boolean | - |
| rrule | string | - |
| source | string | - |
| source_template_task_id | integer | - |
| start_date | string | - |
| status | object | - |
| status_id | integer | - |
| status_updated_at | string | - |
| tag_ids | Array of integer | - |
| tags | Array of object | - |
| toggl_user_id | integer | - |
| updated_at | string | - |
| workspace_id | integer | - |
assignees
| Name | Type | Description |
|---|
| id | integer | - |
| type | string | Valid values: user, team. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
| Name | Type | Description |
|---|
| all_day | boolean | - |
| calendar_event_id | integer | - |
| calendar_id | integer | - |
| event_classification | string | EventClassification is the calendar provider's own classification of the event behind this task, normalised by the calendar service — see calmodels.EventClassification for the values. Absent when the provider reported no classification. |
| extension_source | string | Browser-extension provenance: the source/config that produced the task and the page URL it was tracked from. Written by the extension's start-from-description flow; ExtensionURL is queryable via FindByURL. |
| extension_url | string | - |
| external_id | string | - |
| ical_uid | string | - |
| last_asserted_track_project_id | integer | LastAssertedTrackProjectID is the Track planned_task.project_id that the Focus→Track mirror last successfully wrote for this task. Track→Focus uses it to distinguish a stale echo (Track still holds this value after a Focus-side project move) from an intentional Track-side project move. Internal mirror state, written by toggl_api focus_sync_worker; not user-facing. |
| last_integration_dates | object | LastIntegrationDates are the start and end dates the task's integration last sent. Integration sync overwrites the task's dates only when the source's dates differ from these, so dates set in Focus survive unrelated source edits. Internal sync state; not user-facing. |
| meeting_link | string | - |
| project_assignment | object | - |
| updated_at | string | - |
last_integration_dates
| Name | Type | Description |
|---|
| end | string | - |
| start | string | - |
project_assignment
| Name | Type | Description |
|---|
| accuracy | number | - |
| confirmed_at | string | - |
| match_tier | string | Valid values: exact_name, similar_name. |
| matched_name | string | - |
| normalized_name | string | - |
| origin | string | Valid values: manual, auto_suggestion, confirmed_suggestion, integration, legacy, explicit_mapping. |
| suggested_at | string | - |
project
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| client | object | - |
| color | string | - |
| custom_field_values | Array of object | CustomFieldValues are the parent project's CF values, hydrated by callers that surface them (currently the task list, via task.service.hydrateTaskProjectCustomFieldValues which routes through customfield.Service.GetFieldsByIDs and respects the PermissionViewWorkspaceProjectCustomFields gate). Producers that don't hydrate (e.g. timeentry) leave the slice empty; omitempty hides it on those responses. |
| draft | boolean | - |
| estimate_source | string | Valid values: manual, tasks, designation. |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
| recurring_project_id | integer | RecurringProjectID links an instance to its recurring template, so clients can lane an entry under a collapsed series. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
rate
| Name | Type | Description |
|---|
| billable | boolean | - |
| currency | string | - |
| end_at | string | - |
| has_more_rates | boolean | - |
| hourly_rate | number | - |
| project_color | string | - |
| project_created_at | string | - |
| project_id | integer | - |
| project_name | string | - |
| project_rate_id | integer | - |
| start_at | string | - |
| workspace_rate_id | integer | - |
status
| Name | Type | Description |
|---|
| emoji | string | - |
| id | integer | - |
| name | string | - |
| type | string | Valid values: todo, done, in_progress, blocked. |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
400
Invalid request
403
AI is turned off for the organization (ai_disabled)
429
The caller's weekly Toggl AI allowance is used up (usage_exhausted); error_values.resets_at says when it resets
500
Internal Server Error
503
Task generation failed
POST Parse text list and retrieve tasks
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/from-list
Parses the provided text list and returns a list of tasks.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X POST https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/from-list \
-H "Content-Type: application/json" \
-d '\{"prompt":"string"\}' \
-u <email>:<password>
bytes, err := json.Marshal('\{"prompt":"string"\}')
if err != nil {
print(err)
}
req, err := http.NewRequest(http.MethodPost,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/from-list", bytes.NewBuffer(bytes))
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/from-list')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "application/json"
req.body = \{"prompt":"string"\}.to_json
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/from-list", {
method: "POST",
body: \{"prompt":"string"\},
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.post('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/from-list', json=\{"prompt":"string"\}, headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::POST, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/from-list".to_string())
.json(&serde_json::json!(\{"prompt":"string"\}))
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
Body
| Name | Type | Description |
|---|
| prompt | string | - |
Response
200
List parsed successfully
| Name | Type | Description |
|---|
| items | Array of object | - |
items
| Name | Type | Description |
|---|
| allocation_unit | string | Valid values: percent, flat. |
| archived_at | string | - |
| assignee_user_ids | Array of integer | - |
| assignees | Array of object | A unified column for all task entity assignments |
| auto_log_time | boolean | - |
| billable | boolean | null |
| client | object | - |
| color | string | - |
| created_at | string | - |
| custom_field_values | Array of object | - |
| deleted_at | string | - |
| description | string | - |
| end_date | string | - |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | - |
| id | integer | - |
| is_recurring_series | boolean | IsRecurringSeries marks a canonical series root (S). Server-owned and read-only: no current API path can set it, and the response only exposes the marker while series behavior stays disabled. |
| is_template | boolean | - |
| metadata | object | - |
| name | string | - |
| notes | string | - |
| parent_task_id | integer | - |
| parent_task_name | string | - |
| pinned | boolean | - |
| position | integer | - |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | - |
| private | boolean | - |
| project | object | - |
| project_id | integer | - |
| recurrence_date | string | - |
| recurring_rule | string | The rule of the task's series (RRULE with DTSTART); omitted for a normal task and once the series has stopped. |
| recurring_series_id | integer | The series this task is an occurrence of; omitted for a normal task. Only the server sets it. |
| recurring_task_id | integer | - |
| rollup_enabled | boolean | - |
| rrule | string | - |
| source | string | - |
| source_template_task_id | integer | - |
| start_date | string | - |
| status | object | - |
| status_id | integer | - |
| status_updated_at | string | - |
| tag_ids | Array of integer | - |
| tags | Array of object | - |
| toggl_user_id | integer | - |
| updated_at | string | - |
| workspace_id | integer | - |
assignees
| Name | Type | Description |
|---|
| id | integer | - |
| type | string | Valid values: user, team. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
| Name | Type | Description |
|---|
| all_day | boolean | - |
| calendar_event_id | integer | - |
| calendar_id | integer | - |
| event_classification | string | EventClassification is the calendar provider's own classification of the event behind this task, normalised by the calendar service — see calmodels.EventClassification for the values. Absent when the provider reported no classification. |
| extension_source | string | Browser-extension provenance: the source/config that produced the task and the page URL it was tracked from. Written by the extension's start-from-description flow; ExtensionURL is queryable via FindByURL. |
| extension_url | string | - |
| external_id | string | - |
| ical_uid | string | - |
| last_asserted_track_project_id | integer | LastAssertedTrackProjectID is the Track planned_task.project_id that the Focus→Track mirror last successfully wrote for this task. Track→Focus uses it to distinguish a stale echo (Track still holds this value after a Focus-side project move) from an intentional Track-side project move. Internal mirror state, written by toggl_api focus_sync_worker; not user-facing. |
| last_integration_dates | object | LastIntegrationDates are the start and end dates the task's integration last sent. Integration sync overwrites the task's dates only when the source's dates differ from these, so dates set in Focus survive unrelated source edits. Internal sync state; not user-facing. |
| meeting_link | string | - |
| project_assignment | object | - |
| updated_at | string | - |
last_integration_dates
| Name | Type | Description |
|---|
| end | string | - |
| start | string | - |
project_assignment
| Name | Type | Description |
|---|
| accuracy | number | - |
| confirmed_at | string | - |
| match_tier | string | Valid values: exact_name, similar_name. |
| matched_name | string | - |
| normalized_name | string | - |
| origin | string | Valid values: manual, auto_suggestion, confirmed_suggestion, integration, legacy, explicit_mapping. |
| suggested_at | string | - |
project
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| client | object | - |
| color | string | - |
| custom_field_values | Array of object | CustomFieldValues are the parent project's CF values, hydrated by callers that surface them (currently the task list, via task.service.hydrateTaskProjectCustomFieldValues which routes through customfield.Service.GetFieldsByIDs and respects the PermissionViewWorkspaceProjectCustomFields gate). Producers that don't hydrate (e.g. timeentry) leave the slice empty; omitempty hides it on those responses. |
| draft | boolean | - |
| estimate_source | string | Valid values: manual, tasks, designation. |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
| recurring_project_id | integer | RecurringProjectID links an instance to its recurring template, so clients can lane an entry under a collapsed series. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
rate
| Name | Type | Description |
|---|
| billable | boolean | - |
| currency | string | - |
| end_at | string | - |
| has_more_rates | boolean | - |
| hourly_rate | number | - |
| project_color | string | - |
| project_created_at | string | - |
| project_id | integer | - |
| project_name | string | - |
| project_rate_id | integer | - |
| start_at | string | - |
| workspace_rate_id | integer | - |
status
| Name | Type | Description |
|---|
| emoji | string | - |
| id | integer | - |
| name | string | - |
| type | string | Valid values: todo, done, in_progress, blocked. |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
400
Invalid request
403
AI is turned off for the organization (ai_disabled)
429
The caller's weekly Toggl AI allowance is used up (usage_exhausted); error_values.resets_at says when it resets
500
Internal Server Error
503
Task generation failed
POST Generates tasks from prompt
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/prompt
Generates tasks from prompt
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X POST https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/prompt \
-H "Content-Type: application/json" \
-d '\{"prompt":"string"\}' \
-u <email>:<password>
bytes, err := json.Marshal('\{"prompt":"string"\}')
if err != nil {
print(err)
}
req, err := http.NewRequest(http.MethodPost,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/prompt", bytes.NewBuffer(bytes))
if err != nil {
print(err)
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.SetBasicAuth("<email>", "<password>")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
print(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
print(err)
}
fmt.Print(string(body))
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/prompt')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "application/json"
req.body = \{"prompt":"string"\}.to_json
req.basic_auth '<email>', '<password>'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
puts JSON.parse(res.body)
fetch("https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/prompt", {
method: "POST",
body: \{"prompt":"string"\},
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64.encode(<email>:<password>)}`
},
})
.then((resp) => resp.json())
.then((json) => {
console.log(json);
})
.catch(err => console.error(err));
import requests
from base64 import b64encode
data = requests.post('https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/prompt', json=\{"prompt":"string"\}, headers={'content-type': 'application/json', 'Authorization' : 'Basic %s' % b64encode(b"<email>:<password>").decode("ascii")})
print(data.json())
extern crate tokio;
extern crate serde_json;
use reqwest::{Client};
use reqwest::header::{CONTENT_TYPE};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new().basic_auth("<email>", "<password>");
let json = client.request(Method::POST, "https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/workflows/tasks/prompt".to_string())
.json(&serde_json::json!(\{"prompt":"string"\}))
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| organization_id | integer | true | organization ID |
| workspace_id | integer | true | workspace ID |
Body
| Name | Type | Description |
|---|
| prompt | string | - |
Response
200
Prompt parsed successfully
| Name | Type | Description |
|---|
| items | Array of object | - |
items
| Name | Type | Description |
|---|
| allocation_unit | string | Valid values: percent, flat. |
| archived_at | string | - |
| assignee_user_ids | Array of integer | - |
| assignees | Array of object | A unified column for all task entity assignments |
| auto_log_time | boolean | - |
| billable | boolean | null |
| client | object | - |
| color | string | - |
| created_at | string | - |
| custom_field_values | Array of object | - |
| deleted_at | string | - |
| description | string | - |
| end_date | string | - |
| estimate_type | string | Valid values: daily, total. |
| estimated_mins | integer | - |
| id | integer | - |
| is_recurring_series | boolean | IsRecurringSeries marks a canonical series root (S). Server-owned and read-only: no current API path can set it, and the response only exposes the marker while series behavior stays disabled. |
| is_template | boolean | - |
| metadata | object | - |
| name | string | - |
| notes | string | - |
| parent_task_id | integer | - |
| parent_task_name | string | - |
| pinned | boolean | - |
| position | integer | - |
| priority | string | Valid values: none, low, medium, high. |
| priority_at | string | - |
| private | boolean | - |
| project | object | - |
| project_id | integer | - |
| recurrence_date | string | - |
| recurring_rule | string | The rule of the task's series (RRULE with DTSTART); omitted for a normal task and once the series has stopped. |
| recurring_series_id | integer | The series this task is an occurrence of; omitted for a normal task. Only the server sets it. |
| recurring_task_id | integer | - |
| rollup_enabled | boolean | - |
| rrule | string | - |
| source | string | - |
| source_template_task_id | integer | - |
| start_date | string | - |
| status | object | - |
| status_id | integer | - |
| status_updated_at | string | - |
| tag_ids | Array of integer | - |
| tags | Array of object | - |
| toggl_user_id | integer | - |
| updated_at | string | - |
| workspace_id | integer | - |
assignees
| Name | Type | Description |
|---|
| id | integer | - |
| type | string | Valid values: user, team. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
| Name | Type | Description |
|---|
| all_day | boolean | - |
| calendar_event_id | integer | - |
| calendar_id | integer | - |
| event_classification | string | EventClassification is the calendar provider's own classification of the event behind this task, normalised by the calendar service — see calmodels.EventClassification for the values. Absent when the provider reported no classification. |
| extension_source | string | Browser-extension provenance: the source/config that produced the task and the page URL it was tracked from. Written by the extension's start-from-description flow; ExtensionURL is queryable via FindByURL. |
| extension_url | string | - |
| external_id | string | - |
| ical_uid | string | - |
| last_asserted_track_project_id | integer | LastAssertedTrackProjectID is the Track planned_task.project_id that the Focus→Track mirror last successfully wrote for this task. Track→Focus uses it to distinguish a stale echo (Track still holds this value after a Focus-side project move) from an intentional Track-side project move. Internal mirror state, written by toggl_api focus_sync_worker; not user-facing. |
| last_integration_dates | object | LastIntegrationDates are the start and end dates the task's integration last sent. Integration sync overwrites the task's dates only when the source's dates differ from these, so dates set in Focus survive unrelated source edits. Internal sync state; not user-facing. |
| meeting_link | string | - |
| project_assignment | object | - |
| updated_at | string | - |
last_integration_dates
| Name | Type | Description |
|---|
| end | string | - |
| start | string | - |
project_assignment
| Name | Type | Description |
|---|
| accuracy | number | - |
| confirmed_at | string | - |
| match_tier | string | Valid values: exact_name, similar_name. |
| matched_name | string | - |
| normalized_name | string | - |
| origin | string | Valid values: manual, auto_suggestion, confirmed_suggestion, integration, legacy, explicit_mapping. |
| suggested_at | string | - |
project
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| client | object | - |
| color | string | - |
| custom_field_values | Array of object | CustomFieldValues are the parent project's CF values, hydrated by callers that surface them (currently the task list, via task.service.hydrateTaskProjectCustomFieldValues which routes through customfield.Service.GetFieldsByIDs and respects the PermissionViewWorkspaceProjectCustomFields gate). Producers that don't hydrate (e.g. timeentry) leave the slice empty; omitempty hides it on those responses. |
| draft | boolean | - |
| estimate_source | string | Valid values: manual, tasks, designation. |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
| recurring_project_id | integer | RecurringProjectID links an instance to its recurring template, so clients can lane an entry under a collapsed series. |
client
| Name | Type | Description |
|---|
| active | boolean | - |
| id | integer | - |
| name | string | - |
custom_field_values
| Name | Type | Description |
|---|
| custom_field_id | integer | - |
| custom_field_name | string | - |
| field_type | string | - |
| selected_options | Array of object | - |
| value | object | - |
selected_options
| Name | Type | Description |
|---|
| is_deleted | boolean | - |
| option_id | integer | - |
| option_name | string | - |
rate
| Name | Type | Description |
|---|
| billable | boolean | - |
| currency | string | - |
| end_at | string | - |
| has_more_rates | boolean | - |
| hourly_rate | number | - |
| project_color | string | - |
| project_created_at | string | - |
| project_id | integer | - |
| project_name | string | - |
| project_rate_id | integer | - |
| start_at | string | - |
| workspace_rate_id | integer | - |
status
| Name | Type | Description |
|---|
| emoji | string | - |
| id | integer | - |
| name | string | - |
| type | string | Valid values: todo, done, in_progress, blocked. |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
400
Invalid request
403
AI is turned off for the organization (ai_disabled)
429
The caller's weekly Toggl AI allowance is used up (usage_exhausted); error_values.resets_at says when it resets
500
Internal Server Error
503
Task generation failed