diff --git a/src/backend/InvenTree/InvenTree/api_version.py b/src/backend/InvenTree/InvenTree/api_version.py
index 94cf10e91e..fab6ad53f0 100644
--- a/src/backend/InvenTree/InvenTree/api_version.py
+++ b/src/backend/InvenTree/InvenTree/api_version.py
@@ -1,14 +1,19 @@
 """InvenTree API version information."""
 
 # InvenTree API version
-INVENTREE_API_VERSION = 241
+INVENTREE_API_VERSION = 242
 
 """Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
 
 
 INVENTREE_API_TEXT = """
 
-v241 - 2024-09-18 : https://github.com/inventree/InvenTree/pull/7906
+v242 - 2024-08-20 : https://github.com/inventree/InvenTree/pull/7932
+    - Adds "level" attribute to BuildOrder serializer
+    - Allow ordering of BuildOrder API by "level" attribute
+    - Allow "parent" filter for BuildOrder API to have "cascade=True" option
+
+v241 - 2024-08-18 : https://github.com/inventree/InvenTree/pull/7906
     - Adjusts required fields for the MeUserDetail endpoint
 
 v240 - 2024-08-16 : https://github.com/inventree/InvenTree/pull/7900
diff --git a/src/backend/InvenTree/build/api.py b/src/backend/InvenTree/build/api.py
index 67a7b0ef17..d456b2d78b 100644
--- a/src/backend/InvenTree/build/api.py
+++ b/src/backend/InvenTree/build/api.py
@@ -34,7 +34,6 @@ class BuildFilter(rest_filters.FilterSet):
         """Metaclass options."""
         model = Build
         fields = [
-            'parent',
             'sales_order',
             'part',
         ]
@@ -49,6 +48,35 @@ class BuildFilter(rest_filters.FilterSet):
             return queryset.filter(status__in=BuildStatusGroups.ACTIVE_CODES)
         return queryset.exclude(status__in=BuildStatusGroups.ACTIVE_CODES)
 
+    cascade = rest_filters.BooleanFilter(label=_('Cascade'), method='filter_cascade')
+
+    def filter_cascade(self, queryset, name, value):
+        """Filter by whether or not the build is a 'cascade' build.
+
+        Note: this only applies when the 'parent' field filter is specified.
+        """
+
+        # No filtering here, see 'filter_parent'
+        return queryset
+
+    parent = rest_filters.ModelChoiceFilter(
+        queryset=Build.objects.all(),
+        label=_('Parent Build'),
+        field_name='parent',
+        method='filter_parent'
+    )
+
+    def filter_parent(self, queryset, name, parent):
+        """Filter by 'parent' build order."""
+
+        cascade = str2bool(self.data.get('cascade', False))
+
+        if cascade:
+            builds = parent.get_descendants(include_self=False)
+            return queryset.filter(pk__in=[b.pk for b in builds])
+
+        return queryset.filter(parent=parent)
+
     overdue = rest_filters.BooleanFilter(label='Build is overdue', method='filter_overdue')
 
     def filter_overdue(self, queryset, name, value):
@@ -175,6 +203,7 @@ class BuildList(DataExportViewMixin, BuildMixin, ListCreateAPI):
         'responsible',
         'project_code',
         'priority',
