It is suggested to first read:
Darwinium Profiling for overview
JavaScript Profiling for general considerations
In a Darwinium Tags deployment, a script Tag is added by your team directly to pages in scope.
Profiling
Darwinium JS tags are added on a specific page
profiling start function invoked on page load. This performs fingerprinting of the user device, connection, behavioural biometrics and more.
profiling continues to run until user performs an action (like hitting submit), profiling collect function is called
The collect function produces a profileBlob, which should be passed to your back-end, ready to include in the Darwinium Event API step
API call (event capture)
If using API, Darwinium Event API is then called from your back-end for risk assessment
The profileBlob is included in header named dwn-profiling on the API call.
Full data is returned in the API response body in JSON format, including risk scores and signals
The event forms a row of data in the Darwinium Portal
.png?sv=2026-02-06&spr=https&st=2026-08-21T07%3A22%3A00Z&se=2026-08-21T07%3A40%3A00Z&sr=c&sp=r&sig=5gy%2F1rbxcro3Uwwfc29ml3llzXYPne07k0KlcHbpb0o%3D)
CDN (event capture)
If using Tags on a CDN deployment, a Darwinium deployed worker on the submit request will strip profiling header and call Event API automatically
Step 1 - Decide Host subdomain, Validate Certificate
Subdomain(s) of the website being covered should be agreed eg. aps.yourhost.com for the JS Tags to be hosted on.
If not using CDN, Darwinium will supply an SSL certificate to cover the chosen subdomain. The usual way we provision these is via AWS Certificate Manager.
Validate the Cert
The domain of the cert will need to be validated/signed by you.
(best) Add CNAME name and value supplied by Darwinium to your DNS to act as validation of domain. This method is best as ensures certs can be auto-renewed.
OR validation can be done via email to domain owner
OR we can manually send a .csr to be signed
Add CNAME record: subdomain → CloudFront
Finally, create a CNAME record in your DNS pointing it to the CloudFront distribution Darwinium provisions
Name: aps.yourhost.com → Value: d1exampleexample.cloudfront.net
Step 2 - Add CloudFront as a Target in Darwinium Portal
To deploy Tags, CloudFront deployment details should be created and added in your Portal node.
See: https://docs.darwinium.com/docs/cloudfront-deployment#step-8-add-the-ids-into-the-darwinium-portal
Darwinium can perform this on your behalf.
Step 3 - Deploy the Profiling URL in Darwinium Portal
To ensure Darwinium JS profiling tags are delivered on a URL on the chosen subdomain, a step is set up in Darwinium Portal
1. In the Darwinium Marketplace tab of the Workflows Editor, locate "Darwinium profiling (Tag only - no proxy)" and click install. This will install several files in your node's repo. The key file used is dwn_profiling_tag.snippet

2. Activate the snippet in your journey by opening the journey, navigating to Configuration and clicking Add Snippet. Click ... and locate dwn_profiling_tag.snippet
3. Add a Tag Profiling Step to your journey, using the left-hand sidebar:

