Skip to main content
RapidDev - Software Development Agency
retool-integrationsREST API Resource

How to Integrate Retool with Toggl

Connect Retool to Toggl Track using a REST API Resource targeting the Toggl API v9 (api.track.toggl.com/api/v9). Authenticate with Basic Auth using your API token as the username and the literal string 'api_token' as the password. Query time entries, projects, clients, and the Reports API to build utilization dashboards, project billing reports, and team timesheet overviews with Retool Charts and Tables.

What you'll learn

  • How to obtain your Toggl API token and configure Basic Auth in a Retool REST API Resource
  • How to query Toggl time entries and the Reports API for aggregated time data
  • How to build a team utilization dashboard showing billable versus non-billable hours by project
  • How to use JavaScript transformers to aggregate Toggl's time entries into project-level summaries
  • How to join Toggl time entry data with project and client information for billing reports
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner16 min read25 minutesOtherLast updated April 2026RapidDev Engineering Team
TL;DR

Connect Retool to Toggl Track using a REST API Resource targeting the Toggl API v9 (api.track.toggl.com/api/v9). Authenticate with Basic Auth using your API token as the username and the literal string 'api_token' as the password. Query time entries, projects, clients, and the Reports API to build utilization dashboards, project billing reports, and team timesheet overviews with Retool Charts and Tables.

Quick facts about this guide
FactValue
ToolToggl
CategoryOther
MethodREST API Resource
DifficultyBeginner
Time required25 minutes
Last updatedApril 2026

Why connect Retool to Toggl?

Toggl Track's built-in reports are good for individual time review, but agencies and teams often need custom aggregations that Toggl's native interface cannot provide: billable hours by client across multiple projects in a single view, utilization rates calculated against contracted hours, or payroll-ready timesheet exports combining Toggl hours with rates from a separate billing system. Retool removes these constraints by querying the Toggl API and presenting time data in fully customizable dashboards.

The most impactful use case is a project billing dashboard that shows billable and non-billable hours per project per week, calculates revenue at configured hourly rates, and identifies which projects are over or under their time budgets. Agency operations teams can use this to prepare client invoices, identify scope creep early, and compare estimated versus actual hours for project planning. Retool's Table component handles the aggregation display while JavaScript transformers handle the grouping and calculation logic.

Toggl's API has two distinct surfaces: the main v9 API for CRUD operations on time entries, projects, clients, and workspaces, and the Reports API (api.track.toggl.com/reports/api/v3) for pre-aggregated analytics data. The Reports API is particularly useful for Retool dashboards because it returns data already summed by project, client, or user for a date range — avoiding the need to fetch and aggregate thousands of raw time entries in a JavaScript transformer for longer reporting periods.

Integration method

REST API Resource

Toggl Track connects via Retool's REST API Resource targeting the Toggl API v9 at https://api.track.toggl.com/api/v9. Authentication uses HTTP Basic Auth with a unique format: the API token as the username and the literal string 'api_token' as the password — this is converted to a Base64 Authorization header by Retool automatically when using the Basic Auth method. All API requests proxy through Retool's server-side infrastructure, keeping credentials secure. You query time entries, workspaces, projects, and the detailed Reports API for analytics.

Prerequisites

  • A Toggl Track account with workspace admin access to view team data
  • Your Toggl API token from Profile Settings → Profile tab → API Token at the bottom of the page
  • The workspace ID for your Toggl workspace (visible in the Toggl web app URL or from the /me/workspaces API endpoint)
  • Toggl Track Starter plan or higher for the Reports API (the free plan has limited API access)
  • A Retool account with Resource creation permissions

Step-by-step guide

1

Find your Toggl API token

Toggl Track provides a personal API token in your profile settings. This token grants access to all workspaces your account belongs to and does not expire unless manually regenerated. In the Toggl Track web app (track.toggl.com), click your name or avatar in the bottom left of the sidebar to open the account menu. Select Profile Settings. On the Profile Settings page, scroll to the very bottom of the page. In the section labeled API Token, you will see your current API token displayed as a string of lowercase alphanumeric characters. Click the eye icon to reveal it if it is masked. Click Copy to clipboard. If you need to regenerate the token (e.g., for security reasons), click Reset and confirm — this immediately invalidates the old token. Note your workspace ID as well: you can find it by clicking your workspace name in the Toggl sidebar, then selecting Settings — the workspace ID appears in the browser URL (track.toggl.com/workspaces/{id}/settings). Alternatively, call the /me/workspaces endpoint after setting up the Resource to retrieve all workspaces your account has access to. The workspace_id is required for most workspace-scoped endpoints including the Reports API. Most teams have a single workspace, but multi-workspace accounts must specify the correct workspace_id for each query.

