diff --git a/docs/technical-details/reference/content-types.md b/docs/technical-details/reference/content-types.md
index 90ab593a..8d0feaf3 100644
--- a/docs/technical-details/reference/content-types.md
+++ b/docs/technical-details/reference/content-types.md
@@ -6,6 +6,12 @@ title: Content Types
Harper supports several different content types (or MIME types) for both HTTP request bodies (describing operations) as well as for serializing content into HTTP response bodies. Harper follows HTTP standards for specifying both request body content types and acceptable response body content types. Any of these content types can be used with any of the standard Harper operations.
+:::tip Need a custom content type?
+
+Harper's extensible content type system lets you add support for any serialization format (XML, YAML, proprietary formats, etc.) by registering custom handlers in the [`contentTypes`](./globals.md#contenttypes) global Map. See the linked API reference for detailed implementation types, handler properties, and examples.
+
+:::
+
For request body content, the content type should be specified with the `Content-Type` header. For example with JSON, use `Content-Type: application/json` and for CBOR, include `Content-Type: application/cbor`. To request that the response body be encoded with a specific content type, use the `Accept` header. If you want the response to be in JSON, use `Accept: application/json`. If you want the response to be in CBOR, use `Accept: application/cbor`.
The following content types are supported:
diff --git a/docs/technical-details/reference/globals.md b/docs/technical-details/reference/globals.md
index 70d81839..f0d57675 100644
--- a/docs/technical-details/reference/globals.md
+++ b/docs/technical-details/reference/globals.md
@@ -325,3 +325,59 @@ Returns map of shard number to an array of its associated nodes
### `server.hostname`
Returns the hostname of the current node
+
+### `server.contentTypes`
+
+Returns the `Map` of registered content type handlers. Same as the [`contentTypes`](./globals#contenttypes) global.
+
+## `contentTypes`
+
+Returns a [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) of content type handlers for request/response serialization.
+
+HarperDB uses content negotiation to automatically handle data serialization and deserialization for HTTP requests and other protocols. This process works by:
+
+1. **Request Processing**: Comparing the `Content-Type` header with registered handlers to deserialize incoming data into structured formats for processing and storage
+2. **Response Generation**: Comparing the `Accept` header with registered handlers to serialize structured data into the appropriate response format
+
+### Built-in Content Types
+
+HarperDB includes handlers for common formats:
+
+- **JSON** (`application/json`)
+- **CBOR** (`application/cbor`)
+- **MessagePack** (`application/msgpack`)
+- **CSV** (`text/csv`)
+- **Event-Stream** (`text/event-stream`)
+- And more...
+
+### Custom Content Type Handlers
+
+You can extend or replace content type handlers by modifying the `contentTypes` map from the `server` global (or `harperdb` export). The map is keyed by MIME type, with values being handler objects containing these optional properties:
+
+#### Handler Properties
+
+- **`serialize(data: any): Buffer | Uint8Array | string`**
+ Called to convert data structures into the target format for responses. Should return binary data (Buffer/Uint8Array) or a string.
+
+- **`serializeStream(data: any): ReadableStream`**
+ Called to convert data structures into streaming format. Useful for handling asynchronous iterables or large datasets.
+
+- **`deserialize(buffer: Buffer | string): any`**
+ Called to convert incoming request data into structured format. Receives a string for text MIME types (`text/*`) and a Buffer for binary types. Only used if `deserializeStream` is not defined.
+
+- **`deserializeStream(stream: ReadableStream): any`**
+ Called to convert incoming request streams into structured format. Returns deserialized data (potentially as an asynchronous iterable).
+
+- **`q: number`** _(default: 1)_
+ Quality indicator between 0 and 1 representing serialization fidelity. Used in content negotiation to select the best format when multiple options are available. The server chooses the content type with the highest product of client quality × server quality values.
+
+For example, if you wanted to define an XML serializer (that can respond with XML to requests with `Accept: text/xml`) you could write:
+
+```javascript
+contentTypes.set('text/xml', {
+ serialize(data) {
+ return '' ... some serialization '';
+ },
+ q: 0.8,
+});
+```
diff --git a/versioned_docs/version-4.4/technical-details/reference/content-types.md b/versioned_docs/version-4.4/technical-details/reference/content-types.md
index 90ab593a..8d0feaf3 100644
--- a/versioned_docs/version-4.4/technical-details/reference/content-types.md
+++ b/versioned_docs/version-4.4/technical-details/reference/content-types.md
@@ -6,6 +6,12 @@ title: Content Types
Harper supports several different content types (or MIME types) for both HTTP request bodies (describing operations) as well as for serializing content into HTTP response bodies. Harper follows HTTP standards for specifying both request body content types and acceptable response body content types. Any of these content types can be used with any of the standard Harper operations.
+:::tip Need a custom content type?
+
+Harper's extensible content type system lets you add support for any serialization format (XML, YAML, proprietary formats, etc.) by registering custom handlers in the [`contentTypes`](./globals.md#contenttypes) global Map. See the linked API reference for detailed implementation types, handler properties, and examples.
+
+:::
+
For request body content, the content type should be specified with the `Content-Type` header. For example with JSON, use `Content-Type: application/json` and for CBOR, include `Content-Type: application/cbor`. To request that the response body be encoded with a specific content type, use the `Accept` header. If you want the response to be in JSON, use `Accept: application/json`. If you want the response to be in CBOR, use `Accept: application/cbor`.
The following content types are supported:
diff --git a/versioned_docs/version-4.4/technical-details/reference/globals.md b/versioned_docs/version-4.4/technical-details/reference/globals.md
index 48483d22..dc7bd1f0 100644
--- a/versioned_docs/version-4.4/technical-details/reference/globals.md
+++ b/versioned_docs/version-4.4/technical-details/reference/globals.md
@@ -255,3 +255,59 @@ This records the provided value as a metric into Harper's analytics. Harper effi
- `path` - This is an optional path (like a URL path). For a URL like /my-resource/, you would typically include a path of "my-resource", not including the id so you can group by all the requests to "my-resource" instead of individually aggregating by each individual id.
- `method` - Optional method to group by.
- `type` - Optional type to group by.
+
+### `server.contentTypes`
+
+Returns the `Map` of registered content type handlers. Same as the [`contentTypes`](./globals#contenttypes) global.
+
+## `contentTypes`
+
+Returns a [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) of content type handlers for request/response serialization.
+
+HarperDB uses content negotiation to automatically handle data serialization and deserialization for HTTP requests and other protocols. This process works by:
+
+1. **Request Processing**: Comparing the `Content-Type` header with registered handlers to deserialize incoming data into structured formats for processing and storage
+2. **Response Generation**: Comparing the `Accept` header with registered handlers to serialize structured data into the appropriate response format
+
+### Built-in Content Types
+
+HarperDB includes handlers for common formats:
+
+- **JSON** (`application/json`)
+- **CBOR** (`application/cbor`)
+- **MessagePack** (`application/msgpack`)
+- **CSV** (`text/csv`)
+- **Event-Stream** (`text/event-stream`)
+- And more...
+
+### Custom Content Type Handlers
+
+You can extend or replace content type handlers by modifying the `contentTypes` map from the `server` global (or `harperdb` export). The map is keyed by MIME type, with values being handler objects containing these optional properties:
+
+#### Handler Properties
+
+- **`serialize(data: any): Buffer | Uint8Array | string`**
+ Called to convert data structures into the target format for responses. Should return binary data (Buffer/Uint8Array) or a string.
+
+- **`serializeStream(data: any): ReadableStream`**
+ Called to convert data structures into streaming format. Useful for handling asynchronous iterables or large datasets.
+
+- **`deserialize(buffer: Buffer | string): any`**
+ Called to convert incoming request data into structured format. Receives a string for text MIME types (`text/*`) and a Buffer for binary types. Only used if `deserializeStream` is not defined.
+
+- **`deserializeStream(stream: ReadableStream): any`**
+ Called to convert incoming request streams into structured format. Returns deserialized data (potentially as an asynchronous iterable).
+
+- **`q: number`** _(default: 1)_
+ Quality indicator between 0 and 1 representing serialization fidelity. Used in content negotiation to select the best format when multiple options are available. The server chooses the content type with the highest product of client quality × server quality values.
+
+For example, if you wanted to define an XML serializer (that can respond with XML to requests with `Accept: text/xml`) you could write:
+
+```javascript
+contentTypes.set('text/xml', {
+ serialize(data) {
+ return '' ... some serialization '';
+ },
+ q: 0.8,
+});
+```
diff --git a/versioned_docs/version-4.5/technical-details/reference/content-types.md b/versioned_docs/version-4.5/technical-details/reference/content-types.md
index 90ab593a..8d0feaf3 100644
--- a/versioned_docs/version-4.5/technical-details/reference/content-types.md
+++ b/versioned_docs/version-4.5/technical-details/reference/content-types.md
@@ -6,6 +6,12 @@ title: Content Types
Harper supports several different content types (or MIME types) for both HTTP request bodies (describing operations) as well as for serializing content into HTTP response bodies. Harper follows HTTP standards for specifying both request body content types and acceptable response body content types. Any of these content types can be used with any of the standard Harper operations.
+:::tip Need a custom content type?
+
+Harper's extensible content type system lets you add support for any serialization format (XML, YAML, proprietary formats, etc.) by registering custom handlers in the [`contentTypes`](./globals.md#contenttypes) global Map. See the linked API reference for detailed implementation types, handler properties, and examples.
+
+:::
+
For request body content, the content type should be specified with the `Content-Type` header. For example with JSON, use `Content-Type: application/json` and for CBOR, include `Content-Type: application/cbor`. To request that the response body be encoded with a specific content type, use the `Accept` header. If you want the response to be in JSON, use `Accept: application/json`. If you want the response to be in CBOR, use `Accept: application/cbor`.
The following content types are supported:
diff --git a/versioned_docs/version-4.5/technical-details/reference/globals.md b/versioned_docs/version-4.5/technical-details/reference/globals.md
index 8a842e70..0118882d 100644
--- a/versioned_docs/version-4.5/technical-details/reference/globals.md
+++ b/versioned_docs/version-4.5/technical-details/reference/globals.md
@@ -302,3 +302,59 @@ server.resources.getMatch('/NewResource/some-id');
/ or specify the export/protocol type, to allow it to be limited:
server.resources.getMatch('/NewResource/some-id', 'my-protocol');
```
+
+### `server.contentTypes`
+
+Returns the `Map` of registered content type handlers. Same as the [`contentTypes`](./globals#contenttypes) global.
+
+## `contentTypes`
+
+Returns a [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) of content type handlers for request/response serialization.
+
+HarperDB uses content negotiation to automatically handle data serialization and deserialization for HTTP requests and other protocols. This process works by:
+
+1. **Request Processing**: Comparing the `Content-Type` header with registered handlers to deserialize incoming data into structured formats for processing and storage
+2. **Response Generation**: Comparing the `Accept` header with registered handlers to serialize structured data into the appropriate response format
+
+### Built-in Content Types
+
+HarperDB includes handlers for common formats:
+
+- **JSON** (`application/json`)
+- **CBOR** (`application/cbor`)
+- **MessagePack** (`application/msgpack`)
+- **CSV** (`text/csv`)
+- **Event-Stream** (`text/event-stream`)
+- And more...
+
+### Custom Content Type Handlers
+
+You can extend or replace content type handlers by modifying the `contentTypes` map from the `server` global (or `harperdb` export). The map is keyed by MIME type, with values being handler objects containing these optional properties:
+
+#### Handler Properties
+
+- **`serialize(data: any): Buffer | Uint8Array | string`**
+ Called to convert data structures into the target format for responses. Should return binary data (Buffer/Uint8Array) or a string.
+
+- **`serializeStream(data: any): ReadableStream`**
+ Called to convert data structures into streaming format. Useful for handling asynchronous iterables or large datasets.
+
+- **`deserialize(buffer: Buffer | string): any`**
+ Called to convert incoming request data into structured format. Receives a string for text MIME types (`text/*`) and a Buffer for binary types. Only used if `deserializeStream` is not defined.
+
+- **`deserializeStream(stream: ReadableStream): any`**
+ Called to convert incoming request streams into structured format. Returns deserialized data (potentially as an asynchronous iterable).
+
+- **`q: number`** _(default: 1)_
+ Quality indicator between 0 and 1 representing serialization fidelity. Used in content negotiation to select the best format when multiple options are available. The server chooses the content type with the highest product of client quality × server quality values.
+
+For example, if you wanted to define an XML serializer (that can respond with XML to requests with `Accept: text/xml`) you could write:
+
+```javascript
+contentTypes.set('text/xml', {
+ serialize(data) {
+ return '' ... some serialization '';
+ },
+ q: 0.8,
+});
+```
diff --git a/versioned_docs/version-4.6/technical-details/reference/content-types.md b/versioned_docs/version-4.6/technical-details/reference/content-types.md
index 90ab593a..8d0feaf3 100644
--- a/versioned_docs/version-4.6/technical-details/reference/content-types.md
+++ b/versioned_docs/version-4.6/technical-details/reference/content-types.md
@@ -6,6 +6,12 @@ title: Content Types
Harper supports several different content types (or MIME types) for both HTTP request bodies (describing operations) as well as for serializing content into HTTP response bodies. Harper follows HTTP standards for specifying both request body content types and acceptable response body content types. Any of these content types can be used with any of the standard Harper operations.
+:::tip Need a custom content type?
+
+Harper's extensible content type system lets you add support for any serialization format (XML, YAML, proprietary formats, etc.) by registering custom handlers in the [`contentTypes`](./globals.md#contenttypes) global Map. See the linked API reference for detailed implementation types, handler properties, and examples.
+
+:::
+
For request body content, the content type should be specified with the `Content-Type` header. For example with JSON, use `Content-Type: application/json` and for CBOR, include `Content-Type: application/cbor`. To request that the response body be encoded with a specific content type, use the `Accept` header. If you want the response to be in JSON, use `Accept: application/json`. If you want the response to be in CBOR, use `Accept: application/cbor`.
The following content types are supported:
diff --git a/versioned_docs/version-4.6/technical-details/reference/globals.md b/versioned_docs/version-4.6/technical-details/reference/globals.md
index 8f78b7f7..ea7cede9 100644
--- a/versioned_docs/version-4.6/technical-details/reference/globals.md
+++ b/versioned_docs/version-4.6/technical-details/reference/globals.md
@@ -325,3 +325,61 @@ Returns map of shard number to an array of its associated nodes
### `server.hostname`
Returns the hostname of the current node
+
+### `server.contentTypes`
+
+Returns the `Map` of registered content type handlers. Same as the [`contentTypes`](./globals#contenttypes) global.
+
+## `contentTypes`
+
+Returns a [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) of content type handlers for request/response serialization.
+
+HarperDB uses content negotiation to automatically handle data serialization and deserialization for HTTP requests and other protocols. This process works by:
+
+1. **Request Processing**: Comparing the `Content-Type` header with registered handlers to deserialize incoming data into structured formats for processing and storage
+2. **Response Generation**: Comparing the `Accept` header with registered handlers to serialize structured data into the appropriate response format
+
+### Built-in Content Types
+
+HarperDB includes handlers for common formats:
+
+- **JSON** (`application/json`)
+- **CBOR** (`application/cbor`)
+- **MessagePack** (`application/msgpack`)
+- **CSV** (`text/csv`)
+- **Event-Stream** (`text/event-stream`)
+- And more...
+
+For detailed information about each built-in content type, including usage recommendations and performance characteristics, see the [Content Types reference](./content-types.md).
+
+### Custom Content Type Handlers
+
+You can extend or replace content type handlers by modifying the `contentTypes` map from the `server` global (or `harperdb` export). The map is keyed by MIME type, with values being handler objects containing these optional properties:
+
+#### Handler Properties
+
+- **`serialize(data: any): Buffer | Uint8Array | string`**
+ Called to convert data structures into the target format for responses. Should return binary data (Buffer/Uint8Array) or a string.
+
+- **`serializeStream(data: any): ReadableStream`**
+ Called to convert data structures into streaming format. Useful for handling asynchronous iterables or large datasets.
+
+- **`deserialize(buffer: Buffer | string): any`**
+ Called to convert incoming request data into structured format. Receives a string for text MIME types (`text/*`) and a Buffer for binary types. Only used if `deserializeStream` is not defined.
+
+- **`deserializeStream(stream: ReadableStream): any`**
+ Called to convert incoming request streams into structured format. Returns deserialized data (potentially as an asynchronous iterable).
+
+- **`q: number`** _(default: 1)_
+ Quality indicator between 0 and 1 representing serialization fidelity. Used in content negotiation to select the best format when multiple options are available. The server chooses the content type with the highest product of client quality × server quality values.
+
+For example, if you wanted to define an XML serializer (that can respond with XML to requests with `Accept: text/xml`) you could write:
+
+```javascript
+contentTypes.set('text/xml', {
+ serialize(data) {
+ return '' ... some serialization '';
+ },
+ q: 0.8,
+});
+```