run
Replayable flows
Since 0.2.1 Requires Cloak Proxy 0.2.1 or later.
Turn captured requests, such as log in, create an order and pay, into an API client flow that reads fresh IDs, tokens and cookies from each response.
Make Replayable Flow turns a sequence of captured requests into a flow in the API client that sends them again in order. Replaying captured requests as they are usually fails: the order ID in step 3 belongs to an order the server created during the capture, and the access token from the login has expired. A replayable flow fixes that by reading every value a later request reuses from the fresh response of an earlier one, so each run works with new IDs and tokens. Load-testing tools call this correlation.
Use it to reproduce a bug that needs several calls, to keep a smoke test of a real user journey, or to start a test from what your app actually does.
Make a flow from captured requests
Section titled “Make a flow from captured requests”-
In the traffic list, select the requests of the journey, for example the login, the order and the payment. Order doesn’t matter: Cloak Proxy sorts them by when they started.
To pick every request that carried one value, trace it and click Make Replayable Flow in the Trace Value window instead.
-
Right-click one of the selected requests and choose Make Replayable Flow from N Requests… (or Make Replayable Flow… for one request).
The sheet lists the steps and the values it will chain between them.
-
Check Values chained. Each entry says which response provides the value and which later requests use it.
-
Change the Flow name if you like, and choose whether to check each step’s status.
-
Click Create Flow (or press Return).
The API client opens on Flows with the new flow selected.
-
Click Run (⌘ ↩) to replay it.
Make Replayable Flow… is unavailable when you right-click an encrypted tunnel, and tunnels in a selection are left out.
Three values chained across four steps: a token, a user ID and an order ID.
- Flow name. Also the name of the new collection.
- The steps, in the order they were captured.
- The variable the flow uses, and the captured value.
- Which response provides it, and which requests use it and where.
- Add a Check after each step that succeeded when captured.
- Create the collection and the flow, and open it.
The Make Replayable Flow sheet
Section titled “The Make Replayable Flow sheet”| Part | What it shows or does |
|---|---|
| Flow name | The name of the flow and of its collection. It starts as Replay: followed by the first request’s method and path and how many more there are, such as Replay: POST /v1/login and 3 more. |
| Steps (N) | One line per request: method, host and path, in time order. |
| Values chained (N) | Every value carried from a response to later requests: the variable, such as {{orderId}}, the captured value (long ones are shortened, such as eyJhbGciOiJI…iJ9.c2ln), From step N’s response, and where in it, and Used in with each step and where. When there are none, it says No later request reuses a value from an earlier response, so the steps replay as captured. |
| Check that each step succeeds, like it did when captured | On by default. Adds a Check block after each step whose captured status was below 400. |
| Cancel | Closes the sheet (Esc). |
| Create Flow | Creates the collection and the flow, and opens the flow in the API client. |
On Linux, Make Replayable Flow… opens in a small window of its own rather than a sheet, with the same parts.
What Create Flow makes
Section titled “What Create Flow makes”Two things go into your workspace:
- A collection named like the flow, with one request per step, named by number and request, such as
1. POST /v1/loginand2. POST /v1/orders. Each one is a copy of the captured request, made the same way as Save to API Client: the method, URL, headers and decompressed body, with the captured response saved as an example. Chained values are replaced with{{variables}}. - A flow in Flows with the same name. It runs the steps in order.
For each step, the flow has these blocks:
| Block | Example | What it does |
|---|---|---|
| Send Request | step2 |
Sends the step’s request and saves the result as step1, step2 and so on. |
| Check | step2.status < 400, message Step 2 (POST api.shopapp.example/v1/orders) should succeed, like it did when captured (201) |
Fails the run if the step didn’t succeed. Only when the status check is on and the step succeeded when captured. |
| Set Variable | orderId = step2.body.data.order.id |
Reads a value from this step’s fresh response for later steps. One per value the step provides. |
For the screenshot above, the flow looks like this:
Send Request 1. POST /v1/login → step1Check step1.status < 400Set Variable accessToken = step1.body.access_tokenSet Variable userId = step1.body.user.idSend Request 2. POST /v1/orders → step2 (Authorization: Bearer {{accessToken}})Check step2.status < 400Set Variable orderId = step2.body.data.order.idSend Request 3. GET /v1/orders/{{orderId}} → step3 (Authorization: Bearer {{accessToken}})Check step3.status < 400Send Request 4. POST /v1/payments?order_id={{orderId}} → step4 (X-User-Id: {{userId}})Check step4.status < 400It’s an ordinary flow: you can edit, reorder or delete blocks, add Output blocks, set inputs, or automate it. See Flows for every block.
How values are chained
Section titled “How values are chained”Cloak Proxy goes through the steps in order. For each response, it collects the values that look like identifiers, then checks whether a later request uses them.
-
Find candidate values in a response. It looks at every string and number in a JSON response body (up to the first 200 items of each array) and at the response headers, except standard ones such as
Date,Content-Type,Set-Cookie,ETag,Cache-Control,Serverand the security headers. -
Keep only values that look like IDs or tokens. A value qualifies when it:
- is at least 4 characters long, with no spaces, and
- contains a digit, or is at least 20 characters long, and
- isn’t a Unix timestamp in seconds or milliseconds, a date such as
2026-10-14, a version number such as1.2.3, or a number with fewer than 5 digits.
So
fc68188e,usr_42aband a JWT qualify;true,admin,2026-10-14T10:00:00Zand1760436000don’t. -
Skip values the app made itself. If an earlier request (or the same one) already sent the value, the server didn’t create it, so it isn’t chained.
-
Find where later requests use it. It searches each later request’s path, query parameters, headers and body (form fields or raw text). A value must match as a whole token:
48213isn’t replaced inside948213, but is in/orders/48213or"id": "48213". -
Replace it with a variable. Every use in a later request becomes
{{variable}}, and a Set Variable block after the providing step reads the fresh value. A value is chained from the first response that has it, once.
Values that no later request uses aren’t chained. Values the app got before the first selected request, such as a token from a login you didn’t select, stay exactly as captured.
Variable names
Section titled “Variable names”The variable is named after where the value was in the response:
| Found at | Variable | Read with |
|---|---|---|
body $.access_token |
accessToken |
step1.body.access_token |
body $.user.id |
userId |
step1.body.user.id |
body $.data.order.id |
orderId |
step2.body.data.order.id |
body $.items[0].sku_code |
skuCode |
step3.body.items[0].sku_code |
header X-Request-Id |
requestId |
step1.headers["x-request-id"] |
The name comes from the last key, in camelCase. When that key is a generic word such as id, uuid, token, key, code, value or number, the key before it is added in the singular: orders.id gives orderId. Header names lose an X- prefix. If two values would get the same name, the second gets a number, such as orderId2. Names that clash with flow variables, such as response, item, index, trigger, vars and step1, are avoided the same way.
Cookies
Section titled “Cookies”Cookies come from the run, not the capture. When an earlier step’s response set a cookie with Set-Cookie, that cookie is removed from the captured Cookie header of later requests. When the flow runs, the API client’s cookie jar sends the fresh cookie the server set during the run.
A request’s own Cookie header and the cookie jar are merged: the request sends its own cookies plus every cookie from the jar it doesn’t already have. When both have a cookie with the same name, the request’s own value wins.
Run the flow
Section titled “Run the flow”In the API client, open the flow under Flows and click Run (⌘ ↩). The Run pane shows each step with its status and time, the chained values being set, and whether each check passed. See Read the run results.
From the command line, run it with cloakctl flow run, for example from CI or cron. The command exits with 1 when a check fails:
cloakctl flow run "Replay: POST /v1/login and 3 more"The requests use the API client’s settings, the active environment and your variables. To run the same flow against staging, replace the host in each request with a variable such as {{baseUrl}} and set it per environment.
When a replay fails
Section titled “When a replay fails”| Problem | What to do |
|---|---|
The first request fails with 401 |
Its credentials or token came from before the capture and have expired. Select the login request too, or update the token in the first request. |
A later step fails with 404 or 400 |
A value wasn’t chained: it may be computed by the app, sent in a shape Cloak Proxy doesn’t recognize, or too short to qualify. Find it with Trace Value, then add a Set Variable block and put {{name}} in the request yourself. |
| A step fails because a value is a one-time code | Codes sent by email or SMS, CAPTCHA answers and signed nonces can’t be replayed. Replace that step, or start the flow after it. |
| A Check fails | The step returned a status of 400 or higher. Read the step’s response in the Run pane. A status that differs from the capture but is below 400, such as 200 instead of 201, passes. |
Make a flow from an AI assistant
Section titled “Make a flow from an AI assistant”The MCP server has a build_replay_flow tool. It takes ids (the request numbers, in any order), and optionally name (default Replay of N requests) and check_status (default true). It creates the collection and the flow, opens them in the API client, and returns the steps and every chained value with where it comes from and where it’s used. Run the flow with run_flow. See the MCP tools reference.