Pro tip: Toggl's API uses a unique Basic Auth convention: the API token is the username, and the literal string 'api_token' (not your actual password) is the password. This is not a bug — it is how Toggl's API is designed. When configuring Retool's Basic Auth, set Username to your token value and Password to the literal text 'api_token'.

Expected result: You have your Toggl API token (a 32-character hexadecimal string) and your workspace ID. Both are needed for configuring the Retool Resource and writing queries.

2

Configure the Toggl API Resource in Retool

In Retool, navigate to the Resources tab and click Add Resource. Select REST API from the list. Name the resource Toggl Track API. In the Base URL field, enter https://api.track.toggl.com/api/v9 — this is the current Toggl API v9 base URL. Toggl's API has two separate base URLs: the main API (api.track.toggl.com/api/v9) for CRUD operations, and the Reports API (api.track.toggl.com/reports/api/v3) for analytics. You will need two separate Resources in Retool to access both, since they have different base URLs. Create the main API Resource now. In the Authentication section, select Basic Auth from the dropdown (not Bearer Token — Toggl uses Basic Auth with a special password value). Set the Username field to {{ config.TOGGL_API_TOKEN }} and the Password field to api_token — literally the text 'api_token', not a variable. This is Toggl's documented authentication method: the API token acts as the username while the literal string 'api_token' serves as the password in the Basic Auth pair. Create the configuration variable: navigate to Settings → Configuration Variables. Click Add variable, name it TOGGL_API_TOKEN, paste your Toggl API token as the value, and enable the secret toggle. Click Save on the Toggl Track API Resource. Test it by creating a GET query to /me — this returns your user profile including your id and all workspace memberships. Create a second Resource named Toggl Reports API with Base URL https://api.track.toggl.com/reports/api/v3 using the same Basic Auth configuration. The Reports API requires the same credentials as the main API.

Pro tip: Retool's Basic Auth configuration automatically Base64-encodes the username:password pair and adds the Authorization: Basic [encoded] header to every request. You do not need to manually encode or add the Authorization header — selecting Basic Auth in the Resource configuration handles this entirely.

Expected result: Two Retool Resources are saved: Toggl Track API (for time entries and project CRUD) and Toggl Reports API (for analytics). A test GET query to /me on the main API returns your user profile, confirming authentication works.

3

Query the Reports API for project-level aggregates

For dashboard use, the Toggl Reports API is more efficient than the raw time entries API because it returns pre-aggregated data. Create a query targeting your Toggl Reports API Resource. Set Method to POST (the Reports API v3 uses POST for summary reports despite being a read operation). Set Path to /workspace/{{ retoolContext.configVars.TOGGL_WORKSPACE_ID }}/summary/time_entries. Set the Body type to JSON. The request body specifies your report parameters: add start_date set to {{ formatDate(dateRangePicker.value[0], 'YYYY-MM-DD') }}, end_date set to {{ formatDate(dateRangePicker.value[1], 'YYYY-MM-DD') }}, and grouping set to 'projects' to aggregate by project. Optionally add sub_grouping set to 'users' for a breakdown by user within each project. The Reports API returns a groups array where each group represents a project with its total seconds worked, billable seconds, and sub-groups showing per-user breakdowns. Add a JavaScript transformer to convert the seconds values to hours, join with project and client names using a lookup from the /workspace/{id}/projects endpoint, and format the output for display. Create a second GET query to /workspace/{{ retoolContext.configVars.TOGGL_WORKSPACE_ID }}/projects on the main Toggl Track API Resource to fetch project metadata including project names, client associations, and whether the project is billable.

reports_transformer.js
1// JavaScript transformer for Toggl Reports API summary response
2// Input: data = Reports API summary response object
3// Also references: getProjects.data = project list from main API
4const groups = data.groups || [];
5const projects = getProjects.data || [];
6
7// Build project lookup map
8const projectMap = {};
9projects.forEach(p => {
10 projectMap[p.id] = {
11 name: p.name,
12 client_id: p.client_id,
13 billable: p.billable,
14 color: p.color
15 };
16});
17
18return groups.map(group => {
19 const projectId = group.id;
20 const project = projectMap[projectId] || {};
21 const totalSeconds = group.seconds || 0;
22 const billableSeconds = group.billable_seconds || 0;
23
24 return {
25 project_id: projectId,
26 project_name: project.name || `Project ${projectId}`,
27 is_billable: project.billable || false,
28 total_seconds: totalSeconds,
29 billable_seconds: billableSeconds,
30 non_billable_seconds: totalSeconds - billableSeconds,
31 hours_total: (totalSeconds / 3600).toFixed(2),
32 hours_billable: (billableSeconds / 3600).toFixed(2),
33 hours_display: `${Math.floor(totalSeconds / 3600)}h ${Math.floor((totalSeconds % 3600) / 60)}m`,
34 billable_pct: totalSeconds > 0
35 ? ((billableSeconds / totalSeconds) * 100).toFixed(0) + '%'
36 : '0%'
37 };
38}).sort((a, b) => b.total_seconds - a.total_seconds);

