# Migrate from GET /workspaces/{id} with loadAll for workspace hierarchies

The legacy operation `GET /2.0/workspaces/{workspaceId}?loadAll=true` retrieves an entire workspace hierarchy in a single call, but with an unbounded result set. This approach can strain performance, increase network latency, and consume unnecessary resources. It has been deprecated in favor of more efficient, granular operations.

This article shows you how to build a workspace hierarchy by combining calls to two replacement operations:

- [`GET /2.0/workspaces/{workspaceId}/children`](/api/smartsheet/openapi/workspaces/get-workspace-children)
- [`GET /2.0/folders/{folderId}/children`](/api/smartsheet/openapi/folders/get-folder-children)


The examples use the **Smartsheet Python SDK**, but the same principles apply to other Smartsheet SDKs and REST API clients.

Tip
Instead of fetching an entire hierarchy, consider querying items in a specific folder or the workspace root. To identify an item's workspace or locate an item's folder without traversing the hierarchy, use the `GET /2.0/<resource_name>/{id}/path` operation. For example, `GET /sheets/{id}/path` returns the item's full path—its workspace and all parent folders—in a single call.

Once you've identified a workspace or folder of interest, you can examine its metadata with `GET /2.0/<resource_name>/{id}/metadata` and retrieve its children with the `GET /2.0/<resource_name>/{id}/children`.

## At a glance

Here's what's involved with traversing a workspace hierarchy:

1. Get the workspace's immediate child folders via the `get_workspace_children(...)` function.
2. Get the full-depth folder structure by using recursion and calling the `get_folder_children(...)` function.


