Replay Workbench
Re-send single requests, edit them, and measure captured-vs-live drift.
The replay workbench re-sends one captured request against the live target, lets you edit every part of it, and then lines the live response up against the captured one. It is built for authorized testing of systems you have permission to test: every guardrail below exists so a replay stays a deliberate, bounded act.
Open the workbench
In the API lab, open the Catalog tab (see /docs/en/api-re/catalog/), expand a route, and click the play icon (Replay request) on any captured request row. The dialog opens pre-filled with a safe copy of the request: credential headers, sensitive query values, secret-looking path segments, and body secrets are redacted until you explicitly opt in.
Edit the request
- Method — free text, uppercased on send; must be 1–32 valid HTTP token characters.
- URL — must be an absolute
httporhttpsURL. Reset restores the captured URL. - Headers — an editable name/value table. Transport-managed headers (
Host,Content-Length,Connection,Transfer-Encoding,TE,Trailer,Upgrade,Keep-Alive,Accept-Encoding,Proxy-Authenticate,Proxy-Authorization) and HTTP/2 pseudo-headers are excluded and cannot be edited. Names must be valid HTTP tokens, unique per header, and values may not contain control characters. - Body — a text editor. Structured bodies (JSON, forms) open with secrets redacted; an opaque (binary or unstructured) body shows a placeholder and blocks sending until you either edit in a deliberate body or opt in to the captured bytes.
- Timeout — 1–120 seconds, default 30.
Safety model
| Guardrail | Behavior |
|---|---|
| No redirect following | 3xx responses are returned as-is (rejection class redirect) so you see the endpoint’s real answer. |
| Timeout and preview caps | Per-request timeout is capped at 120 s; response bodies are previewed up to 4 MiB. |
| Credentials excluded by default | Captured authorization/cookie headers, sensitive query values, path secrets, and body secrets are stripped unless you tick Include captured credentials in this replay. |
| Mutation confirmation | Any method other than GET, HEAD, or OPTIONS requires the Confirm potentially state-changing request checkbox before Send enables. |
| Destination confirmation | Editing the URL to a different scheme, host, or port requires Confirm destination change. |
| Typed replacements | Header or credential values you type are treated as deliberate and sent exactly as entered. |
The backend enforces request limits regardless of the UI: request body ≤ 16 MiB, URL ≤ 16 KiB, ≤ 256 header edits per replay, header value ≤ 64 KiB.
[!WARNING] Replays hit real endpoints. Confirm you are authorized to send the edited request — especially for state-changing methods or credential A/B probes — before clicking Replay.
Send and read the response
Click Replay <METHOD>. The result bar shows the status, duration, transport and ClientHello profile, the replay-history ID, gRPC trailers (grpc-status/grpc-message) when present, and a rejection class badge when the response is not 2xx:
| Class | Meaning |
|---|---|
client-certificate-required | 400 with an nginx-style “No required SSL certificate” body |
unauthorized / forbidden / not-found | 401 / 403 / 404 |
rate-limited | 429 |
antifraud-reject | 451 |
redirect | any other 3xx |
client-error / server-error | remaining 4xx / 5xx |
transport-error | the request failed before a response arrived |
Captured-vs-live drift
Below the result, the Original ↔ replay diff compares the captured exchange with the live one using the shared semantic comparison (/docs/en/analysis/comparing/) and produces a verdict: match, drift, or transport-error. Drift signals:
- Status drift — captured vs replayed status code.
- Header changes — added/removed/changed response headers, ignoring volatile ones (
Date,ETag,Set-Cookie,X-Request-Id,CF-Ray, trace IDs, and friends). - Semantic body diff — field-level JSON, Form, XML, HTML, or CSV comparison with a changed-field count; unparseable bodies fall back to a byte-differs note.
- Duration delta — replayed minus captured milliseconds.
Chain variables and computed fields
Use {{name}} in the URL, header values, or body. After a replay, Extract response into chain saves a JSON path ($.access_token), response header, or regex match as a variable persisted locally for subsequent requests. Computed fields are recomputed per send:
{{ cookie:gssca-goldapple }} {{ header:x-ts }} {{ query:item }}
{{ p = randomHex:4; p + sha1(fgsscSecret + cookie:gssca-goldapple + p) | skip:4 }}
{{ hmac-sha256(secret, "msg") }} {{ nowMs() }} {{ uuid4() }} {{ crc32(body) }}
Named nonces (p = randomHex:4) stay stable across all fields of one replay; pipes include skip, take, upper, lower, urlencode, base64, base64url. The Fingerprint & egress panel in the same dialog selects the transport (native Go or fingerprint-faithful uTLS), the ClientHello profile, HTTP/1.1 forcing, an egress proxy (http, https, socks5, socks5h), and an mTLS client certificate (auto uses the host-pinned cert).
Bulk replay
On a route in the Catalog, click Replay all & diff. The dialog replays up to 200 observed calls for that route sequentially, grouped by capture, showing per-row captured → replayed status and a match/drift/skipped verdict plus running matched/drifted counts.
- The backend accepts at most 50 requests per batch; the dialog chunks larger sets automatically.
- If the route’s method may change state, the run is blocked until you tick I confirm this may change server state.
- Include captured credentials applies to the whole batch; the per-request timeout is 30 s and an overall deadline (requests × timeout + 30 s) bounds the run.
Replay history
Every completed replay is persisted to the local database (when storage is available); a failed persistence surfaces a “history not retained” warning rather than losing the response. Open the API lab’s Replays tab to browse the last 100 entries: each row shows method, URL, status, duration, and timestamp. Expand a row for the full original ↔ replay comparison, delete entries you no longer need, or click Derive capture to turn a replay into a standalone capture session.
Stored history is sanitized: unless the replay included captured credentials, URLs, headers, and bodies are redacted before storage (body previews capped at 32 KiB), and egress proxy configuration is never recorded.