diff --git a/testing/script/request/request-object.mdx b/testing/script/request/request-object.mdx
index 8956ef97..b28b72f5 100644
--- a/testing/script/request/request-object.mdx
+++ b/testing/script/request/request-object.mdx
@@ -34,6 +34,98 @@ console.log(req.headers);
} */
```
+## `headerList`
+
+The `req.headerList` property exposes a structured, writable API for managing request headers. All key lookups are case-insensitive. The existing `req.headers` raw object remains untouched for backward compatibility — both are kept in sync.
+
+```javascript
+// Read
+req.headerList.get('Content-Type'); // 'application/json'
+req.headerList.has('Authorization'); // true
+req.headerList.one('Content-Type'); // { key: 'Content-Type', value: 'application/json' }
+req.headerList.all(); // [{ key, value }, ...]
+req.headerList.count(); // 3
+
+// Search
+req.headerList.find(h => h.key.startsWith('X-'));
+req.headerList.filter(h => h.value.includes('json'));
+req.headerList.indexOf('Content-Type');
+
+// Iteration
+req.headerList.forEach((h, i) => { /* ... */ });
+req.headerList.map(h => h.key);
+req.headerList.reduce((acc, h) => acc, {});
+
+// Transform
+req.headerList.toObject(); // { 'Content-Type': 'application/json', ... }
+req.headerList.toString(); // 'Content-Type: application/json\n...'
+
+// Write
+req.headerList.append({ key: 'X-Custom', value: 'val' });
+req.headerList.append('X-Custom: val'); // string format
+req.headerList.append('X-Custom', 'val'); // two-arg form
+req.headerList.set({ key: 'Content-Type', value: 'text/plain' });
+req.headerList.set('Content-Type', 'text/plain');
+req.headerList.delete('X-Custom');
+req.headerList.delete(h => h.key.startsWith('X-'));
+req.headerList.clear();
+req.headerList.populate([{ key: 'A', value: '1' }]);
+req.headerList.repopulate([{ key: 'A', value: '1' }]);
+```
+
+### Method Reference
+
+#### Read
+
+| Method | Returns | Description |
+| --- | --- | --- |
+| `get(name)` | `string \| undefined` | Value of the first header matching the key |
+| `one(name)` | `object \| undefined` | Full header object `{ key, value }` for the matching key |
+| `all()` | `object[]` | Cloned array of all header objects `{ key, value, disabled? }` |
+| `count()` | `number` | Number of headers (including disabled) |
+
+#### Search
+
+| Method | Returns | Description |
+| --- | --- | --- |
+| `has(name)` | `boolean` | `true` if a header with that key exists |
+| `has(name, value)` | `boolean` | `true` if key exists and value matches exactly |
+| `find(fn, context?)` | `object \| undefined` | First header where the predicate returns truthy |
+| `filter(fn, context?)` | `object[]` | All headers where the predicate returns truthy |
+| `indexOf(item)` | `number` | Index of a header by string key or `{ key, value }` object; `-1` if not found |
+
+#### Iteration
+
+| Method | Returns | Description |
+| --- | --- | --- |
+| `forEach(fn, context?)` | `void` | Calls `fn(header, index)` for every header |
+| `map(fn, context?)` | `any[]` | Returns a new array of mapped values |
+| `reduce(fn, initial?, context?)` | `any` | Reduces headers to a single value |
+
+#### Transform
+
+| Method | Returns | Description |
+| --- | --- | --- |
+| `toObject()` | `object` | Plain `{ key: value }` map |
+| `toString()` | `string` | HTTP wire format `Key: Value\n...` (skips disabled headers) |
+| `toJSON()` | `object[]` | Same as `all()` — suitable for `JSON.stringify()` |
+
+#### Write
+
+| Method | Returns | Description |
+| --- | --- | --- |
+| `append(headerObj \| name, value?)` | `void` | Sets a header; accepts `{ key, value }`, `"Key: Value"` string, or `(name, value)` two-arg form. Bruno does not support duplicate header keys, so `append()` overwrites any existing header with the same key. |
+| `set(headerObj \| name, value?)` | `boolean \| null` | Sets or replaces a header. Returns `true` if new, `false` if updated, `null` if input was nil. |
+| `delete(predicate, context?)` | `void` | Deletes header(s) by key string, `{ key }` object, or predicate function |
+| `clear()` | `void` | Removes all headers (enabled and disabled) |
+| `populate(items \| string)` | `void` | Adds items from an array or multi-line string, skipping keys that already exist |
+| `repopulate(items \| string)` | `void` | Clears all headers, then populates with new items |
+| `assimilate(source, prune?)` | `void` | Merges headers from a PropertyList or array; if `prune` is `true`, removes headers not present in source |
+
+
+ Disabled headers are surfaced via `req.headerList` with `{ disabled: true }` on the entry — you can query or filter them just like enabled headers. The HTTP wire-format `toString()` skips disabled headers.
+
+
## Method
The `method` property of the `req` object specifies the HTTP method used for the request. Common HTTP methods include "GET", "POST", "PUT", "DELETE", etc. The method indicates the type of action the request wishes to perform on the resource. The value of the `method` property should be a string representing the desired HTTP method for the request.
diff --git a/testing/script/response/response-object.mdx b/testing/script/response/response-object.mdx
index 051ef0d9..86e2d5a5 100644
--- a/testing/script/response/response-object.mdx
+++ b/testing/script/response/response-object.mdx
@@ -31,6 +31,74 @@ The `headers` property contains HTTP headers associated with the response. These
The `status` property represents the HTTP status code of the response. It indicates the outcome of the request, such as success, redirection, client error, or server error.
+## `headerList`
+
+The `res.headerList` property exposes a structured, read-only API for inspecting response headers. All key lookups are case-insensitive. The existing `res.headers` raw object remains available unchanged.
+
+```javascript
+// Read
+res.headerList.get('content-type'); // 'application/json'
+res.headerList.has('x-request-id'); // true
+res.headerList.one('Cache-Control'); // { key: 'Cache-Control', value: 'no-cache' }
+res.headerList.all(); // [{ key, value }, ...]
+res.headerList.count(); // 2
+
+// Search
+res.headerList.find(h => h.key.toLowerCase() === 'content-type');
+res.headerList.filter(h => h.key.startsWith('x-'));
+res.headerList.indexOf('content-type');
+
+// Iteration
+res.headerList.forEach((h, i) => { /* ... */ });
+res.headerList.map(h => h.key);
+res.headerList.reduce((acc, h) => acc, {});
+
+// Transform
+res.headerList.toObject(); // plain object map
+res.headerList.toString(); // HTTP wire format
+```
+
+
+ `res.headerList` is read-only. Calling write methods (`append`, `set`, `delete`, `clear`, `populate`, `repopulate`, `assimilate`) throws a `"HeaderList is read-only"` error.
+
+
+### Method Reference
+
+#### Read
+
+| Method | Returns | Description |
+| --- | --- | --- |
+| `get(name)` | `string \| undefined` | Value of the first header matching the key |
+| `one(name)` | `object \| undefined` | Full header object `{ key, value }` for the matching key |
+| `all()` | `object[]` | Cloned array of all header objects `{ key, value }` |
+| `count()` | `number` | Number of headers |
+
+#### Search
+
+| Method | Returns | Description |
+| --- | --- | --- |
+| `has(name)` | `boolean` | `true` if a header with that key exists |
+| `has(name, value)` | `boolean` | `true` if key exists and value matches exactly |
+| `find(fn, context?)` | `object \| undefined` | First header where the predicate returns truthy |
+| `filter(fn, context?)` | `object[]` | All headers where the predicate returns truthy |
+| `indexOf(item)` | `number` | Index of a header by string key or `{ key, value }` object; `-1` if not found |
+
+#### Iteration
+
+| Method | Returns | Description |
+| --- | --- | --- |
+| `forEach(fn, context?)` | `void` | Calls `fn(header, index)` for every header |
+| `map(fn, context?)` | `any[]` | Returns a new array of mapped values |
+| `reduce(fn, initial?, context?)` | `any` | Reduces headers to a single value |
+
+#### Transform
+
+| Method | Returns | Description |
+| --- | --- | --- |
+| `toObject()` | `object` | Plain `{ key: value }` map |
+| `toString()` | `string` | HTTP wire format `Key: Value\n...` |
+| `toJSON()` | `object[]` | Same as `all()` — suitable for `JSON.stringify()` |
+
## Example Usage
```javascript
@@ -47,6 +115,7 @@ const res = {
// Accessing response properties
console.log(res.body); // Output: '{"message": "Hello, world!"}'
console.log(res.headers['Content-Type']); // Output: 'application/json'
+console.log(res.headerList.get('content-type')); // Output: 'application/json' (case-insensitive)
console.log(res.status); // Output: 200
```