Exports
Export requests as curl, Python, Postman, OpenAPI, and TypeScript.
Traffic Jam turns captured requests into runnable artifacts: a curl command or Python requests script for a single call, a Postman collection or OpenAPI 3.1 spec for a route catalog, and TypeScript/JavaScript/Go types for observed JSON bodies. Every format runs through the same safe-export pipeline, which redacts credentials by default.
Where exports live
| Entry point | What it produces |
|---|---|
| API lab → catalog row → Copy curl icon | Redacted curl for one captured request |
| API lab → catalog toolbar → OpenAPI / Postman | Catalog-wide spec or collection download |
| Route details → Inferred schema → TypeScript tab | Request/Response type definitions |
| Compare view → body Copy menu | TypeScript interface / JavaScript typedef / Go struct for one JSON body |
| Replay dialog → Copy curl | curl honoring the dialog’s sensitive-values checkbox |
| Request minimizer → Copy minimized curl | curl rebuilt from the minimized effective request |
The catalog and route model are part of the API lab — see /docs/en/api-re/.
Copy a single request as curl or Python
The catalog’s per-request copy button always produces a redacted command (includeSensitiveValues: false). The generated curl keeps the method (adversarial method strings are shell-quoted), adds --compressed, and preserves even GET request bodies via --data-raw:
curl 'https://example.test/users?page=2' -X 'POST' \
-H 'Content-Type: application/json' \
-H 'X-Request-ID: request-123' \
--data-raw '{"username":"alice"}' --compressed
The same pipeline generates a Python requests script (requests.request(METHOD, url, headers=headers, data=payload), printing status and body). The Postman exporter points to the cURL or Python export when a binary body cannot be represented in Postman.
Hop-by-hop and managed headers are dropped from all command exports: accept-encoding, connection, keep-alive, proxy-authenticate, proxy-authorization, te, trailer, transfer-encoding, upgrade, content-length, host, HTTP/2 pseudo-headers (:method, :authority, …), credential-named headers such as Authorization and Cookie, and Content-Encoding when the captured body was already decoded.
Export the whole catalog: Postman and OpenAPI
In the API lab catalog toolbar, pick a scope — Current view · N routes (the filtered catalog, the default) or All captured · N routes — then click OpenAPI or Postman. A confirmation dialog shows route and call counts; for Postman it also offers an Include captured credentials checkbox (off by default, reset after each export). Confirming downloads:
traffic-jam-postman-current-view.json/traffic-jam-postman-all-captured.jsontraffic-jam-openapi-current-view.json/traffic-jam-openapi-all-captured.json
Postman output is a collection v2.1.0 document with one folder per host. Modeled path templates become Postman path variables (/users/{id} → /users/:id) pre-filled with replace-me so you must supply a safe value before sending. Each request carries up to three captured example responses, a raw body with language detection (json, xml, graphql, or text), and a description noting capture counts and the route-model rules that produced it.
OpenAPI output is an OpenAPI 3.1.0 spec. Routes are grouped by method and path shape; path parameters get inferred schemas (integer for all-numeric values, string with format: uuid for UUIDs); query and header parameters are listed by name with captured values omitted. Observed authentication becomes components.securitySchemes: http schemes for Bearer/Basic/Digest (with bearerFormat: JWT for three-segment tokens), and apiKey definitions for sensitive headers, cookies (session, token, jwt-style names), and query parameters; routes seen both with and without credentials get an empty alternative requirement. Bodies are schema-inferred per media type with up to three redacted examples, each recording its decode provenance in x-traffic-jam-decode. Methods outside the OpenAPI verb set are listed under x-traffic-jam-unsupported-operations instead of being dropped.
[!NOTE] The OpenAPI export is always fully redacted — it has no sensitive-values opt-in. Captured response reason phrases are never exported, and credential-shaped strings in hosts, header names, media types, and path parameter names are neutralized (a credential-shaped host becomes
redacted.invalid).
TypeScript and other type codegen
The route details panel’s Inferred schema section has Request, Response, and TypeScript tabs. The TypeScript tab emits type aliases named after the route, e.g. export type PostExampleTestUsersRequest = { … } and the matching …Response, built from the inferred JSON schemas; Copy puts them on the clipboard, and the schema tabs offer a JSON Schema download (<route-id>-<request|response>-schema.json).
In the Compare view, the body Copy menu generates types from a single JSON body: a TypeScript export interface, a JSDoc @typedef, or a Go struct with json:"…,omitempty" tags on optional fields.
The export safety model
Captures from authorized testing contain live credentials, so artifacts are shareable by default and exact values require an explicit opt-in (the Include captured credentials checkbox, or the replay dialog’s sensitive-values toggle covered in /docs/en/replay/). Masking in analysis views is described in /docs/en/security/.
| Captured data | Default export | With explicit opt-in |
|---|---|---|
Credential headers (Authorization, Cookie, …) | Dropped entirely | Included verbatim |
| Other sensitive header values | Value replaced with a redaction marker | Included verbatim |
| Sensitive query/fragment values | Replaced with <redacted> | Included verbatim |
Path segments under auth/tokens/oauth/passwords/sessions/… parents, or shaped like known tokens (AKIA…, eyJ… JWTs, gh[pous]_…, github_pat_…, sk/pk-live/test, xox[baprs]-…, 32+ mixed alphanumerics) | Redaction marker (UUIDs and numeric IDs are kept) | Included verbatim |
| Secret-looking JSON/form fields, even under neutral keys or as property names | Redacted | Included verbatim |
| Opaque (binary or lossy) bodies | Replaced with a placeholder / omitted | Exact hex bytes |
Body export options
prepareExportBody classifies every captured body as text, hex, or opaque:
| Classification | Condition | curl | Python | Postman |
|---|---|---|---|---|
text | Hex decodes as UTF-8 to exactly the stored preview | --data-raw (redacted) | data=payload string | Raw body |
hex | Binary body, opt-in enabled | printf %s '<hex>' | xxd -r -p | curl … --data-binary @- | bytes.fromhex("<hex>") | Still flagged not runnable; exact bytes kept in x-traffic-jam-exact-body-hex |
opaque | Binary body without opt-in, or a truncated capture | # NOT RUNNABLE: … comment | raise RuntimeError("NOT RUNNABLE: …") | ⚠ name prefix, body omitted, warning in description |
The safety manifest
Postman and OpenAPI exports embed an x-traffic-jam-export manifest (version 2) so downstream reviewers can see what happened:
{
"version": 2,
"policy": {
"capturedSensitiveValues": "redacted",
"opaqueBodies": "omitted",
"pathCredentials": "redacted"
},
"report": {
"routes": 42, "calls": 318,
"urlRedactions": 7, "headerRedactions": 84,
"bodyRedactions": 12, "opaqueBodies": 3, "truncatedBodies": 1,
"warnings": ["3 opaque bodies are omitted from examples because it cannot be inspected safely."]
}
}
With the opt-in enabled, policy fields read included-by-explicit-opt-in. Keep the opt-in off for anything that leaves your machine; a standalone Go collector is a separate workflow — see /docs/en/collector/.