The Tag Profiling step has several customizations that enable flexible deployment and allow you to choose which features are included. Reducing the number of features included can help to reduce the size of the file delivered to your end-user and optimize performance. A complete deployment with all features enabled has a footprint of approximately 90kb.
.png?sv=2026-02-06&spr=https&st=2026-08-21T07%3A22%3A00Z&se=2026-08-21T07%3A40%3A00Z&sr=c&sp=r&sig=5gy%2F1rbxcro3Uwwfc29ml3llzXYPne07k0KlcHbpb0o%3D)
Host - The agreed upon subdomain from Step1. It can also be a Host Alias.
If you are using this feature as part of an existing edge deployment, this will align with the hostname used in your other steps and SSL will be automatically configured based on your existing CDN vendor settings.
ListenURL - URL to serve tags on. Can be anything, but should start with
/and end in.js.For example:
/dwnfp.js
JavaScript Variable Name - Variable name of the Darwinium profiling object that will be invoked in Step3.
For example:
dwn
Build and Deploy the journey from within Darwinium to make the profiling step live
You can test the profiling tags are working by going to https://aps.yourhost.com/yourlistenurl.js
If deployed, it should be delivering the Darwinium profiling javascript.
Why are we using a subdomain? Why are listen URL and JS Variable name parameters?
It is important that tags appear to be hosted using a 1st-party domain. This inhibits ad-blockers from blocklisting our own domain and making them ineffective.
Furthermore, we have pre-emptively avoided blockers from blocking or replacing particular javascript variables (such as 'dwn') by enabling the ability for you to specify your own variable name. Once you become acquainted with the use of profiling, it is recommended that you customize your variable name for this reason.
Step 4 - Implement Tags on your Application Frontend
Technical Specification of Tags Interface
Darwinium tag only API interface
a. Add the script to your page
Your application will need to import the tags from your Profiling Tags Step. The most straightforward means of doing this is to add it as a script tag to your application's head.
Be sure to replace "https://aps.yourhost.com/yourlistenurl.js" with your Host and your Listen URL values you specified in the Step 1.
<script type="text/javascript" src="https://aps.yourhost.com/yourlistenurl.js"></script>b. Create a new Profiling Instance
Next, instruct Darwinium to start profiling. Typically you should do this when your page loads (in the case of a simple page), or when a point of interest (such as a form appearing) is presented to the end user.
// On page load
let profilingInstance = dwn.start({
geo_location_enabled: false, //capture geolocation data, true triggers popup
mouse: true, // capture mouse biometrics
key_bm: //key biometrics: each of these is a selector for an input field
//that you wish to profile, and a Darwinium context of what the field is.
[{selector: '#grid-first-name', context: 'FIRST_NAME'},
{selector: '#grid-last-name', context: 'LAST_NAME'},
{selector: '#grid-password', context: 'PASSWORD'},
{selector: '#grid-city', context: 'ADDRESS_STREET3'}
]
})The selector string values (eg. in example #grid-first-name) should be replaced with CSS selectors of inputs on your site page
The context values (eg. in example FIRST_NAME) should be replaced by sensible choices from the fixed keyboard context list
The characters in context value are case insensitive, e.g. first_name, First_Name, FIRST_NAME are all accepted
You can create as many profiling instances as you'd like. They will continue to collect Biometric data until told to stop. It is often preferable to start/stop instances as actions occur on your front end experience.
c. Collect profiling data and pass it to your application backend
You will want to provide the intelligence gathered by profiling when an action such as a form submit occurs onto your backend, where it can be passed to Darwinium's API steps for further decisioning. In the following example we will intercept a submit button call and send that to our backend. A typical way of passing it is in the header of the existing request to your back end.
As a best practice, Darwinium profiling should always been stopped during the collection of sensitive data that is not being used in conjunction with Darwinium decisioning. For example, if Darwinium is implemented for Register and Login but not card payments, then profiling should be stopped
const handleSubmit = (e) => {
e.preventDefault();
//
profilingInstance.collect().then((profileBlob) => {
// Add your logic to submit to your backend server here.
// For example, you can use the fetch API to send the profileBlob to your backend server,
// along with any form field values
// Note: use try/catch to ensure fallback submit if profilingInstance not loaded.
});
}d. tryCollect() same as collect() but it will response profiling data straight away
tryCollect() will response whatever collected profiling data and response it immediately, it wouldn’t wait for all profiling finished.
let profilingBlob = profilingInstance.tryCollect()
// Add your logic to submit to your backend server here.
// For example, you can use the fetch API to send the profileBlob to your backend server,
// along with any form field valuese. (Optionally) Stop Profiling
You can collect profiling data from the same instance as many times as needed. If you no-longer wish to use it, you can release the instance using:
profilingInstance.stop();Step 5 - Configure API step in Portal to generate Darwinium Events with Profiling
If using Proxy (CDN) steps for events, the profileBlob will be scraped automatically and event generated.
If using API steps for events, the Darwinium API call should performed from that backend.
For each unique event that you wish to add custom decisioning on, you should create and deploy API steps in your journey. Assign appropriate event types for each of these and whatever rules and additional decisioning logic you see fit.
For example, if you are looking to profile Logins and Payments, add API steps called Login and Payment respectively.
.png?sv=2026-02-06&spr=https&st=2026-08-21T07%3A22%3A00Z&se=2026-08-21T07%3A40%3A00Z&sr=c&sp=r&sig=5gy%2F1rbxcro3Uwwfc29ml3llzXYPne07k0KlcHbpb0o%3D)
See:
On your backend, make a call to your node's Darwinium API endpoint
The profiling blob should be included as a header to that Darwinium API, named dwn-profiling
The details and formatting of API url, headers and body can be obtained using the API helper on your step.
Considerations: Content Security Policy, CORS, Permissions
Although Darwinium serves all Javascript from your domain, it also utilizes calls to other domains in order to maximize device intelligence gathering.
If you are using CORS. script-src, connect-src directives, or policy permissions you may need to update these to facilitate all of the Darwinium profiling. See: Darwinium Profiling for those considerations
Adjust CORS, CSP and policy permissions
Failure to account for those may mean you will be blocking some or all aspects of the Darwinium profiling.
Benefits of Darwinium Tags
1. No missing data: The profiling using JS promises to ensure control and knowledge over when profiling has completed. Means there is no concept of missing or dropped profiling data.
2. First party: Darwinium profiling does not require a fetch or running of third party script. Profiling is done directly from your domain making it more secure.
3. Blocker protection: Tags are run directly rather than from a URL, meaning they are resistant to blockers that block on URL format.
3. Application Performance: There is control over the start and stopping times for profiling, allowing finer grained control over how long, where and when profiling should be performed
4. Simpler Profiling: The profiling is performed without the need for a profiling session identifier.
5. Traceability: Gives visibility and control over the error catching process for logging and traceability.
Comparison to Edge
The Tags approach has the following main differences compared to Edge approach:
In scenarios where the Edge is not viable for deployment (CDN limitations or technical limitiations) Darwinium can still operate through a JS tags approach. Decisions on these events are performed in the same way and the data stored in the same places as an Edge deployment.
Manually implemented profiling tags have tighter control over timing and control. This makes them useful, even in edge-only implementations, for usecases such as single-page applications.
Profiling a new interaction point in journey requires adding the tags and API call to relevant page(s)
Tracking and decisioning on interactions requires an API call rather than operating on existing requests. By extension, Darwinium cannot perform the header enrichment of existing requests
Darwinium cannot perform journey interventions (redirects, session terminates)
Example Project
An example project (implemented in next.js) that demonstrates the use of tags-based profiling end-to-end can be downloaded here (documentation permission required)
Tags Example Project