Use root JSON paths with list Values.
diff --git a/openstack/cdn/v1/services/requests.go b/openstack/cdn/v1/services/requests.go
index 62925c3..87443bf 100644
--- a/openstack/cdn/v1/services/requests.go
+++ b/openstack/cdn/v1/services/requests.go
@@ -215,6 +215,10 @@
 	baseElement string
 }
 
+func (p Path) renderRoot() string {
+	return "/" + p.baseElement
+}
+
 func (p Path) renderDash() string {
 	return fmt.Sprintf("/%s/-", p.baseElement)
 }
@@ -237,6 +241,7 @@
 type value interface {
 	toPatchValue() interface{}
 	appropriatePath() Path
+	renderRootOr(func(p Path) string) string
 }
 
 // Patch represents a single update to an existing Service. Multiple updates to a service can be
@@ -258,7 +263,7 @@
 func (i Insertion) ToCDNServiceUpdateMap() map[string]interface{} {
 	return map[string]interface{}{
 		"op":    "add",
-		"path":  i.Value.appropriatePath().renderIndex(i.Index),
+		"path":  i.Value.renderRootOr(func(p Path) string { return p.renderIndex(i.Index) }),
 		"value": i.Value.toPatchValue(),
 	}
 }
@@ -276,7 +281,7 @@
 func (a Append) ToCDNServiceUpdateMap() map[string]interface{} {
 	return map[string]interface{}{
 		"op":    "add",
-		"path":  a.Value.appropriatePath().renderDash(),
+		"path":  a.Value.renderRootOr(func(p Path) string { return p.renderDash() }),
 		"value": a.Value.toPatchValue(),
 	}
 }
@@ -293,7 +298,7 @@
 func (r Replacement) ToCDNServiceUpdateMap() map[string]interface{} {
 	return map[string]interface{}{
 		"op":    "replace",
-		"path":  r.Value.appropriatePath().renderIndex(r.Index),
+		"path":  r.Value.renderRootOr(func(p Path) string { return p.renderIndex(r.Index) }),
 		"value": r.Value.toPatchValue(),
 	}
 }
diff --git a/openstack/cdn/v1/services/results.go b/openstack/cdn/v1/services/results.go
index 3e806be..40581a4 100644
--- a/openstack/cdn/v1/services/results.go
+++ b/openstack/cdn/v1/services/results.go
@@ -30,6 +30,10 @@
 	return PathDomains
 }
 
+func (d Domain) renderRootOr(render func(p Path) string) string {
+	return render(d.appropriatePath())
+}
+
 // DomainList provides a useful way to perform bulk operations in a single Patch.
 type DomainList []Domain
 
@@ -45,6 +49,10 @@
 	return PathDomains
 }
 
+func (list DomainList) renderRootOr(_ func(p Path) string) string {
+	return list.appropriatePath().renderRoot()
+}
+
 // OriginRule represents a rule that defines when an origin should be accessed.
 type OriginRule struct {
 	// Specifies the name of this rule.
@@ -87,6 +95,10 @@
 	return PathOrigins
 }
 
+func (o Origin) renderRootOr(render func(p Path) string) string {
+	return render(o.appropriatePath())
+}
+
 // OriginList provides a useful way to perform bulk operations in a single Patch.
 type OriginList []Domain
 
@@ -102,6 +114,10 @@
 	return PathOrigins
 }
 
+func (list OriginList) renderRootOr(_ func(p Path) string) string {
+	return list.appropriatePath().renderRoot()
+}
+
 // TTLRule specifies a rule that determines if a TTL should be applied to an asset.
 type TTLRule struct {
 	// Specifies the name of this rule.
@@ -137,6 +153,10 @@
 	return PathCaching
 }
 
+func (c CacheRule) renderRootOr(render func(p Path) string) string {
+	return render(c.appropriatePath())
+}
+
 // CacheRuleList provides a useful way to perform bulk operations in a single Patch.
 type CacheRuleList []Domain
 
@@ -152,6 +172,10 @@
 	return PathCaching
 }
 
+func (list CacheRuleList) renderRootOr(_ func(p Path) string) string {
+	return list.appropriatePath().renderRoot()
+}
+
 // RestrictionRule specifies a rule that determines if this restriction should be applied to an asset.
 type RestrictionRule struct {
 	// Specifies the name of this rule.