diff --git a/_config.yml b/_config.yml
index 8904b78dd3..cd06d919b6 100644
--- a/_config.yml
+++ b/_config.yml
@@ -18,6 +18,11 @@ collections:
name: Format Registry
output: true
permalink: /registry/:collection/:title
+ media-type:
+ slug: media-type
+ name: Media Type Registry
+ output: true
+ permalink: /registry/:collection/:title
extension:
slug: extension
name: Specification Extension Registry
diff --git a/_includes/media-type-entry.md b/_includes/media-type-entry.md
new file mode 100644
index 0000000000..e4f7aad062
--- /dev/null
+++ b/_includes/media-type-entry.md
@@ -0,0 +1,28 @@
+# Media Type Registry
+
+## {{ page.name }}: {{ page.description }}
+
+**Media Type(s):**
+
+{% for media_type in page.media_types %}• {{ media_type.name }} ({% if media_type.iana %}[IANA]({{ media_type.iana }}){% else %}not IANA-registered{% endif %}) – {% for spec in media_type.specifications %}[{{ spec.name }}]({{ spec.url }}){% if spec.note %} ({{ spec.note }}){% endif %}{% unless forloop.last %}, {% endunless %}{% endfor %}{% unless forloop.last %}
{% endunless %}{% endfor %}
+{% if page.default_for %}
+
+This page also applies to any unrecognized {{ page.default_for }} media type.
+{% endif %}
+
+{% if page.references %}
+**OAS References:**
+
+{% for ref in page.references %}• [{{ ref.section }}](https://spec.openapis.org/oas/latest.html#{{ ref.anchor }}){% if ref.parent %} ([{{ ref.parent }}](https://spec.openapis.org/oas/latest.html#{{ ref.parentAnchor }})){% endif %}{% unless forloop.last %}
{% endunless %}{% endfor %}
+{% endif %}
+
+## Summary
+
+{{ include.summary }}
+
+{% if include.remarks %}
+## Remarks
+
+{{ include.remarks }}
+{% endif %}
+
diff --git a/registries/_media-type/binary.md b/registries/_media-type/binary.md
new file mode 100644
index 0000000000..1bb7ddce96
--- /dev/null
+++ b/registries/_media-type/binary.md
@@ -0,0 +1,61 @@
+---
+owner: handrews
+name: Binary
+description: Non-text-based media types
+media_types:
+ - name: application/octet-stream
+ iana: https://www.iana.org/assignments/media-types/application/octet-stream
+ specifications:
+ - name: RFC2045
+ url: https://www.rfc-editor.org/rfc/rfc2045
+ - name: RFC2046 §4.5.1
+ url: https://www.rfc-editor.org/rfc/rfc2046#section-4.5.1
+ - name: audio/*
+ iana: https://www.iana.org/assignments/media-types/media-types.xhtml#audio
+ specifications:
+ - name: RFC2045
+ url: https://www.rfc-editor.org/rfc/rfc2045
+ - name: RFC2046 §4.2
+ url: https://www.rfc-editor.org/rfc/rfc2046#section-4.3
+ - name: image/*
+ iana: https://www.iana.org/assignments/media-types/media-types.xhtml#image
+ specifications:
+ - name: RFC2045
+ url: https://www.rfc-editor.org/rfc/rfc2045
+ - name: RFC2046 §4.2
+ url: https://www.rfc-editor.org/rfc/rfc2046#section-4.2
+ - name: video/*
+ iana: https://www.iana.org/assignments/media-types/media-types.xhtml#video
+ specifications:
+ - name: RFC2045
+ url: https://www.rfc-editor.org/rfc/rfc2045
+ - name: RFC2046 §4.4
+ url: https://www.rfc-editor.org/rfc/rfc2046#section-4.4
+default_for: binary
+references:
+ - section: Working with Binary Data
+ anchor: working-with-binary-data
+ parent: Working with Data
+ parentAnchor: Working with Data
+ - section: Binary Streams
+ anchor: binary-streams
+ parent: Media Type Object
+ parentAnchor: media-type-object
+ - section: "`Content-Transfer-Encoding` and `contentEncoding`"
+ anchor: content-transfer-encoding-and-contentencoding
+ parent: Encoding Object
+ parentAnchor: encoding-object
+layout: default
+---
+
+{% capture summary %}
+As of OAS v3.1, binary data is modeled using an empty Schema Object, in accordance with JSON Schema's guidance regarding [non-JSON instances](https://www.ietf.org/archive/id/draft-bhutton-json-schema-01.html#name-non-json-instances).
+{% endcapture %}
+
+{% capture remarks %}
+As specified in [Working with Binary Data](https://spec.openapis.org/oas/latest.html#working-with-binary-data), modeling binary data that has been encoded into a string is handled differently from raw binary data, with two variations: with the [Schema Object](https://spec.openapis.org/oas/latest.html#schema-object)'s `contentMediaType` and `contentEncoding`, or with a `Content-Transfer-Encoding` header in the [Encoding Object](https://spec.openapis.org/oas/latest.html#encoding-object) (for media types that use Encoding Objects). Consult the specification for how these two mechanisms interact when they both apply.
+
+In OAS v3.0, raw binary content was modeled as `type: string, format: binary`, while `type: string, format: byte` was used for base64-encoded binary. This was dropped in favor of JSON Schema draft 2020-12's support because it did not allow specifying the media type along with the binary encoding.
+{% endcapture %}
+
+{% include media-type-entry.md summary=summary remarks=remarks %}
diff --git a/registries/_media-type/forms.md b/registries/_media-type/forms.md
new file mode 100644
index 0000000000..874c4fe28d
--- /dev/null
+++ b/registries/_media-type/forms.md
@@ -0,0 +1,55 @@
+---
+owner: handrews
+name: Forms
+description: Ordered name-value pairs
+media_types:
+ - name: application/x-www-form-urlencoded
+ iana: https://www.iana.org/assignments/media-types/application/x-www-form-urlencoded
+ specifications:
+ - name: WHATWG URL
+ url: https://url.spec.whatwg.org/#application/x-www-form-urlencoded
+ - name: HTTP 4.01 §17.13.4.1
+ url: https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1
+ note: historical
+ - name: RFC1866 §8.2.1
+ url: https://datatracker.ietf.org/doc/html/rfc1866#section-8.2.1
+ note: historical but cited by later RFCs and the OAS
+ - name: multipart/form-data
+ iana: https://www.iana.org/assignments/media-types/multipart/form-data
+ specifications:
+ - name: RFC7578
+ url: https://www.rfc-editor.org/rfc/rfc7578.html
+references:
+ - section: Encoding By Name
+ anchor: encoding-by-name
+ parent: Encoding Usage and Restrictions
+ parentAnchor: encoding-usage-and-restrictions
+ - section: Encoding the `x-www-form-urlencoded` Media Type
+ anchor: encoding-the-x-www-form-urlencoded-media-type
+ parent: Encoding Object
+ parentAnchor: encoding-object
+ - section: Encoding multipart Media Types
+ anchor: encoding-multipart-media-types
+ parent: Encoding Object
+ parentAnchor: encoding-object
+ - section: "Appendix C: Using RFC6570-Based Serialization"
+ anchor: appendix-c-using-rfc6570-based-serialization
+ - section: "Appendix E: Percent-Encoding and Form Media Types"
+ anchor: appendix-e-percent-encoding-and-form-media-types
+layout: default
+---
+
+{% capture summary %}
+Web-style form data consists of name-value pairs, with duplicate names allowed, and are structured either in a way compatible with URI form query strings or as a `multipart` document.
+{% endcapture %}
+
+{% capture remarks %}
+Both form media types use the [Encoding Object](https://spec.openapis.org/oas/latest.html#encoding-object) to map object properties from schema-ready data structures to name-value pairs, with special rules for arrays causing each array value to be treated as a separate pair with the same name.
+While the ordering of pairs is significant in these formats, the OAS does not (as of v3.2) provide a way to control such ordering.
+
+As of OAS v3.2, endpoint URL query strings can be modeled as a media type using `in: querystring` in the [Parameter Object](https://spec.openapis.org/oas/latest.html#parameter-object). The query string can also be modeled using multiple `in: query` Parameter Objects through mechanisms similar to the Encoding Object.
+
+Note that URL-encoded forms have been defined by different standards organizations at different times, leading to inconsistencies regarding percent-encoding in later standards and implementations; this is addressed in detail in [Appendix E](https://spec.openapis.org/oas/latest.html#appendix-e-percent-encoding-and-form-media-types).
+{% endcapture %}
+
+{% include media-type-entry.md summary=summary remarks=remarks %}
diff --git a/registries/_media-type/linksets.md b/registries/_media-type/linksets.md
new file mode 100644
index 0000000000..414f978822
--- /dev/null
+++ b/registries/_media-type/linksets.md
@@ -0,0 +1,34 @@
+---
+owner: handrews
+name: Link Sets
+description: Sets of RFC8288 Web Links
+media_types:
+ - name: application/linkset
+ iana: https://www.iana.org/assignments/media-types/application/linkset
+ specifications:
+ - name: RFC9264
+ url: https://www.rfc-editor.org/rfc/rfc9264
+ - name: RFC8288
+ url: https://www.rfc-editor.org/rfc/rfc8288
+ - name: application/linkset+json
+ iana: https://www.iana.org/assignments/media-types/application/linkset+json
+ specifications:
+ - name: RFC9264
+ url: https://www.rfc-editor.org/rfc/rfc9264
+references:
+ - section: Modeling Link Headers
+ anchor: modeling-link-headers
+ parent: Header Object
+ parentAnchor: header-object
+layout: default
+---
+
+{% capture summary %}
+The JSON form for linksets is used to define the schema-ready data form for both of these media types, with `application/linkset` being usable for HTTP `Link` header values using the conversion defined in the RFC.
+{% endcapture %}
+
+{% capture remarks %}
+The `application/linkset+json` data model is used with the [Schema Object](https://spec.openapis.org/oas/latest.html#schema-object) for both media types, with the choice of the parent key for the [Media Type Object](https://spec.openapis.org/oas/latest.html#media-type-object) (with or without `+json`) determining only the serialization format.
+{% endcapture %}
+
+{% include media-type-entry.md summary=summary remarks=remarks %}
diff --git a/registries/_media-type/sequential_json.md b/registries/_media-type/sequential_json.md
new file mode 100644
index 0000000000..a3c0961642
--- /dev/null
+++ b/registries/_media-type/sequential_json.md
@@ -0,0 +1,49 @@
+---
+owner: handrews
+name: Sequential JSON
+description: Multiple concatenated JSON documents suitable for streaming
+media_types:
+ - name: application/jsonl
+ registered: false
+ specifications:
+ - name: JSON Lines
+ url: https://jsonlines.org/
+ - name: application/json-seq
+ registered: https://www.iana.org/assignments/media-types/application/json-seq
+ specifications:
+ - name: RFC7464
+ url: https://www.rfc-editor.org/rfc/rfc7464
+ - name: RFC8091
+ url: https://www.rfc-editor.org/rfc/rfc8091
+ - name: application/x-ndjson
+ registered: false
+ specifications:
+ - name: Newline Delimited JSON
+ url: https://github.com/ndjson/ndjson-spec
+references:
+ - section: Sequential Media Types
+ anchor: sequential-media-types
+ parent: Media Types
+ parentAnchor: media-types
+ - section: Streaming Sequential Media Types
+ anchor: streaming-sequential-media-types
+ parent: Media Type Object
+ parentAnchor: media-type-object
+ - section: Sequential JSON
+ anchor: sequential-json
+ parent: Media Type Examples
+ parentAnchor: media-type-examples
+layout: default
+---
+
+{% capture summary %}
+Sequential JSON media types concatenate multiple JSON documents into one document or stream, and only vary in their choices of delimiter and the restrictions on what whitespace is allowed between JSON syntax tokens.
+{% endcapture %}
+
+{% capture remarks %}
+All sequential JSON media types support the same two approaches:
+* Use the `schema` field to model the whole document as if it were a JSON array
+* Use `itemSchema` to model one item at a time for streaming purposes, where all items use the same schema
+{% endcapture %}
+
+{% include media-type-entry.md summary=summary remarks=remarks %}
diff --git a/registries/_media-type/sequential_multipart.md b/registries/_media-type/sequential_multipart.md
new file mode 100644
index 0000000000..f49ab1c7f7
--- /dev/null
+++ b/registries/_media-type/sequential_multipart.md
@@ -0,0 +1,66 @@
+---
+owner: handrews
+name: Sequential Multipart
+description: Multipart subtypes with unnamed parts
+media_types:
+ - name: multipart/*
+ iana: https://www.iana.org/assignments/media-types/media-types.xhtml#multipart
+ specifications:
+ - name: RFC2045
+ url: https://www.rfc-editor.org/rfc/rfc2045
+ - name: RFC2046 §5.1
+ url: https://www.rfc-editor.org/rfc/rfc2046#section-5.1
+ - name: multipart/mixed
+ iana: https://www.iana.org/assignments/media-types/multipart/mixed
+ specifications:
+ - name: RFC2045
+ url: https://www.rfc-editor.org/rfc/rfc2045
+ - name: RFC2046 §5.1.3
+ url: https://www.rfc-editor.org/rfc/rfc2046#section-5.1.3
+ - name: multipart/alternative
+ iana: https://www.iana.org/assignments/media-types/multipart/alternative
+ specifications:
+ - name: RFC2045
+ url: https://www.rfc-editor.org/rfc/rfc2045
+ - name: RFC2046 §5.1.4
+ url: https://www.rfc-editor.org/rfc/rfc2046#section-5.1.4
+ - name: multipart/related
+ iana: https://www.iana.org/assignments/media-types/multipart/related
+ specifications:
+ - name: RFC2389
+ url: https://www.rfc-editor.org/rfc/rfc2389
+ - name: RFC2557
+ url: https://www.rfc-editor.org/rfc/rfc2557
+ - name: multipart/byteranges
+ iana: https://www.iana.org/assignments/media-types/multipart/byteranges
+ specifications:
+ - name: RFC9110 §14.6
+ url: https://www.rfc-editor.org/rfc/rfc9110#name-media-type-multipart-bytera
+references:
+ - section: Encoding By Position
+ anchor: encoding-by-position
+ parent: Encoding Usage and Restrictions
+ parentAnchor: encoding-usage-and-restrictions
+ - section: Encoding `multipart` Media Types
+ anchor: encoding-multipart-media-types
+ parent: Encoding Object
+ parentAnchor: encoding-object
+layout: default
+---
+
+{% capture summary %}
+All `multipart` media types are based on a common syntax defined by `multipart/mixed`, and any `multipart` subtype not explicitly registered is expected to be usable by treating it as `multipart/mixed` in accordance with [RFC2046 §5.1.3](https://www.rfc-editor.org/rfc/rfc2046.html#section-5.1.3).
+{% endcapture %}
+
+{% capture remarks %}
+All known `multipart` subtypes except `multipart/form-data` are ordered, without any names for the parts.
+They are either modeled as arrays using `schema`, or a uniform schema can be applied to each part for streaming purposes using `itemSchema` (this is particularly relevant to `multipart/byteranges`).
+In both cases, `itemEncoding` can used to manage the media type and headers of each, while if `schema` is used, `prefixEncoding` is also available for describing some fixed number of initial parts in a specific order.
+
+The `boundary` required parameter is common to all `multipart` subtypes, but does not need to be described explicitly in OpenAPI Descriptions as it is typically generated and used automatically, with a value that is not predictable in advance.
+
+Note that OAS v3.0 claimed support for `multipart/mixed`, but behaviour was undefined. The claim of support was removed in OAS v3.0.4 and OAS v3.1.1, but can be seen in older patch releases of the 3.0 and 3.1 lines.
+{% endcapture %}
+
+{% include media-type-entry.md summary=summary remarks=remarks %}
+
diff --git a/registries/_media-type/sse.md b/registries/_media-type/sse.md
new file mode 100644
index 0000000000..9b19d62fac
--- /dev/null
+++ b/registries/_media-type/sse.md
@@ -0,0 +1,41 @@
+---
+owner: handrews
+name: Server-Sent Events
+description: Event streams for SSE
+media_types:
+ - name: text/event-stream
+ iana: false
+ specifications:
+ - name: WHATWG HTML §Server-Sent Events
+ url: https://html.spec.whatwg.org/multipage/server-sent-events.html#parsing-an-event-stream
+ - name: WHATWG HTML §IANA
+ url: https://html.spec.whatwg.org/multipage/iana.html#text/event-stream
+references:
+ - section: Sequential Media Types
+ anchor: sequential-media-types
+ parent: Media Types
+ parentAnchor: media-types
+ - section: Special Considerations for `text/event-stream` Content
+ anchor: special-considerations-for-text-event-stream-conten
+ parent: Media Type Object
+ parentAnchor: media-type-object
+ - section: Server-Sent Event Stream
+ anchor: server-sent-event-streams
+ parent: Media Type Examples
+ parentAnchor: media-type-examples
+layout: default
+---
+
+{% capture summary %}
+Server-Sent Events use the `text/event-stream` media type to stream events.
+Each event is modeled as if it were a JSON object with fields and types
+as given in the SSE specification, ignoring comments (fields with an empty string for the name) and any variations in serialization that represent the same event content.
+{% endcapture %}
+
+{% capture remarks %}
+A complete event stream can be modeled as if it were a JSON array of such objects in the `schema` field, but the more common use case is to use the `itemSchema` field to apply the same schema to each event as it is streamed.
+
+Note that application-level conventions regarding event usage (e.g. "sentinel events") that are not part of the media type specification are not modeled, as the OAS does not currently (as of OAS v3.2) work with semantics above the media type level.
+{% endcapture %}
+
+{% include media-type-entry.md summary=summary remarks=remarks %}
diff --git a/registries/_media-type/text.md b/registries/_media-type/text.md
new file mode 100644
index 0000000000..082bc07f9e
--- /dev/null
+++ b/registries/_media-type/text.md
@@ -0,0 +1,44 @@
+---
+owner: handrews
+name: Text
+description: Text-based media types
+media_types:
+ - name: text/*
+ iana: https://www.iana.org/assignments/media-types/media-types.xhtml#text
+ specifications:
+ - name: RFC2045
+ url: https://www.rfc-editor.org/rfc/rfc2045
+ - name: RFC2046 §4.1
+ url: https://www.rfc-editor.org/rfc/rfc2046#section-4.1
+ - name: text/plain
+ iana: https://www.iana.org/assignments/media-types/text/plain
+ specifications:
+ - name: RFC2046 §4.1.3
+ url: https://www.rfc-editor.org/rfc/rfc2046#section-4.1.3
+ - name: RFC3676
+ url: https://www.rfc-editor.org/rfc/rfc3676
+default_for: text-based (not just text/*)
+references:
+ - section: Parameter Object
+ anchor: parameter-object
+ - section: Header Object
+ anchor: header-object
+ - section: Encoding Object
+ anchor: encoding-object
+ - section: "Appendix D: Serializing Headers and Cookies"
+ anchor: appendix-d-serializing-headers-and-cookies
+layout: default
+---
+
+{% capture summary %}
+A plain text document is modeled as a single string.
+{% endcapture %}
+
+{% capture remarks %}
+In addition to normal use as HTTP message contents or `multipart` parts, `text/plain` is useful with the `content` field of the Parameter Object or Header Object to work around the automatic percent-encoding triggered by the use of the `schema` field.
+In particular, cookies with multiple values are not well-served by `style: form` and are better modeled as text.
+
+Note also that unlike JSON strings, the contents of the string representing the plain text are not quoted when serializing to a document. While a Schema Object of `{type: string, const: foo}` for JSON validates the JSON value `"foo"`, for plain text it validates `foo`, without quotes.
+{% endcapture %}
+
+{% include media-type-entry.md summary=summary remarks=remarks %}
diff --git a/registries/_media-type/xml.md b/registries/_media-type/xml.md
new file mode 100644
index 0000000000..6a2b0f240a
--- /dev/null
+++ b/registries/_media-type/xml.md
@@ -0,0 +1,40 @@
+---
+owner: handrews
+name: XML
+description: Extensible markup language
+media_types:
+ - name: application/xml
+ iana: https://www.iana.org/assignments/media-types/application/xml
+ specifications:
+ - name: RFC7303
+ url: https://www.rfc-editor.org/rfc/rfc7303
+ - name: XML 1.0
+ url: https://www.w3.org/TR/xml/
+ note: commonly used
+ - name: XML 1.1
+ url: https://www.w3.org/TR/xml11/
+ note: rarely used
+ - name: WHATWG DOM
+ url: https://dom.spec.whatwg.org/
+references:
+ - section: XML Object
+ anchor: xml-object
+ - section: XML Modeling
+ anchor: xml-modeling
+ parent: Schema Object
+ parentAnchor: schema-object
+layout: default
+---
+
+{% capture summary %}
+XML is modeled using the OAS's `xml` extension keyword for JSON Schema, which has an XML Object as its value.
+{% endcapture %}
+
+{% capture remarks %}
+As of OAS v3.2, the [XML Object](https://spec.openapis.org/oas/latest.html#xml-object) uses the `nodeType` field to determine the type of [interface node](https://dom.spec.whatwg.org/#interface-node) to which a given Schema Object corresponds: `element`, `attribute`, `text`, `cdata`, or `none`. If `nodeType` is set to `none`, a Schema Object does not correspond to anything and the nodes corresponding to its immediate subschemas are placed directly under the node of its parent schema.
+
+Certain behaviors are retained for compatibility with OAS v3.1, including implicit text nodes for elements with a primitive type, and somewhat complex rules for the default value of `nodeType`.
+In OAS v3.1 and earlier, only elements, their implicit primitive-type text nodes, and attributes were supported, with the now-deprecated `attribute` and `wrapped` flags as controls.
+{% endcapture %}
+
+{% include media-type-entry.md summary=summary remarks=remarks %}
diff --git a/registry/media-type.md b/registry/media-type.md
new file mode 100644
index 0000000000..f18817edc9
--- /dev/null
+++ b/registry/media-type.md
@@ -0,0 +1,29 @@
+---
+title: Media Type Registry
+layout: default
+permalink: /registry/media-type/index.html
+parent: Registry
+---
+
+# Media Type Registry
+
+This registry lists the non-JSON media types addressed by the OpenAPI Specification (OAS), and links to the appropriate OAS sections and external specifications.
+See [Working With Data](https://spec.openapis.org/oas/latest.html#working-with-data) and [Parsing and Serializing](https://spec.openapis.org/oas/latest.html#parsing-and-serializing) for a discussion of serialized, schema-ready, and application forms of data, and how to convert among the forms.
+
+## Specification Versions
+
+This registry is for and [linked from](https://spec.openapis.org/oas/latest.html#media-types) version 3.2 and later of the OAS. Earlier versions and other specifications such as Arazzo MAY support approaches added in this registry, as long as the necessary Objects and fields are available in those versions.
+
+## Contributing
+
+Please open a [discussion](https://github.com/OAI/OpenAPI-Specification/discussions) explaining your _**use cases**_ for any media type(s) you would like to see added.
+
+## Media Types
+
+**Note:** Media types with a structured suffix are handled the same way as the media type corresponding to the suffix (e.g. all `+json` media types are handled as `application/json`).
+
+|Group|Description|Media Types|
+|---|---|---|
+{% for value in site.media-type %}| {{ value.name }} | {{ value.description }} | {% for mt in value.media_types %}{{ mt.name }}{% unless forloop.last %}
{% endunless%}{% endfor %}{% if value.default_for %}
any unrecognized {{ value.default_for }} media type{% endif %}|
+{% endfor %}
+