This product is not supported for your selected Datadog site. ().
Overview
A relay proxy sits between your application and Datadog. The Feature Flag SDK sends requests to a URL on your domain, and your proxy forwards them to Datadog.
Two types of requests must be forwarded:
Flag configuration requests: POST to the Datadog CDN to fetch precomputed flag assignments. The SDK sends the evaluation context in the request body. Your proxy forwards the body and headers unchanged.
Event requests (exposures and evaluations): POST to Datadog intake endpoints. Mobile SDKs send to fixed paths on the Datadog API. The Browser SDK uses a ddforward query parameter that encodes the target path and parameters, which your proxy must decode and use to construct the final Datadog URL.
The code samples on this page use the US1 site (datadoghq.com) as an example. Replace the Datadog origins with the corresponding values for your Datadog site.
Datadog site
Flag CDN origin
Mobile intake origin
Browser intake origin
US1
preview.ff-cdn.datadoghq.com
api.datadoghq.com
browser-intake-datadoghq.com
EU1
preview.ff-cdn.datadoghq.eu
api.datadoghq.eu
browser-intake-datadoghq.eu
US3
preview.ff-cdn.us3.datadoghq.com
api.us3.datadoghq.com
browser-intake-us3-datadoghq.com
US5
preview.ff-cdn.us5.datadoghq.com
api.us5.datadoghq.com
browser-intake-us5-datadoghq.com
AP1
preview.ff-cdn.ap1.datadoghq.com
api.ap1.datadoghq.com
browser-intake-ap1-datadoghq.com
AP2
preview.ff-cdn.ap2.datadoghq.com
api.ap2.datadoghq.com
browser-intake-ap2-datadoghq.com
UK1
preview.ff-cdn.uk1.datadoghq.com
api.uk1.datadoghq.com
browser-intake-uk1-datadoghq.com
Choose a proxy implementation
NGINX works as a relay proxy on any infrastructure: cloud VMs, Kubernetes, Docker, or bare metal.
Flag configuration and mobile event relay
Add the following server block to your NGINX configuration.
nginx.conf
server{listen443ssl;server_nameproxy.example.com;# ssl_certificate /etc/ssl/certs/proxy.example.com.crt;
# ssl_certificate_key /etc/ssl/private/proxy.example.com.key;
# Flag configuration relay (all platforms)
location/precompute-assignments{proxy_passhttps://preview.ff-cdn.datadoghq.com/precompute-assignments;proxy_ssl_server_nameon;proxy_set_headerHostpreview.ff-cdn.datadoghq.com;proxy_pass_request_bodyon;}# Mobile SDK event relay: exposures
location/api/v2/exposures{proxy_passhttps://api.datadoghq.com/api/v2/exposures;proxy_ssl_server_nameon;proxy_set_headerHostapi.datadoghq.com;proxy_pass_request_bodyon;}# Mobile SDK event relay: evaluations
location/api/v2/flagevaluation{proxy_passhttps://api.datadoghq.com/api/v2/flagevaluation;proxy_ssl_server_nameon;proxy_set_headerHostapi.datadoghq.com;proxy_pass_request_bodyon;}}
After deploying, set the SDK options as follows:
SDK option
Value
Flag config (useCustomFlagEndpoint / customFlagsEndpoint)
The Browser SDK appends a ddforward query parameter containing the URL-encoded target path. Standard NGINX cannot decode this parameter in a proxy_pass directive. Use OpenResty, which extends NGINX with Lua scripting, to handle browser events.
Add this location block to the OpenResty server configuration alongside the standard NGINX blocks above. The Lua code requires the lua-resty-http library.
A Cloudflare Worker handles all request types in a single script and runs at the edge with no infrastructure to manage.
Create a Worker in your Cloudflare dashboard and deploy the following script. Update DATADOG_SITE if your Datadog site is not US1.
worker.js
constDATADOG_SITE='datadoghq.com';constFLAG_CDN_ORIGIN=`preview.ff-cdn.${DATADOG_SITE}`;constMOBILE_INTAKE_ORIGIN=`api.${DATADOG_SITE}`;const_parts=DATADOG_SITE.split('.');const_tld=_parts.pop();constBROWSER_INTAKE_ORIGIN=`browser-intake-${_parts.join('-')}.${_tld}`;exportdefault{asyncfetch(request){consturl=newURL(request.url);// Flag configuration relay: forward to Datadog CDN
if(url.pathname==='/precompute-assignments'){consttarget=`https://${FLAG_CDN_ORIGIN}/precompute-assignments`;returnfetch(target,{method:request.method,headers:request.headers,body:request.body,});}// Mobile SDK event relay: forward to Datadog API
if(url.pathname==='/api/v2/exposures'||url.pathname==='/api/v2/flagevaluation'){consttarget=`https://${MOBILE_INTAKE_ORIGIN}${url.pathname}`;returnfetch(target,{method:request.method,headers:request.headers,body:request.body,});}// Browser SDK event relay: decode ddforward and forward to browser intake
if(url.pathname==='/intake'){constddforward=url.searchParams.get('ddforward');if(!ddforward){returnnewResponse('missing ddforward',{status:400});}consttarget=`https://${BROWSER_INTAKE_ORIGIN}${ddforward}`;constforwardedHeaders=newHeaders(request.headers);forwardedHeaders.set('X-Forwarded-For',request.headers.get('CF-Connecting-IP')||'');forwardedHeaders.delete('cookie');returnfetch(target,{method:request.method,headers:forwardedHeaders,body:request.body,});}returnnewResponse('not found',{status:404});},};
After deploying, configure a custom domain for your Worker (for example, proxy.example.com) and set the SDK options as follows:
SDK option
Value
Flag config
https://proxy.example.com/precompute-assignments
Exposures (mobile)
https://proxy.example.com/api/v2/exposures
Evaluations (mobile)
https://proxy.example.com/api/v2/flagevaluation
Browser events (proxy)
https://proxy.example.com/intake
The Next.js API routes work as a relay proxy when deployed on Vercel or any Node.js hosting platform.
Create three API routes: one for flag configuration, one for mobile events, and one for browser events.
Flag configuration route
app/api/flag-config/route.ts
constFLAG_CDN=`https://preview.ff-cdn.datadoghq.com/precompute-assignments`;exportasyncfunctionPOST(req: Request){constheaders: HeadersInit={'Content-Type':req.headers.get('Content-Type')??'application/vnd.api+json',};// Pass through authentication headers from the SDK
constclientToken=req.headers.get('dd-client-token');constappId=req.headers.get('dd-application-id');if(clientToken)headers['dd-client-token']=clientToken;if(appId)headers['dd-application-id']=appId;constresponse=awaitfetch(FLAG_CDN,{method:'POST',headers,body: req.body,// @ts-ignore – required for streaming request body in Node.js
duplex:'half',});returnnewResponse(response.body,{status: response.status});}
Mobile event route
A catch-all route handles both /api/v2/exposures and /api/v2/flagevaluation and forwards each to the Datadog mobile intake.