This article explains how to move historical time tracking data from Everhour into Asana’s native Timesheets and Budgets add-on. By following these steps, you can consolidate your team’s time data, ensuring accurate project reporting and budget tracking within a single platform.
The migration begins by retrieving your existing data. To ensure you have all historical logs for your team, follow these steps:
To successfully attribute time to the correct records in Asana, your data must map to existing Asana GIDs (Global Identifiers). In an Everhour export, Asana-synced tasks often include a prefix.
|
Data Field |
Everhour Export Label (Sample) |
Required Asana Target |
|
Task ID |
task.id (e.g., as:1212815283326608) |
The numeric GID (e.g., 1212815283326608) |
|
Project ID |
task.projects |
Asana Project GID |
|
Time Spent |
time (Seconds) |
Asana duration_minutes |
Note
When processing the export, ensure you strip any as: prefixes from IDs to match Asana's internal GID format.
Step 3: Implement the migration script (Python)
The script below uses the Asana Create Time Tracking Entry API to recreate logs. The logic utilizes email addresses to match users between systems, ensuring that time is attributed to the correct team member.
import asanaimport json# Initialize Asana Clientclient = asana.Client.access_token('YOUR_PERSONAL_ACCESS_TOKEN')workspace_gid = "YOUR_WORKSPACE_GID"def migrate_everhour_to_asana(json_file_path, user_mapping_file_path):with open(json_file_path) as f:entries = json.load(f)# 1. Fetch Asana users to map emails to GIDsasana_users = {u['email']: u['gid'] for u in client.users.get_users_for_workspace(workspace_gid, opt_fields=['email', 'gid'])}# 2. Load a mapping of Everhour User IDs to Emails# (e.g., from Everhour's Team Member export)with open(user_mapping_file_path) as f:everhour_user_emails = {user['id']: user['email'] for user in json.load(f)}for entry in entries:everhour_user_id = entry['user']user_email = everhour_user_emails.get(everhour_user_id)# Match user by emailasana_user_gid = asana_users.get(user_email)if not asana_user_gid:continue# Clean Task ID (remove 'as:' prefix)task_gid = entry['task']['id'].replace("as:", "")# Convert seconds to minutes for Asana APIduration_mins = entry['time'] // 60# 3. Create entry in Asanatry:client.time_tracking_entries.create_time_tracking_entry(task_gid, {'created_by': asana_user_gid,'duration_minutes': duration_mins,'entered_on': entry['date'],'description': entry.get('comment', '')})print(f"Successfully migrated {duration_mins}m for Task {task_gid}")except Exception as e:print(f"Error for entry {entry['id']}: {e}")migrate_everhour_to_asana('time_2026_01.json', 'users.json')
Why Migrate to Native Asana Time Tracking?
Moving your data into Asana allows you to leverage the full power of the Timesheets and Budgets addon: