The `subtasks` field on tasks is being deprecated

Hi everyone,

To increase the speed and stability of the API, we are transitioning to a world with fewer non-paginated fields.

Deprecations are never fun. Thankfully, this one only affects a small number of apps and we’ve built a workaround that will be useful for many more Asana developers.

What’s Going to Break

The subtasks field on tasks is being deprecated. For example, these requests will fail:

GET /tasks/task-id/opt_expand=subtasks
GET /tasks/task-id/opt_expand=this.subtasks+
GET /tasks/task-id/opt_expand=this.subtasks.subtasks

This was never an official part of our API, however, it was accidentally leaked and a small percentage of developers started using it.

The subtasks field on tasks will be permanently deprecated from the API in 3 months.

The Fix

We have a new task field num_subtasks that allows apps to know how many subtasks are on a task. Use num_subtasks to check if a task has subtasks and then make a subsequent request to GET /tasks/task-id/subtasks to fetch the subtasks instead of requesting them as a field on the parent task.

If you have questions, please ask them in this topic and we’ll be happy to answer them.


Thanks for the details. Just out of curiosity: are you able to know who’s using such a feature and warn them directly? Have a great week-end :wave:

1 Like

@Bastien_Siebman Yes! A direct email is going out next week to every developer that has registered an app that is using the sub_tasks field on tasks. Thankfully, it’s only about 100 people.

1 Like

Awesome! Wow 100 is a lot! I never thought there were so many developers out there :heart_eyes:

That’s actually only a small percentage of the number of active apps. We need to get more people on the community!

1 Like

Just received the email about this change.

Our organization uses subtasks heavily, and we’re using the API to visualize them. If I understand this change, it means that what we’ve been doing in one request (grabbing all tasks and their immediate subtasks) is going to become 40-50 requests. Is that accurate?

Furthermore, the events API doesn’t say it works on subtasks, and I see no push mechanism, so it appears that we have no choice but to poll using all 40-50 requests each time. Is that accurate as well?


Our customers at Everhour also use subtasks a lot.

Everhour provides time tracking possibilities for Asana tasks and subtasks. But now it will require us do much more requests to sync all project tasks.

Do you have alternative option API to get all project tasks & subtasks?


Hi @Brian_Victor, you are correct that it will require more API calls to get all of the subtasks in a project. Without knowing your exact workflow and how deep your subtasks go, I’m not certain how many more requests it will take.

While it was never meant to be supported, you can currently get all of the tasks and subtasks in a project with a single call (GET /projects/project-id/opt_expand=subtasks+). Unfortunately, this expansion is causing stability issues for the API. Once the subtasks field is deprecated, you would need to make this request using the tasks field num_subtasks instead of subtasks+. You can then make subsequent requests on each task that contains subtasks until "num_subtasks": 0.

You can reduce the number of requests required by using the batch API.

Can you tell me a bit more about what you’re trying to achieve with events? You can request events on a project and the stories will bubble up from tasks and subtasks (and all nested subtasks). You can also get events on subtasks directly (this is admittedly a bit confusing as the docs say you can only target projects and tasks, but subtasks are actually tasks in the data model that just have parents that are other tasks. If you query a subtask, you will notice that it says "resource_type": "task").

I’m sorry that this change is frustrating (and somewhat confusing) to have to implement. Let us know if there is anything we can do to make it less painful.


1 Like

Hi @Yury,

Thanks for reaching out and sorry that we have to make this change. The new approach for getting all tasks and subtasks in a project using the num_subtasks field instead of subtasks is actually not that different. We have always required pagination, we are now just also requiring it for accessing lower levels of objects. Without getting too far into the weeds, a main reason for this change is because the potential fan-out of subtask expansion is essentially unbounded (i.e. one task can contain nearly infinite subtasks and fetching these types of tasks is causing stability issues that result in us having to ban apps).

Using num_subtasks, the batch API, and events/webhooks, developers can still reasonably fetch (and stay in sync with) all of the tasks and subtasks in a project.


1 Like

@Jeff_Schneider I was asking about events as a way to avoid polling the entire project just to see if anything had changed. From what you say, it appears they might work for that. It would still be nice to have a push mechanism. (Webhooks seem to require running a server and forwarding the pushes to the clients.)

What about a way to request a flattened view of tasks? It would be a dramatic improvement if I could request all tasks and subtasks in the project and reassemble the structure on the client. Still more of a pain than the status quo, but not nearly as bad as the suggested 1+N workaround.

@Brian_Victor As you point out, we have two options for getting changes:

  1. Poll for events on a project, task or subtask (note: that events bubble up, so changes to tasks or subtasks would trigger events on a project).
  2. Get events sent to you with webhooks.

Webhooks do add complexity and require that you have a server to receive them. If your app needs to keep data synced in real time then webhooks are a good option. If changes don’t need to be reflected in real time, fetching events is likely the best approach.

We want to avoid developers being able to get all tasks and subtasks in a single request (that’s one of the reasons we are moving away from subtask expansion). A single task can have an infinite number of subtasks. When apps request tasks with too many subtasks, it causes API stability issues, which causes our API engineers to get paged and they have to ban the app. This is a poor outcome for everyone.

You want to avoid flattened task requests even with pagination and perhaps depth limits? I understand not wanting unbounded responses, but I feel like there must be a way to avoid that without also requiring an explosion of requests. I’m happy to explore ideas with you if you’re open to looking for such a way.

To elaborate on our use case, we have about 40-50 active tasks at a time on the current iteration’s project. Each of those has an average of about 4 subtasks. Currently I can easily get everything in one request. If I had a flattened view, and the limit were 100 at a time, I would require 2, which is tenable. Requesting all subtasks manually requires 41-51 requests. When I’m on mobile and it takes a few seconds to complete one request, that turns into a multiple minute load time. That’s not something that’s going to work.

Hi, we are using lot of these “hidden undocumented sub-queries”, because we don’t know from the root if the container have or not subitems.
This new num_subtasks field is totally welcome.
May I suggest to also add


I just found an issue… if I query my task using opt_fields parameter, I can get this new field.
But, it is not included in the default fields, if I query my task without parameters, like this:
I have num_hearts, num_likes, but no num_subtasks.

This is “as designed” - the num_subtasks field is documented as an opt-in field requiring that you ask for it.


Thank you @Phil_Seeman, I just read that in the documentation page!
It’s the only field with that behavior. But, the documentation is not always 100% accurate, as we get some undocumented fields in return of a single task, like “num_hearts” (number), “hearted” (bool), “hearts” (array)… that’s why I took time to mention that we should get num_subtasks also!

There are a number of fields that are not included by default on tasks, such as html_notes and dependencies. The reason we exclude these fields by default is because they involve extra queries and computation to generate, which slow down our response times. We don’t want to unnecessarily slow down our API for users who don’t actually care about these fields, so we require developers that do care about them to explicitly select them with opt_fields.

Hearts and the associated fields are remnants from the rename from “hearts” to “likes.” We didn’t have the deprecation framework in place at the time and were unable to properly remove these fields. In the future, we may run a deprecation to clean this up, but that would cause work for some developers without any benefit to them.


Hi – is there an update timeline for when the subtasks field will be deprecated?

Hi @Ron_Yang, we are still working with some partners to help them migrate away from using this field. We do not currently have an estimate for when we will fully remove it from the API, but we are encouraging all developers to move away from it as soon as they can.