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

How to Integrate Retool with Everhour

Connect Retool to Everhour using a REST API Resource with your Everhour API key in the request header. Query time entries, projects, and members to build utilization dashboards that combine Everhour hours with project data from Asana, Jira, or other tools already connected to Retool — providing cross-tool visibility that neither platform offers on its own.

What you'll learn

  • How to generate an Everhour API key and configure it in a Retool REST API Resource
  • How to query time records filtered by project, member, and date range
  • How to build a team utilization dashboard combining Everhour hours with PM tool data
  • How to use JavaScript transformers to aggregate time data into per-member and per-project summaries
  • How to join Everhour project data with Asana or Jira data already connected to Retool
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner14 min read15 minutesProductivityLast updated April 2026RapidDev Engineering Team
TL;DR

Connect Retool to Everhour using a REST API Resource with your Everhour API key in the request header. Query time entries, projects, and members to build utilization dashboards that combine Everhour hours with project data from Asana, Jira, or other tools already connected to Retool — providing cross-tool visibility that neither platform offers on its own.

Quick facts about this guide
FactValue
ToolEverhour
CategoryProductivity
MethodREST API Resource
DifficultyBeginner
Time required15 minutes
Last updatedApril 2026

Build Cross-Tool Time Tracking Dashboards in Retool with Everhour

Everhour's key differentiator is its deep integration with project management tools — time tracking happens inside Asana tasks, Jira issues, and Trello cards, not in a separate app. This means your time data is already organized by the projects and tasks your team actually works with. Retool amplifies this by connecting to Everhour's API alongside your other tools, enabling dashboards that show hours alongside project status, sprint progress, or sales pipeline data in a single view.

Everhour's API provides access to time records, projects (which map to your PM tool projects), team members, clients, and budgets. Authentication is a single API key passed in the X-Api-Key header. The API is paginated and returns JSON for all responses. Time records include the project ID, task ID (from the connected PM tool), team member, and time value in seconds.

Common Retool apps built on Everhour include: team utilization dashboards that combine Everhour hours with Asana project status, project budget trackers that show hours logged vs estimated hours with burn rate, client billing panels that aggregate hours by client across all projects, and sprint time analysis dashboards for engineering teams that overlay Jira sprint data with actual time spent.

Integration method

REST API Resource

Everhour's API uses a simple API key passed in the X-Api-Key request header. Configure a Retool REST API Resource with the Everhour API base URL and this header, then query time records, projects, members, and clients. Retool proxies all requests server-side, keeping your API key secure and eliminating CORS issues.

Prerequisites

  • An Everhour account with at least one connected project management tool or standalone projects
  • An Everhour API key (generated in Everhour Settings → Integrations → API)
  • A Retool account with permission to create Resources
  • Basic familiarity with Retool's Table and Chart components

Step-by-step guide

1

Generate an Everhour API key

Log into your Everhour account and navigate to Settings by clicking the gear icon in the bottom-left sidebar. In the Settings menu, select the 'Integrations' tab, then scroll down to find the 'API' section. Click 'Generate API Key' to create a new key. Everhour displays the key value — copy it immediately. Unlike some platforms, Everhour allows you to regenerate this key at any time, but doing so will invalidate the old key and break any existing integrations. Store the key in a password manager or secure notes app before proceeding. Note that the API key is tied to your user account and inherits your Everhour permissions — if your account has access to all projects and all team members, the API key will too. For team-wide dashboards, use a dedicated admin account's API key to ensure access to all workspace data, not just your own time entries.

Pro tip: Everhour API keys do not expire automatically. If you ever suspect the key has been compromised, regenerate it immediately in Everhour Settings → Integrations → API. Update the Retool configuration variable after regenerating.

Expected result: You have an Everhour API key copied and ready to configure in Retool.

2

Create the Everhour REST API Resource in Retool

In Retool, navigate to the Resources tab in the left sidebar and click 'Create New'. Select 'REST API' from the resource type list. Set the Base URL to 'https://api.everhour.com'. This is Everhour's API base endpoint — all query paths will be appended to this URL. Under the Headers section, add one required header: set the key to 'X-Api-Key' and the value to '{{ retoolContext.configVars.EVERHOUR_API_KEY }}'. Before saving the resource, go to Retool Settings → Configuration Variables and add a new variable named 'EVERHOUR_API_KEY' with your API key value, checking the 'Secret' toggle so it cannot be accessed from frontend code. Return to the resource configuration and save. Click 'Test Resource' or create a quick query to GET '/team/members' — a successful response confirms the API key is valid and the resource is correctly configured. Name the resource 'Everhour' for easy identification across your Retool apps.

