[ New ] Out of Office API and deprecation of vacation_dates

[ New ] Out of Office API and deprecation of vacation_dates

Summary

We are introducing the new OooEntry resource to the Asana API, enabling support for multiple out-of-office periods per user. This updates Asana’s OOO model from a single, read-only date range to a flexible, multi-entry system with full CRUD support.

As part of this change, the vacation_dates object (containing start_on and end_on) on the Workspace Membership resource is being deprecated and will eventually be removed.

Key highlights:

  • New endpoints: Full CRUD support via /ooo_entries for managing user absences
  • Granular control: Each OooEntry includes a start_date, end_date, user, and workspace
  • Improved filtering: Query absences by date range, with pagination support
  • Write access: Developers can now programmatically create, update, and delete OOO entries, enabling direct syncs with HR and calendar tools
  • Legacy deprecation: The vacation_dates object on Workspace Membership is deprecated in favor of the new /ooo_entries endpoints

Who is affected

This change primarily affects developers who manage user availability or sync OOO data from external HR and calendar systems.

Impact on existing applications:

  • If your integration reads vacation_dates.start_on and vacation_dates.end_on from workspace memberships: you should migrate to querying GET /ooo_entries filtered by user and workspace. During the deprecation period, vacation_dates will continue to be returned, but it represents only a single date range: specifically, the user’s current or next upcoming OOO entry. If a user has multiple OOO periods scheduled, the remaining entries will not be visible through vacation_dates. To get the complete OOO entries, use the new /ooo_entries endpoint.
  • If your integration only reads other workspace membership fields (e.g., is_active, is_admin): no action is required.
  • New capability: Since there was previously no programmatic way to set vacation dates, developers can now use POST /ooo_entries to automate OOO status from tools like calendars or HR systems.

During the transition, vacation_dates on workspace memberships will continue to return a single date range derived from the user’s current or next upcoming OOO entry. This ensures existing integrations continue to function, but it cannot represent multiple scheduled absences. Developers are encouraged to migrate to the new /ooo_entries endpoints for complete and accurate OOO data.


Deprecation details

What is being deprecated

Deprecated field Resource Replacement
vacation_dates.start_on Workspace Membership start_date on OooEntry
vacation_dates.end_on Workspace Membership end_date on OooEntry

Timeline

Phase Target date Description
General availability ~April 20, 2026 New /ooo_entries endpoints available. Double-write to legacy vacation_dates fields active. vacation_dates still returned by default.
Opt-out (activation) ~July 2026 vacation_dates hidden from Workspace Membership responses by default. Send Asana-Disable: vacation_dates_on_user to temporarily restore the field.
End of deprecation ~October 2026 vacation_dates permanently removed from API responses. Asana-Disable header no longer accepted.

Response headers

During the deprecation period, affected API responses will include an Asana-Change header:

Asana-Change: name=vacation_dates_on_user;info=[changelog_url];affected=true

You can control behavior with request headers:

  • Asana-Disable: vacation_dates_on_user — temporarily restore vacation_dates on workspace membership responses after the field is hidden by default (starting ~July 2026)

For more details on how deprecation headers work, see: Deprecations


New endpoints

Endpoint Method Scope Description
/ooo_entries GET ooo_entries:read Get OOO entries for a user. Requires user and workspace. Supports start_date and end_date filters. Paginated.
/ooo_entries POST ooo_entries:write Create an OOO entry for a user in a workspace.
/ooo_entries/{ooo_entry_gid} GET ooo_entries:read Get a single OOO entry by GID.
/ooo_entries/{ooo_entry_gid} PUT ooo_entries:write Update an existing OOO entry (e.g., change dates).
/ooo_entries/{ooo_entry_gid} DELETE ooo_entries:delete Delete an OOO entry.

Note: Reading user and created_by fields on OOO entries also requires the users:read scope.

OAuth scopes

Scope Permission
ooo_entries:read Read OOO entries
ooo_entries:write Create and update OOO entries
ooo_entries:delete Delete OOO entries
users:read Required to read the user and created_by fields

