Skip to main content
When you configure an API Target, the gateway acts as a proxy between your API consumers and your backend server. By default, requests are forwarded as-is to your target server. However, you often need to modify requests before they reach your backend or transform responses before they’re returned to consumers. Target Transformations allow you to:
  • Rewrite paths - Map consumer-facing URLs to your internal API structure
  • Inject headers - Add authentication tokens, API keys, or tracking headers
  • Modify query parameters - Add, remove, or transform URL parameters
  • Transform request bodies - Restructure payloads, add metadata, or wrap content
  • Transform responses - Filter fields, restructure data, or normalize formats
  • Calculate dynamic credits - Charge based on actual usage from response data
All transformations use an Expression Language that lets you access request data, user context, and response data dynamically.

Expression Syntax

Expressions are enclosed in double curly braces:
{{ expression }}
Everything outside {{ }} is treated as static text. You can mix static content with multiple expressions:
/api/v2{{ request.path }}?user={{ context.userId }}

Where Expressions Can Be Used

Expressions are supported in the following Target configuration fields:
FieldTabDescription
Path TransformationRequestRewrite the URL path sent to your backend
Custom HeadersRequestAdd or modify headers sent to your backend
Query ParametersRequestAdd or modify URL query parameters
Request BodyRequestTransform the request payload
Custom Response HeadersResponseAdd or modify headers returned to consumer
Response BodyResponseTransform the response payload
Dynamic CreditsResponseCalculate credits based on response data

Context Variables

Different variables are available depending on where the expression is used.

Request Variables

Available in: Path, Headers, Query, Request Body
VariableTypeDescription
request.methodstringHTTP method (GET, POST, etc.)
request.schemestringProtocol (http or https)
request.hoststringRequest hostname
request.portintServer port
request.pathstringRequest path (after API slug)
request.urlstringFull request URL
request.ipstringClient IP address
request.countrystringClient country code
request.bodystringRaw request body
request.jsonobjectParsed JSON body (if valid JSON)
request.headersobjectRequest headers (single value per key)
request.headersAllobjectRequest headers (array of values per key)
request.queryobjectQuery parameters (single value per key)
request.queryAllobjectQuery parameters (array of values per key)
request.raw.pathstringRaw path before transformation
request.raw.querystringRaw query string

Context Variables

Available in: All expressions
VariableTypeDescription
context.userIdstringObfuscated user identifier
context.usernamestringUser’s username
context.planIdstringSubscription plan slug
context.planTypestringPlan type (periodic or payasyougo)
context.endpointCreditsint|nullCredits defined for this endpoint

Response Variables

Available in: Response Body, Response Headers, Dynamic Credits
VariableTypeDescription
response.statusintHTTP status code from target
response.bodystringRaw response body
response.jsonobjectParsed JSON response (if valid JSON)
response.headersobjectResponse headers (single value per key)
response.headersAllobjectResponse headers (array of values per key)
response.latencyfloatRequest latency in seconds

Rendered Request Variables

Available in: Response Body, Response Headers, Dynamic Credits The renderedRequest object contains the transformed request that was actually sent to the target server.
VariableTypeDescription
renderedRequest.methodstringFinal HTTP method sent
renderedRequest.urlstringFinal URL sent to target
renderedRequest.hoststringTarget hostname
renderedRequest.pathstringTransformed path
renderedRequest.bodystringTransformed request body
renderedRequest.jsonobjectParsed transformed body
renderedRequest.headersobjectHeaders sent to target
renderedRequest.headersAllobjectHeaders sent (array per key)

Accessing Properties

Use dot notation for object properties:
{{ request.json }}
{{ response.headers }}
Use bracket notation for dynamic keys or special characters:
{{ request.headers["x-custom-header"] }}
{{ response.json["data"][0] }}

Functions

String Functions

FunctionDescriptionExample
lower(str)Convert to lowercase{{ lower(request.headers["accept"]) }}
upper(str)Convert to uppercase{{ upper(request.method) }}
trim(str)Remove leading/trailing whitespace{{ trim(request.query["name"]) }}
concat(a, b)Concatenate two strings{{ concat("/v2", request.path) }}
substring(str, start, len?)Extract substring{{ substring(request.path, 0, 10) }}
replace(str, from, to)Replace occurrences{{ replace(request.path, "/v1", "/v2") }}
split(str, delim)Split into array{{ split(request.query["ids"], ",") }}
join(arr, delim)Join array elements{{ join(request.json["tags"], ",") }}
startsWith(str, prefix)Check prefix{{ startsWith(request.path, "/api") }}
endsWith(str, suffix)Check suffix{{ endsWith(request.path, ".json") }}
contains(str, needle)Check if contains{{ contains(request.body, "error") }}
padLeft(str, len, char?)Pad start{{ padLeft(request.query["id"], 10, "0") }}
padRight(str, len, char?)Pad end{{ padRight(request.query["code"], 5) }}

Array Functions

