Running wiretap against multiple OpenAPI specs
Validate traffic against many OpenAPI contracts at once.One proxy, many contracts
wiretap can load many OpenAPI specifications at the same time and route each incoming request to the contract
that owns it. We call this multi-spec mode.
Real systems are rarely described by a single OpenAPI contract. Services each ship their own spec, API gateways stitch together specs from multiple backends/polyrepos, and monorepos collect dozens of contracts in one tree.
multi-spec mode lets wiretap validate traffic across all of them, without having to merge or pre-process the contracts first.
This is much more typical of real-world, multi-service application deployment.
To enable it, point wiretap at more than one spec using --specs, or hand it a directory to scan with --spec-dir.
Let wiretap discover all the service OpenAPI contracts automatically, just point it at a directory.
How it works
When wiretap boots in multi-spec mode, it does three things:
- Discovers every spec from the supplied flags, directories, and globs.
- Analyzes the loaded contracts for conflicts and prints a report.
- Routes each live request through the ordered spec resolver.
Discovery
wiretap accepts explicit paths, globs, directories, and remote URLs.
Directory and glob discovery picks up files if they have a .yaml, .yml, or .json extension and contain an
OpenAPI marker (openapi:, "openapi", swagger:, or "swagger"). Explicit paths and remote URLs are loaded as
provided, and any invalid contract is reported as a load error.
Anything else in the directory is ignored, so you can drop wiretap on top of an existing repo without curating the layout.
Discovery preserves order: specs supplied through --spec and --specs come first, including globs and remote URLs.
Directory matches follow. Directory and glob matches are walked in lexical path order. The first discovered spec becomes
the primary contract unless you set --spec or contract in wiretap.yaml. CLI values take priority when both are
supplied. The primary contract is the one returned to the monitor UI for schema previews and references.
To skip files or folders, use --ignore with one or more glob patterns:
Routing
For every inbound request, wiretap walks the loaded contracts in discovery order.
Inside a single spec, matching is specificity-first: literal segments (/users/me) score higher than templated
segments (/users/{id}). Across specs, discovery order is the tiebreak. The first spec with a matching path and
method wins. If earlier specs only match the path, wiretap keeps walking so a later path-and-method match can still win.
If no spec matches both path and method, wiretap falls back to the first spec that matched the path. If no spec covers
the path, it falls back to the first spec so you still get a clean path not found validation error instead of a silent
passthrough. Resolved routes are cached so repeat traffic skips the walk.
Operation-level and path-level servers: blocks are honored. If a spec defines /v2 as a server base path, requests to
/v2/users are routed to that spec and the base path is stripped before validation.
Conflict analysis
Loading multiple specs at once means routes might overlap. wiretap detects multiple kinds of conflict at startup and prints
a report:
| Conflict | Meaning |
|---|---|
| cross-spec-duplicate | Two specs define the exact same route on the same method |
| cross-spec-ambiguous | Two specs define routes on the same method that could match the same request |
| within-spec-duplicate | A single spec defines the same route twice (after server base paths are applied) |
| within-spec-ambiguous | A single spec defines two routes that could match the same request |
| duplicate-operation-id | Two operations share the same operationId |
Ambiguity is detected with type awareness. /users/{id} typed as integer does not collide with /users/me,
because me cannot satisfy integer. string parameters overlap anything, and integer overlaps number.
When a request hits a conflicting route at runtime, the matched transaction is tagged with a spec conflict marker and surfaced in the monitor UI with a warning banner showing which specs cover the same route.
This makes ambiguous traffic visible during interactive debugging, not just at startup.
Ignoring operationId conflicts
Duplicate operationId values across specs are flagged by default. If your contracts intentionally re-use ids (common
when versioning specs side-by-side), suppress them with --ignore-clashing-operationid:
Dry run
The --dry-run flag tells wiretap to discover, analyze, and report — then exit. No HTTP server is started, no
traffic is proxied. It’s the fastest way to check that a set of contracts is loadable and conflict-free.
A dry run exits with status code 0 when all specs load and no conflicts are found, and non-zero when conflicts or load errors are detected.
The same report you see in multi-spec mode at startup is produced by --dry-run, including load errors with the
file and reason.
Dry run is also useful locally when adding a new spec to an existing tree. Run it once, see the diff in the report, decide whether the new conflicts are intentional.
Combine
--dry-runwith--ignore-clashing-operationidif your CI gate cares about routes but not ids.
Configuration file
Every flag has a wiretap.yaml equivalent.
contracts:
- ./users.yaml
- ./orders.yaml
contractDirs:
- ./contracts
contractIgnore:
- "**/legacy/**"
- "**/*-draft.yaml"
contract: ./users.yaml # primary spec (optional)
ignoreClashingOperationId: true
dryRun: false
| Property | Type | Description |
|---|---|---|
| contracts | []string |
Explicit list of OpenAPI specs to load |
| contractDirs | []string |
Directories to recursively scan for specs |
| contractIgnore | []string |
Glob patterns to exclude during discovery |
| contract | string |
Path to the primary spec (used by the monitor UI) |
| ignoreClashingOperationId | boolean |
Suppress duplicate-operation-id conflicts |
| dryRun | boolean |
Run discovery and analysis, then exit |
In single-spec setups, --spec works exactly as it always has — multi-spec mode activates automatically when more
than one spec is loaded.