Fixed rules break down once you need logic. You might need to add a signature header computed from the body, change a field only when another field has a certain value, or count requests across calls. HTTPS Capture runs JavaScript scripts on matching traffic, directly on the iPhone. It is similar to the scripting found in desktop tools like Proxyman or mitmproxy.
Create a script
- On the Capture tab, tap Rules → Scripts.
- Turn on Enable Scripts.
- Tap New Script to start from a template, use Examples to pick one of the built-in samples, or Import Script to load a
.capture.jsfile.
The editor has syntax highlighting, line numbers and bracket completion. When you save, the script is checked for errors, and it applies to new requests right away.
The script format
Every script calls Capture.defineScript once:
Capture.defineScript({
name: "Add debug header",
version: "1.0.0",
match: {
urls: ["https://api.example.com/*"],
methods: ["GET", "POST"]
},
onRequestHeaders(context, request) {
request.headers.set("X-Debug", "1");
request.queries.set("lang", "en");
return request;
}
});
There are five optional hooks:
| Hook | When it runs |
|---|---|
shouldMatch(request) | Extra check; return false to skip this request |
onRequestHeaders(context, request) | Before the request is sent; change URL, method, headers or query |
onRequest(context, request) | After the full request body is available |
onResponseHeaders(context, request, response) | When response headers arrive |
onResponse(context, request, response) | After the full response body is available |
Example: edit a JSON response
Capture.defineScript({
name: "Unlock feature flag",
version: "1.0.0",
match: { urls: ["https://api.example.com/config*"] },
onResponse(context, request, response) {
const body = JSON.parse(response.body || "{}");
body.features = body.features || {};
body.features.newCheckout = true;
response.body = JSON.stringify(body);
return response;
}
});
Useful APIs
request.url,method,host,port,path: read or change the destinationrequest.headersandrequest.queries:get,set,append,delete, or simple property access likerequest.headers["X-Debug"] = "1"request.body/response.bodyas text, orbodyBytesfor binary dataresponse.statusCodecontext.state: share data between the hooks of the same requestcontext.shared: share data across requests while capture is runningenv.get(key)/env.set(key, value): persistent values, such as a token you want to reuseCapture.crypto.md5(),Capture.crypto.sha256(),Capture.base64.encode()/decode()console.log()output appears under Runtime Logs
Return null from a request hook to block that request.
Safe by design
Scripts run in a sandbox. Network APIs (fetch, XMLHttpRequest, WebSocket) are disabled, and each hook has a strict time limit. If a script throws an error or runs too long, the traffic passes through unchanged and the error is logged. A bug in your script won’t take the network down. Only the first enabled script that matches handles a given request, and you can drag scripts to set their priority.
Let AI write the script
Tap AI Prompt to copy the complete scripting reference. Paste it into ChatGPT, Claude or another assistant together with what you want, and you will get a script that follows the API exactly.
For simple fixed changes, a rewrite rule is quicker. For one-off manual edits, use a breakpoint.
Ready to try it?
HTTPS Capture · Capture and decrypt HTTPS traffic on iPhone
Free on the App Store