Response shape

A single OooEntry object:

// GET /ooo_entries/{ooo_entry_gid}
{
  "data": {
    "gid": "999001",
    "resource_type": "ooo_entry",
    "start_date": "2026-02-10",
    "end_date": "2026-02-18",
    "user": {
      "gid": "12345",
      "resource_type": "user",
      "name": "Jamie Smith"
    },
    "created_by": {
      "gid": "67890",
      "resource_type": "user",
      "name": "Alex Chen"
    },
    "workspace": {
      "gid": "11111",
      "resource_type": "workspace",
      "name": "Acme Corp"
    }
  }
}

Response fields

Field Type Description
gid string Globally unique identifier for the OOO entry.
resource_type string The base type of this resource (ooo_entry).
start_date string Start date of the OOO period (ISO date format).
end_date string End date of the OOO period (ISO date format).
user object The user the OOO entry is associated with. Requires users:read scope.
created_by object The user who created the OOO entry. Requires users:read scope.
workspace object The workspace the OOO entry belongs to.

Constraints

  • OOO entries for the same user cannot overlap. Attempting to create an overlapping entry will return a 400 Bad Request error.
  • The start_date must be on or before end_date. Providing a start date after the end date will return a 400 Bad Request error.

Usage

Fetching OOO entries for a user

Retrieve all OOO entries for a specific user in a workspace. Both user and workspace are required parameters:

GET /ooo_entries?user={user_gid}&workspace={workspace_gid}

You can also filter by date range to find entries that intersect with a specific period. For example, to find all current or future OOO entries, pass today’s date as the start date filter:

GET /ooo_entries?user={user_gid}&workspace={workspace_gid}&start_date=2026-04-07

Results are paginated. Use the limit (1–100) and offset parameters to page through results.

Creating an OOO entry

// POST /ooo_entries
{
  "data": {
    "start_date": "2026-03-01",
    "end_date": "2026-03-05",
    "user": "12345",
    "workspace": "67890"
  }
}

Returns the full record of the newly created OOO entry.

Updating an OOO entry

Only the fields provided in the data block will be updated; any unspecified fields will remain unchanged.

// PUT /ooo_entries/{ooo_entry_gid}
{
  "data": {
    "start_date": "2026-03-01",
    "end_date": "2026-03-07"
  }
}

Returns the complete updated OOO entry record.

Deleting an OOO entry

DELETE /ooo_entries/{ooo_entry_gid}

Returns an empty data record.


Migration steps

1. Switch to the new endpoint for reading OOO data

Previously, you could check a user’s OOO status by fetching their workspace membership and reading vacation_dates:

// Old way
GET /workspace_memberships/{gid}?opt_fields=vacation_dates

Now, query the dedicated /ooo_entries endpoint:

// New way
GET /ooo_entries?user={user_gid}&workspace={workspace_gid}

2. Implement write capabilities

Since OOO dates could not be set via API before, you can now build sync logic to update Asana when a user is away. For example, syncing a new absence from an HR tool:

// POST /ooo_entries
{
  "data": {
    "start_date": "2026-03-01",
    "end_date": "2026-03-05",
    "user": "12345",
    "workspace": "67890"
  }
}

3. Handle multi-entry responses

The legacy vacation_dates field returned a single date range. The new /ooo_entries endpoint returns a list of OooEntry objects, since a user may have multiple scheduled absences. Update your application logic to handle arrays of OOO entries.

4. Update your OAuth scopes

If your app uses OAuth, you will need to request the new scopes: ooo_entries:read, ooo_entries:write, and ooo_entries:delete. Reading user details on OOO entries also requires users:read.

Summary of changes

Legacy (vacation_dates) New (OooEntry)
Single start_on / end_on object Multiple OooEntry objects per user
Read-only via API Full CRUD (Create, Read, Update, Delete)
Tied to Workspace Membership Independent /ooo_entries resource
No scopes required (part of workspace membership) Requires ooo_entries:read, ooo_entries:write, ooo_entries:delete

Resources

4 Likes