GET List task time entries
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/time-entries
Returns a list of time-entries based on the provided workspace ID, task ID and filter params.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/time-entries \
-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}/time-entries")
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}/time-entries')
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}/time-entries", {
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}/time-entries', 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}/time-entries".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 |
| type | string | false | time entry type |
| archived | boolean | false | filter in/out archived TEs |
| time_block_id | integer | false | filter by timeblock id |
Response
200
| Name | Type | Description |
|---|
| data | Array of object | - |
| page | integer | - |
| per_page | integer | - |
data
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| billable_source | string | Valid values: manual, task_default. |
| calendar_event_id | integer | - |
| created_at | string | - |
| deleted_at | string | - |
| description | string | - |
| duration | integer | - |
| id | integer | - |
| planned_at | string | - |
| planned_duration | integer | - |
| planned_start | string | - |
| project_id | integer | - |
| start | string | - |
| tag_ids | Array of integer | TagIDs is the entry's manual tag override. NULL (nil) means no override: the effective tags fall through to the linked task's tags. A non-nil value — including an empty array — is entry-authoritative. |
| tags | Array of object | Tags is the hydrated effective tag set: the override when TagIDs is set, else the linked task's active tags. Read-only. |
| task_id | integer | null |
| time_block_id | integer | - |
| timezone | string | Timezone is the effective IANA timezone hydrated on reads: the workspace timezone snapshotted at creation when set, else the creator's snapshot; NULL when unresolved. |
| toggl_user_id | integer | - |
| tracked_at | string | - |
| type | string | The type of time entry: either an activity or a break. Valid values: activity, break. |
| updated_at | string | - |
| workspace_id | integer | - |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
400
Invalid request
403
Insufficient permissions
500
Internal Server Error
POST Create a new time entry
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/time-entries
Creates a new time entry in the specified workspace.
An optional user_id field can be provided to create a time entry on behalf of another user.
When user_id differs from the authenticated user, the caller must have manage_time_entries permission.
An optional project_id overrides the task's project for this entry. When omitted, the entry inherits the task's project.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X POST https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/time-entries \
-H "Content-Type: application/json" \
-d '\{"billable":"boolean","calendar_event_id":"integer","description":"string","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","start":"string","tag_ids":[\{\}],"time_block_id":"integer","tracked_at":"string","type":"string","user_id":"integer"\}' \
-u <email>:<password>
bytes, err := json.Marshal('\{"billable":"boolean","calendar_event_id":"integer","description":"string","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","start":"string","tag_ids":[\{\}],"time_block_id":"integer","tracked_at":"string","type":"string","user_id":"integer"\}')
if err != nil {
print(err)
}
req, err := http.NewRequest(http.MethodPost,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/tasks/{task_id}/time-entries", 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/{task_id}/time-entries')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "application/json"
req.body = \{"billable":"boolean","calendar_event_id":"integer","description":"string","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","start":"string","tag_ids":[\{\}],"time_block_id":"integer","tracked_at":"string","type":"string","user_id":"integer"\}.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/{task_id}/time-entries", {
method: "POST",
body: \{"billable":"boolean","calendar_event_id":"integer","description":"string","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","start":"string","tag_ids":[\{\}],"time_block_id":"integer","tracked_at":"string","type":"string","user_id":"integer"\},
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}/time-entries', json=\{"billable":"boolean","calendar_event_id":"integer","description":"string","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","start":"string","tag_ids":[\{\}],"time_block_id":"integer","tracked_at":"string","type":"string","user_id":"integer"\}, 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}/time-entries".to_string())
.json(&serde_json::json!(\{"billable":"boolean","calendar_event_id":"integer","description":"string","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","start":"string","tag_ids":[\{\}],"time_block_id":"integer","tracked_at":"string","type":"string","user_id":"integer"\}))
.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 |
|---|
| billable | boolean | - |
| calendar_event_id | integer | - |
| description | string | - |
| duration | integer | - |
| planned_at | string | - |
| planned_duration | integer | - |
| planned_start | string | - |
| project_id | integer | - |
| 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. |
| time_block_id | integer | - |
| tracked_at | string | - |
| type | string | The type of time entry. This could either be an activity, or a break. Valid values: activity, break. |
| user_id | integer | - |
Response
201
Time entry created successfully
400
Invalid request
403
Insufficient permissions
422
Required field is missing (error=required_fields_missing) or is being cleared on a grandfathered entry (error=required_fields_deletion)
500
Internal Server Error
GET List task time entries
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/time-entries
Returns a list of time-entries based on the provided workspace ID and filter params.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/time-entries \
-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}/time-entries")
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}/time-entries')
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}/time-entries", {
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}/time-entries', 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}/time-entries".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 | from timestamp |
| task_id | integer | false | task id |
| status_id | integer | false | status id |
| type | string | false | time entry type |
| page | integer | false | page number |
| per_page | integer | false | results per page |
| order_by | []string | false | order by |
| archived | boolean | false | filter in/out archived TEs |
| time_block_id | integer | false | filter by timeblock |
| include_taskless | boolean | false | include taskless time entries |
| expand_calendar_event | boolean | false | hydrate calendar event details inline |
Response
200
| Name | Type | Description |
|---|
| data | Array of object | - |
| page | integer | - |
| per_page | integer | - |
data
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| billable_source | string | Valid values: manual, task_default. |
| calendar_event | object | - |
| calendar_event_id | integer | - |
| created_at | string | - |
| deleted_at | string | - |
| description | string | - |
| duration | integer | - |
| id | integer | - |
| planned_at | string | - |
| planned_duration | integer | - |
| planned_start | string | - |
| project | object | - |
| project_id | integer | - |
| start | string | - |
| tag_ids | Array of integer | TagIDs is the entry's manual tag override. NULL (nil) means no override: the effective tags fall through to the linked task's tags. A non-nil value — including an empty array — is entry-authoritative. |
| tags | Array of object | Tags is the hydrated effective tag set: the override when TagIDs is set, else the linked task's active tags. Read-only. |
| task | object | - |
| task_id | integer | null |
| time_block_id | integer | - |
| timezone | string | Timezone is the effective IANA timezone hydrated on reads: the workspace timezone snapshotted at creation when set, else the creator's snapshot; NULL when unresolved. |
| toggl_user_id | integer | - |
| tracked_at | string | - |
| type | string | The type of time entry: either an activity or a break. Valid values: activity, break. |
| updated_at | string | - |
| workspace_id | integer | - |
calendar_event
| Name | Type | Description |
|---|
| all_day | boolean | - |
| background_color | string | null |
| end_time | string | - |
| foreground_color | string | null |
| html_link | string | - |
| id | integer | - |
| meeting_link | string | null |
| provider | string | - |
| start_time | string | - |
| title | string | - |
project
| Name | Type | Description |
|---|
| archived_at | string | - |
| 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 | - |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
client
| Name | Type | Description |
|---|
| 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 | - |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
task
| 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 | - |
| 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_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_task_id | integer | - |
| 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 |
|---|
| 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 | - |
| 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. |
| meeting_link | string | - |
| project_assignment | object | - |
| updated_at | 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 | - |
| 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 | - |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
client
| Name | Type | Description |
|---|
| 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 | - |
400
Invalid request
403
Insufficient permissions
500
Internal Server Error
POST Create new time entries in bulk
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/time-entries/bulk
Creates new time entries in bulk for the specified workspace.
An optional user_id field can be provided per entry to create time entries on behalf of another user.
When user_id differs from the authenticated user, the caller must have manage_time_entries permission.
task_id is optional; omitting it creates a taskless entry, optionally scoped to project_id.
When both task_id and project_id are provided, project_id overrides the task's project for the entry.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X POST https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/time-entries/bulk \
-H "Content-Type: application/json" \
-d '[\{"billable":"boolean","calendar_event_id":"integer","description":"string","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","start":"string","tag_ids":[\{\}],"task_id":"integer","time_block_id":"integer","tracked_at":"string","type":"string","user_id":"integer"\}]' \
-u <email>:<password>
bytes, err := json.Marshal('[\{"billable":"boolean","calendar_event_id":"integer","description":"string","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","start":"string","tag_ids":[\{\}],"task_id":"integer","time_block_id":"integer","tracked_at":"string","type":"string","user_id":"integer"\}]')
if err != nil {
print(err)
}
req, err := http.NewRequest(http.MethodPost,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/time-entries/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}/time-entries/bulk')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "application/json"
req.body = [\{"billable":"boolean","calendar_event_id":"integer","description":"string","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","start":"string","tag_ids":[\{\}],"task_id":"integer","time_block_id":"integer","tracked_at":"string","type":"string","user_id":"integer"\}].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}/time-entries/bulk", {
method: "POST",
body: [\{"billable":"boolean","calendar_event_id":"integer","description":"string","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","start":"string","tag_ids":[\{\}],"task_id":"integer","time_block_id":"integer","tracked_at":"string","type":"string","user_id":"integer"\}],
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}/time-entries/bulk', json=[\{"billable":"boolean","calendar_event_id":"integer","description":"string","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","start":"string","tag_ids":[\{\}],"task_id":"integer","time_block_id":"integer","tracked_at":"string","type":"string","user_id":"integer"\}], 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}/time-entries/bulk".to_string())
.json(&serde_json::json!([\{"billable":"boolean","calendar_event_id":"integer","description":"string","duration":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","start":"string","tag_ids":[\{\}],"task_id":"integer","time_block_id":"integer","tracked_at":"string","type":"string","user_id":"integer"\}]))
.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 |
|---|
| billable | boolean | - |
| calendar_event_id | integer | - |
| description | string | - |
| duration | integer | - |
| planned_at | string | - |
| planned_duration | integer | - |
| planned_start | string | - |
| project_id | integer | - |
| 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. |
| task_id | integer | - |
| time_block_id | integer | - |
| tracked_at | string | - |
| type | string | The type of time entry. This could either be an activity, or a break. Valid values: activity, break. |
| user_id | integer | - |
Response
204
No Content
400
Invalid request
403
Insufficient permissions
422
One or more time entries violate required-field constraints (error=bulk_required_fields_missing)
500
Internal Server Error
DELETE Delete time entries in bulk
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/time-entries/bulk
Deletes time entries by the provided IDs.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X DELETE https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/time-entries/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}/time-entries/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}/time-entries/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}/time-entries/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}/time-entries/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}/time-entries/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 | TimeEntry IDs |
Response
204
No Content
400
Invalid request
403
Insufficient permissions
404
Time entry does not exist
500
Internal Server Error
PATCH Partial bulk update time entry
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/time-entries/bulk
Partial updates an existing time entry
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X PATCH https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/time-entries/bulk \
-H "Content-Type: application/json" \
-d '[\{"billable":"boolean","description":"string","duration":"integer","id":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","reset_billable_to_default":"boolean","start":"string","tag_ids":[\{\}],"task_id":"integer","time_block_id":"integer","tracked_at":"string","type":"string"\}]'
bytes, err := json.Marshal('[\{"billable":"boolean","description":"string","duration":"integer","id":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","reset_billable_to_default":"boolean","start":"string","tag_ids":[\{\}],"task_id":"integer","time_block_id":"integer","tracked_at":"string","type":"string"\}]')
if err != nil {
print(err)
}
req, err := http.NewRequest(http.MethodGet,
"https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/time-entries/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}/time-entries/bulk')
req = Net::HTTP::Patch.new(uri)
req['Content-Type'] = "application/json"
req.body = [\{"billable":"boolean","description":"string","duration":"integer","id":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","reset_billable_to_default":"boolean","start":"string","tag_ids":[\{\}],"task_id":"integer","time_block_id":"integer","tracked_at":"string","type":"string"\}].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}/time-entries/bulk", {
method: "PATCH",
body: [\{"billable":"boolean","description":"string","duration":"integer","id":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","reset_billable_to_default":"boolean","start":"string","tag_ids":[\{\}],"task_id":"integer","time_block_id":"integer","tracked_at":"string","type":"string"\}],
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}/time-entries/bulk', json=[\{"billable":"boolean","description":"string","duration":"integer","id":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","reset_billable_to_default":"boolean","start":"string","tag_ids":[\{\}],"task_id":"integer","time_block_id":"integer","tracked_at":"string","type":"string"\}], 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}/time-entries/bulk".to_string())
.json(&serde_json::json!([\{"billable":"boolean","description":"string","duration":"integer","id":"integer","planned_at":"string","planned_duration":"integer","planned_start":"string","project_id":"integer","reset_billable_to_default":"boolean","start":"string","tag_ids":[\{\}],"task_id":"integer","time_block_id":"integer","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 |
|---|
| items | Array of object | - |
items
| Name | Type | Description |
|---|
| billable | boolean | - |
| description | string | null |
| duration | integer | - |
| id | integer | - |
| planned_at | string | null |
| planned_duration | integer | null |
| planned_start | string | null |
| project_id | integer | null |
| reset_billable_to_default | boolean | - |
| start | string | null |
| tag_ids | Array of integer | TagIDs is tri-state: absent leaves the stored override untouched; explicit null clears the override (reset to task inheritance); an array (including empty) sets a manual, entry-authoritative override. |
| task_id | integer | null |
| time_block_id | integer | null |
| tracked_at | string | null |
| type | string | Valid values: activity, break. |
Response
204
No Content
400
Invalid request
403
Insufficient permissions
404
Time entry does not exist
422
One or more time entries violate required-field constraints (error=bulk_required_fields_missing)
500
Internal Server Error
PATCH Restore time entries in bulk
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/time-entries/bulk/restore
Restores time entries by the provided IDs.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X PATCH https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/time-entries/bulk/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}/time-entries/bulk/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}/time-entries/bulk/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}/time-entries/bulk/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}/time-entries/bulk/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}/time-entries/bulk/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 |
Query
| name | type | required | description |
|---|
| ids | []integer | true | TimeEntry IDs |
Response
204
No Content
400
Invalid request
403
Insufficient permissions
404
Time entry does not exist
500
Internal Server Error
GET List task time entries, streaming the response
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/time-entries/stream
Returns a list of time-entries based on the provided workspace ID and filter params.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/time-entries/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}/time-entries/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}/time-entries/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}/time-entries/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}/time-entries/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}/time-entries/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 |
|---|
| date_from | string | true | from timestamp |
| date_to | string | true | from timestamp |
| task_id | integer | false | task id |
| status_id | integer | false | status id |
| type | string | false | time entry type |
| order_by | []string | false | order by |
| archived | boolean | false | filter in/out archived TEs |
| include_taskless | boolean | false | include taskless time entries |
| expand_calendar_event | boolean | false | hydrate calendar event details inline |
Response
200
| Name | Type | Description |
|---|
| items | Array of object | - |
items
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| billable_source | string | Valid values: manual, task_default. |
| calendar_event | object | - |
| calendar_event_id | integer | - |
| created_at | string | - |
| deleted_at | string | - |
| description | string | - |
| duration | integer | - |
| id | integer | - |
| planned_at | string | - |
| planned_duration | integer | - |
| planned_start | string | - |
| project | object | - |
| project_id | integer | - |
| start | string | - |
| tag_ids | Array of integer | TagIDs is the entry's manual tag override. NULL (nil) means no override: the effective tags fall through to the linked task's tags. A non-nil value — including an empty array — is entry-authoritative. |
| tags | Array of object | Tags is the hydrated effective tag set: the override when TagIDs is set, else the linked task's active tags. Read-only. |
| task | object | - |
| task_id | integer | null |
| time_block_id | integer | - |
| timezone | string | Timezone is the effective IANA timezone hydrated on reads: the workspace timezone snapshotted at creation when set, else the creator's snapshot; NULL when unresolved. |
| toggl_user_id | integer | - |
| tracked_at | string | - |
| type | string | The type of time entry: either an activity or a break. Valid values: activity, break. |
| updated_at | string | - |
| workspace_id | integer | - |
calendar_event
| Name | Type | Description |
|---|
| all_day | boolean | - |
| background_color | string | null |
| end_time | string | - |
| foreground_color | string | null |
| html_link | string | - |
| id | integer | - |
| meeting_link | string | null |
| provider | string | - |
| start_time | string | - |
| title | string | - |
project
| Name | Type | Description |
|---|
| archived_at | string | - |
| 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 | - |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
client
| Name | Type | Description |
|---|
| 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 | - |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
task
| 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 | - |
| 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_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_task_id | integer | - |
| 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 |
|---|
| 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 | - |
| 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. |
| meeting_link | string | - |
| project_assignment | object | - |
| updated_at | 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 | - |
| 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 | - |
| id | integer | - |
| is_template | boolean | - |
| name | string | - |
| permissions | Array of string | - |
| private | boolean | - |
| rate | object | - |
client
| Name | Type | Description |
|---|
| 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 List task time entries by time block ids, streaming the response
https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/time-entries/time-block-ids/stream
Returns a list of time-entries based on the provided workspace ID and filter params.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl https://focus.toggl.com/api/organizations/{organization_id}/workspaces/{workspace_id}/time-entries/time-block-ids/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}/time-entries/time-block-ids/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}/time-entries/time-block-ids/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}/time-entries/time-block-ids/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}/time-entries/time-block-ids/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}/time-entries/time-block-ids/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 |
|---|
| time_block_id | []integer | true | filter by timeblock ids |
Response
200
| Name | Type | Description |
|---|
| items | Array of object | - |
items
| Name | Type | Description |
|---|
| archived_at | string | - |
| billable | boolean | - |
| billable_source | string | Valid values: manual, task_default. |
| calendar_event_id | integer | - |
| created_at | string | - |
| deleted_at | string | - |
| description | string | - |
| duration | integer | - |
| id | integer | - |
| planned_at | string | - |
| planned_duration | integer | - |
| planned_start | string | - |
| project_id | integer | - |
| start | string | - |
| tag_ids | Array of integer | TagIDs is the entry's manual tag override. NULL (nil) means no override: the effective tags fall through to the linked task's tags. A non-nil value — including an empty array — is entry-authoritative. |
| tags | Array of object | Tags is the hydrated effective tag set: the override when TagIDs is set, else the linked task's active tags. Read-only. |
| task_id | integer | null |
| time_block_id | integer | - |
| timezone | string | Timezone is the effective IANA timezone hydrated on reads: the workspace timezone snapshotted at creation when set, else the creator's snapshot; NULL when unresolved. |
| toggl_user_id | integer | - |
| tracked_at | string | - |
| type | string | The type of time entry: either an activity or a break. Valid values: activity, break. |
| updated_at | string | - |
| workspace_id | integer | - |
| Name | Type | Description |
|---|
| color | string | - |
| id | integer | - |
| name | string | - |
400
Invalid request
403
Insufficient permissions
500
Internal Server Error