diff --git a/src/oas.md b/src/oas.md
index e91c9cb08a..ab75857cce 100644
--- a/src/oas.md
+++ b/src/oas.md
@@ -1641,6 +1641,9 @@ These fields MAY be used either with or without the RFC6570-style serialization
| ---- | :----: | ---- |
| contentType | `string` | The `Content-Type` for encoding a specific property. The value is a comma-separated list, each element of which is either a specific media type (e.g. `image/png`) or a wildcard media type (e.g. `image/*`). Default value depends on the property type as shown in the table below. |
| headers | Map[`string`, [Header Object](#header-object) \| [Reference Object](#reference-object)] | A map allowing additional information to be provided as headers. `Content-Type` is described separately and SHALL be ignored in this section. This field SHALL be ignored if the media type is not a `multipart`. |
+| encoding | Map[`string`, [Encoding Object](#encoding-object)] | Applies nested Encoding Objects in the same manner as the [Media Type Object](#media-type-object)'s `encoding` field. |
+| prefixEncoding | [[Encoding Object](#encoding-object)] | Applies nested Encoding Objects in the same manner as the [Media Type Object](#media-type-object)'s `prefixEncoding` field. |
+| itemEncoding | [Encoding Object](#encoding-object) | Applies nested Encoding Objects in the same manner as the [Media Type Object](#media-type-object)'s `itemEncoding` field. |
This object MAY be extended with [Specification Extensions](#specification-extensions).
@@ -1674,6 +1677,11 @@ See also [Appendix C: Using RFC6570 Implementations](#appendix-c-using-rfc6570-b
Note that the presence of at least one of `style`, `explode`, or `allowReserved` with an explicit value is equivalent to using `schema` with `in: "query"` Parameter Objects.
The absence of all three of those fields is the equivalent of using `content`, but with the media type specified in `contentType` rather than through a Media Type Object.
+##### Nested Encoding
+
+Nested formats requiring encoding, most notably nested `multipart/mixed`, can be supported with this Object's `encoding`, `prefixEncoding`, and / or `itemEncoding` fields.
+Implementations MUST support one level of nesting, and MAY support additional levels.
+
##### Encoding the `x-www-form-urlencoded` Media Type
To work with content using form url encoding via [RFC1866](https://tools.ietf.org/html/rfc1866), use the `application/x-www-form-urlencoded` media type in the [Media Type Object](#media-type-object).
@@ -1869,6 +1877,31 @@ requestBody:
As seen in the [Encoding Object's `contentType` field documentation](#encoding-content-type), the empty schema for `items` indicates a media type of `application/octet-stream`.
+###### Example: Nested `multipart/mixed`
+
+This defines a two-part `multipart/mixed` where the first part is a JSON array and the second part is a nested `multipart/mixed` document.
+The nested parts are XML, plain text, and a PNG image.
+
+```yaml
+multipart/mixed:
+ schema:
+ type: array
+ prefixItems:
+ - type: array
+ - type: array
+ prefixItems:
+ - type: object
+ - type: string
+ - {}
+ prefixEncoding:
+ - {} # Accept the default application/json
+ - contentType: multipart/mixed
+ prefixEncoding:
+ - contentType: application/xml
+ - {} # Accept the default text/plain
+ - contentType: image/png
+```
+
#### Responses Object
A container for the expected responses of an operation.
diff --git a/src/schemas/validation/schema.yaml b/src/schemas/validation/schema.yaml
index 9990fefb67..d79902c765 100644
--- a/src/schemas/validation/schema.yaml
+++ b/src/schemas/validation/schema.yaml
@@ -561,9 +561,24 @@ $defs:
allowReserved:
default: false
type: boolean
+ encoding:
+ type: object
+ additionalProperties:
+ $ref: '#/$defs/encoding'
+ prefixEncoding:
+ type: array
+ items:
+ $ref: '#/$defs/encoding'
+ itemEncoding:
+ $ref: '#/$defs/encoding'
allOf:
- $ref: '#/$defs/specification-extensions'
- $ref: '#/$defs/styles-for-form'
+ - dependentSchemas:
+ encoding:
+ properties:
+ prefixEncoding: false
+ itemEncoding: false
unevaluatedProperties: false
responses:
diff --git a/tests/schema/fail/encoding-enc-item-exclusion.yaml b/tests/schema/fail/encoding-enc-item-exclusion.yaml
new file mode 100644
index 0000000000..658f848be9
--- /dev/null
+++ b/tests/schema/fail/encoding-enc-item-exclusion.yaml
@@ -0,0 +1,12 @@
+openapi: 3.2.0
+info:
+ title: API
+ version: 1.0.0
+components:
+ requestBodies:
+ content:
+ multipart/mixed:
+ prefixEncoding:
+ - contentType: multipart/mixed
+ encoding: {}
+ prefixEncoding: []
diff --git a/tests/schema/fail/encoding-enc-prefix-exclusion.yaml b/tests/schema/fail/encoding-enc-prefix-exclusion.yaml
new file mode 100644
index 0000000000..8f62070d3b
--- /dev/null
+++ b/tests/schema/fail/encoding-enc-prefix-exclusion.yaml
@@ -0,0 +1,12 @@
+openapi: 3.2.0
+info:
+ title: API
+ version: 1.0.0
+components:
+ requestBodies:
+ content:
+ multipart/mixed:
+ prefixEncoding:
+ - contentType: multipart/mixed
+ encoding: {}
+ itemEncoding: []
diff --git a/tests/schema/pass/media-type-examples.yaml b/tests/schema/pass/media-type-examples.yaml
index 2ab4e68076..72470f82e0 100644
--- a/tests/schema/pass/media-type-examples.yaml
+++ b/tests/schema/pass/media-type-examples.yaml
@@ -117,6 +117,10 @@ paths:
type: string
forCoverage2:
type: string
+ nested1:
+ type: object
+ nested2:
+ type: array
encoding:
addresses:
# require XML Content-Type in utf-8 encoding
@@ -138,3 +142,12 @@ paths:
forCoverage2:
style: spaceDelimited
explode: true
+ nested1:
+ contentType: multipart/form-data
+ encoding:
+ inner: {}
+ nested2:
+ contentType: multipart/mixed
+ prefixEncoding:
+ - {}
+ itemEncoding: {}