Create a Collection inside another Collection with python
Each collection has a children (collection) property. Easy to figure out using the python console:

&gt;&gt;&gt; C.scene.collection.
                       all_objects
                       animation_data_clear(
                       animation_data_create(
                       as_pointer(
                       bl_rna
                       bl_rna_get_subclass(
                       bl_rna_get_subclass_py(
                       children
                       ...


To get the first level of all sub-collections, you can just iterate through the list:

&gt;&gt;&gt; for coll in C.scene.collection.children:
...     print (coll.name)
...     
Collection
Collection 2
Collection 3
...


To add a new collection, create a new data-block and then use .link(collection) method to add it to whatever your main collection is:

&gt;&gt;&gt; C.scene.collection.children.link(
link()
CollectionChildren.link(child)
Add this collection as child of this collection

&gt;&gt;&gt; my_sub_coll = bpy.data.collections.new("My Sub Collection")
&gt;&gt;&gt; C.scene.collection.children.link(my_sub_coll)


The same principle applies to all collections, no matter the collection is on the first or any other level. Example on how to add a new (sub) collection to the active collection:

&gt;&gt;&gt; active_coll = C.view_layer.active_layer_collection.collection
&gt;&gt;&gt; active_coll.children.link(my_sub_coll)




You can also specify the each collection by its name C.scene.collection.children["Collection"] or you can even use the index operator C.scene.collection.children[0] but that's error prone. In case the name of the collection or the scene hierarchy changes you're lost. Better practice is using pythons get() method to basically perform a search for the collection in the first place:

&gt;&gt;&gt; C.scene.collection.children.get("Collection")
bpy.data.collections['Collection']


Basic example using .get():

import bpy

C = bpy.context

main_coll = C.scene.collection.children.get("Collection")
if main_coll:
    # Create the new collection
    my_sub_coll = bpy.data.collections.new("My Sub Collection")
    # Add it to the found collection
    main_coll.children.link(my_sub_coll)


Advanced example on how to add a new collection to an arbitrary collection in the scene using a recursive loop based on https://blender.stackexchange.com/a/137866:

import bpy

def traverse_tree(t):
    yield t
    for child in t.children:
        yield from traverse_tree(child)

coll = bpy.context.scene.collection

for c in traverse_tree(coll):
    if c.name == "MyCollection": # Specify the name of you main collection here
        my_sub_coll = bpy.data.collections.new("My Sub Collection")
        # Add it to the main collection
        c.children.link(my_sub_coll)




Notice that you add objects to the collection(s) the same way by just passing an object  when calling the .link(object) method on the actual object (collection) property, which is actually pretty nice and convenient:

&gt;&gt;&gt; my_sub_coll.objects.link(C.object)