[New] Subtasks now expose inherited project memberships in the API

Summary

In Asana, a subtask inherits its ancestor tasks’ project associations even when it has not been added to those projects directly. The web and desktop apps already show these inherited projects, but the API has only ever exposed direct project memberships — so integrations could not reconstruct what users see in the product.

We’re closing that gap with two additive, opt-in reads, plus one change to default custom_fields behavior.

New, opt-in — nothing changes unless you ask for it:

  • effective_memberships — a new Task field available via opt_fields. Returns the union of direct and inherited memberships as an array of EffectiveTaskMembership: the same shape as the existing memberships field, plus an is_inherited boolean on each entry.

  • include_inherited_projects — a new query parameter on GET /tasks/{task_gid}/projects(default false). When true, inherited projects are included in the response.

Changing by default:

  • custom_fields on a task now reflects the task’s full effective project set — direct projects plus projects inherited from the entire ancestor chain. Previously it stopped at the immediate parent’s projects, so subtasks nested two or more levels deep were missing field values that the product displays.

Unchanged:

  • projects and memberships continue to return direct memberships only.

  • Write paths (POST /tasks, addProject, removeProject, etc.) continue to modify direct memberships only.

  • GET /workspaces/{workspace_gid}/tasks/search with projects.any already returns tasks that inherit a project via a parent. That behavior is unchanged; we’re documenting it explicitly.

  • Access control. The new field and parameter do not expose projects that your token cannot already read.

Why use effective_memberships? If your integration needs to answer “which projects does this task effectively belong to?” — to mirror what users see in Asana, to sync tasks into external systems by project, or to resolve which custom fields apply to a task — effective_memberships answers it in a single request, with is_inherited telling you whether each association is direct or inherited.

Who is affected

If you read custom_fields on tasks, review this change. It affects default responses. Subtasks nested two or more levels deep may begin returning additional field entries, because custom_fields now includes fields from projects across the full ancestor chain. No existing entries change or disappear — new entries may appear. If your integration iterates over custom_fields, confirm it handles fields it doesn’t recognize gracefully. This is already a good practice, since fields can be added to a project at any time.

If you want inherited project data, it’s opt-in. effective_memberships is returned only when requested via opt_fields, and include_inherited_projects defaults to false. Default responses for projects, memberships, and GET /tasks/{task_gid}/projects are unchanged, as is search behavior.

If you don’t read custom_fields on subtasks, no action is required.

Timeline

This is available now!

Usage

New opt-in field on Tasks: effective_memberships

GET /tasks/1204234?opt_fields=name,effective_memberships.project.name,effective_memberships.section.name,effective_memberships.is_inherited
{
  "data": {
    "gid": "1204234",
    "name": "Draft launch email",
    "effective_memberships": [
      {
        "project": {
          "gid": "1201",
          "resource_type": "project",
          "name": "Q3 Marketing Launch"
        },
        "section": {
          "gid": "4401",
          "resource_type": "section",
          "name": "In Progress"
        },
        "is_inherited": false
      },
      {
        "project": {
          "gid": "1305",
          "resource_type": "project",
          "name": "Company Roadmap"
        },
        "is_inherited": true
      }
    ]
  }
}

Behavior notes:

  • If a task is both directly in a project and inherits that same project from an ancestor, a single entry is returned with is_inherited: false.

  • Inherited entries omit section, since an inherited association has no section placement.

  • The field is also available via opt_fields on the GET /tasks list endpoint.

Response fields

Field Type Description
effective_memberships array Union of direct and inherited memberships
effective_memberships[].project object A project the task is associated with, directly or by inheritance
effective_memberships[].section object Section placement for a direct membership; omitted when inherited
effective_memberships[].is_inherited boolean true if inherited from an ancestor task, false if direct

Required scopes: effective_memberships object requires projects:read and/or project_sections:read, the same as memberships on the Get a task endpoint.

New parameter on the Get projects a task is in endpoint: include_inherited_projects

GET /tasks/1204234/projects?include_inherited_projects=true
{
  "data": [
    {
      "gid": "1201",
      "resource_type": "project",
      "name": "Q3 Marketing Launch"
    },
    {
      "gid": "1305",
      "resource_type": "project",
      "name": "Company Roadmap"
    }
  ]
}
Parameter Type Default Description
include_inherited_projects boolean false When true, inherited projects are included in the response

Omit the parameter, or pass false, and the endpoint returns direct projects only — exactly as it does today. The response shape is unchanged either way.

custom_fields depth change

No request changes are needed. custom_fields on a task now includes field values from every project the task effectively belongs to, including projects inherited from any ancestor task. When the same field is provided by both a direct project and an ancestor’s project, it appears once, with the task’s single value.

Field Change
custom_fields Now reflects field values from the task’s full effective project set (direct projects plus the entire ancestor chain). Previously limited to direct projects and the immediate parent’s projects.

Why we’re making this change

Subtask project inheritance has been visible in the Asana web and desktop apps but absent from the API, leaving integrations unable to reconstruct what users actually see. Exposing inheritance through additive, opt-in reads closes that gap without disrupting existing integrations, and the custom_fields depth change corrects an inconsistency where deeply nested subtasks were missing field values the product displays.

Resources

Questions and Feedback

We’d love to hear from you in this thread, in particular:

  • Does the effective_memberships shape (mirroring memberships plus is_inherited) cover your use cases, or would a projects-only view (like a hypothetical effective_projects) also be useful?

  • If your integration reads custom_fields on deeply nested subtasks, does the depth change cause problems on your side?

5 Likes

Nicely implemented!

I’m just curious - this is more of an architecture than an API question - why the decision was made not to infer the subtask’s section from its parent’s section?

1 Like

Thanks for your question!

Sections represent a task’s actual placement in a project. When subtasks are shown in a project view, they appear beneath their parent inside the parent’s expandable row, so their visual location naturally follows the parent’s section. That doesn’t create a separate section placement for the subtask itself.

Inferring one in the API could also be ambiguous when multiple ancestors belong to the same project in different sections. If the subtask is added directly to the project, its own section is returned.

Here is an example:

  • Task A is in Project P → section “Backlog”
  • Its subtask B is also directly in Project P → section “In Progress”
  • B’s subtask C isn’t directly in Project P

C inherits Project P through both A and B. Because the API returns one deduplicated inherited membership for Project P, it has no unambiguous section: “Backlog” or “In Progress”

Thanks, @Szymon_Wozniak - that makes sense. I figured there was probably a use case that I hadn’t thought through and that was indeed the case!

1 Like

@Dominik_Brdak and @Szymon_Wozniak - this is a fantastic and sensible update! Been waiting for this for a very long time, and thrilled to see it! Thanks for your hard work!

1 Like