Pro tip: The Toggl Reports API v3 uses POST for its summary and details endpoints because the request body can contain complex filter configurations. This is intentional API design, not a mistake. Do not try to convert these to GET requests — they will return a 405 error.

Expected result: The Reports API query returns an array of project-level summaries with total hours, billable hours, and billable percentage. The data is sorted by total hours descending and is ready to bind to a Table component.

4

Build the utilization and billing dashboard

With project aggregates available, build the billing dashboard. Add a DateRangePicker at the top of the canvas defaulting to the current month (first to last day). Add a Select dropdown for client filtering — populate it from a GET query to /workspace/{{ retoolContext.configVars.TOGGL_WORKSPACE_ID }}/clients on the main Toggl API. Drag a Table component and bind it to the Reports transformer output. Configure columns: Project Name, Hours Total, Hours Billable, Hours Non-Billable, and Billable %. Add conditional formatting to highlight rows where billable percentage falls below a threshold (reference a Number input for the minimum billable rate target). Add a Stat component row at the top with three key metrics: Total Hours tracked (sum of all hours), Total Billable Hours (sum of billable hours), and Blended Billable Rate (total billable hours / total hours as a percentage) — compute these in a JavaScript query. Drag a Bar Chart and bind it to the project aggregates, setting the X axis to project_name and adding two data series: hours_billable (green) and non_billable_seconds converted to hours (orange) — this creates a stacked bar showing the split between billable and non-billable work per project at a glance. Add a Line Chart bound to a second Reports API query with grouping set to 'days' to show daily hours trend over the selected period.

period_summary.js
1// JavaScript query: period-level summary stats for Stat components
2const projects = getReportSummary.data || [];
3
4const totalSeconds = projects.reduce((s, p) => s + (p.total_seconds || 0), 0);
5const billableSeconds = projects.reduce((s, p) => s + (p.billable_seconds || 0), 0);
6const nonBillableSeconds = totalSeconds - billableSeconds;
7
8return {
9 total_hours: (totalSeconds / 3600).toFixed(1),
10 billable_hours: (billableSeconds / 3600).toFixed(1),
11 non_billable_hours: (nonBillableSeconds / 3600).toFixed(1),
12 billable_rate: totalSeconds > 0
13 ? ((billableSeconds / totalSeconds) * 100).toFixed(0) + '%'
14 : '0%',
15 project_count: projects.length
16};

Pro tip: For revenue calculations (hours × rate), avoid storing hourly rates in Toggl — instead, maintain a rates table in Retool Database or a connected PostgreSQL database and join Toggl hours with rates in a JavaScript transformer. This keeps billing rates in your own systems where they are auditable and access-controlled.

Expected result: A complete billing dashboard shows period-total Stats, a project-by-project hours Table with billable percentage, a stacked Bar Chart of billable versus non-billable hours, and a daily hours trend Line Chart. All data updates when the date range picker changes.

5

Add raw time entry view and export

Supplement the summary view with a detailed time entries panel for auditing individual sessions. Create a GET query targeting /workspace/{{ retoolContext.configVars.TOGGL_WORKSPACE_ID }}/time_entries on the main Toggl Track API Resource. Add URL parameters: start_date and end_date for the date range, and optionally user_ids for team member filtering. The time entries endpoint returns individual sessions with description, project_id, start, stop, duration (in seconds — negative values indicate a currently running timer), billable flag, and tags. Add a JavaScript transformer to enrich entries with project names from the projects lookup and format the duration into hours:minutes display strings. Drag a second Table component onto the canvas (place it in a Tab container to keep the layout clean) and bind it to the enriched time entries. Configure the Table with: Description, Project, User, Date, Start, End, Duration, and Billable columns. Add a CSV export button — in Retool, add a Button component with an event handler that triggers a downloadFile action, passing the Table data formatted as CSV. This creates a one-click export of filtered time entries for payroll or invoice documentation. For production agency tools integrating Toggl billing data with project management systems, client portals, and accounting software in Retool, RapidDev's team can architect comprehensive billing operations platforms.

