Scripting Recipes
Small, real scripts you can drop in and tweak. The first set are script rules: they rewrite live traffic with handleRequest / handleResponse (see the Scripting Overview). The second set use the pro API, which runs in Composer pre-request and test scripts and in Flow script nodes (see the Scripting API Reference).
Script rules
Section titled “Script rules”Stamp every request with a trace ID
Section titled “Stamp every request with a trace ID”Phase: request. Match: api.example.com/*.
function handleRequest(request) { request.headers['X-Request-Id'] = Math.random().toString(16).slice(2, 18); return request;}Adds a short hex trace ID to every outgoing request so server logs can be cross-referenced with what Probe captured.
Strip cookies for matching requests
Section titled “Strip cookies for matching requests”Phase: request. Useful when you want to test an unauthenticated path without logging out of the browser.
function handleRequest(request) { for (const name of Object.keys(request.headers)) { const lower = name.toLowerCase(); if (lower === 'cookie' || lower === 'authorization') delete request.headers[name]; } return request;}Removes the auth headers from this rule's matched requests only.
Send a share of requests to an error endpoint
Section titled “Send a share of requests to an error endpoint”Phase: request. Forces a percentage of calls to fail so you can exercise the client's error path.
function handleRequest(request) { if (Math.random() < 0.2) { // Reroute the upstream to an endpoint we know returns 500. request.url = 'https://httpstat.us/500'; } return request;}20% of matching requests get rewritten to an upstream that always returns 500. To serve a canned response without going to a real origin, use Map Local instead.
Flip a JSON field in the response
Section titled “Flip a JSON field in the response”Phase: response. Match: api.example.com/v1/me.
function handleResponse(request, response) { const data = JSON.parse(response.body || '{}'); data.user.role = 'admin'; response.body = JSON.stringify(data); return response;}Your client sees role: "admin" while the server still answered with the real value. For a fully canned body, Map Local doesn't even hit the network.
Composer and Flow scripts (pro)
Section titled “Composer and Flow scripts (pro)”Sign a request with HMAC-SHA256
Section titled “Sign a request with HMAC-SHA256”Where: a Composer pre-request script.
const ts = Math.floor(Date.now() / 1000).toString();// The script sees the body before {{variables}} are resolved: sign what is sent.const body = pro.variables.replaceIn(pro.request.body.raw || '');const secret = pro.environment.get('apiSecret');
const sig = pro.crypto.hmacSha256(ts + body, secret);
pro.request.headers.upsert({ key: 'X-Timestamp', value: ts });pro.request.headers.upsert({ key: 'X-Signature', value: sig });Signs the timestamp + body with a secret pulled from the environment, attaching both as headers to the request that goes out.
Decode a JWT and log the payload
Section titled “Decode a JWT and log the payload”Where: a Composer pre-request script. Useful when you want to see who a call is authenticating as.
const auth = pro.request.headers.get('Authorization') || '';const token = auth.replace(/^Bearer\s+/i, '');if (token) { const decoded = pro.crypto.jwtDecode(token); console.log('sub:', decoded.payload.sub, 'exp:', decoded.payload.exp);}Logs the sub and exp claims of the bearer token to the Composer script console.
Capture a token from the login response
Section titled “Capture a token from the login response”Where: the test script of your login request in Composer.
if (pro.response.code === 200) { const token = pro.response.json().accessToken; pro.environment.set('authToken', token); console.log('captured authToken (' + token.length + ' chars)');}Pulls the accessToken out of the login response and saves it as the current value of authToken in the active environment, so later requests can reference it as {{authToken}}.
Assert response shape
Section titled “Assert response shape”Where: a Composer test script, or a Flow script assertion.
pro.test('status is 200', function () { pro.expect(pro.response.code).to.equal(200);});
pro.test('content type is JSON', function () { pro.expect(pro.response.headers.get('Content-Type')).to.contain('application/json');});
pro.test('body has the right shape', function () { pro.expect(pro.response.json()).to.have.jsonSchema({ type: 'object', required: ['userId', 'email'], properties: { userId: { type: 'integer' }, email: { type: 'string' }, }, });});Three independent test blocks — failures in one don't hide the others. Results show up in the Composer test results with pass/fail badges.
Refresh an expired token mid-flight
Section titled “Refresh an expired token mid-flight”Where: a Composer pre-request script (or the collection's).
const token = pro.environment.get('authToken');const exp = parseInt(pro.environment.get('authExp') || '0', 10);const nowSec = Math.floor(Date.now() / 1000);
if (!token || nowSec >= exp) { const res = pro.sendRequest({ url: 'https://api.example.com/auth/refresh', method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ refreshToken: pro.environment.get('refreshToken') }), }); if (res.code === 200) { const body = res.json(); pro.environment.set('authToken', body.accessToken); pro.environment.set('authExp', String(nowSec + body.expiresIn)); pro.request.headers.upsert({ key: 'Authorization', value: 'Bearer ' + body.accessToken }); } else { console.error('refresh failed:', res.code, res.status); }}Checks an expiry stored in the environment, calls the refresh endpoint synchronously via pro.sendRequest, then attaches the fresh token to the original request before it goes out. Up to 5 sub-requests per execution are allowed.
Time a single endpoint
Section titled “Time a single endpoint”Where: a Composer test script. Logs the response time only when it crosses a threshold.
if (pro.response.responseTime > 500) { console.warn( pro.info.requestName, 'took', pro.response.responseTime + 'ms', '(>' + 500 + 'ms threshold)', );}Quiet most of the time, noisy when the endpoint is slow.
Related
Section titled “Related”- Scripting Overview
- Scripting API Reference
- Map Remote — for upstream rewrites you'd otherwise script.
- Breakpoints — for one-off manual edits instead of a scripted rule.