Message Builder Policy
General Information
Policy Type
policy-message-builder
Description
Message Builder policy evaluates a list of rows sequentially. Each row reads from a source (body, header, query parameter, or context) and writes the result to a target custom variable. Template mode supports JEXL expressions and multi-line scripts with loops and conditionals.
Endpoints
List Policies
GET /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/
Add Policy
POST /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/
Update Policy
PUT /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/
Delete Policy
DELETE /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/
List Policies
Endpoint
GET /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/
Request
Headers
| Header | Value |
|---|---|
| Authorization | Bearer {token} |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| projectName | string | Yes | Project name |
| apiProxyName | string | Yes | API Proxy name |
Response
Success Response (200 OK)
{
"status": "SUCCESS",
"resultList": [
{
"apiProxy": {
"name": "PetAPI",
"requestPolicyList": [
{
"type": "policy-message-builder",
"name": "pet-enrichment-builder",
"description": "Enriches pet request payload with context and custom variables",
"active": true,
"rowList": [
{
"buildMode": "TEMPLATE",
"template": "#{body.$.name}",
"targetVariable": {
"name": "petName",
"type": "CUSTOM"
},
"required": false,
"continueOnError": true,
"defaultValue": "unknown"
}
]
}
],
"responsePolicyList": [],
"errorPolicyList": []
}
}
],
"resultCount": 1
}
cURL Example
curl -X GET \
"https://demo.apinizer.com/apiops/projects/MyProject/apiProxies/PetAPI/policies/" \
-H "Authorization: Bearer YOUR_TOKEN"
Add Policy
Endpoint
POST /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/
Request
Headers
| Header | Value |
|---|---|
| Authorization | Bearer {token} |
| Content-Type | application/json |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| projectName | string | Yes | Project name |
| apiProxyName | string | Yes | API Proxy name |
| policyName | string | Yes | Policy name |
Request Body
Full JSON Body Example
The following example builds an enriched JSON payload from request body, headers, query parameters, and context variables. It also produces a nested conditional element using intermediate custom variables.
{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": true,
"deployTargetEnvironmentNameList": ["production"],
"order": 1
},
"policy": {
"type": "policy-message-builder",
"description": "Enriches pet request payload with context and custom variables",
"active": true,
"rowList": [
{
"buildMode": "TEMPLATE",
"template": "#{body.$.name}",
"targetVariable": {
"name": "petName",
"type": "CUSTOM"
},
"required": false,
"continueOnError": true,
"defaultValue": "unknown"
},
{
"buildMode": "TEMPLATE",
"template": "#{body.$.category.name}",
"targetVariable": {
"name": "categoryLabel",
"type": "CUSTOM"
},
"required": false,
"continueOnError": true,
"defaultValue": ""
},
{
"buildMode": "TEMPLATE",
"template": "#{body.$.status == 'available' ? 'AVAILABLE' : body.$.status == 'pending' ? 'PENDING' : 'SOLD'}",
"targetVariable": {
"name": "statusLabel",
"type": "CUSTOM"
},
"required": false,
"continueOnError": true,
"defaultValue": ""
},
{
"buildMode": "TEMPLATE",
"template": "null",
"targetVariable": {
"name": "nestedObject",
"type": "CUSTOM"
},
"required": false,
"continueOnError": true,
"defaultValue": "null"
},
{
"policyCondition": {
"conditionRuleList": [
{
"conditionCriteria": "AND",
"conditionRuleList": [
{
"conditionCriteria": "VALUE",
"firstVariable": {
"type": "BODY",
"jsonPathValue": "$.status",
"messageContentType": "JSON"
},
"variableDataType": "STRING",
"valueComparisonOperator": "EQ",
"secondValueSource": "VALUE",
"secondValue": "available"
}
]
}
]
},
"buildMode": "TEMPLATE",
"template": "{\"displayName\":\"#{petName} - #{categoryLabel}\",\"statusLabel\":\"#{statusLabel}\"}",
"targetVariable": {
"name": "nestedObject",
"type": "CUSTOM"
},
"required": false,
"continueOnError": true,
"defaultValue": "null"
},
{
"buildMode": "TEMPLATE",
"template": "{\"request\":{\"headers\":{\"contentType\":\"#{header.Content-Type}\",\"xRequestId\":\"#{header.X-Request-Id}\"},\"query\":{\"format\":\"#{query.format}\"},\"body\":{\"id\":#{body.$.id},\"name\":\"#{petName}\",\"category\":{\"id\":#{body.$.category.id},\"name\":\"#{categoryLabel}\",\"nested\":#{nestedObject}},\"photoUrls\":#{body.$.photoUrls},\"tags\":#{body.$.tags},\"status\":\"#{body.$.status}\"}},\"context\":{\"httpMethod\":\"#{context.request.httpMethod}\",\"clientIp\":\"#{context.request.remoteAddress}\",\"correlationId\":\"#{context.message.correlationId}\",\"year\":\"#{context.system.year}\",\"dateTime\":\"#{context.system.dateTime}\",\"environment\":\"#{context.environment.name}\"},\"computed\":{\"operationType\":\"#{context.request.httpMethod == 'POST' ? 'create' : context.request.httpMethod == 'PUT' ? 'update' : context.request.httpMethod == 'DELETE' ? 'delete' : 'read'}\",\"summary\":\"#{petName} (#{categoryLabel}) - #{statusLabel}\"}}",
"targetVariable": {
"name": "enrichedPayload",
"type": "CUSTOM"
},
"required": false,
"continueOnError": true,
"defaultValue": "{}"
}
]
}
}
Request Body Fields
operationMetadata
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| targetScope | string | Yes | - | Policy scope: ALL or ENDPOINT |
| targetEndpoint | string | No* | - | Endpoint path (required if targetScope=ENDPOINT) |
| targetEndpointHTTPMethod | string | No* | - | HTTP method (required if targetScope=ENDPOINT) |
| targetPipeline | string | Yes | - | Pipeline: REQUEST, RESPONSE, or ERROR |
| deploy | boolean | No | true | Whether to deploy after adding policy |
| deployTargetEnvironmentNameList | array | No | [] | List of environment names to deploy to |
| order | integer | No | null | Policy execution order (starts from 1) |
Enum: targetScope
ALL- Policy applies to all endpointsENDPOINT- Policy applies only to specified endpoint
Enum: targetPipeline
REQUEST- Executes in request pipelineRESPONSE- Executes in response pipelineERROR- Executes in error pipeline
Enum: targetEndpointHTTPMethod
GET,POST,PUT,DELETE,PATCH,OPTIONS,HEAD
policy
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| type | string | Yes | - | Policy type: policy-message-builder |
| description | string | No | - | Policy description |
| active | boolean | No | true | Whether policy is active |
| rowList | array | Yes | - | List of message builder rows (at least one) |
rowList[] (Message Builder Row)
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| buildMode | string | Yes | - | Build mode: FORM or TEMPLATE |
| sourceVariable | object | Yes (FORM mode) | - | Source variable to read the value from |
| targetVariable | object | Yes | - | Target variable to write the result to |
| template | string | Yes (TEMPLATE mode) | - | Template string with #{...} expressions |
| required | boolean | No | false | If true, throws an error when the source value is empty |
| continueOnError | boolean | No | true | If true, processing continues to next row when an error occurs |
| defaultValue | string | No | - | Value to use when source is empty |
| policyCondition | object | No | - | Row-level condition; row is skipped when condition is not met |
Enum: buildMode
FORM- Copies value directly from source variable to target variableTEMPLATE- Evaluates#{...}template expressions (supports JEXL expressions and multi-line scripts)
variable (sourceVariable / targetVariable)
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes (CUSTOM type) | Variable name (used to reference in templates as #{name}) |
| type | string | Yes | Variable type (see EnumVariableType below) |
| headerName | string | Yes (HEADER type) | Header name (e.g., Content-Type, X-Request-Id) |
| paramType | string | Yes (PARAMETER type) | Parameter category: QUERY, PATH, or FORM |
| paramName | string | Yes (QUERY/PATH param) | Query or path parameter name |
| formName | string | Yes (FORM param) | Form field name |
| jsonPathValue | string | Yes (BODY/JSON type), Optional (CUSTOM) | JSONPath expression (e.g., $.user.name, $[0].id). For CUSTOM type, extracts a specific value from the variable's JSON content. |
| xpathValue | string | Yes (BODY/XML type), Optional (CUSTOM) | XPath expression (e.g., /root/user/name). For CUSTOM type, extracts a specific value from the variable's XML content. |
| messageContentType | string | Yes (BODY type), Optional (CUSTOM with path) | Body content type: JSON or XML. Required when using jsonPathValue or xpathValue with CUSTOM type. |
| contextValue | string | Yes (CONTEXT_VALUES type) | Context value enum (see EnumVariableContextValue below) |
Enum: EnumVariableType
| Value | Description | Required Fields |
|---|---|---|
HEADER | Request or response header value | headerName |
PARAMETER | Query, path, or form parameter | paramType, paramName or formName |
BODY | Request or response body field | jsonPathValue or xpathValue, messageContentType |
CUSTOM | Custom variable stored in the variable map. Optionally supports jsonPathValue/xpathValue with messageContentType to extract a specific value from the variable's content. | name, optionally jsonPathValue or xpathValue + messageContentType |
CONTEXT_VALUES | Gateway context value (runtime metadata) | contextValue |
Enum: EnumVariableParameterType
QUERY- URL query parameterPATH- URL path parameterFORM- Form-encoded parameter
Enum: EnumMessageContentType
JSON- JSON body (use withjsonPathValue)XML- XML body (use withxpathValue)
Enum: EnumVariableContextValue (contextValue)
| Value | Description |
|---|---|
REQUEST_HTTP_METHOD | HTTP method (GET, POST, PUT, DELETE, etc.) |
REQUEST_REMOTE_ADDRESS | Client IP address |
REQUEST_CONTENT_TYPE | Request Content-Type header |
REQUEST_REQUEST_URI | Full request URI |
REQUEST_QUERY_STRING | Raw query string |
REQUEST_USERNAME_KEY | Authenticated username or API key |
RESPONSE_STATUS_CODE | Response HTTP status code |
MESSAGE_CORRELATION_ID | Unique correlation ID assigned by the gateway |
ENVIRONMENT_ID | Gateway environment ID |
ENVIRONMENT_NAME | Gateway environment name |
APIPROXY_ID | API Proxy ID |
APIPROXY_NAME | API Proxy name |
APIPROXYGROUP_ID | API Proxy Group ID |
APIPROXYGROUP_NAME | API Proxy Group name |
APIMETHOD_ID | API Method ID |
APIMETHOD_NAME | API Method name |
APIMETHOD_HTTPMETHOD | API Method HTTP method |
APIMETHOD_ENDPOINT | API Method endpoint path |
APIMETHOD_BACKEND_HTTPMETHOD | Backend API method HTTP method |
APIMETHOD_BACKEND_ENDPOINT | Backend API method endpoint path |
DATETIME_YEAR | Current year (integer) |
DATETIME_MONTH | Current month (integer, 1-12) |
DATETIME_DAY_OF_WEEK | Day of week (integer, 1=Monday, 7=Sunday) |
DATETIME_DAY_OF_MONTH | Day of month (integer, 1-31) |
DATETIME_HOUR | Current hour (0-23) |
DATETIME_MINUTE | Current minute (0-59) |
DATETIME_SECOND | Current second (0-59) |
DATETIME_EPOCH_MILLIS | Epoch milliseconds since 1970-01-01T00:00:00Z |
DATETIME_FORMATTED_TEXT | Date-time in yyyy-MM-dd'T'HH:mm:ss.SSS'Z' format |
DATE_FORMATTED_TEXT | Date in yyyy-MM-dd format |
TIME_FORMATTED_TEXT | Time in HH:mm:ss format |
CREDENTIAL_USERNAME | Authenticated credential username |
CREDENTIAL_EMAIL | Authenticated credential email |
CREDENTIAL_FULLNAME | Authenticated credential full name |
policyCondition
The policyCondition object defines a row-level condition. The row is skipped when the condition evaluates to false.
| Field | Type | Required | Description |
|---|---|---|---|
| conditionRuleList | array | Yes | List of condition rules |
conditionRule fields:
| Field | Type | Required | Description |
|---|---|---|---|
| conditionCriteria | string | Yes | Rule type: AND, OR, NOT, or VALUE |
| conditionRuleList | array | Yes (AND/OR/NOT) | Nested list of condition rules |
| firstVariable | object | Yes (VALUE) | Left-hand side variable for comparison |
| variableDataType | string | Yes (VALUE) | Data type: STRING, NUMERIC, or DATE |
| valueComparisonOperator | string | Yes (VALUE) | Comparison operator (see below) |
| secondValueSource | string | Yes (VALUE) | Right-hand side source: VALUE (literal) or VARIABLE |
| secondValue | string | Yes (VALUE, secondValueSource=VALUE) | Literal value to compare against |
| secondVariable | object | Yes (VALUE, secondValueSource=VARIABLE) | Variable to compare against |
Enum: valueComparisonOperator
EQ- EqualsNE- Not equalsEQ_IGNORE_CASE- Equals, case insensitive (string only)NE_IGNORE_CASE- Not equals, case insensitive (string only)LT- Less thanLE- Less than or equalGT- Greater thanGE- Greater than or equalCONTAINS- String containsNOT_CONTAINS- String does not containCONTAINS_IGNORE_CASE- String contains, case insensitiveNOT_CONTAINS_IGNORE_CASE- String does not contain, case insensitiveSTARTS_WITH- String starts withNOT_STARTS_WITH- String does not start withSTARTS_WITH_IGNORE_CASE- String starts with, case insensitiveNOT_STARTS_WITH_IGNORE_CASE- String does not start with, case insensitiveENDS_WITH- String ends withNOT_ENDS_WITH- String does not end withENDS_WITH_IGNORE_CASE- String ends with, case insensitiveNOT_ENDS_WITH_IGNORE_CASE- String does not end with, case insensitiveIS_EXISTS- Variable exists (regardless of value)IS_NOT_EXISTS- Variable does not existIS_NOT_EMPTY- Variable exists and is not emptyIS_EMPTY- Variable does not exist or is emptyEXISTS_AND_EMPTY- Variable exists but is emptyIN- Value is in listNOT_IN- Value is not in listIN_IGNORE_CASE- Value is in list, case insensitiveNOT_IN_IGNORE_CASE- Value is not in list, case insensitive
Response
Success Response (200 OK)
{
"status": "SUCCESS",
"deploymentResult": {
"success": true,
"deploymentResults": [
{
"environmentName": "production",
"success": true,
"message": "Deployment successful"
}
]
}
}
cURL Example
curl -X POST \
"https://demo.apinizer.com/apiops/projects/MyProject/apiProxies/PetAPI/policies/pet-enrichment-builder/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": true,
"deployTargetEnvironmentNameList": ["production"],
"order": 1
},
"policy": {
"type": "policy-message-builder",
"description": "Enriches pet request payload",
"active": true,
"rowList": [
{
"buildMode": "TEMPLATE",
"template": "#{body.$.name}",
"targetVariable": {
"name": "petName",
"type": "CUSTOM"
},
"required": false,
"continueOnError": true,
"defaultValue": "unknown"
},
{
"buildMode": "TEMPLATE",
"template": "{\"id\":#{body.$.id},\"name\":\"#{petName}\",\"status\":\"#{body.$.status}\",\"method\":\"#{context.request.httpMethod}\",\"correlationId\":\"#{context.message.correlationId}\"}",
"targetVariable": {
"name": "enrichedPayload",
"type": "CUSTOM"
},
"required": false,
"continueOnError": true,
"defaultValue": "{}"
}
]
}
}'
Update Policy
Endpoint
PUT /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/
Request
Headers
| Header | Value |
|---|---|
| Authorization | Bearer {token} |
| Content-Type | application/json |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| projectName | string | Yes | Project name |
| apiProxyName | string | Yes | API Proxy name |
| policyName | string | Yes | Policy name |
Request Body
Same structure as Add Policy request body.
Full JSON Body Example
{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": true,
"deployTargetEnvironmentNameList": ["production"]
},
"policy": {
"type": "policy-message-builder",
"description": "Updated: Enriches pet payload with JEXL script for tags",
"active": true,
"rowList": [
{
"buildMode": "TEMPLATE",
"template": "#{body.$.name}",
"targetVariable": {
"name": "petName",
"type": "CUSTOM"
},
"required": false,
"continueOnError": true,
"defaultValue": "unknown"
},
{
"buildMode": "TEMPLATE",
"template": "#{body.$.status == 'available' ? 'AVAILABLE' : body.$.status == 'pending' ? 'PENDING' : 'SOLD'}",
"targetVariable": {
"name": "statusLabel",
"type": "CUSTOM"
},
"required": false,
"continueOnError": true,
"defaultValue": ""
},
{
"buildMode": "TEMPLATE",
"template": "#{\n var out = '[';\n var first = true;\n for (item : body.$.tags) {\n if (!first) { out = out + ','; }\n out = out + '{\"id\":' + item.id + ',\"label\":\"' + item.name + '\"}';\n first = false;\n }\n out + ']'\n}",
"targetVariable": {
"name": "tagList",
"type": "CUSTOM"
},
"required": false,
"continueOnError": true,
"defaultValue": "[]"
},
{
"buildMode": "TEMPLATE",
"template": "{\"name\":\"#{petName}\",\"status\":\"#{statusLabel}\",\"tags\":#{tagList},\"correlationId\":\"#{context.message.correlationId}\"}",
"targetVariable": {
"name": "enrichedPayload",
"type": "CUSTOM"
},
"required": false,
"continueOnError": true,
"defaultValue": "{}"
}
]
}
}
Response
Success Response (200 OK)
{
"status": "SUCCESS",
"deploymentResult": {
"success": true,
"deploymentResults": [
{
"environmentName": "production",
"success": true,
"message": "Deployment successful"
}
]
}
}
cURL Example
curl -X PUT \
"https://demo.apinizer.com/apiops/projects/MyProject/apiProxies/PetAPI/policies/pet-enrichment-builder/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": true,
"deployTargetEnvironmentNameList": ["production"]
},
"policy": {
"type": "policy-message-builder",
"description": "Updated: Enriches pet payload",
"active": true,
"rowList": [
{
"buildMode": "TEMPLATE",
"template": "#{body.$.name}",
"targetVariable": { "name": "petName", "type": "CUSTOM" },
"required": false,
"continueOnError": true,
"defaultValue": "unknown"
}
]
}
}'
Delete Policy
Endpoint
DELETE /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/
Request
Headers
| Header | Value |
|---|---|
| Authorization | Bearer {token} |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| projectName | string | Yes | Project name |
| apiProxyName | string | Yes | API Proxy name |
| policyName | string | Yes | Policy name |
Response
Success Response (200 OK)
{
"status": "SUCCESS",
"deploymentResult": {
"success": true
}
}
cURL Example
curl -X DELETE \
"https://demo.apinizer.com/apiops/projects/MyProject/apiProxies/PetAPI/policies/pet-enrichment-builder/" \
-H "Authorization: Bearer YOUR_TOKEN"
Template Syntax Reference
Simple Variable Access
| Syntax | Description |
|---|---|
#{body.$.field} | JSON body field via JSONPath |
#{body.$[0].field} | JSON array body — first element field |
#{body./root/field} | XML body field via XPath |
#{header.Header-Name} | Request header value |
#{query.paramName} | URL query parameter |
#{path.paramName} | URL path parameter |
#{form.fieldName} | Form-encoded parameter |
#{customVarName} | Custom variable from current row chain |
Region-Aware Variable Access
| Syntax | Description |
|---|---|
#{request.body.$.field} | Request body field (explicit region) |
#{request.header.Name} | Request header (explicit region) |
#{response.body.$.field} | Response body field (explicit region) |
#{response.header.Name} | Response header (explicit region) |
#{request.body./root/field} | Request body XPath (explicit region) |
#{response.body./root/field} | Response body XPath (explicit region) |
Custom Variable Path (JSONPath/XPath on variable content)
| Syntax | Description |
|---|---|
#{myVar.$.user.name} | JSONPath on custom variable's JSON content |
#{myVar./root/element} | XPath on custom variable's XML content |
#{myVar./bookstore/book[1]/title} | XPath with predicate on custom variable |
Context Variable Syntax
| Syntax | contextValue Enum |
|---|---|
#{context.request.httpMethod} | REQUEST_HTTP_METHOD |
#{context.request.remoteAddress} | REQUEST_REMOTE_ADDRESS |
#{context.message.correlationId} | MESSAGE_CORRELATION_ID |
#{context.apiProxy.name} | APIPROXY_NAME |
#{context.apiMethod.httpMethod} | APIMETHOD_HTTPMETHOD |
#{context.system.year} | DATETIME_YEAR |
#{context.system.dateTime} | DATETIME_FORMATTED_TEXT |
#{context.environment.name} | ENVIRONMENT_NAME |
#{context.credential.username} | CREDENTIAL_USERNAME |
JEXL Expression Examples
#{body.$.price * 1.18}
#{body.$.firstName + ' ' + body.$.lastName}
#{body.$.status == 'available' ? 'IN_STOCK' : 'OUT_OF_STOCK'}
#{context.request.httpMethod == 'POST' ? 'create' : 'read'}
JEXL Script (Multi-Line) Example
#{
var out = '[';
var first = true;
for (item : body.$.tags) {
if (!first) { out = out + ','; }
out = out + '{"id":' + item.id + ',"name":"' + item.name + '"}';
first = false;
}
out + ']'
}
The
returnkeyword is not used in JEXL Script. The value of the last evaluated expression is returned automatically.