data FEATURE add lyd_new_ext_list()
diff --git a/doc/transition.dox b/doc/transition.dox
index 2699d4f..24f4f19 100644
--- a/doc/transition.dox
+++ b/doc/transition.dox
@@ -354,7 +354,7 @@
  * lyd_new(), lyd_new_output()  | ::lyd_new_inner(), ::lyd_new_list(), ::lyd_new_list2() | Redesigned functionality to better fit new lyd_node structures, creating RPC's output data is now done via a flag parameter of the functions.
  * lyd_new_leaf(), lyd_new_output_leaf() | ::lyd_new_term()       | ^
  * lyd_new_anydata(), lyd_new_output_anydata() | ::lyd_new_any()  | ^
- * lyd_new_yangdata()           | ::lyd_new_ext_inner(), ::lyd_new_ext_term() | Additional functionality to lyd_new_* functions to cover top-level nodes in extension instances.
+ * lyd_new_yangdata()           | ::lyd_new_ext_inner(), ::lyd_new_ext_list(), ::lyd_new_ext_term() | Additional functionality to lyd_new_* functions to cover top-level nodes in extension instances.
  * lyd_insert_attr()            | ::lyd_new_meta()                | Unify naming used in other functions with the similar functionality.
  * -                            | ::lyd_new_attr()                | Added functionality to store the data (temporarily) not connected with schema definitions.
  * -                            | ::lyd_new_attr2()               | ^
diff --git a/src/tree_data.c b/src/tree_data.c
index f611481..7b9d461 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -946,6 +946,54 @@
 }
 
 API LY_ERR
+lyd_new_ext_list(const struct lysc_ext_instance *ext, const char *name, struct lyd_node **node, ...)
+{
+    struct lyd_node *ret = NULL, *key;
+    const struct lysc_node *schema, *key_s;
+    struct ly_ctx *ctx = ext ? ext->module->ctx : NULL;
+    va_list ap;
+    const char *key_val;
+    LY_ERR rc = LY_SUCCESS;
+
+    LY_CHECK_ARG_RET(ctx, ext, node, name, LY_EINVAL);
+
+    schema = lysc_ext_find_node(ext, NULL, name, 0, LYS_LIST, 0);
+    if (!schema) {
+        if (ext->argument) {
+            LOGERR(ctx, LY_EINVAL, "List node \"%s\" not found in instance \"%s\" of extension %s.",
+                    name, ext->argument, ext->def->name);
+        } else {
+            LOGERR(ctx, LY_EINVAL, "List node \"%s\" not found in instance of extension %s.", name, ext->def->name);
+        }
+        return LY_ENOTFOUND;
+    }
+    /* create list inner node */
+    LY_CHECK_RET(lyd_create_inner(schema, &ret));
+
+    va_start(ap, node);
+
+    /* create and insert all the keys */
+    for (key_s = lysc_node_child(schema); key_s && (key_s->flags & LYS_KEY); key_s = key_s->next) {
+        key_val = va_arg(ap, const char *);
+
+        rc = lyd_create_term(key_s, key_val, key_val ? strlen(key_val) : 0, NULL, LY_PREF_JSON, NULL, LYD_HINT_DATA,
+                NULL, &key);
+        LY_CHECK_GOTO(rc, cleanup);
+        lyd_insert_node(ret, NULL, key);
+    }
+
+cleanup:
+    va_end(ap);
+    if (rc) {
+        lyd_free_tree(ret);
+        ret = NULL;
+    } else if (node) {
+        *node = ret;
+    }
+    return rc;
+}
+
+API LY_ERR
 lyd_new_list2(struct lyd_node *parent, const struct lys_module *module, const char *name, const char *keys,
         ly_bool output, struct lyd_node **node)
 {
diff --git a/src/tree_data.h b/src/tree_data.h
index 4d8b985..bc77d3d 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -128,7 +128,7 @@
  * Note, that in case the node is defined in an extension instance, the functions mentioned above do not work until you
  * provide parent where the new node is supposed to be inserted. The reason is that all the functions searches for the
  * top-level nodes directly inside modules. To create a top-level node defined in an extension instance, use
- * ::lyd_new_ext_inner() and ::lyd_new_ext_term() functions.
+ * ::lyd_new_ext_inner(), ::lyd_new_ext_term() and ::lyd_new_ext_list() functions.
  *
  * The [metadata](@ref howtoPluginsExtensionsMetadata) (and attributes in opaq nodes) can be created with ::lyd_new_meta()
  * and ::lyd_new_attr().
@@ -175,6 +175,7 @@
  *
  * - ::lyd_new_ext_inner()
  * - ::lyd_new_ext_term()
+ * - ::lyd_new_ext_list()
  *
  * - ::lyd_dup_single()
  * - ::lyd_dup_siblings()
@@ -955,6 +956,22 @@
 LY_ERR lyd_new_list(struct lyd_node *parent, const struct lys_module *module, const char *name, ly_bool output, struct lyd_node **node, ...);
 
 /**
+ * @brief Create a new top-level list node defined in the given extension instance.
+ *
+ * To create a list node with parent (no matter if defined inside extension instance or a standard tree) or a top-level
+ * list node of a standard module's tree, use ::lyd_new_list() or ::lyd_new_list2().
+ *
+ * @param[in] ext Extension instance where the list node being created is defined.
+ * @param[in] name Schema node name of the new data node. The node must be #LYS_LIST.
+ * @param[out] node The created node.
+ * @param[in] ... Ordered key values of the new list instance, all must be set. In case of an instance-identifier
+ * or identityref value, the JSON format is expected (module names instead of prefixes). No keys are expected for
+ * key-less lists.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_new_ext_list(const struct lysc_ext_instance *ext, const char *name, struct lyd_node **node, ...);
+
+/**
  * @brief Create a new list node in the data tree.
  *
  * @param[in] parent Parent node for the node being created. NULL in case of creating a top level element.
diff --git a/tests/utests/data/test_new.c b/tests/utests/data/test_new.c
index a0a573c..1c66543 100644
--- a/tests/utests/data/test_new.c
+++ b/tests/utests/data/test_new.c
@@ -122,10 +122,10 @@
     lyd_free_tree(node);
 
     assert_int_equal(lyd_new_inner(NULL, mod, "l1", 0, &node), LY_ENOTFOUND);
-    CHECK_LOG_CTX("Inner node (and not a list) \"l1\" not found.", NULL);
+    CHECK_LOG_CTX("Inner node (not a list) \"l1\" not found.", NULL);
 
     assert_int_equal(lyd_new_inner(NULL, mod, "l2", 0, &node), LY_ENOTFOUND);
-    CHECK_LOG_CTX("Inner node (and not a list) \"l2\" not found.", NULL);
+    CHECK_LOG_CTX("Inner node (not a list) \"l2\" not found.", NULL);
 
     /* anydata */
     assert_int_equal(lyd_new_any(NULL, mod, "any", "some-value", 0, LYD_ANYDATA_STRING, 0, &node), LY_SUCCESS);