time_entries_transformer.js
1// JavaScript transformer for raw time entries
2// Adds project names and formats duration for display
3const entries = data || [];
4const projects = getProjects.data || [];
5
6const projectMap = {};
7projects.forEach(p => { projectMap[p.id] = p.name; });
8
9return entries
10 .filter(e => e.duration > 0) // Exclude currently running timers
11 .map(entry => {
12 const durationSec = entry.duration || 0;
13 const hours = Math.floor(durationSec / 3600);
14 const minutes = Math.floor((durationSec % 3600) / 60);
15 const seconds = durationSec % 60;
16
17 return {
18 id: entry.id,
19 description: entry.description || '(no description)',
20 project_name: projectMap[entry.project_id] || 'No Project',
21 project_id: entry.project_id,
22 date: entry.start ? entry.start.substring(0, 10) : '',
23 start_time: entry.start ? new Date(entry.start).toLocaleTimeString() : '',
24 end_time: entry.stop ? new Date(entry.stop).toLocaleTimeString() : '',
25 duration_seconds: durationSec,
26 duration_display: `${hours}h ${String(minutes).padStart(2, '0')}m`,
27 billable: entry.billable ? 'Yes' : 'No',
28 tags: entry.tags?.join(', ') || ''
29 };
30 })
31 .sort((a, b) => new Date(b.date) - new Date(a.date));

Pro tip: In Toggl's API, a duration value of -1 indicates a time entry that is currently running (the timer has been started but not stopped). Filter out entries with negative durations when building historical reports — include them only if building a live activity panel showing currently active timers.

Expected result: A detailed time entries Table shows individual sessions with project names, durations, and billable flags. A CSV export button downloads the filtered entries. The summary Tab and detail Tab provide two complementary views of the same time period.

Common use cases

Project utilization and billing dashboard

Build a Retool dashboard showing billable and non-billable hours per project for the current month, with revenue calculations at configured rates. A Table shows each project with total hours, billable hours, billable percentage, and estimated revenue. A Bar Chart compares hours across projects. A date range picker controls the reporting period, and a client filter narrows the view to a single client's projects.

Retool Prompt

Build a Retool Toggl billing dashboard that queries the Toggl Reports API for all projects in a workspace for the current month. Show a Table with project name, client name, total hours, billable hours, and estimated revenue (hours × rate from a configuration). Add a Bar Chart comparing billable hours by project. Include a client filter Select and a date range picker.

Copy this prompt to try it in Retool

Team timesheet overview for payroll

Create a Retool weekly timesheet dashboard showing hours logged by each team member per project, suitable for payroll processing. Query the Toggl Reports API with the user dimension to get per-user aggregates, then pivot the data in a JavaScript transformer to create a user-by-project matrix. Export the matrix as a downloadable CSV formatted for payroll input.

Retool Prompt

Build a Retool Toggl team timesheet report that queries the Reports API for all users in a workspace for a selected week. Create a pivot table (users as rows, projects as columns, hours at intersection) in a JavaScript transformer. Display the pivot in a Retool Table with row totals. Add a week selector and CSV export button.

Copy this prompt to try it in Retool

Live timer and recent entries panel

Build a Retool panel showing the current running timer (if any) across team members alongside their last 10 time entries. Query the /me/time_entries endpoint for recent entries and the /time_entries/current endpoint for the active timer. Display a status board showing who is currently tracking time and for how long, useful for team leads to see real-time work activity.

Retool Prompt

Build a Retool Toggl live activity panel that queries the current running time entry for each team member. Show a status grid with user name, current task description, project, and elapsed time. Below the status grid, show the last 10 time entries in a Table with description, project, duration, and start/end times. Auto-refresh every 60 seconds.

Copy this prompt to try it in Retool

Troubleshooting

API returns 403 Forbidden on all requests, even /me

Cause: The Basic Auth credentials are incorrectly configured — either the API token is wrong, or the password field is not set to the literal string 'api_token'.

Solution: In the Retool Resource configuration, verify the Basic Auth password field contains exactly the text 'api_token' (all lowercase, with underscore) — not your Toggl account password and not the word 'password'. Verify the API token in the Username field matches the token shown in Toggl Profile Settings. A common mistake is pasting the token into the Password field and using 'api_token' as the Username — the order matters.

Reports API returns 405 Method Not Allowed

Cause: The Reports API v3 summary and details endpoints require POST requests, not GET. Using GET on these endpoints returns a 405 error.

Solution: Change the query Method from GET to POST. The Toggl Reports API v3 uses POST for its /summary/time_entries and /details/time_entries endpoints even though they are read operations. Set the Body type to JSON and include the required parameters (start_date, end_date, grouping) in the request body rather than as URL parameters.