+        'level',
     ]
 
     ordering_field_aliases = {
diff --git a/src/backend/InvenTree/build/serializers.py b/src/backend/InvenTree/build/serializers.py
index 9598daac85..66fd69309d 100644
--- a/src/backend/InvenTree/build/serializers.py
+++ b/src/backend/InvenTree/build/serializers.py
@@ -76,6 +76,7 @@ class BuildSerializer(NotesFieldMixin, DataImportExportSerializerMixin, InvenTre
             'responsible',
             'responsible_detail',
             'priority',
+            'level',
         ]
 
         read_only_fields = [
@@ -84,8 +85,11 @@ class BuildSerializer(NotesFieldMixin, DataImportExportSerializerMixin, InvenTre
             'completion_data',
             'status',
             'status_text',
+            'level',
         ]
 
+    level = serializers.IntegerField(label=_('Build Level'), read_only=True)
+
     url = serializers.CharField(source='get_absolute_url', read_only=True)
 
     status_text = serializers.CharField(source='get_status_display', read_only=True)
diff --git a/src/frontend/src/tables/Filter.tsx b/src/frontend/src/tables/Filter.tsx
index 948ef95634..4105286703 100644
--- a/src/frontend/src/tables/Filter.tsx
+++ b/src/frontend/src/tables/Filter.tsx
@@ -28,6 +28,7 @@ export type TableFilter = {
   defaultValue?: any;
   value?: any;
   displayValue?: any;
+  active?: boolean;
 };
 
 /**
diff --git a/src/frontend/src/tables/InvenTreeTable.tsx b/src/frontend/src/tables/InvenTreeTable.tsx
index 233378af0c..1a39276b35 100644
--- a/src/frontend/src/tables/InvenTreeTable.tsx
+++ b/src/frontend/src/tables/InvenTreeTable.tsx
@@ -164,12 +164,14 @@ export function InvenTreeTable<T = any>({
   // Construct table filters - note that we can introspect filter labels from column names
   const filters: TableFilter[] = useMemo(() => {
     return (
-      props.tableFilters?.map((filter) => {
-        return {
-          ...filter,
-          label: filter.label ?? fieldNames[filter.name] ?? `${filter.name}`
-        };
-      }) ?? []
+      props.tableFilters
+        ?.filter((f: any) => f.active != false)
+        ?.map((filter) => {
+          return {
+            ...filter,
+            label: filter.label ?? fieldNames[filter.name] ?? `${filter.name}`
+          };
+        }) ?? []
     );
   }, [props.tableFilters, fieldNames]);
 
diff --git a/src/frontend/src/tables/build/BuildOrderTable.tsx b/src/frontend/src/tables/build/BuildOrderTable.tsx
index ef7a9fec50..737419d551 100644
--- a/src/frontend/src/tables/build/BuildOrderTable.tsx
+++ b/src/frontend/src/tables/build/BuildOrderTable.tsx
@@ -27,63 +27,6 @@ import {
 import { StatusFilterOptions, TableFilter } from '../Filter';
 import { InvenTreeTable } from '../InvenTreeTable';
 
-/**
- * Construct a list of columns for the build order table
- */
-function buildOrderTableColumns(): TableColumn[] {
-  return [
-    ReferenceColumn({}),
-    {
-      accessor: 'part',
-      sortable: true,
-      switchable: false,
-      render: (record: any) => PartColumn(record.part_detail)
-    },
-    {
-      accessor: 'part_detail.IPN',
-      sortable: true,
-      switchable: true,
-      title: t`IPN`
-    },
-    {
-      accessor: 'title',
-      sortable: false
-    },
-    {
-      accessor: 'completed',
-      sortable: true,
-      switchable: false,
-      render: (record: any) => (
-        <ProgressBar
-          progressLabel={true}
-          value={record.completed}
-          maximum={record.quantity}
-        />
-      )
-    },
-    StatusColumn({ model: ModelType.build }),
-    ProjectCodeColumn({}),
-    {
-      accessor: 'priority',
-      sortable: true
-    },
-    CreationDateColumn({}),
-    TargetDateColumn({}),
-    DateColumn({
-      accessor: 'completion_date',
-      sortable: true
-    }),
-    {
-      accessor: 'issued_by',
-      sortable: true,
-      render: (record: any) => (
-        <RenderUser instance={record?.issued_by_detail} />
-      )
-    },
-    ResponsibleColumn({})
-  ];
-}
-
 /*
  * Construct a table of build orders, according to the provided parameters
  */
@@ -96,7 +39,65 @@ export function BuildOrderTable({
   parentBuildId?: number;
   salesOrderId?: number;
 }) {
-  const tableColumns = useMemo(() => buildOrderTableColumns(), []);
+  const tableColumns = useMemo(() => {
+    return [
+      ReferenceColumn({}),
+      {
+        accessor: 'part',
+        sortable: true,
+        switchable: false,
+        render: (record: any) => PartColumn(record.part_detail)
+      },
+      {
+        accessor: 'part_detail.IPN',
+        sortable: true,
+        switchable: true,
+        title: t`IPN`
+      },
+      {
+        accessor: 'title',
+        sortable: false
+      },
+      {
+        accessor: 'completed',
+        sortable: true,
+        switchable: false,
+        render: (record: any) => (
+          <ProgressBar
+            progressLabel={true}
+            value={record.completed}
+            maximum={record.quantity}
+          />
+        )
+      },
+      StatusColumn({ model: ModelType.build }),
+      ProjectCodeColumn({}),
+      {
+        accessor: 'level',
+        sortable: true,
+        switchable: true,
+        hidden: !parentBuildId
+      },
+      {
+        accessor: 'priority',
+        sortable: true
+      },
+      CreationDateColumn({}),
+      TargetDateColumn({}),
+      DateColumn({
+        accessor: 'completion_date',
+        sortable: true
+      }),
+      {
+        accessor: 'issued_by',
+        sortable: true,
+        render: (record: any) => (
+          <RenderUser instance={record?.issued_by_detail} />
+        )
+      },
+      ResponsibleColumn({})
+    ];
+  }, [parentBuildId]);
 
   const projectCodeFilters = useProjectCodeFilters();
   const ownerFilters = useOwnerFilters();
@@ -109,6 +110,13 @@ export function BuildOrderTable({
         label: t`Active`,
         description: t`Show active orders`
       },
+      {
+        name: 'cascade',
+        type: 'boolean',
+        label: t`Cascade`,
+        description: t`Display recursive child orders`,
+        active: !!parentBuildId
+      },
       {
         name: 'status',
         label: t`Status`,
@@ -151,7 +159,7 @@ export function BuildOrderTable({
         choices: ownerFilters.choices
       }
     ];
-  }, [projectCodeFilters.choices, ownerFilters.choices]);
+  }, [parentBuildId, projectCodeFilters.choices, ownerFilters.choices]);
 
   const user = useUserState();