Scripting and Testing

Pre-Request Scripts

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

CapabilityHow
Read any variablefc.environment.get("key")
Set or update any variablefc.environment.set("key", "value")
Read collection variablesfc.collectionVariables.get("key")
Set collection variablesfc.collectionVariables.set("key", "value")
Read the current iteration's data (Collection Runner)fc.iterationData.get("column")
Resolve {{variable}} placeholders in a stringfc.variables.replaceIn("https://{{host}}/path")
Skip the next requestfc.execution.skipRequest()
Jump to a named requestfc.execution.setNextRequest("Request Name")
Stop the entire runfc.execution.abort()
Log to the Consoleconsole.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.subtle work 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.