Note
The example uses [token-based pagination](/api/smartsheet/guides/basics/pagination#token-based-pagination) to page through results returned from the operations.

Tip
The example demonstrates getting the nested folders only, but you can update the `children_resource_types` parameter (a list) to retrieve sheets, reports, and dashboards (referred to as `sights`).

## Example code

Here's an example Python module that demonstrates traversing a workspace hierarchy to store a representation of it in a variable called `workspace_tree`.


```python
import argparse
import os

import smartsheet
from smartsheet.models import Folder

class TreeNode:
    def __init__(self, name, id):
        self.name = name
        self.id = id
        self.children = []  # List to store child nodes

    def add_node(self, child):
        self.children.append(child)
        
    def print_hierarchy(self, level=0):
        indent = "  " * level
        print(f"{indent}- {self.name} (ID: {self.id})")
        
        # Recursively call this method for every child child
        for child in self.children:
            child.print_hierarchy(level + 1)

def expand_tree(smart: smartsheet.Smartsheet, folder_node: TreeNode):
    # Recursively get each folder's child folders
    last_key = None

    def traverse_folder(node: TreeNode) -> None:
        # Page through results based on the token called last_key. None value gets the first page.
        last_key = None
        while True:
            # Call Folders.get_folder_children(...) to get the folder's immediate child folders
            response = smart.Folders.get_folder_children(
                node.id, children_resource_types=["folders"], last_key=last_key
            )
            assert isinstance(response, smartsheet.models.paginated_children_result.PaginatedChildrenResult)
            
            for child in response.data:
                if type(child) is Folder:
                    new_node = TreeNode(child.name, child.id)
                    folder_node.add_node(new_node)
                    traverse_folder(new_node)
            
            last_key = getattr(response, "last_key", None)
            if not last_key:
                break
        
    traverse_folder(folder_node)

def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("workspace_id", type=int, help="Smartsheet workspace ID")
    args = parser.parse_args()

    token = os.getenv("SMARTSHEET_API_TOKEN")
    if not token:
        raise RuntimeError("Missing required environment variable: SMARTSHEET_API_TOKEN")

    workspace_id = args.workspace_id

    smart = smartsheet.Smartsheet(token)

    # Build a tree to store the workspace folder hierarchy
    workspace_tree = TreeNode("Workspace", workspace_id)
    
    # Page through results based on the token called last_key. None value gets the first page.
    last_key = None
    while True:
        # Call Workspaces.get_workspace_children(...) to get the workspace's immediate child folders
        response = smart.Workspaces.get_workspace_children(
            workspace_id, children_resource_types=["folders"], last_key=last_key
        )
        assert isinstance(response, smartsheet.models.paginated_children_result.PaginatedChildrenResult)

        for child in response.data:
            if type(child) is Folder:
                new_node = TreeNode(child.name, child.id)
                workspace_tree.add_node(new_node)
                expand_tree(smart, new_node)

        last_key = getattr(response, "last_key", None)
        if not last_key:
            break

    workspace_tree.print_hierarchy()

if __name__ == "__main__":
    main()
```

## Code walkthrough

Here are the steps taken to creating the example code.

### Step 1: Define a class to store the workspace hierarchy

Create a class to store each element's name and ID.

For example,


```python
class TreeNode:
    def __init__(self, name, id):
        self.name = name
        self.id = id
        self.children = []  # List to store child nodes

    def add_node(self, child):
        self.children.append(child)
```

You can expand on this to save additional metadata.

### Step 2: Instantiate the tree root

Create a tree root node to store the workspace metadata.


```python
workspace_tree = TreeNode("Workspace", workspace_id)
```

### Step 3: Get the workspace children

Call `get_workspace_children(...)` to get the workspace's immediate children.

The example, retrieves the workspace's immediate folders.


```python
last_key = None

// The while loop is left out for demonstrating this step.

response = smart.Workspaces.get_workspace_children(
    workspace_id, children_resource_types=["folders"], last_key=last_key
)
```

Pass in `last_key` set to `None` to get the first page of children.

Set the `children_resource_types` parameter to a list of all the types you want. The example gets folders only, but you can specify a comma separated list of strings that represent any of the valid types.

For example,


```python
children_resource_types=["folders","sheets","reports","sights"]
```

### Step 4: Page through the child data

Page through the results using the `last_key` token parameter and process the workspace's immediate folders.


```python
last_key = None
while True:
    response = smart.Workspaces.get_workspace_children(
        workspace_id, children_resource_types=["folders"], last_key=last_key
    )
    assert isinstance(response, smartsheet.models.paginated_children_result.PaginatedChildrenResult)

    for child in response.data:
        if type(child) is Folder:
            new_node = TreeNode(child.name, child.id)
            workspace_tree.add_node(new_node)
            expand_tree(smart, new_node)

    last_key = getattr(response, "last_key", None)
    if not last_key:
        break
```

The `while` loop continues until the `get_workspace_children(...)` function returns an empty `last_key` response attribute. This is how token-based pagination works.

The `for` loop iterates over the child data, checks its type, adds a tree node that represents the child, and continues processing the folder hierarchy with `expand_tree(...)` (explained next).

### Step 5: Define recursive logic for the folders

Define logic to recursively traverse folders and add child metadata to the tree.

The example accomplishes the following `expand_tree(...)` function.


```python
def expand_tree(smart: smartsheet.Smartsheet, workspace_tree: TreeNode):
    # Recursively get each folder's child folders
    last_key = None

    def traverse_folder(node: TreeNode) -> None:
        # Page through results based on the token called last_key. None value gets the first page.
        last_key = None
        while True:
            # Call Folders.get_folder_children(...) to get the folder's immediate child folders
            response = smart.Folders.get_folder_children(
                node.id, children_resource_types=["folders"], last_key=last_key
            )
            assert isinstance(response, smartsheet.models.paginated_children_result.PaginatedChildrenResult)
            
            for child in response.data:
                if type(child) is Folder:
                    new_node = TreeNode(child.name, child.id)
                    workspace_tree.add_node(new_node)
                    traverse_folder(new_node)
            
            last_key = getattr(response, "last_key", None)
            if not last_key:
                break
    
    traverse_folder(workspace_tree)
```

The function uses an inner function called `traverse_folder(...)` to recursively traverse the Smartsheet workspace folders.

The `traverse_folder(...)` does these things:

- Calls `get_folder_children` to get folder children (in this case, folders).
- Adds a tree node for each child folder.
- Continues to the next page of results (if any) with token-based pagination.


## Conclusion

That's how to get a workspace's hierarchy!

Note
As an added bonus (and for verification) the example prints the workspace hierarchy.

See the `TreeNode` class' `print_hierarchy(...)` function that's called at the end of `main` with `workspace_tree.print_hierarchy()`

As you process workspace hierarchies, consider these additional options:

- Specify the child types you want (sheets, reports, sights) via the `children_resource_types` comma-separated string list parameter in calls to `get_workspace_children(...)` and `get_folder_children(...)`.
- Get metadata on the workspace or folders with `get_workspace_metadata(...)` or `get_folder_metadata(...)` respectively.


## Related topics

[Migrate from `GET /workspaces/{id}`](/api/smartsheet/guides/updating-code/migrate-from-get-workspace)

[Pagination - SDK examples](/api/smartsheet/guides/basics/pagination-sdk-examples)

[Token-based pagination](/api/smartsheet/guides/basics/pagination#token-based-pagination)