FunctionDescriptionExample
first(arr)Get first element{{ first(response.json["results"]) }}
last(arr)Get last element{{ last(response.json["items"]) }}
slice(arr, start, len?)Extract portion{{ slice(response.json["data"], 0, 5) }}
keys(obj)Get object keys{{ keys(request.headers) }}
values(obj)Get object values{{ values(request.query) }}
in(needle, arr)Check membership{{ in(request.method, ["GET", "POST"]) }}
merge(arr1, arr2)Merge arrays{{ merge(arr1, arr2) }}
len(arr)Get length{{ len(response.json["results"]) }}

Encoding Functions

FunctionDescriptionExample
urlEncode(str)URL encode{{ urlEncode(request.query["callback"] }}
base64Encode(str)Base64 encode{{ base64Encode(request.body) }}
base64Decode(str)Base64 decode{{ base64Decode(request.headers["auth"]) }}
jsonEncode(val)JSON encode{{ jsonEncode(request.json["data"]) }}
jsonDecode(str)JSON decode{{ jsonDecode(request.body) }}

Type Functions

FunctionDescriptionExample
toInt(val)Convert to integer{{ toInt(request.query["page"]) }}
toFloat(val)Convert to float{{ toFloat(request.query["price"]) }}
isString(val)Check if string{{ isString(request.body) }}
isNumber(val)Check if number{{ isNumber(request.json["count"]) }}
isArray(val)Check if array{{ isArray(response.json["items"]) }}
isBool(val)Check if boolean{{ isBool(request.json["active"]) }}

Utility Functions

FunctionDescriptionExample
empty(val)Check if null/empty{{ empty(request.query["filter"]) }}
exists(val)Check if not null{{ exists(request.json["user"]) }}
default(val, fallback)Default if empty{{ default(request.query["page"], "1") }}
coalesce(a, b, ...)First non-empty{{ coalesce(request.json["id"], request.query["id"] }}
min(a, b)Minimum value{{ min(request.json["count"], 100) }}
max(a, b)Maximum value{{ max(request.json["page"], 1) }}
abs(val)Absolute value{{ abs(request.json["offset"]) }}
round(val, precision?)Round number{{ round(response.json["price"], 2) }}
floor(val)Round down{{ floor(response.json["rating"]) }}
ceil(val)Round up{{ ceil(response.json["pages"]) }}
buildQuery(params)Build URL query string{{ buildQuery({"page":1,"limit":10}) }}

Hash & Random Functions

FunctionDescriptionExample
hash(algo, str)Hash string{{ hash("sha256", request.body) }}
uuid()Generate UUID v4{{ uuid() }}
random(min?, max?)Random integer{{ random(1, 100) }}
Supported hash algorithms: md5, sha1, sha256, sha512

Date Functions

FunctionDescriptionExample
now()Current Unix timestamp{{ now() }}
date(format, timestamp?)Format date{{ date("Y-m-d H:i:s") }}

URL Functions

FunctionDescriptionExample
parseUrl(url, component)Parse URL part{{ parseUrl(request.url, 1) }}
Component values: 1=scheme, 2=host, 3=port, 5=path, 6=query, 7=fragment

Operators

Comparison

{{ request.json["count"] > 10 }}
{{ request.method == "POST" }}
{{ response.status != 200 }}
{{ request.json["price"] >= 100 }}

Logical

{{ request.json["active"] && request.json["verified"] }}
{{ request.query["format"] == "xml" || request.query["format"] == "json" }}
{{ !empty(request.json["email"]) }}

Ternary

{{ request.json["premium"] ? "pro" : "free" }}
{{ empty(request.query["limit"]) ? 10 : toInt(request.query["limit"]) }}

String Concatenation

{{ "/api/v2" ~ request.path }}
{{ request.json.["first"] ~ " " ~ request.json["last"] }}

Arithmetic

{{ request.json["price"] * 1.1 }}
{{ response.json["total"] / response.json["count"] }}
{{ request.json["page"] + 1 }}

Usage Examples

Path Transformation

Prefix all requests with a version:
/v2{{ request.path }}
Dynamic path based on request:
/users/{{ request.json["user_id"] }}/profile

Custom Headers

Add authentication header:
Bearer {{ base64Encode(context.userId ~ ":" ~ context.planId) }}
Forward user context:
{{ context.userId }}

Query Parameters

Default pagination:
{{ default(request.query["limit"], "20") }}

Request Body Transformation

Wrap original body:
{
  "data": {{ request.body }},
  "metadata": {
    "user": "{{ context.userId }}",
    "timestamp": {{ now() }}
  }
}

Response Body Transformation

Extract specific fields:
{
  "items": {{ jsonEncode(response.json["data"]["results"]) }},
  "total": {{ response.json["data"]["total_count"] }}
}

Dynamic Credits

Use credits from response header:
{{ response.headers["x-credits-used"] }}
Calculate credits based on response:
{{ len(response.json["results"]) }}
Fixed credits on success, zero on error:
{{ response.status >= 200 && response.status < 300 ? context.endpointCredits : 0 }}

Limits

  • Maximum template size: 200,000 characters
  • Maximum expressions per template: 100

Notes

  • Expressions that fail to evaluate will throw an error and the request will return a gateway error
  • JSON objects and arrays in expression results are automatically serialized
  • The request.json and response.json variables are null if the body is not valid JSON
  • Header names are case-insensitive and normalized to lowercase