You can use the transform-headers
policy to override headers in incoming or outgoing traffic.
Header transformations are executed in the following order:
- Set/replace headers
- Append headers: add values to existing headers or add a new header
- This is not supported for Native APIs
- Remove headers
- Keep only whitelisted headers
- Headers added/appended by this policy can be removed
- Whitelisting applies to headers added/appended by this policy
For Native Kafka APIs, the transform-headers policy operates on Kafka record headers instead of HTTP headers.
Key differences for Native Kafka APIs:
- Headers are stored as Kafka record headers
- Header values are stored as Kafka
Buffer
objects - Append headers functionality is not supported for Native Kafka APIs
Here are some usage examples of using Transform Headers.
Although each transformation can be configured individually, examples below emphasise that they can be cumulative.
Given the following headers:
Content-Type: application/json
When applying 'set/replace' with:
X-Hello
and valueWorld
Content-Type
and value*/*
Then headers are transformed as follows:
X-Hello: World
Content-Type: */*
Given the following headers:
X-Hello: World
Content-Type: */*
When applying 'amend' with:
X-Hello
and valueGood morning
X-Extra
and valueSuperfluous
Then headers are transformed as follows:
X-Hello: World,Good morning
X-Extra: Superfluous
Content-Type: */*
Given the following headers:
X-Hello: World,Good morning
X-Extra: Superfluous
Content-Type: */*
When applying 'remove' with:
- name
X-Extra
Then headers are transformed as follows:
X-Hello: World,Good morning
Content-Type: */*
Given the following headers:
X-Hello: World,Good morning
Content-Type: */*
When applying 'whitelisting' with:
- name
Content-Type
Then headers are transformed as follows:
Content-Type: */*
For Native Kafka APIs, the transform-headers policy works with Kafka record headers instead of HTTP headers. Here are examples for both publish and subscribe phases:
Given the following Kafka record headers:
X-Correlation-Id: abc-123
X-Internal-Header: debug-info
When applying 'set/replace' with:
X-Gravitee-Request-Id
and value{#request.id}
X-Source-System
and valueapi-gateway
And removing:
X-Internal-Header
Then headers are transformed as follows:
X-Correlation-Id: abc-123
X-Gravitee-Request-Id: req-456
X-Source-System: api-gateway
Given the following Kafka record headers:
X-Correlation-Id: abc-123
X-Debug-Header: debug-info
Content-Type: application/json
When applying 'set/replace' with:
X-Processing-Timestamp
and value{#date.now()}
And removing:
X-Debug-Header
Then headers are transformed as follows:
X-Correlation-Id: abc-123
X-Processing-Timestamp: 2024-01-15T10:30:00Z
Content-Type: application/json
Note: Append headers functionality is not supported for Native Kafka APIs.
The transform-headers
policy can be applied to the following API types and flow phases.
PROXY
MESSAGE
NATIVE KAFKA
- Publish
- Subscribe
- Request
- Response
Strikethrough text indicates that a version is deprecated.
Plugin version | APIM |
---|---|
5.x | 4.9.x to latest |
4.x | 4.6.x to 4.8.x |
3.x | 4.0.x to 4.5.x |
Name json name |
Type constraint |
Mandatory | Description |
---|---|---|---|
Set/replace headersaddHeaders |
array | Values defined here will replace existing values if a header with the same name is already defined in the request. See "Set/replace headers" section. |
|
Append headersappendHeaders |
array | Similar to set / Replace headers, but the values will be appended instead of being replaced if a header with the same name is already defined in the request. Multiple entries can be used to append several values to the same header name. See "Append headers" section. |
|
Remove headersremoveHeaders |
array (string) | ||
Headers to keepwhitelistHeaders |
array (string) | Works like a whitelist. All other headers will be removed. |
Name json name |
Type constraint |
Mandatory | Description |
---|---|---|---|
Namename |
string^\S*$ |
âś… | Name of the header |
Valuevalue |
string | âś… | Value of the header |
Name json name |
Type constraint |
Mandatory | Description |
---|---|---|---|
Namename |
string^\S*$ |
âś… | Name of the header |
Valuevalue |
string | âś… | Value of the header |
Proxy API on Request phase
{
"api": {
"definitionVersion": "V4",
"type": "PROXY",
"name": "Transform Headers example API",
"flows": [
{
"name": "Common Flow",
"enabled": true,
"selectors": [
{
"type": "HTTP",
"path": "/",
"pathOperator": "STARTS_WITH"
}
],
"request": [
{
"name": "Transform Headers",
"enabled": true,
"policy": "transform-headers",
"configuration":
{
"addHeaders": [
{
"name": "X-Gravitee-Request-Id",
"value": "{#request.id}"
}
],
"appendHeaders": [
{
"name": "Accept-Encoding",
"value": "gzip"
}
],
"removeHeaders": ["User-Agent"]
}
}
]
}
]
}
}
Proxy API with whitelisting on Response phase
{
"api": {
"definitionVersion": "V4",
"type": "PROXY",
"name": "Transform Headers example API",
"flows": [
{
"name": "Common Flow",
"enabled": true,
"selectors": [
{
"type": "HTTP",
"path": "/",
"pathOperator": "STARTS_WITH"
}
],
"response": [
{
"name": "Transform Headers",
"enabled": true,
"policy": "transform-headers",
"configuration":
{
"whitelistHeaders": ["X-Gravitee-Transaction-Id", "Content-Type", "Content-Length", "Connection"]
}
}
]
}
]
}
}
Message API CRD
apiVersion: "gravitee.io/v1alpha1"
kind: "ApiV4Definition"
metadata:
name: "transform-headers-message-api-crd"
spec:
name: "Transform Headers example"
type: "MESSAGE"
flows:
- name: "Common Flow"
enabled: true
selectors:
matchRequired: false
mode: "DEFAULT"
subscribe:
- name: "Transform Headers"
enabled: true
policy: "transform-headers"
configuration:
addHeaders:
- name: X-Gravitee-Request-Id
value: '{#request.id}'
appendHeaders:
- name: Accept-Encoding
value: gzip
removeHeaders:
- User-Agent
Native Kafka API CRD
apiVersion: "gravitee.io/v1alpha1"
kind: "ApiV4Definition"
metadata:
name: "transform-headers-kafka-native-api-crd"
spec:
name: "Transform Headers example"
type: "NATIVE"
flows:
- name: "Common Flow"
enabled: true
selectors:
matchRequired: false
mode: "DEFAULT"
subscribe:
- name: "Transform Headers"
enabled: true
policy: "transform-headers"
configuration:
addHeaders:
- name: X-Gravitee-Request-Id
value: '{#request.id}'
removeHeaders:
- X-Internal-Header
whitelistHeaders:
- X-Internal-Metadata
- X-Debug-Header
5.0.1 (2025-09-18)
- update apim to 4.9.0-alpha.2 (47c996b)
5.0.0 (2025-09-17)
- include cause throwable in the execution failure (e5f45da)
- requires APIM version 4.9.0 or later
4.2.0 (2025-09-16)
- add EL assistant on el field (aaf1756)
4.1.3 (2025-08-08)
- deps: bump gravitee-apim to 4.6.17 (08b2ca0)
4.1.2 (2025-07-24)
- update gravitee-parent to 22.5.1 (a172e29)
4.1.1 (2025-07-24)
- revert schema-form.json ref part for v2 and v4 to resolve Transform Headers UI issue (65a780c)
4.1.0 (2025-06-18)
- add Kafka usage to docgen documentation (439ad7a)
4.0.2 (2025-06-18)
- allow message to be used in EL (bff1dd4)
4.0.1 (2025-06-17)
- last review changes and orb for docgen (14b17bf)
- rewrite docs with doc-gen (050c79d)
- update dependencies and orbs (443ae8d)
4.0.0 (2025-04-17)
- handle KafkaPolicy on message request and response (6c17501)
- requires APIM version 4.6.0 or later
3.2.1 (2025-04-16)
- revert BC commit -- "feat: handle KafkaPolicy on message request and response" (855b5c2)
3.2.0 (2025-04-16)
- handle KafkaPolicy on message request and response (1002fe1)
3.1.0 (2025-04-11)
- add append header support (da55073)
3.0.2 (2023-11-13)
- make acceptlist case insensitive (4748140)
3.0.1 (2023-07-20)
- update policy description (09173df)
3.0.0 (2023-07-18)
- deps: update gravitee-parent (84ca37a)
- clean and validate json schema for v4 (da2a5bc)
- deps: require Java17
2.1.0-alpha.2 (2023-06-29)
- use new execution mode V4 Emulation (7d17544)
2.1.0-alpha.1 (2023-06-27)
- clean and validate json schema for v4 (da2a5bc)
2.0.1-alpha.1 (2023-06-22)
- add missing manifest information (ee3bf0b)
2.0.1 (2023-06-23)
- addition of supported API type & flow phase for this policy (db53540)
2.0.0 (2023-06-22)
- fixed little typo in README.adoc (e88ce29)
- add support of message level transformation (f821384)
- this version is using the latest dependencies introduced by Gravitee V4.0
1.10.0 (2022-03-24)
- Add support for request / response's payload to define HTTP headers values (0cb0b2c), closes gravitee-io/issues#7333
1.9.1 (2022-01-24)
- support arrays with null elements (140bded), closes gravitee-io/issues#5778
- transform-headers: Provide more logs in case of EL error (f4efd92), closes gravitee-io/issues#6479
1.9.0 (2022-01-22)
- headers: Internal HTTP headers refactoring (3b9919e), closes gravitee-io/issues#6772