resource-config.json
1{
2 "Base URL": "https://api.everhour.com",
3 "Headers": {
4 "X-Api-Key": "{{ retoolContext.configVars.EVERHOUR_API_KEY }}",
5 "Content-Type": "application/json"
6 }
7}

Pro tip: Everhour's API returns a 401 Unauthorized if the X-Api-Key header is missing or the key is invalid. If you see this error after saving the resource, double-check that the header name is exactly 'X-Api-Key' with the capital A and K — header names are case-sensitive in some environments.

Expected result: The Everhour REST API Resource is saved. A test GET to /team/members returns a list of your workspace team members with a 200 response.

3

Query time records with date and project filters

Create a new query in your Retool app using the Everhour resource. Set the method to GET and the path to '/time/records'. Everhour's time records endpoint accepts several query parameters for filtering the results: 'limit' sets the maximum number of records per page (up to 50), 'page' enables pagination starting from 1, 'from' and 'to' accept date strings in YYYY-MM-DD format to filter by date range, 'projects' accepts a comma-separated list of project IDs, and 'users' accepts comma-separated user IDs. Add a DateRangePicker component to your Retool app to drive the 'from' and 'to' parameters dynamically. The time records response is an array of objects, each containing a 'time' field (in seconds — divide by 3600 to get hours), 'date', 'user' object, and 'task' object with the project information. Run the query to inspect the response structure before building transformers.

time-records-query.js
1// GET /time/records
2// Query parameters:
3// from: {{ dateRange.start || new Date(new Date().getFullYear(), new Date().getMonth(), 1).toISOString().split('T')[0] }}
4// to: {{ dateRange.end || new Date().toISOString().split('T')[0] }}
5// limit: 50
6// page: {{ pagination.page || 1 }}
7// users: {{ userFilter.value || '' }}
8// projects: {{ projectFilter.value || '' }}

Pro tip: Everhour stores time values in seconds, not hours. Always divide the 'time' field by 3600 in your transformer to convert to hours. For display, use Math.round(seconds / 3600 * 100) / 100 to get hours rounded to two decimal places.

Expected result: The query returns an array of time records for the selected date range, each showing the user, task, project, and time in seconds logged for that entry.

4

Build a utilization summary transformer

Add a JavaScript transformer to the time records query to aggregate raw records into per-member and per-project summaries. Open the query's Advanced tab and enable 'Transform query results'. The transformer receives the raw array of time records in the 'data' variable and should return a reshaped array suitable for display in a Retool Table or Chart. Group records by user ID, summing the total seconds logged. Convert to hours and calculate a utilization percentage based on a configurable target (such as 8 hours per working day). Add a second grouping by project to show the top projects per user. Bind the transformer output to a Table component by setting the Table's data property to '{{ getTimeRecords.data }}'. Add a Bar Chart component with the summary data to show team-level utilization visually, binding the x-axis to user names and the y-axis to total hours logged.

utilization_transformer.js
1// Transformer: aggregate time records by user
2const records = data || [];
3const userMap = {};
4
5records.forEach(record => {
6 const userId = record.user ? record.user.id : 'unknown';
7 const userName = record.user ? record.user.name : 'Unknown';
8 const projectName = record.task && record.task.projects
9 ? record.task.projects[0]
10 : 'No Project';
11 const hours = (record.time || 0) / 3600;
12
13 if (!userMap[userId]) {
14 userMap[userId] = {
15 user_id: userId,
16 user_name: userName,
17 total_hours: 0,
18 project_breakdown: {}
19 };
20 }
21
22 userMap[userId].total_hours += hours;
23
24 if (!userMap[userId].project_breakdown[projectName]) {
25 userMap[userId].project_breakdown[projectName] = 0;
26 }
27 userMap[userId].project_breakdown[projectName] += hours;
28});
29
30return Object.values(userMap).map(user => ({
31 user_name: user.user_name,
32 total_hours: Math.round(user.total_hours * 100) / 100,
33 top_project: Object.entries(user.project_breakdown)
34 .sort((a, b) => b[1] - a[1])
35 .map(([name, hrs]) => `${name}: ${Math.round(hrs * 10) / 10}h`)
36 .slice(0, 3)
37 .join(', ')
38})).sort((a, b) => b.total_hours - a.total_hours);

Pro tip: If some time records have a null user field (deleted team members), the transformer handles this with a fallback to 'Unknown'. Filter these out with records.filter(r => r.user) before processing if you want clean data.

Expected result: The Table shows each team member's name, total hours, and top projects by time spent for the selected date range. The Chart displays a bar graph comparing total hours across team members.

5

Add project budget tracking and cross-tool data joining

Create a second query to fetch Everhour project data including budget information. Use GET '/projects' with a 'status=active' parameter to get all active projects. The project response includes budget object with 'value' (estimated hours) and 'progress' (total logged seconds). Create a JavaScript transformer that computes the burn rate percentage for each project: (logged_hours / budget_hours) * 100. Display this in a Table with conditional row colors — green for under 70%, yellow for 70-90%, red for over 90% — using Retool's row color feature based on the percentage value. For cross-tool joining, if you have an Asana or Jira resource also configured in Retool, create a JavaScript query that takes '{{ everhourProjects.data }}' and matches project names or IDs against the other tool's project list, merging status and deadline fields. For complex integrations involving multiple Resources, custom transformers, and Workflows, RapidDev's team can help architect and build your Retool solution.

project_budget_transformer.js
1// GET /projects
2// Query parameter: status=active
3
4// Transformer: compute budget burn rate
5const projects = data || [];
6return projects.map(project => {
7 const budgetHours = project.budget && project.budget.value
8 ? project.budget.value
9 : null;
10 const loggedSeconds = project.budget && project.budget.progress
11 ? project.budget.progress
12 : 0;
13 const loggedHours = Math.round(loggedSeconds / 3600 * 100) / 100;
14 const burnPct = budgetHours && budgetHours > 0
15 ? Math.round((loggedHours / budgetHours) * 100)
16 : null;
17
18 return {
19 project_id: project.id,
20 project_name: project.name,
21 budget_hours: budgetHours || 'No budget',
22 logged_hours: loggedHours,
23 remaining_hours: budgetHours ? Math.max(0, budgetHours - loggedHours) : 'N/A',
24 burn_pct: burnPct !== null ? `${burnPct}%` : 'N/A',
25 status: burnPct === null ? 'no_budget'
26 : burnPct < 70 ? 'on_track'
27 : burnPct < 90 ? 'at_risk'
28 : 'over_budget'
29 };
30}).sort((a, b) => {
31 const order = { over_budget: 0, at_risk: 1, on_track: 2, no_budget: 3 };
32 return order[a.status] - order[b.status];
33});

Pro tip: Everhour's budget.value field stores hours as a decimal number (e.g., 40 = 40 hours). The budget.progress field stores logged time in seconds, not hours — always convert by dividing by 3600 before comparing against the budget value.

Expected result: The project table shows all active projects sorted by budget risk, with over-budget projects at the top. Row colors visually indicate project health status.

Common use cases

Build a team utilization dashboard combining Everhour and Asana data

Query Everhour time records for the current period grouped by team member, then join with Asana project status using a JavaScript query in Retool. Display each team member's total hours, hours by project category, and utilization percentage alongside the projects they are contributing to. This gives managers visibility into where team capacity is actually going across all active initiatives.

Retool Prompt

Build a Retool team utilization dashboard that queries Everhour time records for the current month, groups hours by team member, and shows total hours, billable hours, and top three projects by time spent for each person. Include a bar chart comparing utilization rates across the team.

Copy this prompt to try it in Retool

Create a project budget and burn rate tracker

Pull Everhour project data including budget hours and logged hours for all active projects. Calculate the burn rate by comparing total hours logged so far against the project timeline and budget. Flag projects where at the current burn rate the budget will be exceeded before the deadline, giving project managers early warning to adjust scope or resources.

Retool Prompt

Create a Retool project health panel showing all active Everhour projects with budget hours, total logged hours, remaining hours, percentage consumed, and a projected completion date based on current burn rate. Highlight rows in red where projected hours exceed budget.

Copy this prompt to try it in Retool

Build a client billing summary panel for finance teams

Query all Everhour time records grouped by client across all projects in the current billing period. Apply each client's billing rate to calculate billable amounts. Display a summary table showing total hours, billable hours, non-billable hours, and estimated invoice amount per client. Let finance teams review and adjust before generating invoices in their accounting tool.

Retool Prompt

Build a Retool client billing panel showing all Everhour clients with total hours logged this month, billable hours, and estimated billing amount based on an hourly rate configured in a Retool editable table. Include a total row and an export button.

Copy this prompt to try it in Retool

Troubleshooting

API returns 401 Unauthorized on every request

Cause: The X-Api-Key header is missing, the key value is incorrect, or the header name is spelled or capitalized incorrectly. Everhour requires this exact header name to authenticate requests.

Solution: Navigate to Everhour Settings → Integrations → API and verify your API key is still active — it may have been regenerated since you configured the resource. In Retool, open the Everhour resource settings and confirm the header name is exactly 'X-Api-Key' and the value correctly references your configuration variable. Test by temporarily hardcoding the key to rule out variable substitution issues.

Time records query returns fewer records than expected or appears incomplete

Cause: Everhour paginates the /time/records endpoint with a maximum of 50 records per page. If the selected date range covers more than 50 time entries, only the first page is returned by default without a 'page' parameter.

Solution: Add a Pagination component to your Retool app and bind its current page to the 'page' query parameter in your time records query. For bulk data exports, use Retool Workflows to loop through all pages: start at page 1, check if the response length equals 50 (indicating more pages exist), and continue incrementing until a partial page is returned. Combine results into a single array.

Project IDs in time records do not match the IDs returned by the /projects endpoint

Cause: Everhour time records associate time with tasks (from the connected PM tool), not directly with Everhour projects. The project information is nested inside the task object as task.projects — this is an array of project IDs, not a direct project reference.

Solution: Access the project ID via record.task.projects[0] in your transformer. Fetch the /projects list separately in a second query, build a lookup object keyed by project ID, and use it to enrich each time record with the project name and budget information. Run the projects query with 'Run when page loads' enabled so the lookup table is available before the transformer runs.

Dashboard shows no data for some team members who have logged time

Cause: The API key belongs to a user account that does not have admin permissions in Everhour, limiting access to their own time records rather than all workspace members' records.

Solution: In Everhour, navigate to Settings → Team and ensure the account whose API key you are using has an Admin role. If you cannot change the role, create a dedicated admin service account, add it to the workspace with Admin permissions, and generate a new API key from that account's settings. Update the Retool configuration variable with the new key.

Best practices

  • Store your Everhour API key in Retool configuration variables marked as secret — never hardcode it directly in query headers or transformer code
  • Always include date range filters when querying time records — open-ended queries across large workspaces can be slow and may hit pagination limits requiring multiple requests
  • Build a team members lookup query that runs on app load and store results in a Retool state variable — use this to populate dropdown filters with user names instead of requiring users to know numeric IDs
  • Cache the projects query in Retool's query caching settings for 10-15 minutes — project lists change infrequently and do not need real-time refresh on every interaction
  • Use Retool Workflows for end-of-week or end-of-month reports that aggregate large date ranges — Workflows can loop through all pagination pages and export combined results to Google Sheets or send via email
  • Divide all time values by 3600 in transformers immediately after receiving the API response — Everhour stores time in seconds throughout its API, and doing the conversion once in the transformer prevents confusion in downstream calculations
  • When joining Everhour data with Asana or Jira data in a JavaScript query, match on project names rather than IDs since each tool uses its own internal ID system for the same projects

Alternatives

Frequently asked questions

Does Retool have a native Everhour connector?

No, Retool does not have a native Everhour connector. You connect using a REST API Resource with your Everhour API key in the X-Api-Key header. Everhour's REST API is straightforward and well-documented, providing access to time records, projects, team members, clients, and budget data.

Can I create and edit time records from Retool?

Yes. Use POST to /time/records to create new time entries with a JSON body containing the task ID, user ID, time in seconds, and date. Use PUT to /time/records/{id} to update existing records. Use DELETE to /time/records/{id} to remove entries. All write operations require the API key to belong to a user with appropriate permissions for the project being modified.

How do I get project IDs and user IDs for filtering queries?

Make GET requests to /projects and /team/members endpoints respectively. These return all accessible projects and team members with their Everhour IDs. Build Select dropdown components in your Retool app populated from these queries, then bind their selected values to the filter parameters in your time records query. This avoids requiring users to know internal numeric IDs.

Can I access Everhour time data for tasks from Asana or Jira?

Yes. Everhour's API returns task objects that include the connected PM tool's task ID in the task.foreignId field and the platform name in task.type (e.g., 'asana', 'jira'). You can use these foreign IDs to join Everhour time data with Asana or Jira data from other Retool Resources, enabling dashboards that show time logged alongside task status and project milestones.

Are there rate limits on the Everhour API?

Everhour enforces rate limiting on API requests, though the exact limits are not publicly documented. For typical Retool dashboard use with cached queries refreshing every few minutes, you are unlikely to hit limits. For Workflows that process large datasets in loops, add a short delay between iterations and handle 429 responses by waiting and retrying.

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.