POST Generate flexible query report
https://focus.toggl.com/api/reports/workspaces/{workspace_id}/query
Executes a flexible query against the analytics database and returns formatted results. Every field of the request body is optional on its own -- omitting period runs the query unbounded -- but the body must carry at least one selector (attributes, groupings or aggregations) or it is rejected with a 400 before reaching the engine. Other operations share this dto.QueryRequest body and add their own period rule; each states it in its own description.
Each row is one time entry of the workspace members the caller may see in reports; select columns with attributes, or summarise with groupings plus aggregations.
Groupings support show_empty: true (zero-time rows) for a member, project or client first grouping, and for task as a second grouping under project; matching workspace entities without any time entry in the period are then returned with NULL aggregates. show_empty requires the use_zero_time_rows permission, and a round transformation requires use_report_rounding.
Response formats (response_format): json_row (an array of flat objects in data_json_row), table (the default, in data_table) or hierarchical (nested by grouping, in data_hierarchical). Aggregations without groupings or attributes return the totals: one row, or the root node in hierarchical.
Properties accepted wherever a property is expected (case-insensitive):
- Time entry:
time_entry_id, description, duration (seconds), billable_duration (seconds, 0 when not billable), non_billable_duration (seconds, duration minus billable_duration), duration_percentage (share of the total duration, 0–1), billable_duration_percentage (share of the total billable duration, 0–1, as Toggl Track's billable percentage; null when nothing is billable, but 0 on hierarchical parent and root nodes, which sum their children), time_entry_billable, effective_billable (the entry's billable flag, falling back to the task's), created_at, updated_at, archived_at.
- Start and stop:
start_utc (UTC), start, start_date, start_time, stop, stop_date, stop_time (local to the timezone the entry was tracked in, or to the caller's timezone with view_in_my_timezone), timezone.
- Calendar buckets of
start: day (day of month), weekday (0 = Sunday), week, week_bow_1, week_bow_2, week_bow_3, week_bow_4, week_bow_5, week_bow_6, week_bow_7 (week number with weeks starting on day N, 1 = Monday … 7 = Sunday), month, quarter, year, year_week (YYYYWW), year_month (YYYYMM), year_quarter (year × 100 + quarter, e.g. 202603).
- Member:
user_account_id, user_name, designation_id (the member's designation), user_group_id, user_group_name, user_group_ids, user_group_names, user_tag_id, user_tag_name, user_tag_ids, user_tag_names, member_estimated_mins, member_project_estimated_mins, member_client_estimated_mins (minutes).
- Project and client:
project_id, project_name, parent_project_ids, project_estimated_mins (minutes), recurring_project_id, client_id, client_name, client_estimated_mins (minutes), workspace_id.
- Task:
task_id, task_name, parent_task_ids, task_creator_id, task_status, task_status_id, task_status_updated_at, task_priority, task_start_date, task_end_date, task_estimated_mins (minutes), task_progress (tracked duration over the estimate, 1 = 100%), task_billable.
- Tags:
tag_id, tag_name (one row per tag), tag_ids, tag_names (arrays).
- Rates and money:
hourly_rate (per hour, in currency), amount (billable earnings, hourly_rate × billable hours), currency. labor_cost_hourly_rate, labor_cost and labor_cost_currency also require the view_labor_cost_rates permission.
- Converted money, aggregation only and with
response_format json_row or hierarchical: converted_amount, converted_labor_cost and converted_profit (converted_amount minus converted_labor_cost), each converted into the request's currency (default the workspace's) and returned with that code in the response's currency. A missing exchange rate fails the report with 422. converted_labor_cost and converted_profit also require the view_labor_cost_rates permission.
- Custom fields:
project_custom_field:<id>, task_custom_field:<id>, user_custom_field:<id>.
- Aliases:
user and user_id (user_account_id), client (client_id), workspace (workspace_id), time_entry (time_entry_id), created (created_at), updated (updated_at), group_ids and group_names (user_group_ids, user_group_names), project_ids (parent_project_ids), task_ids (parent_task_ids).
Aggregation functions: sum, avg, min, max, count, array, array_ordered. To sort by an aggregate, use function(property) as the ordination property, for example sum(duration).
Filter operators: =, !=, >, >=, <, <=, in, not in, contains, not contains, contains one of, not contains one of, starts with, ends with, empty, not empty, is between, is not between; combine conditions with and / or.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X POST https://focus.toggl.com/api/reports/workspaces/{workspace_id}/query \
-H "Content-Type: application/json" \
-d '\{"aggregation_filters":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{\},"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"aggregations":[\{"function":"string","property":"string"\}],"attributes":[\{"property":"string"\}],"chart_key":"string","conversion_date":\{\},"currency":"string","filters":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"groupings":[\{"property":"string","show_empty":"boolean"\}],"limit":"integer","modifiers":\{\},"ordinations":[\{"direction":"string","nulls":"string","property":"string"\}],"pagination":\{"page":"integer","per_page":"integer"\},"period":\{"from":"string","preset":"string","to":"string"\},"shared_report_id":"integer","transformations":[\{"name":"string","parameters":[\{\}]\}],"view_in_my_timezone":"boolean"\}' \
-u <email>:<password>
bytes, err := json.Marshal('\{"aggregation_filters":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{\},"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"aggregations":[\{"function":"string","property":"string"\}],"attributes":[\{"property":"string"\}],"chart_key":"string","conversion_date":\{\},"currency":"string","filters":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"groupings":[\{"property":"string","show_empty":"boolean"\}],"limit":"integer","modifiers":\{\},"ordinations":[\{"direction":"string","nulls":"string","property":"string"\}],"pagination":\{"page":"integer","per_page":"integer"\},"period":\{"from":"string","preset":"string","to":"string"\},"shared_report_id":"integer","transformations":[\{"name":"string","parameters":[\{\}]\}],"view_in_my_timezone":"boolean"\}')
if err != nil {
print(err)
}
req, err := http.NewRequest(http.MethodPost,
"https://focus.toggl.com/api/reports/workspaces/{workspace_id}/query", 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/reports/workspaces/{workspace_id}/query')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "application/json"
req.body = \{"aggregation_filters":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{\},"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"aggregations":[\{"function":"string","property":"string"\}],"attributes":[\{"property":"string"\}],"chart_key":"string","conversion_date":\{\},"currency":"string","filters":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"groupings":[\{"property":"string","show_empty":"boolean"\}],"limit":"integer","modifiers":\{\},"ordinations":[\{"direction":"string","nulls":"string","property":"string"\}],"pagination":\{"page":"integer","per_page":"integer"\},"period":\{"from":"string","preset":"string","to":"string"\},"shared_report_id":"integer","transformations":[\{"name":"string","parameters":[\{\}]\}],"view_in_my_timezone":"boolean"\}.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/reports/workspaces/{workspace_id}/query", {
method: "POST",
body: \{"aggregation_filters":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{\},"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"aggregations":[\{"function":"string","property":"string"\}],"attributes":[\{"property":"string"\}],"chart_key":"string","conversion_date":\{\},"currency":"string","filters":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"groupings":[\{"property":"string","show_empty":"boolean"\}],"limit":"integer","modifiers":\{\},"ordinations":[\{"direction":"string","nulls":"string","property":"string"\}],"pagination":\{"page":"integer","per_page":"integer"\},"period":\{"from":"string","preset":"string","to":"string"\},"shared_report_id":"integer","transformations":[\{"name":"string","parameters":[\{\}]\}],"view_in_my_timezone":"boolean"\},
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/reports/workspaces/{workspace_id}/query', json=\{"aggregation_filters":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{\},"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"aggregations":[\{"function":"string","property":"string"\}],"attributes":[\{"property":"string"\}],"chart_key":"string","conversion_date":\{\},"currency":"string","filters":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"groupings":[\{"property":"string","show_empty":"boolean"\}],"limit":"integer","modifiers":\{\},"ordinations":[\{"direction":"string","nulls":"string","property":"string"\}],"pagination":\{"page":"integer","per_page":"integer"\},"period":\{"from":"string","preset":"string","to":"string"\},"shared_report_id":"integer","transformations":[\{"name":"string","parameters":[\{\}]\}],"view_in_my_timezone":"boolean"\}, 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/reports/workspaces/{workspace_id}/query".to_string())
.json(&serde_json::json!(\{"aggregation_filters":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{\},"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"aggregations":[\{"function":"string","property":"string"\}],"attributes":[\{"property":"string"\}],"chart_key":"string","conversion_date":\{\},"currency":"string","filters":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"groupings":[\{"property":"string","show_empty":"boolean"\}],"limit":"integer","modifiers":\{\},"ordinations":[\{"direction":"string","nulls":"string","property":"string"\}],"pagination":\{"page":"integer","per_page":"integer"\},"period":\{"from":"string","preset":"string","to":"string"\},"shared_report_id":"integer","transformations":[\{"name":"string","parameters":[\{\}]\}],"view_in_my_timezone":"boolean"\}))
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.json()
.await?;
println!("{:#?}", json);
Ok(())
}
Parameters
Path
| name | type | required | description |
|---|
| workspace_id | integer | true | workspace ID |
Query
| name | type | required | description |
|---|
| response_format | string | false | response data format: json_row, table (default) or hierarchical |
| include_dicts | boolean | false | include dictionary data in response; the timesheets dictionary additionally requires the query to project time_entry_id, user_account_id and start_utc, and is never returned on a shared read |
Body
| Name | Type | Description |
|---|
| aggregation_filters | Array of object | Restrict which groups are returned, by their aggregated values. |
| aggregations | Array of object | Functions computed over each group, e.g. the sum of duration. At most 15. |
| attributes | Array of object | Property columns returned for each row. |
| chart_key | string | ChartKey selects which of the shared report's stored chart queries to run. Required whenever SharedReportID is present, and meaningless without it. |
| conversion_date | object | ConversionDate is the profitability report's optional "as of" date: every converted value is looked up at this one date instead of each row's own business/fee date. Optional — omitted means each row uses its own date. Applies to actuals and fixed fees; the forecast always converts at today. A date past our latest published rate falls back to that latest rate (no error). Has no effect unless the request selects a converted property (converted_amount / converted_labor_cost / converted_profit, or converted_revenue on the profitability report). |
| currency | string | Currency is the profitability report's FX-conversion target (ISO 4217). Optional: when omitted, the converted properties target the workspace's configured currency. Malformed input is a 400. Has no effect unless the request selects a converted property (converted_amount / converted_labor_cost / converted_profit, or converted_revenue on the profitability report). |
| filters | Array of object | Restrict which time entries are included. |
| groupings | Array of object | Group rows by each property in order; use with aggregations. |
| limit | integer | Maximum number of rows returned. |
| modifiers | object | Accepts only emptyGroups (boolean). |
| ordinations | Array of object | Sort order of the rows. At most 15. Paginated row-level queries are also sorted by start_utc and time_entry_id in the first ordination's direction, then by selected per-value attributes such as tag_id, so tied rows keep the same order on every page. |
| pagination | object | Page through the rows. |
| period | object | Date range the report covers. |
| shared_report_id | integer | SharedReportID names a shared report to read instead of running this request. Its presence changes what the whole body means: the report runs the owner's stored query as the owner, and every other field here — fragments, pagination — is discarded. Period is the one exception: on an unlocked share that stores a period (a preset or fixed dates) it is the window served, still as the owner. A locked share, and a share that stores no period, discard it. Absent, the request is served by value exactly as it always was. |
| transformations | Array of object | Adjust property values before aggregation, e.g. duration rounding. |
| view_in_my_timezone | boolean | ViewInMyTimezone converts every local time in the report into the requesting user's own timezone instead of the one each entry was tracked in. The timezone itself is never taken from the payload: the API resolves it from the requester's account preference. Restricted to requesters who read other members' time. |
aggregation_filters
| Name | Type | Description |
|---|
| aggregation | object | Aggregation whose result is filtered, as in a HAVING clause. |
| conditions | Array of object | Nested aggregation filters, combined by an and / or operator. |
| operator | string | Operator such as >, <= or is between, or and / or to combine conditions. |
| property | string | The aggregation written as function(property), e.g. sum(duration); send it or aggregation, not both. |
| value | object | Value compared against the aggregated result. |
aggregation
| Name | Type | Description |
|---|
| function | string | One of sum, avg, min, max, count, array or array_ordered. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
conditions
| Name | Type | Description |
|---|
| aggregation | object | Aggregation whose result is filtered, as in a HAVING clause. |
| conditions | Array of object | Nested aggregation filters, combined by an and / or operator. |
| operator | string | Operator such as >, <= or is between, or and / or to combine conditions. |
| property | string | The aggregation written as function(property), e.g. sum(duration); send it or aggregation, not both. |
| value | object | Value compared against the aggregated result. |
aggregation
| Name | Type | Description |
|---|
| function | string | One of sum, avg, min, max, count, array or array_ordered. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
conditions
| Name | Type | Description |
|---|
| aggregation | object | Aggregation whose result is filtered, as in a HAVING clause. |
| conditions | Array of object | Nested aggregation filters, combined by an and / or operator. |
| operator | string | Operator such as >, <= or is between, or and / or to combine conditions. |
| property | string | The aggregation written as function(property), e.g. sum(duration); send it or aggregation, not both. |
| value | object | Value compared against the aggregated result. |
aggregation
| Name | Type | Description |
|---|
| function | string | One of sum, avg, min, max, count, array or array_ordered. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
conditions
| Name | Type | Description |
|---|
| aggregation | object | Aggregation whose result is filtered, as in a HAVING clause. |
| conditions | Array of object | Nested aggregation filters, combined by an and / or operator. |
| operator | string | Operator such as >, <= or is between, or and / or to combine conditions. |
| property | string | The aggregation written as function(property), e.g. sum(duration); send it or aggregation, not both. |
| value | object | Value compared against the aggregated result. |
aggregations
| Name | Type | Description |
|---|
| function | string | One of sum, avg, min, max, count, array or array_ordered. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
attributes
| Name | Type | Description |
|---|
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
conversion_date
filters
| Name | Type | Description |
|---|
| conditions | Array of object | Nested filters, combined by an and / or operator. |
| operator | string | Operator such as =, in or is between, or and / or to combine conditions. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
| value | object | Value compared against; an array for in, contains one of and the between operators. |
conditions
| Name | Type | Description |
|---|
| conditions | Array of object | Nested filters, combined by an and / or operator. |
| operator | string | Operator such as =, in or is between, or and / or to combine conditions. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
| value | object | Value compared against; an array for in, contains one of and the between operators. |
conditions
| Name | Type | Description |
|---|
| conditions | Array of object | Nested filters, combined by an and / or operator. |
| operator | string | Operator such as =, in or is between, or and / or to combine conditions. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
| value | object | Value compared against; an array for in, contains one of and the between operators. |
conditions
| Name | Type | Description |
|---|
| conditions | Array of object | Nested filters, combined by an and / or operator. |
| operator | string | Operator such as =, in or is between, or and / or to combine conditions. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
| value | object | Value compared against; an array for in, contains one of and the between operators. |
groupings
| Name | Type | Description |
|---|
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
| show_empty | boolean | Also return entities with no time in the period; see the endpoint description for where it is allowed. Requires the use_zero_time_rows permission. |
modifiers
ordinations
| Name | Type | Description |
|---|
| direction | string | asc or desc. |
| nulls | string | first or last. |
| property | string | Property to sort by, or an aggregation written as function(property), e.g. sum(duration). |
| Name | Type | Description |
|---|
| page | integer | Page number, starting at 1. Requires per_page. |
| per_page | integer | Number of rows per page. |
period
| Name | Type | Description |
|---|
| from | string | First day of the period, e.g. 2026-09-01. Send from and to, or preset. |
| preset | string | A named period: today, yesterday, thisWeek, prevWeek, weekToDate, last2Weeks, thisMonth, prevMonth, monthToDate, last30Days, last90Days, thisQuarter, lastQuarter, quarterToDate, thisSemester, lastSemester, semesterToDate, last12Months, thisYear, prevYear, yearToDate or allTime. |
| to | string | Last day of the period. |
| Name | Type | Description |
|---|
| name | string | Name of the transformation; round rounds duration and billable_duration and requires the use_report_rounding permission. |
| parameters | Array of Object | Parameters for round: the mode (round_up, round_nearest or round_down), the interval in minutes as a string (1, 5, 6, 10, 12, 15, 30, 60 or 240), and optionally the level (time_entry, the default, or grouping). |
Response
200
Report as JSON
| Name | Type | Description |
|---|
| currency | string | ISO 4217 code every converted_* value is in; set only when the query selects a converted property. |
| data_hierarchical | object | - |
| data_json_row | Array of object | - |
| data_table | object | - |
| dictionaries | object | - |
| total_count | integer | - |
data_hierarchical
data_json_row
dictionaries
| Name | Type | Description |
|---|
| clients | object | - |
| custom_field_options | object | - |
| custom_fields | object | - |
| designations | object | - |
| groups | object | - |
| projects | object | - |
| status | object | - |
| tags | object | - |
| tasks | object | - |
| timesheets | object | - |
| user_tags | object | - |
| users | object | - |
clients
custom_field_options
custom_fields
designations
groups
projects
status
tasks
timesheets
users
400
Invalid request parameters
401
Unauthorized
402
Report view quota exceeded
403
Forbidden — the plan lacks the report export entitlement
404
Shared report or chart not found
422
Currency conversion requested but an FX rate is missing for the period, or the shared report chart cannot be served through a share -- nothing left to render once its member custom fields are removed, or a shape the requested response format cannot render (shared_chart_restricted)
500
Internal server error
POST Generate dictionary from filters
https://focus.toggl.com/api/reports/workspaces/{workspace_id}/query/dictionary
Generates a dictionary containing task, project, client, and status information based on the provided filters.
Two body shapes are accepted. The legacy shape is a bare JSON array of filter criteria (dto.FilterRequest), which remains the way to call this endpoint by value.
The object shape documented below reads a shared report instead: it requires shared_report_id and chart_key, the stored query's filters replace any filters sent with it, and the dictionary resolves through the share owner's entity access.
An object body that names no shared_report_id is rejected as an invalid body.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X POST https://focus.toggl.com/api/reports/workspaces/{workspace_id}/query/dictionary \
-H "Content-Type: application/json" \
-d '[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}]' \
-u <email>:<password>
bytes, err := json.Marshal('[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}]')
if err != nil {
print(err)
}
req, err := http.NewRequest(http.MethodPost,
"https://focus.toggl.com/api/reports/workspaces/{workspace_id}/query/dictionary", 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/reports/workspaces/{workspace_id}/query/dictionary')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "application/json"
req.body = [\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}].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/reports/workspaces/{workspace_id}/query/dictionary", {
method: "POST",
body: [\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],
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/reports/workspaces/{workspace_id}/query/dictionary', json=[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}], 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/reports/workspaces/{workspace_id}/query/dictionary".to_string())
.json(&serde_json::json!([\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}]))
.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 |
|---|
| items | Array of object | - |
items
| Name | Type | Description |
|---|
| conditions | Array of object | Nested filters, combined by an and / or operator. |
| operator | string | Operator such as =, in or is between, or and / or to combine conditions. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
| value | object | Value compared against; an array for in, contains one of and the between operators. |
conditions
| Name | Type | Description |
|---|
| conditions | Array of object | Nested filters, combined by an and / or operator. |
| operator | string | Operator such as =, in or is between, or and / or to combine conditions. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
| value | object | Value compared against; an array for in, contains one of and the between operators. |
conditions
| Name | Type | Description |
|---|
| conditions | Array of object | Nested filters, combined by an and / or operator. |
| operator | string | Operator such as =, in or is between, or and / or to combine conditions. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
| value | object | Value compared against; an array for in, contains one of and the between operators. |
conditions
| Name | Type | Description |
|---|
| conditions | Array of object | Nested filters, combined by an and / or operator. |
| operator | string | Operator such as =, in or is between, or and / or to combine conditions. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
| value | object | Value compared against; an array for in, contains one of and the between operators. |
conditions
| Name | Type | Description |
|---|
| conditions | Array of object | Nested filters, combined by an and / or operator. |
| operator | string | Operator such as =, in or is between, or and / or to combine conditions. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
| value | object | Value compared against; an array for in, contains one of and the between operators. |
Response
200
Successfully generated dictionary
| Name | Type | Description |
|---|
| clients | object | - |
| custom_field_options | object | - |
| custom_fields | object | - |
| designations | object | - |
| groups | object | - |
| projects | object | - |
| status | object | - |
| tags | object | - |
| tasks | object | - |
| timesheets | object | - |
| user_tags | object | - |
| users | object | - |
clients
custom_field_options
custom_fields
designations
groups
projects
status
tasks
timesheets
users
400
Invalid request parameters
401
Unauthorized
403
Forbidden
404
Shared report or chart not found
500
Internal server error
POST Generate workload report
https://focus.toggl.com/api/reports/workspaces/{workspace_id}/workload
Generates a workload report based on the given input.
'period' is optional in the shared dto.QueryRequest schema but required here: it must resolve to concrete bounds, either as 'from' plus 'to' or as a 'preset', and a missing period or one that resolves to nothing is rejected with a 400. The exception is a shared-report marker body ('shared_report_id' plus 'chart_key'), whose stored query supplies the period.
Breakdown reports (grouped by user_account_id) support optional pagination via 'page' and 'per_page', with a maximum per_page of 200.
A breakdown may nest one 'client_id' or 'project_id' grouping under its member rows, with at most one time period grouping beside it; the grouping order is normalised to member, client/project, period.
Nested rows carry logged and billable duration and no capacity of their own. With a time period grouping, the period rows under a client or project repeat the member's 'sum_working_minutes' and 'is_time_off' for that period, which are properties of the member's day rather than of the client or project; they omit the baseline and elapsed sums, so the capacity share below is undefined on them.
Without a time period grouping, each nested row also carries the member's scheduled sums split by the task's project ('sum_scheduled_minutes', 'sum_scheduled_draft_minutes', 'sum_scheduled_remaining_minutes'; a client via its projects), and a project or client with scheduled work but no tracked time gets its own row. With a time period grouping the nested rows omit the scheduled sums, which stay on the member row along with its own per-period cells keyed by the period value.
Paginated response includes 'total_count' with the total number of users matching the filters.
An ordination on 'user_account_id' ('asc' or 'desc') orders breakdown members by display name across the whole result, not just the current page; it defaults to ascending. Ordinations on other properties are passed through to the reporting engine.
Totals rows, trend buckets, and breakdown nodes include full-period working, baseline working, elapsed working, scheduled, scheduled draft, and scheduled remaining sums in minutes.
The fields are 'sum_working_minutes', 'sum_baseline_working_minutes', 'sum_elapsed_working_minutes', 'sum_scheduled_minutes', 'sum_scheduled_draft_minutes', and 'sum_scheduled_remaining_minutes'.
Working minutes exclude public holidays and deduct overlapping PTO. Elapsed working minutes include only dates through the requester's local today.
Baseline working minutes are the same working minutes before those two deductions (public holidays and overlapping PTO added back), so 'sum_working_minutes' over 'sum_baseline_working_minutes' is the share of capacity that remains. It is never zeroed by the forecasting gate.
A shared-report read ('shared_report_id' marker body, or a public link) omits 'sum_baseline_working_minutes' and 'sum_elapsed_working_minutes' entirely, and its users dictionary omits 'weekly_working_hours_is_default'.
Scheduled minutes cover non-draft task estimates, projected unmaterialized recurring periods, and planned calendar events.
Scheduled draft minutes are gross task estimates from visible draft projects. Zero means none or not visible.
A draft legacy calendar task can overlap with its still-planned calendar event, so the draft and scheduled sums are not strictly additive.
Scheduled remaining minutes net each assignee's tracked time and roll unfinished estimates forward from the requester's local today.
Past and overdue task slices are zero, while planned events count only from today.
A breakdown period node shown as time off ('is_time_off' true) also names the dominant policy behind it: 'leave_type' (one of vacation, sick, parental, or other), 'policy_name', and 'emoji'.
All three are added only for a caller who holds 'manage_time_off' on the organization, since the leave category is manager-only. When a period spans several policies, the one with the most minutes labels it.
These three fields are omitted when the period carries no policy-backed leave, for example a holiday-only period.
All three scheduled sums are zeroed unless the caller holds 'view_reports_forecasting', which is mapped to the Premium-only reports_forecasting feature. The response shape is unchanged, so a client without the entitlement degrades to logged-only rather than erroring. 'sum_working_minutes' is never zeroed — capacity is not a forecast.
- cURL
- Go
- Ruby
- JavaScript
- Python
- Rust
curl -X POST https://focus.toggl.com/api/reports/workspaces/{workspace_id}/workload \
-H "Content-Type: application/json" \
-d '\{"aggregation_filters":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{\},"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"aggregations":[\{"function":"string","property":"string"\}],"attributes":[\{"property":"string"\}],"chart_key":"string","conversion_date":\{\},"currency":"string","filters":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"groupings":[\{"property":"string","show_empty":"boolean"\}],"limit":"integer","modifiers":\{\},"ordinations":[\{"direction":"string","nulls":"string","property":"string"\}],"pagination":\{"page":"integer","per_page":"integer"\},"period":\{"from":"string","preset":"string","to":"string"\},"shared_report_id":"integer","transformations":[\{"name":"string","parameters":[\{\}]\}],"view_in_my_timezone":"boolean"\}' \
-u <email>:<password>
bytes, err := json.Marshal('\{"aggregation_filters":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{\},"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"aggregations":[\{"function":"string","property":"string"\}],"attributes":[\{"property":"string"\}],"chart_key":"string","conversion_date":\{\},"currency":"string","filters":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"groupings":[\{"property":"string","show_empty":"boolean"\}],"limit":"integer","modifiers":\{\},"ordinations":[\{"direction":"string","nulls":"string","property":"string"\}],"pagination":\{"page":"integer","per_page":"integer"\},"period":\{"from":"string","preset":"string","to":"string"\},"shared_report_id":"integer","transformations":[\{"name":"string","parameters":[\{\}]\}],"view_in_my_timezone":"boolean"\}')
if err != nil {
print(err)
}
req, err := http.NewRequest(http.MethodPost,
"https://focus.toggl.com/api/reports/workspaces/{workspace_id}/workload", 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/reports/workspaces/{workspace_id}/workload')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = "application/json"
req.body = \{"aggregation_filters":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{\},"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"aggregations":[\{"function":"string","property":"string"\}],"attributes":[\{"property":"string"\}],"chart_key":"string","conversion_date":\{\},"currency":"string","filters":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"groupings":[\{"property":"string","show_empty":"boolean"\}],"limit":"integer","modifiers":\{\},"ordinations":[\{"direction":"string","nulls":"string","property":"string"\}],"pagination":\{"page":"integer","per_page":"integer"\},"period":\{"from":"string","preset":"string","to":"string"\},"shared_report_id":"integer","transformations":[\{"name":"string","parameters":[\{\}]\}],"view_in_my_timezone":"boolean"\}.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/reports/workspaces/{workspace_id}/workload", {
method: "POST",
body: \{"aggregation_filters":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{\},"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"aggregations":[\{"function":"string","property":"string"\}],"attributes":[\{"property":"string"\}],"chart_key":"string","conversion_date":\{\},"currency":"string","filters":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"groupings":[\{"property":"string","show_empty":"boolean"\}],"limit":"integer","modifiers":\{\},"ordinations":[\{"direction":"string","nulls":"string","property":"string"\}],"pagination":\{"page":"integer","per_page":"integer"\},"period":\{"from":"string","preset":"string","to":"string"\},"shared_report_id":"integer","transformations":[\{"name":"string","parameters":[\{\}]\}],"view_in_my_timezone":"boolean"\},
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/reports/workspaces/{workspace_id}/workload', json=\{"aggregation_filters":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{\},"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"aggregations":[\{"function":"string","property":"string"\}],"attributes":[\{"property":"string"\}],"chart_key":"string","conversion_date":\{\},"currency":"string","filters":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"groupings":[\{"property":"string","show_empty":"boolean"\}],"limit":"integer","modifiers":\{\},"ordinations":[\{"direction":"string","nulls":"string","property":"string"\}],"pagination":\{"page":"integer","per_page":"integer"\},"period":\{"from":"string","preset":"string","to":"string"\},"shared_report_id":"integer","transformations":[\{"name":"string","parameters":[\{\}]\}],"view_in_my_timezone":"boolean"\}, 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/reports/workspaces/{workspace_id}/workload".to_string())
.json(&serde_json::json!(\{"aggregation_filters":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{"function":"string","property":"string"\},"conditions":[\{"aggregation":\{\},"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"aggregations":[\{"function":"string","property":"string"\}],"attributes":[\{"property":"string"\}],"chart_key":"string","conversion_date":\{\},"currency":"string","filters":[\{"conditions":[\{"conditions":[\{"conditions":[\{"conditions":[\{\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"operator":"string","property":"string","value":\{\}\}],"groupings":[\{"property":"string","show_empty":"boolean"\}],"limit":"integer","modifiers":\{\},"ordinations":[\{"direction":"string","nulls":"string","property":"string"\}],"pagination":\{"page":"integer","per_page":"integer"\},"period":\{"from":"string","preset":"string","to":"string"\},"shared_report_id":"integer","transformations":[\{"name":"string","parameters":[\{\}]\}],"view_in_my_timezone":"boolean"\}))
.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 |
|---|
| aggregation_filters | Array of object | Restrict which groups are returned, by their aggregated values. |
| aggregations | Array of object | Functions computed over each group, e.g. the sum of duration. At most 15. |
| attributes | Array of object | Property columns returned for each row. |
| chart_key | string | ChartKey selects which of the shared report's stored chart queries to run. Required whenever SharedReportID is present, and meaningless without it. |
| conversion_date | object | ConversionDate is the profitability report's optional "as of" date: every converted value is looked up at this one date instead of each row's own business/fee date. Optional — omitted means each row uses its own date. Applies to actuals and fixed fees; the forecast always converts at today. A date past our latest published rate falls back to that latest rate (no error). Has no effect unless the request selects a converted property (converted_amount / converted_labor_cost / converted_profit, or converted_revenue on the profitability report). |
| currency | string | Currency is the profitability report's FX-conversion target (ISO 4217). Optional: when omitted, the converted properties target the workspace's configured currency. Malformed input is a 400. Has no effect unless the request selects a converted property (converted_amount / converted_labor_cost / converted_profit, or converted_revenue on the profitability report). |
| filters | Array of object | Restrict which time entries are included. |
| groupings | Array of object | Group rows by each property in order; use with aggregations. |
| limit | integer | Maximum number of rows returned. |
| modifiers | object | Accepts only emptyGroups (boolean). |
| ordinations | Array of object | Sort order of the rows. At most 15. Paginated row-level queries are also sorted by start_utc and time_entry_id in the first ordination's direction, then by selected per-value attributes such as tag_id, so tied rows keep the same order on every page. |
| pagination | object | Page through the rows. |
| period | object | Date range the report covers. |
| shared_report_id | integer | SharedReportID names a shared report to read instead of running this request. Its presence changes what the whole body means: the report runs the owner's stored query as the owner, and every other field here — fragments, pagination — is discarded. Period is the one exception: on an unlocked share that stores a period (a preset or fixed dates) it is the window served, still as the owner. A locked share, and a share that stores no period, discard it. Absent, the request is served by value exactly as it always was. |
| transformations | Array of object | Adjust property values before aggregation, e.g. duration rounding. |
| view_in_my_timezone | boolean | ViewInMyTimezone converts every local time in the report into the requesting user's own timezone instead of the one each entry was tracked in. The timezone itself is never taken from the payload: the API resolves it from the requester's account preference. Restricted to requesters who read other members' time. |
aggregation_filters
| Name | Type | Description |
|---|
| aggregation | object | Aggregation whose result is filtered, as in a HAVING clause. |
| conditions | Array of object | Nested aggregation filters, combined by an and / or operator. |
| operator | string | Operator such as >, <= or is between, or and / or to combine conditions. |
| property | string | The aggregation written as function(property), e.g. sum(duration); send it or aggregation, not both. |
| value | object | Value compared against the aggregated result. |
aggregation
| Name | Type | Description |
|---|
| function | string | One of sum, avg, min, max, count, array or array_ordered. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
conditions
| Name | Type | Description |
|---|
| aggregation | object | Aggregation whose result is filtered, as in a HAVING clause. |
| conditions | Array of object | Nested aggregation filters, combined by an and / or operator. |
| operator | string | Operator such as >, <= or is between, or and / or to combine conditions. |
| property | string | The aggregation written as function(property), e.g. sum(duration); send it or aggregation, not both. |
| value | object | Value compared against the aggregated result. |
aggregation
| Name | Type | Description |
|---|
| function | string | One of sum, avg, min, max, count, array or array_ordered. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
conditions
| Name | Type | Description |
|---|
| aggregation | object | Aggregation whose result is filtered, as in a HAVING clause. |
| conditions | Array of object | Nested aggregation filters, combined by an and / or operator. |
| operator | string | Operator such as >, <= or is between, or and / or to combine conditions. |
| property | string | The aggregation written as function(property), e.g. sum(duration); send it or aggregation, not both. |
| value | object | Value compared against the aggregated result. |
aggregation
| Name | Type | Description |
|---|
| function | string | One of sum, avg, min, max, count, array or array_ordered. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
conditions
| Name | Type | Description |
|---|
| aggregation | object | Aggregation whose result is filtered, as in a HAVING clause. |
| conditions | Array of object | Nested aggregation filters, combined by an and / or operator. |
| operator | string | Operator such as >, <= or is between, or and / or to combine conditions. |
| property | string | The aggregation written as function(property), e.g. sum(duration); send it or aggregation, not both. |
| value | object | Value compared against the aggregated result. |
aggregations
| Name | Type | Description |
|---|
| function | string | One of sum, avg, min, max, count, array or array_ordered. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
attributes
| Name | Type | Description |
|---|
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
conversion_date
filters
| Name | Type | Description |
|---|
| conditions | Array of object | Nested filters, combined by an and / or operator. |
| operator | string | Operator such as =, in or is between, or and / or to combine conditions. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
| value | object | Value compared against; an array for in, contains one of and the between operators. |
conditions
| Name | Type | Description |
|---|
| conditions | Array of object | Nested filters, combined by an and / or operator. |
| operator | string | Operator such as =, in or is between, or and / or to combine conditions. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
| value | object | Value compared against; an array for in, contains one of and the between operators. |
conditions
| Name | Type | Description |
|---|
| conditions | Array of object | Nested filters, combined by an and / or operator. |
| operator | string | Operator such as =, in or is between, or and / or to combine conditions. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
| value | object | Value compared against; an array for in, contains one of and the between operators. |
conditions
| Name | Type | Description |
|---|
| conditions | Array of object | Nested filters, combined by an and / or operator. |
| operator | string | Operator such as =, in or is between, or and / or to combine conditions. |
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
| value | object | Value compared against; an array for in, contains one of and the between operators. |
groupings
| Name | Type | Description |
|---|
| property | string | Property name, e.g. user_name or project_custom_field:42; see the endpoint description for every accepted name. |
| show_empty | boolean | Also return entities with no time in the period; see the endpoint description for where it is allowed. Requires the use_zero_time_rows permission. |
modifiers
ordinations
| Name | Type | Description |
|---|
| direction | string | asc or desc. |
| nulls | string | first or last. |
| property | string | Property to sort by, or an aggregation written as function(property), e.g. sum(duration). |
| Name | Type | Description |
|---|
| page | integer | Page number, starting at 1. Requires per_page. |
| per_page | integer | Number of rows per page. |
period
| Name | Type | Description |
|---|
| from | string | First day of the period, e.g. 2026-09-01. Send from and to, or preset. |
| preset | string | A named period: today, yesterday, thisWeek, prevWeek, weekToDate, last2Weeks, thisMonth, prevMonth, monthToDate, last30Days, last90Days, thisQuarter, lastQuarter, quarterToDate, thisSemester, lastSemester, semesterToDate, last12Months, thisYear, prevYear, yearToDate or allTime. |
| to | string | Last day of the period. |
| Name | Type | Description |
|---|
| name | string | Name of the transformation; round rounds duration and billable_duration and requires the use_report_rounding permission. |
| parameters | Array of Object | Parameters for round: the mode (round_up, round_nearest or round_down), the interval in minutes as a string (1, 5, 6, 10, 12, 15, 30, 60 or 240), and optionally the level (time_entry, the default, or grouping). |
Response
200
Successfully generated workload report
| Name | Type | Description |
|---|
| currency | string | ISO 4217 code every converted_* value is in; set only when the query selects a converted property. |
| data_hierarchical | object | - |
| data_json_row | Array of object | - |
| data_table | object | - |
| dictionaries | object | - |
| total_count | integer | - |
data_hierarchical
data_json_row
dictionaries
| Name | Type | Description |
|---|
| clients | object | - |
| custom_field_options | object | - |
| custom_fields | object | - |
| designations | object | - |
| groups | object | - |
| projects | object | - |
| status | object | - |
| tags | object | - |
| tasks | object | - |
| timesheets | object | - |
| user_tags | object | - |
| users | object | - |
clients
custom_field_options
custom_fields
designations
groups
projects
status
tasks
timesheets
users
400
Invalid request parameters
403
Insufficient permissions
404
Shared report or chart not found
422
Shared report chart cannot be served through a share -- nothing left to render once its member custom fields are removed, or a shape the requested response format cannot render (shared_chart_restricted)
500
Internal server error