[New] Categories for Time Tracking Entries

[New] Categories for Time Tracking Entries

Summary

The Asana API now supports Time Tracking Categories — a way to label time tracking entries with categories like “Development,” “Meetings,” or “Design Review.” Categories give managers enhanced visibility into how time is being spent across their teams, enabling more granular reporting and filtering.

This update introduces a new TimeTrackingCategory resource with full CRUD endpoints, and adds a categories field to existing time tracking entry endpoints.

Note: Time tracking categories require the Timesheets & Budgets Add-on (TBAO) to be active on your workspace. API requests to these endpoints from domains without an active TBAO add-on will return a 403 error.

Who is affected

Developers building integrations for:

  • Resource management and workforce planning tools
  • Financial reporting and billing systems
  • Custom timesheet interfaces and dashboards

Permissions:

  • Admins can create, update, and delete categories
  • All users can read categories and assign them to their own time tracking entries

Timeline

This is available now!

For complete details on time tracking entries, visit the Asana API documentation.

Usage

TimeTrackingCategory model

The full TimeTrackingCategory response includes:

Field Name Type Description
gid string The unique global ID of the category
name string The display name (e.g., “Development”). Must be unique within the workspace
color string The color for display purposes. Accepted values: none, red, orange, yellow-orange, yellow, yellow-green, green, blue-green, aqua, blue, indigo, purple, magenta, hot-pink, pink, cool-gray
is_archived boolean If true, the category cannot be assigned to new entries but remains visible on existing ones

New endpoints

List categories

Returns a paginated list of categories for a workspace.

GET /time_tracking_categories?workspace={workspace_gid}

Required scope: time_tracking_categories:read

The workspace parameter is required. You can optionally filter by is_archived to retrieve only active or only archived categories.
Note: This endpoint returns a compact representation that includes gid, name, and color but does not include is_archived. Use the single-resource endpoint to get the full model.

Example request:

// GET /time_tracking_categories?workspace=12345&is_archived=false

{
  "data": [
    {
      "gid": "67890",
      "name": "Development",
      "color": "blue"
    },
    {
      "gid": "67891",
      "name": "Meetings",
      "color": "green"
    }
  ]
}

Get a single category

Returns the full TimeTrackingCategory model including is_archived.
Required scope: time_tracking_categories:read

// GET /time_tracking_categories/67890

{
  "data": {
    "gid": "67890",
    "name": "Development",
    "color": "blue",
    "is_archived": false
  }
}

Create a category (Admin only)

Required scope: time_tracking_categories:write

// POST /time_tracking_categories

{
  "data": {
    "workspace": "12345",
    "name": "Design Review",
    "color": "purple"
  }
}

Response:

{
  "data": {
    "gid": "67892",
    "name": "Design Review",
    "color": "purple",
    "is_archived": false
  }
}

Update a category (Admin only)

Required scope: time_tracking_categories:write

// PUT /time_tracking_categories/67892

{
  "data": {
    "name": "Design Reviews",
    "color": "red"
  }
}

You can also archive a category by setting is_archived to true. Archived categories cannot be assigned to new entries but remain visible on existing ones.

Delete a category (Admin only)

Required scope: time_tracking_categories:delete

DELETE /time_tracking_categories/{time_tracking_category_gid}

This permanently deletes the category. Returns an empty data record. This action cannot be undone.

List time entries by category

Returns a paginated list of time tracking entries for a specific category. Supports optional start_date and end_date filters for date range queries — useful for reporting workflows.

Required scope: time_tracking_categories:read

GET /time_tracking_categories/{time_tracking_category_gid}/time_tracking_entries
Parameter Type Required Description
start_date string No Filter entries on or after this date (ISO 8601 format)
end_date string No Filter entries on or before this date (ISO 8601 format)
limit integer No Pagination limit
offset string No Pagination offset token

Example request and response:

// GET /time_tracking_categories/67890/time_tracking_entries?start_date=2026-01-01&end_date=2026-03-31&limit=10

{
  "data": [
    {
      "gid": "98765",
      "resource_type": "time_tracking_entry",
      "duration_minutes": 120,
      "entered_on": "2026-02-11",
      "categories": [
        {
          "gid": "67890",
          "name": "Development",
          "color": "blue"
        }
      ]
    }
  ]
}

Updated endpoints

The categories field has been added to the following time tracking entry routes:

Endpoint Method Change
/tasks/{task_gid}/time_tracking_entries POST Accept and return categories
/time_tracking_entries/{time_tracking_entry_gid} PUT Accept and return categories
/time_tracking_entries/{time_tracking_entry_gid} GET Returns categories
/time_tracking_entries GET Returns categories

Note: The categories field is structured as an array of GIDs in requests and returns an array of TimeTrackingCategoryCompact objects in responses. The initial implementation enforces a maximum of one (1) category per entry. This limit may be expanded in the future.

Creating a time entry with a category

// POST /tasks/{task_gid}/time_tracking_entries

{
  "data": {
    "duration_minutes": 60,
    "entered_on": "2026-02-10",
    "categories": ["67890"]
  }
}

Response:

{
  "data": {
    "gid": "11111",
    "resource_type": "time_tracking_entry",
    "duration_minutes": 60,
    "entered_on": "2026-02-10",
    "categories": [
      {
        "gid": "67890",
        "name": "Development",
        "color": "blue"
      }
    ],
    "created_by": {
      "gid": "12345",
      "resource_type": "user",
      "name": "Greg Sanchez"
    }
  }
}

Key constraints

Constraint Details
Category limit Maximum of 500 active (non-archived) categories per workspace
Unique names Category names must be unique within a workspace
Archived categories Cannot be assigned to new entries (returns 400 error)
Single category per entry Only one category can be assigned per time tracking entry (returns 400 if more than one is provided)

Authentication & scopes

To interact with these resources, your app must request the following OAuth scopes:

Scope Required for
time_tracking_categories:read All GET endpoints on categories and entries by category
time_tracking_categories:write POST and PUT endpoints on categories
time_tracking_categories:delete DELETE endpoint on categories

Resources

1 Like