To use RescueTime with Bolt.new, prompt Bolt to create an API route that calls RescueTime's Analytic Data API using your API key as a query parameter (key=YOUR_API_KEY). No SDK is required — plain fetch calls to https://www.rescuetime.com/anapi/data work with a time_scope and restrict_kind parameter. Store your key in .env as RESCUETIME_API_KEY. All calls are outbound and work in Bolt's WebContainer — no deployment needed to test the productivity dashboard.
Build a Personal Productivity Dashboard in Bolt.new with RescueTime Data
RescueTime runs silently in the background on your computer, automatically recording every application you use and every website you visit. Unlike manual time trackers such as Toggl or Clockify, you never need to start or stop a timer — RescueTime's data is always there, reflecting exactly how your time was actually spent rather than how you intended to spend it. This passive tracking produces uniquely honest productivity data that can reveal patterns invisible to manual tracking.
RescueTime's Analytic Data API makes this data available programmatically with one of the simplest authentication mechanisms in any productivity API: append key=YOUR_API_KEY as a URL query parameter and you receive your time tracking data as structured JSON. There is no OAuth flow, no token exchange, and no SDK to install. The API returns rows of data with columns for date, time spent (in seconds), number of people (always 1 for personal), productivity pulse (score from -2 to 2), and category name. By adjusting the time_scope parameter (today, yesterday, week, month, year, or specific dates) and the restrict_kind parameter (document, category, activity, overview, productivity) you can query exactly the data you need for each dashboard view.
Building a productivity dashboard in Bolt.new with RescueTime data is particularly satisfying because the data is immediately meaningful — you see your own actual computer usage patterns. Pair it with Recharts for visualization and Supabase for storing daily snapshots, and you have a comprehensive personal productivity tracker that shows trends over time. The entire integration is outbound API calls, so it works fully in Bolt's WebContainer during development. There are no incoming webhooks, no OAuth callbacks, and no deployment required to see real data in your dashboard.
Integration method
Bolt.new integrates with RescueTime through API routes that call RescueTime's Analytic Data API using simple GET requests with your API key as a query parameter. No SDK or OAuth is needed for personal API access — just append key=YOUR_KEY to the request URL. Responses come as JSON with rows of productivity data. All calls are outbound GET requests, so the full integration works in Bolt's WebContainer during development without deploying.
Prerequisites
- A RescueTime account with the RescueTime app installed and running on your computer (data must be collected before the API returns meaningful results)
- Your RescueTime API key from rescuetime.com/anapi/manage (requires a RescueTime account — free tier includes limited API access)
- A Bolt.new project with React, Recharts for charting, and either Vite or Next.js
- Basic understanding of RescueTime's productivity scale: -2 (very distracting) to 2 (very productive)
- Optional: Supabase for storing daily productivity snapshots to build long-term trend charts
Step-by-step guide
Get Your RescueTime API Key
Get Your RescueTime API Key
RescueTime provides API keys for personal data access through their API management page. Unlike OAuth-based APIs where you request access to another user's data, RescueTime's personal API key gives you access to your own account's data only. Navigate to rescuetime.com/anapi/manage while logged in to your RescueTime account. If you have a free RescueTime Lite account, API access is available but limited to 3 months of historical data and the overview data type. The RescueTime Premium plan ($12/month or $78/year as of 2026) unlocks the full API with all data types, unlimited history, and higher query frequency. On the API management page, you will see your existing API key or an option to create one. Click 'Create new API key' and give it a descriptive label like 'Bolt Dashboard'. The key is displayed immediately — it is a long alphanumeric string like 'BuHXXX'. Copy it right away and store it in your password manager. Unlike some APIs that show the key only once, RescueTime allows you to view it again later on the API management page, but it is good practice to save it immediately. Note that this is a personal API key tied to your account — it provides read access to all your RescueTime data. Never share it publicly or commit it to source control. RescueTime's API does not support OAuth on behalf of other users without building a formal RescueTime connected application.
Pro tip: RescueTime's free Lite plan has limited API access. If you need more than 3 months of history or detailed activity-level data, you need the Premium plan. Check your plan at rescuetime.com/dashboard while logged in.
Expected result: You have your RescueTime API key from rescuetime.com/anapi/manage, ready to add to your .env file.
Add API Key to .env and Understand the Query Parameters
Add API Key to .env and Understand the Query Parameters
Add your RescueTime API key to the .env file in your Bolt project as RESCUETIME_API_KEY. This is a server-side-only variable — do not use the VITE_ or NEXT_PUBLIC_ prefix because your API key should never be exposed in browser-side JavaScript. All RescueTime API calls go through your server-side API routes. The RescueTime Analytic Data API endpoint is https://www.rescuetime.com/anapi/data with GET parameters. The key parameters are: key (your API key), format=json (request JSON instead of CSV), perspective (interval for time-based data or rank for sorted summaries), resolution_time (minute, hour, day, week, month — determines data granularity), time_scope (today, yesterday, week, month, year, or a specific date range), restrict_kind (the data category: overview for the productivity summary, category for category breakdown, activity for individual app/website data, productivity for the productivity pulse). For building a productivity dashboard, the most useful combination is restrict_kind=productivity with resolution_time=day to get daily productivity scores. The response is a JSON object with rows_headers (column names array) and rows (array of data rows). The column order matters: for productivity data, the columns are typically [Date, Time Spent Seconds, Number of People, Efficiency (Pulse)]. Map these by index when processing the response. Prompt Bolt to create a base utility function that handles the common API call pattern with error handling.
Add RESCUETIME_API_KEY to .env with a placeholder value. Create lib/rescuetime.ts that exports an async function fetchRescueTime(params: Record<string, string>) which builds a URL to https://www.rescuetime.com/anapi/data?key={RESCUETIME_API_KEY}&format=json and appends all provided params as query parameters. Fetch with GET, throw on non-200 status, and return the parsed JSON. Also export a constant RESCUETIME_API_BASE and a type RescueTimeResponse with rows_headers: string[] and rows: (string | number)[][].
Paste this in Bolt.new chat
1// lib/rescuetime.ts2export const RESCUETIME_API_BASE = 'https://www.rescuetime.com/anapi/data';34export interface RescueTimeResponse {5 rows_headers: string[];6 rows: (string | number)[][];7 notes: string;8}910export async function fetchRescueTime(params: Record<string, string>): Promise<RescueTimeResponse> {11 const url = new URL(RESCUETIME_API_BASE);12 url.searchParams.set('key', process.env.RESCUETIME_API_KEY!);13 url.searchParams.set('format', 'json');14 Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));1516 const response = await fetch(url.toString(), {17 next: { revalidate: 300 }, // Cache for 5 minutes18 });1920 if (!response.ok) {21 throw new Error(`RescueTime API error: ${response.status} ${response.statusText}`);22 }2324 const data = await response.json();2526 if (data.error) {27 throw new Error(`RescueTime error: ${data.error}`);28 }2930 return data;31}Pro tip: RescueTime's API is rate-limited — add revalidate: 300 (5 minutes) to cache responses. The data only updates every few minutes anyway, so caching doesn't degrade data freshness.
Expected result: RESCUETIME_API_KEY is in .env and lib/rescuetime.ts provides a typed utility function for all RescueTime API calls.
Build the Daily Summary API Route
Build the Daily Summary API Route
The daily productivity summary is the most useful view for a RescueTime dashboard — it tells you at a glance how productive today was. The best query for this uses restrict_kind=efficiency with perspective=rank and time_scope=day (or 'today'). Alternatively, restrict_kind=overview with perspective=rank shows all tracked time grouped into productivity categories. The overview data structure lists rows with columns: date, time_spent (seconds), number_of_people, productivity_pulse, category, activity, and document. The productivity_pulse column uses a 5-point scale: 2 (very productive), 1 (productive), 0 (neutral), -1 (distracting), -2 (very distracting). Group the rows by productivity level and sum the time_spent to get totals for each category. Convert seconds to hours and minutes for display. The total productive hours are the sum of time_spent for rows with productivity_pulse > 0. The productivity pulse score (shown as 0-100 in RescueTime's UI) is calculated as (average_productivity + 2) / 4 * 100 across all tracked time. Build an API route that performs this aggregation and returns clean summary data for the dashboard component. Add caching with revalidate: 300 since the data updates every few minutes regardless.
Create an API route at /api/rescuetime/daily that fetches today's data from RescueTime with restrict_kind=overview and perspective=rank and time_scope=day. Group the rows by productivity_pulse value (-2 to 2). Calculate: totalProductiveHours (pulse 1 and 2), totalNeutralHours (pulse 0), totalDistractingHours (pulse -1 and -2), totalTrackedHours (all), productivityScore (0-100: average pulse mapped from [-2,2] to [0,100]). Return these as JSON along with topCategory (the category name with the most time). Cache with revalidate: 300.
Paste this in Bolt.new chat
1// app/api/rescuetime/daily/route.ts2import { NextResponse } from 'next/server';3import { fetchRescueTime } from '@/lib/rescuetime';45export async function GET() {6 try {7 const data = await fetchRescueTime({8 perspective: 'rank',9 restrict_kind: 'overview',10 time_scope: 'today',11 });1213 const rows = data.rows;1415 let productiveSeconds = 0;16 let neutralSeconds = 0;17 let distractingSeconds = 0;18 let totalWeightedPulse = 0;19 let totalSeconds = 0;20 const categoryTotals: Record<string, number> = {};2122 for (const row of rows) {23 const timeSpent = row[1] as number;24 const pulse = row[3] as number;25 const category = row[4] as string;2627 totalSeconds += timeSpent;28 totalWeightedPulse += pulse * timeSpent;29 categoryTotals[category] = (categoryTotals[category] || 0) + timeSpent;3031 if (pulse > 0) productiveSeconds += timeSpent;32 else if (pulse === 0) neutralSeconds += timeSpent;33 else distractingSeconds += timeSpent;34 }3536 const avgPulse = totalSeconds > 0 ? totalWeightedPulse / totalSeconds : 0;37 const productivityScore = Math.round(((avgPulse + 2) / 4) * 100);3839 const topCategory = Object.entries(categoryTotals)40 .sort(([, a], [, b]) => b - a)[0]?.[0] || 'None';4142 return NextResponse.json({43 productiveHours: Math.round(productiveSeconds / 36) / 100,44 neutralHours: Math.round(neutralSeconds / 36) / 100,45 distractingHours: Math.round(distractingSeconds / 36) / 100,46 totalTrackedHours: Math.round(totalSeconds / 36) / 100,47 productivityScore,48 topCategory,49 });50 } catch (error) {51 const message = error instanceof Error ? error.message : 'Failed to fetch RescueTime data';52 return NextResponse.json({ error: message }, { status: 500 });53 }54}Pro tip: RescueTime stores time in seconds. Divide by 3600 for hours, or use Math.round(seconds / 36) / 100 for a clean 2-decimal-place conversion.
Expected result: GET /api/rescuetime/daily returns today's productivity summary with productive, neutral, and distracting hours plus a 0-100 productivity score.
Build the Dashboard UI with Charts
Build the Dashboard UI with Charts
With the API routes in place, build the dashboard UI using Bolt's AI. The main /productivity page should have a clean header showing today's date and a productivity score meter — display the 0-100 score as a large number with a colored ring (green for 70+, yellow for 40-70, red for below 40). Below the score, show four stat cards: Total Tracked Time, Productive Time (green), Neutral Time (gray), and Distracting Time (red). Add a Recharts BarChart below the stats showing a stacked bar with productive/neutral/distracting for each of the last 7 days — fetch this from /api/rescuetime/trends if you have built that route, or skip it initially and add it in a follow-up prompt. For the category breakdown, use a Recharts PieChart with outer radius as a donut and labels showing the percentage. RescueTime categories include human-readable names like 'Software Development', 'Reference & Learning', 'Communication & Scheduling', 'Social Media', 'Entertainment', which can be colored intuitively. Connect to the /api/rescuetime/daily route with a useEffect on the client side. Since all RescueTime API calls are outbound GET requests, this dashboard works completely in Bolt's WebContainer during development — you see your own real RescueTime data immediately. No deployment is needed to build and test the full dashboard experience.
Build a /productivity dashboard page. Fetch from /api/rescuetime/daily on load. Show: a large circular productivity score (0-100, color-coded green/yellow/red), four stat cards (Total Tracked, Productive, Neutral, Distracting hours in hours format like '3h 24m'), a stacked Recharts BarChart for the last 7 days by day of week (fetch from /api/rescuetime/trends with restrict_kind=productivity and time_scope=week), and a donut PieChart for top categories (fetch from /api/rescuetime/categories). Add a refresh button that re-fetches all three APIs. Show skeleton loaders while fetching. Display an error state if the API key is missing with instructions to add RESCUETIME_API_KEY to .env.
Paste this in Bolt.new chat
1// Helper to format seconds as '3h 24m'2export function formatDuration(seconds: number): string {3 const hours = Math.floor(seconds / 3600);4 const minutes = Math.floor((seconds % 3600) / 60);5 if (hours === 0) return `${minutes}m`;6 if (minutes === 0) return `${hours}h`;7 return `${hours}h ${minutes}m`;8}910// Productivity score color11export function getScoreColor(score: number): string {12 if (score >= 70) return '#22c55e'; // green-50013 if (score >= 40) return '#eab308'; // yellow-50014 return '#ef4444'; // red-50015}Pro tip: RescueTime categories have consistent names across accounts. You can hardcode color mappings for 'Software Development' (green), 'Social Media' (red), 'Communication & Scheduling' (yellow), 'Reference & Learning' (blue), 'Entertainment' (red).
Expected result: The /productivity page loads your real RescueTime data showing today's productivity score, time breakdown stats, and category charts. The data updates every time you click Refresh.
Common use cases
Daily Productivity Summary Dashboard
Display today's productivity pulse score, total time tracked, productive vs. distracting time breakdown, and top applications by time spent. Shows at a glance whether you had a focused day or a scattered one, with historical comparison to your weekly average.
Build a productivity dashboard at /productivity. Create an API route at /api/rescuetime/daily that calls RescueTime's Analytic Data API with time_scope=day, restrict_kind=productivity, and perspective=interval. Return today's total productive hours, distracting hours, neutral hours, and productivity pulse score (0-100). Display these as four stat cards at the top of the page. Add a Recharts bar chart showing productive vs. distracting time by hour of the day. Use my RESCUETIME_API_KEY from .env.
Copy this prompt to try it in Bolt.new
Weekly Productivity Trends Chart
Visualize the last 30 days of productivity data as a line chart showing daily productivity pulse over time. Let users spot their most and least productive days of the week, identify burnout patterns, and see whether their focus time has been improving or declining.
Create an API route at /api/rescuetime/trends that fetches the last 30 days of productivity data from RescueTime using restrict_kind=productivity and time_scope=month. Group by day and return an array of { date, productivePulse, productiveHours, distractingHours }. Build a /trends page with a Recharts LineChart showing productivity pulse over the last 30 days and a BarChart comparing productive vs. distracting hours per day. Add a 7-day moving average line. Cache the response for 1 hour.
Copy this prompt to try it in Bolt.new
Category Time Breakdown
Show how time was distributed across high-level categories: Software Development, Communication, Reference, Social Media, Entertainment. Display as a donut chart with percentage labels and a legend. Let users see which category consumed the most time this week and whether it aligns with their priorities.
Create an API route at /api/rescuetime/categories that queries RescueTime with restrict_kind=category and time_scope=week. Return the top 8 categories with time_spent in hours and percentage of total. Build a category breakdown section on my productivity page using a Recharts PieChart with a donut layout. Show category name and hours in the legend. Add color coding: green for productive categories (Software Development, Reference), yellow for neutral, red for distracting (Social Media, Entertainment).
Copy this prompt to try it in Bolt.new
Troubleshooting
API route returns 'Incorrect API key' or 'This call requires API access'
Cause: The RESCUETIME_API_KEY is incorrect, or your RescueTime account plan does not include API access for the specific data type requested.
Solution: Verify your API key at rescuetime.com/anapi/manage and update RESCUETIME_API_KEY in your .env file. If you are on the Lite (free) plan, try using restrict_kind=overview which is included in the free API tier. Some restrict_kind values like 'document' and 'activity' require the Premium plan.
API returns empty rows array even though RescueTime data exists in the web dashboard
Cause: The time_scope parameter is filtering to a period with no tracked data, or the RescueTime app was not running during the queried time period.
Solution: Try time_scope=week or time_scope=month to broaden the query range. Verify that the RescueTime desktop app was active and tracking during the period you are querying. Check rescuetime.com/dashboard to confirm data exists for the date range before debugging your API call.
Recharts PieChart or BarChart renders but shows no data or all zeros
Cause: The data transformation from RescueTime's rows format to Recharts data format has a column mapping error — columns are being indexed by the wrong position.
Solution: Log the rows_headers array from RescueTime to confirm the exact column order for your restrict_kind. Column positions vary by data type — productivity data has different columns than category or activity data. Map column values by name (find the index of 'Time Spent (seconds)' in rows_headers) rather than hardcoding index positions.
1// Dynamic column mapping2const headers = data.rows_headers;3const timeIdx = headers.indexOf('Time Spent (seconds)');4const pulseIdx = headers.indexOf('Productivity');5const categoryIdx = headers.indexOf('Category');6// Then use row[timeIdx], row[pulseIdx], row[categoryIdx]Best practices
- Cache RescueTime API responses for at least 5 minutes — the data is updated every few minutes by the desktop app, so more frequent API calls don't return newer data
- Always proxy RescueTime API calls through server-side routes — never include your API key in browser-side code or VITE_ prefixed variables
- Use the rows_headers array to map column names to indices dynamically rather than hardcoding positions — column order can vary by restrict_kind parameter
- Store daily summaries in Supabase via a scheduled job to build historical trends beyond what the RescueTime API returns for free tier accounts
- Display a clear empty state with setup instructions if the API returns no data — new RescueTime users may not have enough tracked data to populate the dashboard
- Convert all time values from seconds to human-readable format (hours and minutes) in a shared utility function to keep display code clean
- Respect RescueTime's API rate limits — add request deduplication so rapid page refreshes do not fire multiple concurrent API calls
Alternatives
Clockify requires manual time entry but provides team-wide time tracking with project and client attribution, making it better for billing and work management rather than personal focus analysis.
Toggl focuses on manual time tracking with a polished API and strong reporting, ideal for client billing and project management rather than automatic computer usage monitoring.
Time Doctor combines automatic time tracking with employee monitoring features for remote teams, including screenshots and website blocking — going beyond RescueTime's personal focus.
Everhour integrates time tracking directly into project management tools like Asana and Trello, providing context-aware time tracking that RescueTime's passive monitoring cannot match.
Frequently asked questions
Does RescueTime's API require OAuth or just an API key?
RescueTime's personal Analytic Data API uses simple API key authentication — append key=YOUR_KEY as a query parameter to any API request. There is no OAuth flow for accessing your own data. OAuth would only be needed if you were building an application that accesses multiple users' RescueTime data, which requires registering as a RescueTime connected application partner.
Can I access other users' RescueTime data from my Bolt app?
The simple API key approach only gives access to the account the key belongs to. To access multiple users' RescueTime data (for a team dashboard, for example), you would need to build a RescueTime connected application that uses OAuth to get each user's permission. Contact RescueTime about connected application access via their developer documentation.
Does RescueTime API work in Bolt's WebContainer preview?
Yes, completely. RescueTime API calls are simple GET requests from your server-side API route to RescueTime's servers — no incoming webhooks, no OAuth callbacks. Everything is outbound, so it all works in Bolt's WebContainer during development. You see your real RescueTime productivity data immediately without deploying.
How much historical data does RescueTime's API return?
Free (Lite) accounts get up to 3 months of historical data via the API. Premium accounts get unlimited history. When building trend charts, set your time range based on your plan tier to avoid empty responses for dates beyond your history limit.
What is the RescueTime productivity pulse score?
The productivity pulse is a weighted average of RescueTime's productivity categorizations: 2 points for very productive activities, 1 for productive, 0 for neutral, -1 for distracting, and -2 for very distracting. RescueTime displays this as a 0-100 score by mapping the range [-2, 2] to [0, 100]. In your Bolt app, calculate it as: Math.round(((avgPulse + 2) / 4) * 100) where avgPulse is the time-weighted average of productivity values across all tracked activities.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation