Composite
POST Creates the main project, project members, and milestones.
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/composite/projects
Creates the main project, project members, and milestones. Milestones are automatically associated with the project.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X POST https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/composite/projects \
-H "Content-Type: application/json" \
-d '\{"billable_rates":[\{"currency":"string","end_date":"string","hourly_rate":"integer","start_date":"string"\}],"members":\{"group_ids":[\{\}],"role_id":"integer","user_ids":[\{\}]\},"milestones":[\{"color":"string","completed_at":"string","due_date":"string","name":"string","project_ids":[\{\}],"team_ids":[\{\}]\}],"project":\{"auto_compute_estimates":"boolean","billable":"boolean","client_id":"integer","color":"string","completion_mode":"string","custom_fields":\{\},"description":"string","draft":"boolean","end_date":"string","estimate_source":"string","estimated_mins":"integer","fixed_fee":\{"amount":"number","currency":"string"\},"is_template":"boolean","name":"string","parent_project_id":"integer","pinned":"boolean","private":"boolean","rollover_mode":"string","rrule":"string","start_date":"string","tag_ids":[\{\}]\},"rates":[\{"currency":"string","end_at":"string","hourly_rate":"number","start_at":"string"\}]\}' \
-u <email>:<password>
bytes, err := json.Marshal('\{"billable_rates":[\{"currency":"string","end_date":"string","hourly_rate":"integer","start_date":"string"\}],"members":\{"group_ids":[\{\}],"role_id":"integer","user_ids":[\{\}]\},"milestones":[\{"color":"string","completed_at":"string","due_date":"string","name":"string","project_ids":[\{\}],"team_ids":[\{\}]\}],"project":\{"auto_compute_estimates":"boolean","billable":"boolean","client_id":"integer","color":"string","completion_mode":"string","custom_fields":\{\},"description":"string","draft":"boolean","end_date":"string","estimate_source":"string","estimated_mins":"integer","fixed_fee":\{"amount":"number","currency":"string"\},"is_template":"boolean","name":"string","parent_project_id":"integer","pinned":"boolean","private":"boolean","rollover_mode":"string","rrule":"string","start_date":"string","tag_ids":[\{\}]\},"rates":[\{"currency":"string","end_at":"string","hourly_rate":"number","start_at":"string"\}]\}')
if err != nil {
print(err)
}
req, err := http.NewRequest(http.MethodPost,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/composite/projects", 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}/composite/projects')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "application/json"
req.body = \{"billable_rates":[\{"currency":"string","end_date":"string","hourly_rate":"integer","start_date":"string"\}],"members":\{"group_ids":[\{\}],"role_id":"integer","user_ids":[\{\}]\},"milestones":[\{"color":"string","completed_at":"string","due_date":"string","name":"string","project_ids":[\{\}],"team_ids":[\{\}]\}],"project":\{"auto_compute_estimates":"boolean","billable":"boolean","client_id":"integer","color":"string","completion_mode":"string","custom_fields":\{\},"description":"string","draft":"boolean","end_date":"string","estimate_source":"string","estimated_mins":"integer","fixed_fee":\{"amount":"number","currency":"string"\},"is_template":"boolean","name":"string","parent_project_id":"integer","pinned":"boolean","private":"boolean","rollover_mode":"string","rrule":"string","start_date":"string","tag_ids":[\{\}]\},"rates":[\{"currency":"string","end_at":"string","hourly_rate":"number","start_at":"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}/composite/projects", {
method: "POST",
body: \{"billable_rates":[\{"currency":"string","end_date":"string","hourly_rate":"integer","start_date":"string"\}],"members":\{"group_ids":[\{\}],"role_id":"integer","user_ids":[\{\}]\},"milestones":[\{"color":"string","completed_at":"string","due_date":"string","name":"string","project_ids":[\{\}],"team_ids":[\{\}]\}],"project":\{"auto_compute_estimates":"boolean","billable":"boolean","client_id":"integer","color":"string","completion_mode":"string","custom_fields":\{\},"description":"string","draft":"boolean","end_date":"string","estimate_source":"string","estimated_mins":"integer","fixed_fee":\{"amount":"number","currency":"string"\},"is_template":"boolean","name":"string","parent_project_id":"integer","pinned":"boolean","private":"boolean","rollover_mode":"string","rrule":"string","start_date":"string","tag_ids":[\{\}]\},"rates":[\{"currency":"string","end_at":"string","hourly_rate":"number","start_at":"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}/composite/projects', json=\{"billable_rates":[\{"currency":"string","end_date":"string","hourly_rate":"integer","start_date":"string"\}],"members":\{"group_ids":[\{\}],"role_id":"integer","user_ids":[\{\}]\},"milestones":[\{"color":"string","completed_at":"string","due_date":"string","name":"string","project_ids":[\{\}],"team_ids":[\{\}]\}],"project":\{"auto_compute_estimates":"boolean","billable":"boolean","client_id":"integer","color":"string","completion_mode":"string","custom_fields":\{\},"description":"string","draft":"boolean","end_date":"string","estimate_source":"string","estimated_mins":"integer","fixed_fee":\{"amount":"number","currency":"string"\},"is_template":"boolean","name":"string","parent_project_id":"integer","pinned":"boolean","private":"boolean","rollover_mode":"string","rrule":"string","start_date":"string","tag_ids":[\{\}]\},"rates":[\{"currency":"string","end_at":"string","hourly_rate":"number","start_at":"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}/composite/projects".to_string())
.json(&serde_json::json!(\{"billable_rates":[\{"currency":"string","end_date":"string","hourly_rate":"integer","start_date":"string"\}],"members":\{"group_ids":[\{\}],"role_id":"integer","user_ids":[\{\}]\},"milestones":[\{"color":"string","completed_at":"string","due_date":"string","name":"string","project_ids":[\{\}],"team_ids":[\{\}]\}],"project":\{"auto_compute_estimates":"boolean","billable":"boolean","client_id":"integer","color":"string","completion_mode":"string","custom_fields":\{\},"description":"string","draft":"boolean","end_date":"string","estimate_source":"string","estimated_mins":"integer","fixed_fee":\{"amount":"number","currency":"string"\},"is_template":"boolean","name":"string","parent_project_id":"integer","pinned":"boolean","private":"boolean","rollover_mode":"string","rrule":"string","start_date":"string","tag_ids":[\{\}]\},"rates":[\{"currency":"string","end_at":"string","hourly_rate":"number","start_at":"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 |
|---|---|---|
| billable_rates | Array of object | The billable rates to be created alongside the project. Uses the rate package payload shape (inclusive [start_date, end_date], integer cents). |
| members | object | User data, and other membership details for adding members to the project. |
| milestones | Array of object | The milestones to be created alongside the project. |
| project | object | The project to be created |
| rates | Array of object | The rates to be created alongside the project. |
billable_rates
| Name | Type | Description |
|---|---|---|
| currency | string | - |
| end_date | string | - |
| hourly_rate | integer | HourlyRate uses fixed hundredths of the currency's major unit for every currency (e.g. 5000 = USD 50.00 or JPY 50). |
| start_date | string | - |
members
| Name | Type | Description |
|---|---|---|
| group_ids | Array of integer | - |
| role_id | integer | - |
| user_ids | Array of integer | - |
milestones
| Name | Type | Description |
|---|---|---|
| color | string | - |
| completed_at | string | nolint:lll |
| due_date | string | nolint:lll |
| name | string | - |
| project_ids | Array of integer | - |
| team_ids | Array of integer | - |
project
| Name | Type | Description |
|---|---|---|
| auto_compute_estimates | boolean | Deprecated by estimate_source. Sets it to "tasks" if true. |
| billable | boolean | - |
| client_id | integer | - |
| color | string | - |
| completion_mode | string | Valid values: manual, automatic. |
| custom_fields | object | - |
| description | string | - |
| draft | boolean | - |
| end_date | string | - |
| estimate_source | string | null |
| estimated_mins | integer | - |
| fixed_fee | object | - |
| is_template | boolean | - |
| name | string | - |
| parent_project_id | integer | - |
| pinned | boolean | - |
| private | boolean | - |
| rollover_mode | string | Valid values: expire, carry_all, carry_over. |
| rrule | string | - |
| start_date | string | - |
| tag_ids | Array of integer | - |
custom_fields
fixed_fee
| Name | Type | Description |
|---|---|---|
| amount | number | - |
| currency | string | - |
rates
| Name | Type | Description |
|---|---|---|
| currency | string | - |
| end_at | string | - |
| hourly_rate | number | - |
| start_at | string | - |
Response
201
Composite project creation success
400
Invalid request
402
The plan does not cover the requested milestones
403
Insufficient permissions
500
Internal Server Error
POST Creates the main task, subtasks and time entries in bulk
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/composite/tasks
Creates the main task, subtasks and time entries in bulk. With the recurring_create_paths beta flag on (and repeating tasks enabled), the task's rrule makes a repeating task: the response's task is its first occurrence, which gets the estimate allocations and the time entry; 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}/composite/tasks \
-H "Content-Type: application/json" \
-d '\{"estimate_allocations":[\{"allocated_mins":"integer","allocated_percent":"integer","toggl_user_id":"integer"\}],"subtasks":[\{"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","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":[\{\}]\}],"task":\{"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_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\},"time_entry":\{"calendar_event_id":"integer","description":"string","designation_id":"integer","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","start":"string","tag_ids":[\{\}],"tracked_at":"string","type":"string"\}\}' \
-u <email>:<password>
bytes, err := json.Marshal('\{"estimate_allocations":[\{"allocated_mins":"integer","allocated_percent":"integer","toggl_user_id":"integer"\}],"subtasks":[\{"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","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":[\{\}]\}],"task":\{"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_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\},"time_entry":\{"calendar_event_id":"integer","description":"string","designation_id":"integer","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","start":"string","tag_ids":[\{\}],"tracked_at":"string","type":"string"\}\}')
if err != nil {
print(err)
}
req, err := http.NewRequest(http.MethodPost,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/composite/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}/composite/tasks')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "application/json"
req.body = \{"estimate_allocations":[\{"allocated_mins":"integer","allocated_percent":"integer","toggl_user_id":"integer"\}],"subtasks":[\{"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","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":[\{\}]\}],"task":\{"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_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\},"time_entry":\{"calendar_event_id":"integer","description":"string","designation_id":"integer","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","start":"string","tag_ids":[\{\}],"tracked_at":"string","type":"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}/composite/tasks", {
method: "POST",
body: \{"estimate_allocations":[\{"allocated_mins":"integer","allocated_percent":"integer","toggl_user_id":"integer"\}],"subtasks":[\{"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","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":[\{\}]\}],"task":\{"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_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\},"time_entry":\{"calendar_event_id":"integer","description":"string","designation_id":"integer","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","start":"string","tag_ids":[\{\}],"tracked_at":"string","type":"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}/composite/tasks', json=\{"estimate_allocations":[\{"allocated_mins":"integer","allocated_percent":"integer","toggl_user_id":"integer"\}],"subtasks":[\{"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","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":[\{\}]\}],"task":\{"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_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\},"time_entry":\{"calendar_event_id":"integer","description":"string","designation_id":"integer","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","start":"string","tag_ids":[\{\}],"tracked_at":"string","type":"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}/composite/tasks".to_string())
.json(&serde_json::json!(\{"estimate_allocations":[\{"allocated_mins":"integer","allocated_percent":"integer","toggl_user_id":"integer"\}],"subtasks":[\{"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","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":[\{\}]\}],"task":\{"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_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\},"time_entry":\{"calendar_event_id":"integer","description":"string","designation_id":"integer","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","start":"string","tag_ids":[\{\}],"tracked_at":"string","type":"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 |
|---|---|---|
| estimate_allocations | Array of object | EstimateAllocations are the main task's estimate allocations, created after the task itself. Their value kind must match the task's allocation_unit. |
| subtasks | Array of object | - |
| task | object | - |
| time_entry | object | - |
estimate_allocations
| Name | Type | Description |
|---|---|---|
| allocated_mins | integer | - |
| allocated_percent | integer | - |
| toggl_user_id | integer | - |
subtasks
| 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 | - |
| 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
task
| 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_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
time_entry
| Name | Type | Description |
|---|---|---|
| calendar_event_id | integer | - |
| description | string | - |
| designation_id | integer | null |
| duration | integer | - |
| planned_at | string | - |
| planned_duration | integer | - |
| planned_start | string | - |
| start | string | - |
| tag_ids | Array of integer | TagIDs sets a manual tag override at creation (entry-authoritative, including an explicit empty array). Absent/null = no override: the entry inherits the linked task's tags. |
| tracked_at | string | - |
| type | string | The type of time entry. This could either be an activity, or a break. Valid values: activity, break. |
Response
201
Composite task creation success
400
Invalid request; for a task with rrule and 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); subtasks sent with it, refused after the task is made (error=recurring_subtask)
402
Not available on the current plan
403
Insufficient permissions
404
Task not found
409
Allocation already exists for the entity
422
Allocation unit mismatched, or entity not assigned
500
Internal Server Error
POST Creates the main task, subtasks and time entries in bulk
https://focus.toggl.com/api/workspaces/{workspace_id}/composite/tasks
Creates the main task, subtasks and time entries in bulk.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X POST https://focus.toggl.com/api/workspaces/{workspace_id}/composite/tasks \
-H "Content-Type: application/json" \
-d '\{"estimate_allocations":[\{"allocated_mins":"integer","allocated_percent":"integer","toggl_user_id":"integer"\}],"subtasks":[\{"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","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":[\{\}]\}],"task":\{"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_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\},"time_entry":\{"calendar_event_id":"integer","description":"string","designation_id":"integer","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","start":"string","tag_ids":[\{\}],"tracked_at":"string","type":"string"\}\}' \
-u <email>:<password>
bytes, err := json.Marshal('\{"estimate_allocations":[\{"allocated_mins":"integer","allocated_percent":"integer","toggl_user_id":"integer"\}],"subtasks":[\{"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","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":[\{\}]\}],"task":\{"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_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\},"time_entry":\{"calendar_event_id":"integer","description":"string","designation_id":"integer","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","start":"string","tag_ids":[\{\}],"tracked_at":"string","type":"string"\}\}')
if err != nil {
print(err)
}
req, err := http.NewRequest(http.MethodPost,
"https://focus.toggl.com/api/workspaces/{workspace_id}/composite/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/workspaces/{workspace_id}/composite/tasks')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "application/json"
req.body = \{"estimate_allocations":[\{"allocated_mins":"integer","allocated_percent":"integer","toggl_user_id":"integer"\}],"subtasks":[\{"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","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":[\{\}]\}],"task":\{"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_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\},"time_entry":\{"calendar_event_id":"integer","description":"string","designation_id":"integer","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","start":"string","tag_ids":[\{\}],"tracked_at":"string","type":"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/workspaces/{workspace_id}/composite/tasks", {
method: "POST",
body: \{"estimate_allocations":[\{"allocated_mins":"integer","allocated_percent":"integer","toggl_user_id":"integer"\}],"subtasks":[\{"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","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":[\{\}]\}],"task":\{"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_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\},"time_entry":\{"calendar_event_id":"integer","description":"string","designation_id":"integer","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","start":"string","tag_ids":[\{\}],"tracked_at":"string","type":"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/workspaces/{workspace_id}/composite/tasks', json=\{"estimate_allocations":[\{"allocated_mins":"integer","allocated_percent":"integer","toggl_user_id":"integer"\}],"subtasks":[\{"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","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":[\{\}]\}],"task":\{"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_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\},"time_entry":\{"calendar_event_id":"integer","description":"string","designation_id":"integer","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","start":"string","tag_ids":[\{\}],"tracked_at":"string","type":"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/workspaces/{workspace_id}/composite/tasks".to_string())
.json(&serde_json::json!(\{"estimate_allocations":[\{"allocated_mins":"integer","allocated_percent":"integer","toggl_user_id":"integer"\}],"subtasks":[\{"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","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":[\{\}]\}],"task":\{"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_task_id":"integer","rollup_enabled":"boolean","rrule":"string","start_date":"string","status_id":"integer","tag_ids":[\{\}],"team_assignee_ids":[\{\}]\},"time_entry":\{"calendar_event_id":"integer","description":"string","designation_id":"integer","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","start":"string","tag_ids":[\{\}],"tracked_at":"string","type":"string"\}\}))
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|---|---|---|
| workspace_id | integer | true | workspace ID |
Body
| Name | Type | Description |
|---|---|---|
| estimate_allocations | Array of object | EstimateAllocations are the main task's estimate allocations, created after the task itself. Their value kind must match the task's allocation_unit. |
| subtasks | Array of object | - |
| task | object | - |
| time_entry | object | - |
estimate_allocations
| Name | Type | Description |
|---|---|---|
| allocated_mins | integer | - |
| allocated_percent | integer | - |
| toggl_user_id | integer | - |
subtasks
| 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 | - |
| 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
task
| 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_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
time_entry
| Name | Type | Description |
|---|---|---|
| calendar_event_id | integer | - |
| description | string | - |
| designation_id | integer | null |
| duration | integer | - |
| planned_at | string | - |
| planned_duration | integer | - |
| planned_start | string | - |
| start | string | - |
| tag_ids | Array of integer | TagIDs sets a manual tag override at creation (entry-authoritative, including an explicit empty array). Absent/null = no override: the entry inherits the linked task's tags. |
| tracked_at | string | - |
| type | string | The type of time entry. This could either be an activity, or a break. Valid values: activity, break. |
Response
201
Composite task creation success
400
Invalid request
403
Insufficient permissions
500
Internal Server Error