data tree FEATURE allow setting opaque node prefix
diff --git a/src/tree_data.c b/src/tree_data.c
index ffd3377..2a29a60 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -1093,11 +1093,10 @@
 
 API LY_ERR
 lyd_new_opaq(struct lyd_node *parent, const struct ly_ctx *ctx, const char *name, const char *value,
-        const char *module_name, struct lyd_node **node)
+        const char *prefix, const char *module_name, struct lyd_node **node)
 {
     struct lyd_node *ret = NULL;
-
-    LY_CHECK_ARG_RET(ctx, parent || ctx, parent || node, name, module_name, LY_EINVAL);
+    LY_CHECK_ARG_RET(ctx, parent || ctx, parent || node, name, module_name, !prefix || !strcmp(prefix, module_name), LY_EINVAL);
 
     if (!ctx) {
         ctx = LYD_CTX(parent);
@@ -1106,8 +1105,8 @@
         value = "";
     }
 
-    LY_CHECK_RET(lyd_create_opaq(ctx, name, strlen(name), NULL, 0, module_name, strlen(module_name), value,
-            strlen(value), NULL, LY_PREF_JSON, NULL, 0, &ret));
+    LY_CHECK_RET(lyd_create_opaq(ctx, name, strlen(name), prefix, prefix ? strlen(prefix) : 0, module_name,
+            strlen(module_name), value, strlen(value), NULL, LY_PREF_JSON, NULL, 0, &ret));
     if (parent) {
         lyd_insert_node(parent, NULL, ret);
     }
@@ -1120,7 +1119,7 @@
 
 API LY_ERR
 lyd_new_opaq2(struct lyd_node *parent, const struct ly_ctx *ctx, const char *name, const char *value,
-        const char *module_ns, struct lyd_node **node)
+        const char *prefix, const char *module_ns, struct lyd_node **node)
 {
     struct lyd_node *ret = NULL;
 
@@ -1133,8 +1132,8 @@
         value = "";
     }
 
-    LY_CHECK_RET(lyd_create_opaq(ctx, name, strlen(name), NULL, 0, module_ns, strlen(module_ns), value,
-            strlen(value), NULL, LY_PREF_XML, NULL, 0, &ret));
+    LY_CHECK_RET(lyd_create_opaq(ctx, name, strlen(name), prefix, prefix ? strlen(prefix) : 0, module_ns,
+            strlen(module_ns), value, strlen(value), NULL, LY_PREF_XML, NULL, 0, &ret));
     if (parent) {
         lyd_insert_node(parent, NULL, ret);
     }
@@ -2174,11 +2173,11 @@
 {
     struct lyd_node *iter;
 
-    LY_CHECK_ARG_RET(NULL, parent, node, parent->schema->nodetype & LYD_NODE_INNER, LY_EINVAL);
+    LY_CHECK_ARG_RET(NULL, parent, node, !parent->schema || (parent->schema->nodetype & LYD_NODE_INNER), LY_EINVAL);
 
     LY_CHECK_RET(lyd_insert_check_schema(parent->schema, NULL, node->schema));
 
-    if (node->schema->flags & LYS_KEY) {
+    if (node->schema && (node->schema->flags & LYS_KEY)) {
         LOGERR(parent->schema->module->ctx, LY_EINVAL, "Cannot insert key \"%s\".", node->schema->name);
         return LY_EINVAL;
     }
diff --git a/src/tree_data.h b/src/tree_data.h
index 1a94621..b7ab513 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -1009,13 +1009,14 @@
  * @param[in] parent Parent node for the node beaing created. NULL in case of creating a top level element.
  * @param[in] ctx libyang context. If NULL, @p parent context will be used.
  * @param[in] name Node name.
- * @param[in] value Node value, may be NULL.
+ * @param[in] value Optional node value.
+ * @param[in] prefix Optional node prefix, must be equal to @p module_name if set.
  * @param[in] module_name Node module name.
  * @param[out] node Optional created node.
  * @return LY_ERR value.
  */
 LY_ERR lyd_new_opaq(struct lyd_node *parent, const struct ly_ctx *ctx, const char *name, const char *value,
-        const char *module_name, struct lyd_node **node);
+        const char *prefix, const char *module_name, struct lyd_node **node);
 
 /**
  * @brief Create a new XML opaque node in the data tree. To create a JSON opaque node, use ::lyd_new_opaq().
@@ -1023,13 +1024,14 @@
  * @param[in] parent Parent node for the node beaing created. NULL in case of creating a top level element.
  * @param[in] ctx libyang context. If NULL, @p parent context will be used.
  * @param[in] name Node name.
- * @param[in] value Node value, may be NULL.
+ * @param[in] value Optional node value.
+ * @param[in] prefix Optional node prefix.
  * @param[in] module_ns Node module namespace.
  * @param[out] node Optional created node.
  * @return LY_ERR value.
  */
 LY_ERR lyd_new_opaq2(struct lyd_node *parent, const struct ly_ctx *ctx, const char *name, const char *value,
-        const char *module_ns, struct lyd_node **node);
+        const char *prefix, const char *module_ns, struct lyd_node **node);
 
 /**
  * @brief Create new JSON attribute for an opaque data node. To create an XML attribute, use ::lyd_new_attr2().
diff --git a/src/validation.c b/src/validation.c
index 9e0a42f..fec6d97 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -648,7 +648,7 @@
     }
 
     /* create dummy opaque node */
-    ret = lyd_new_opaq((struct lyd_node *)parent, snode->module->ctx, snode->name, NULL, snode->module->name, &dummy);
+    ret = lyd_new_opaq((struct lyd_node *)parent, snode->module->ctx, snode->name, NULL, NULL, snode->module->name, &dummy);
     LY_CHECK_GOTO(ret, cleanup);
 
     /* connect it if needed */
diff --git a/tests/utests/data/test_new.c b/tests/utests/data/test_new.c
index 55ac4ec..a7776d0 100644
--- a/tests/utests/data/test_new.c
+++ b/tests/utests/data/test_new.c
@@ -161,14 +161,14 @@
 
     UTEST_ADD_MODULE(schema_a, LYS_IN_YANG, NULL, NULL);
 
-    assert_int_equal(lyd_new_opaq(NULL, UTEST_LYCTX, "node1", NULL, "my-module", &root), LY_SUCCESS);
+    assert_int_equal(lyd_new_opaq(NULL, UTEST_LYCTX, "node1", NULL, NULL, "my-module", &root), LY_SUCCESS);
     assert_null(root->schema);
     opq = (struct lyd_node_opaq *)root;
     assert_string_equal(opq->name.name, "node1");
     assert_string_equal(opq->name.module_name, "my-module");
     assert_string_equal(opq->value, "");
 
-    assert_int_equal(lyd_new_opaq(root, NULL, "node2", "value", "my-module2", &node), LY_SUCCESS);
+    assert_int_equal(lyd_new_opaq(root, NULL, "node2", "value", NULL, "my-module2", &node), LY_SUCCESS);
     assert_null(node->schema);
     opq = (struct lyd_node_opaq *)node;
     assert_string_equal(opq->name.name, "node2");