Time entry durations show as negative numbers in the transformer

Cause: Toggl uses a duration value of -1 (or other negative values) for time entries where the timer is currently running. The stop time has not been set yet, so the duration cannot be computed.

Solution: Add a filter step in the JavaScript transformer to exclude entries with duration less than or equal to 0: const entries = data.filter(e => e.duration > 0);. For a live activity panel, handle negative durations separately by computing elapsed time as the difference between the current time and the entry's start timestamp.

typescript
1// Filter out currently-running entries for historical reports
2const completedEntries = data.filter(entry => entry.duration > 0);
3// For live entries, compute elapsed:
4const liveEntries = data
5 .filter(entry => entry.duration < 0)
6 .map(entry => ({
7 ...entry,
8 elapsed_seconds: Math.floor((Date.now() - new Date(entry.start).getTime()) / 1000)
9 }));

Reports API returns an empty groups array for date ranges where entries exist

Cause: The workspace_id in the Reports API URL path is incorrect, or the requesting account does not have visibility into team time entries (requires admin role in the workspace).

Solution: Verify the workspace_id by querying /me/workspaces on the main Toggl API and confirming the correct ID. Ensure the API token belongs to an account with Workspace Admin role — regular workspace members can only see their own time entries, not the full team's data through the Reports API. Check the workspace admin role in Toggl Settings → Team.

Best practices

  • Store the Toggl API token in a Retool configuration variable marked as secret — the token provides full read/write access to your Toggl account, including the ability to modify and delete time entries.
  • Use the Reports API (api.track.toggl.com/reports/api/v3) for date-range aggregations and the main API (api.track.toggl.com/api/v9) for individual entry CRUD — the Reports API is far more efficient for dashboard use cases than fetching and aggregating raw time entries.
  • Create separate Retool Resources for the main Toggl API and the Reports API since they have different base URLs — do not try to handle both from a single Resource with path overrides.
  • Cache Reports API queries for at least 15 minutes — Toggl time data does not update in real time for reporting purposes, and caching significantly reduces API calls when multiple team members view the dashboard.
  • Use workspace admin credentials for team reporting queries — non-admin accounts can only access their own time entries through the API, making them unsuitable for team utilization dashboards.
  • Filter out time entries with negative duration values (currently-running timers) when computing historical totals — include them only in live activity views where you want to show active timers.
  • Join project and client data from the /projects and /clients endpoints into a lookup map rather than making per-entry API calls — build the map once and reference it in the transformer for efficient enrichment.

Alternatives

Frequently asked questions

Why does Toggl's Basic Auth use 'api_token' as the password instead of my account password?

This is Toggl's documented API authentication convention. The API token is treated as a username credential, and the password field is always the literal string 'api_token' as a signal to Toggl's authentication system that you are using token-based auth rather than password-based auth. This allows Toggl to support both authentication modes (email/password and token) through the same Basic Auth mechanism. When configuring Retool's Basic Auth, set Username to your API token value and Password to the exact text 'api_token'.

What is the difference between the Toggl main API and the Reports API, and which should I use in Retool?

The main API (api.track.toggl.com/api/v9) handles CRUD operations on individual resources: creating, reading, updating, and deleting time entries, projects, clients, and workspace settings. The Reports API (api.track.toggl.com/reports/api/v3) returns pre-aggregated analytics data — totals by project, user, or client for a date range. For dashboard use cases in Retool, prefer the Reports API for date-range analytics and use the main API for managing individual time entries and projects.

Can I query time entries for all team members, or only for the token owner?

Workspace admins can query time entries for all workspace members through the Reports API. The detailed reports endpoint (/workspace/{id}/details/time_entries) accepts a user_ids filter to specify which users' entries to include. For the main API's /time_entries endpoint, regular members only see their own entries. Ensure your Retool integration uses a token from a workspace admin account to access team-wide data.

Does Toggl's API support creating or editing time entries from Retool?

Yes. POST to /workspace/{id}/time_entries with a JSON body containing description, project_id, start, duration, and billable fields to create a new time entry. PATCH to /workspace/{id}/time_entries/{id} to update an existing entry. DELETE to /workspace/{id}/time_entries/{id} to delete an entry. These mutations require the token to have appropriate workspace permissions. Add confirmation dialogs in Retool before any delete operations.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Integrations are where projects stall

We wire Retool integrations like this one every week — auth, webhooks, edge cases included. Fixed-price builds from $13K, delivered in 6–10 weeks.

Talk to an integration engineer

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.