---
title: "Working with hierarchical tree data in Storage, Messaging, and KMS APIs"
img: https://s3.us-east-2.amazonaws.com/unified-article-images/working_with_hierarchical_tree_data_in_storage_messaging_and_kms_apis-icon.png
date: 2024-11-07T00:00:00.000Z
tag: Guides
description: "This guide explains how to retrieve and traverse hierarchical data structures (i.e., trees) when working with APIs that support parent-child relationships."
url: "https://docs.unified.to/guides/working_with_hierarchical_tree_data_in_storage_messaging_and_kms_apis"
---

# Working with hierarchical tree data in Storage, Messaging, and KMS APIs
------
_November 7, 2024_

This guide explains how to retrieve and traverse hierarchical data structures (i.e., trees) when working with APIs that support parent-child relationships.


## Overview


Many APIs organize their data in tree-like structures, where records can have parent-child relationships with each other.

1. The **File Storage API** represents both folders and files as a single object type, making tree traversal straightforward. While you can think of folders as the 'containers' for other files and folders, the API treats them all as the same object type.
2. The **Messaging API** and **Tasks API** use a simple parent-child relationship where each object type can contain children of the next type (e.g., projects contain tasks, tasks contain comments, channels contain messages). Objects may also have parents of the same type.
3. Some **KMS APIs** have more complex relationships where pages and spaces can reference each other in multiple directions e.g., a mesh. While most KMS platforms use a simple tree structure (like Confluence), some (like Notion) support this more flexible mesh-like organization.

This guide will show you how to efficiently traverse these hierarchical structures to retrieve all the data you need.


## Before you begin


This guide assumes you have:

- Basic understanding of [tree data structures](https://en.wikipedia.org/wiki/Tree_(abstract_data_type))

## Understanding parent-child relationships


When an API endpoint supports a `parent_id` parameter, it typically indicates that the data is organized in a hierarchical structure. To fully traverse this structure, you'll need to:

1. Get the top-level entities (parent nodes)
2. For each parent, retrieve its children by passing the parent's ID
3. Recursively repeat this process for any children that can also be parents
4. For KMS Page, you can use its `has_children` field to determine if there are children pages to query. If `has_children` is equal `false` , then no children pages exist.  Some integrations di not return this information, so if this field is `undefined` or missing, then you should treat it as a `true`

### Example: Messaging platforms


Let's look at how this works with Discord:

1. Discord servers (also called "guilds") are top-level parents
2. Channels exist within servers as children
3. Messages are also related to channels through their `parent_id`
4. To get all channels:
    - First retrieve all guilds (servers)
    - Then get channels for each guild using the guild's ID as the `parent_channel_id`

```javascript
async function getAllChannels(connectionId) {
    // Get all top-level guilds first
    const guilds = await sdk.messaging.listMessagingChannels({
        connectionId,
    });

    let allChannels = [];

    // For each guild, get its channels
    for (const guild of guilds.data) {
        const channels = await sdk.messaging.listMessagingChannels({
            connectionId,
            parentChannelId: guild.id,
        });
        allChannels = allChannels.concat(channels.data);
    }

    return allChannels;
}
```


**API reference:** [Messaging API](https://docs.unified.to/messaging/overview)


### Example: File storage systems


File storage systems are another common example of hierarchical data. Here's how to recursively traverse a file system to get all files:


```javascript
async function getAllFiles(connectionId, parentId) {
    const response = await sdk.storage.listStorageFiles({
        connectionId,
        parentId,
    });

    if (!response.data) {
        return [];
    }

    let allFiles = [];

    for (const item of response.data) {
        if (item.type === 'FOLDER') {
            // Recursively get files from subfolders
            const subfolderFiles = await getAllFiles(connectionId, item.id);
            allFiles = allFiles.concat(subfolderFiles);
        } else {
            allFiles.push(item);
        }
    }

    return allFiles;
}
```


**API reference:** [File](https://docs.unified.to/storage/overview)[ ](https://docs.unified.to/storage/overview)[Storage API](https://docs.unified.to/storage/overview)


## Best practices


When working with hierarchical data:

1. **Implement pagination**: Some nodes might have many children. Use the `limit` and `offset` parameters to handle large datasets.

```javascript
async function getAllChannelsWithPagination(connectionId, parentId = undefined) {
    let allChannels = [];
    let offset = 0;
    const limit = 100;

    while (true) {
        const response = await sdk.messaging.listMessagingChannels({
            connectionId,
            parentChannelId: parentId,
            limit,
            offset,
        });

        if (!response.data || response.data.length === 0) {
            break;
        }

        allChannels = allChannels.concat(response.data);
        offset += limit;
    }

    return allChannels;
}
```

1. **Handle rate limits**: When recursively fetching data, you might hit API rate limits. Implement backoff strategies and respect the provider's limits.
2. **Cache parent IDs**: If you need to traverse the same structure multiple times, consider caching the parent-child relationships to reduce API calls.

## Integration-specific gotchas


### Working with SharePoint


SharePoint implements a distinct three-level hierarchy that requires special attention:

1. **Sites** (top level)
2. **Drives** (within sites)
3. **Folders/Files** (within drives)

To work with SharePoint's file system:

1. First retrieve the site ID (top-most parent)
2. Use the site ID to list drives
3. Use the drive ID to create or access folders and files

**Important notes:**

- You cannot create files or folders directly at the site level - you must first select a drive
- Write operations are only supported for folders and files, not for sites or drives
- Pagination is not supported for sites and drives listings

## See also

- [How to use the Unified File Storage API](https://docs.unified.to/guides/how_to_use_the_unified_file_storage_api#how-to-use-the-unified-file-storage-api)