Pre-Request Scripts
A pre-request script is JavaScript that runs immediately before a request is sent. By the time Curlex fires the HTTP request, the script has already finished — any variables it set are available for substitution in the URL, headers, body, and auth fields.
Use pre-request scripts when the request itself needs to be built dynamically at the moment it is sent, rather than being fully static.
Where to Write Them
Open any request and click the Scripts tab (fifth tab in the request panel). The Pre-Request Script editor is the top half; the Test Script editor is the bottom half.
Both editors support full JavaScript with a fc object (also available as pm for Postman compatibility) that gives you access to variables, iteration data, and flow control.
What Pre-Request Scripts Can Do
| Capability | How |
|---|---|
| Read any variable | fc.environment.get("key") |
| Set or update any variable | fc.environment.set("key", "value") |
| Read collection variables | fc.collectionVariables.get("key") |
| Set collection variables | fc.collectionVariables.set("key", "value") |
| Read the current iteration's data (Collection Runner) | fc.iterationData.get("column") |
Resolve {{variable}} placeholders in a string | fc.variables.replaceIn("https://{{host}}/path") |
| Skip the next request | fc.execution.skipRequest() |
| Jump to a named request | fc.execution.setNextRequest("Request Name") |
| Stop the entire run | fc.execution.abort() |
| Log to the Console | console.log("message") |
Pre-request scripts cannot access fc.response — the response has not been received yet.
Common Patterns
Generate a Unique Request ID
Many APIs require a unique identifier per request for idempotency or tracing. Generate it fresh every time:
fc.environment.set("requestId", crypto.randomUUID());
Then use {{requestId}} in a header:
X-Request-ID: {{requestId}}
Set a Current Timestamp
Some APIs require a timestamp in the request for signature verification or audit purposes:
// Unix seconds
fc.environment.set("timestamp", Math.floor(Date.now() / 1000).toString());
// ISO 8601
fc.environment.set("isoTimestamp", new Date().toISOString());
Build a HMAC Signature
If an API requires you to sign the request body before sending:
var body = '{"action":"charge","amount":100}';
var secret = fc.environment.get("apiSecret");
// Compute HMAC-SHA256 using the Web Crypto API
var encoder = new TextEncoder();
var keyData = encoder.encode(secret);
var msgData = encoder.encode(body);
crypto.subtle.importKey("raw", keyData, { name: "HMAC", hash: "SHA-256" }, false, ["sign"])
.then(function(key) {
return crypto.subtle.sign("HMAC", key, msgData);
})
.then(function(signature) {
var hex = Array.from(new Uint8Array(signature))
.map(function(b) { return b.toString(16).padStart(2, "0"); })
.join("");
fc.environment.set("signature", hex);
});
Then use {{signature}} in the X-Signature header.
Note: The script executes before the request is sent and Curlex waits for any Promises to resolve, so async operations like
crypto.subtlework correctly.
Point to the Right Server Based on an Environment Variable
var target = fc.environment.get("target");
if (target === "prod") {
fc.environment.set("baseUrl", "https://api.example.com");
} else if (target === "staging") {
fc.environment.set("baseUrl", "https://staging.api.example.com");
} else {
fc.environment.set("baseUrl", "https://dev.api.example.com");
}
Set target in your environment and every request that uses {{baseUrl}} will automatically go to the right server.
Derive a Value from Existing Variables
fc.variables.replaceIn() resolves {{variable}} placeholders in any string, letting you compose values from existing variables:
var userId = fc.environment.get("userId");
var version = fc.environment.get("apiVersion");
// Compose a path from variables
var fullPath = fc.variables.replaceIn("/api/{{apiVersion}}/users/{{userId}}/profile");
fc.environment.set("profilePath", fullPath);
Conditionally Skip a Request
In a Collection Runner sequence, you can skip the next request based on a condition:
var featureEnabled = fc.environment.get("featureEnabled");
if (featureEnabled !== "true") {
fc.execution.skipRequest();
}
Read a Data File Value and Use It to Set Variables
When running with a data file in the Collection Runner, each iteration has a row of data:
var environment = fc.iterationData.get("environment");
var userId = fc.iterationData.get("userId");
fc.environment.set("baseUrl",
environment === "prod" ? "https://api.example.com" : "https://staging.api.example.com"
);
fc.environment.set("userId", userId);
Logging and Debugging
Use console.log() to print values to the Console panel while a script runs:
var token = fc.environment.get("authToken");
console.log("Token is:", token);
console.log("Timestamp:", Date.now());
Open the Console (`Cmd/Ctrl + ``) to see the output. When running in the Collection Runner, pre-request script logs appear in the Pre-request Logs tab of each result's detail panel.
All five console methods work and produce output at the corresponding log level: console.log, console.info, console.warn, console.error, console.debug.
Variable Scope and Persistence
Variables set in a pre-request script are available immediately to the current request — they are substituted into the URL, headers, body, and auth before the request is sent.
In the Collection Runner, variables set in a pre-request script persist for all subsequent requests in the same run. This means you can use a pre-request script on the first request (login) to set an auth token, and every later request in the run will have it available via {{authToken}}.
Variable changes do not persist after the app is closed or after you switch to a different environment — they live in memory for the duration of the session or run.
Postman Compatibility
If you are migrating from Postman, pre-request scripts written using the pm object work without modification:
// These are identical — pm is a full alias for fc
pm.environment.set("key", "value");
fc.environment.set("key", "value");
All pm.environment.*, pm.collectionVariables.*, pm.iterationData.*, pm.variables.replaceIn(), and pm.execution.* methods work the same way.