{"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"drift","__idx":0},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drift"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drift"]}," command detects drift between recorded HTTP traffic and an OpenAPI description."," ","The command reads a traffic log (or a folder of logs), matches each request/response exchange to a documented operation, and reports the discrepancies it finds."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"Experimental"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This is an experimental feature."," ","Its behavior, command, flags, and output may change in future releases."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drift"]}," command supports OpenAPI 3.x descriptions only."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drift"]}," command reports:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["undocumented endpoints"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["undocumented request parameters and headers"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["missing required parameters or request bodies"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["request and response schema mismatches"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["baseline security issues (opt-in OWASP API risk heuristics)"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Spec loading reuses the same engine as the other commands (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["@redocly/openapi-core"]},"), and schema validation reuses the bundled ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["@redocly/ajv"]},", so there are no extra runtime dependencies."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"supported-traffic-formats","__idx":1},"children":["Supported traffic formats"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The traffic input can be provided in any of the following formats."," ","By default the format is detected automatically from the file contents:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["HAR"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Kong"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Nginx JSON"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Apache JSON"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["NDJSON"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["JSON-array traffic files (HAR, Kong, and webserver JSON) are read fully into memory."," ","For very large captures, prefer the NDJSON format, which is streamed."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"usage","__idx":2},"children":["Usage"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly drift <traffic> --api <api>\nredocly drift <traffic> --api <api> [--traffic-format=<option>]\nredocly drift <traffic> --api <api> [--format=<option>] [--output=<file>]\nredocly drift <traffic> --api <api> [--server=<url>]\nredocly drift <traffic> --api <api> [--match-mode=<option>]\nredocly drift <traffic> --api <api> [--coverage] [--coverage-output=<file>]\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"options","__idx":3},"children":["Options"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Option"},"children":["Option"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Type"},"children":["Type"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["traffic"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["REQUIRED."]}," Path to a traffic log file or folder (HAR, Kong, Nginx/Apache JSON, NDJSON)."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--api"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["REQUIRED."]}," OpenAPI description file or folder to validate against."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--traffic-format"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Traffic input format.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Possible values:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["auto"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["har"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["kong"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nginx-json"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["apache-json"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ndjson"]},". Default: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["auto"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--format"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Output format.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Possible values:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pretty"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["json"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["csv"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sarif"]},". Default: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pretty"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--match-mode"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["How requests are located via the description ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["servers"]},". ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["strict-host"]}," also requires the host to match; ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["basepath"]}," matches only the base path.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Possible values:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["strict-host"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["basepath"]},". Default: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["strict-host"]},". Mutually exclusive with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--server"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--server"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Server URL the traffic was captured against (host, host + base path, or a path-only prefix like ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api"]},"). Only requests under it are considered, and the rest of their URL is treated as the API path. Replaces the description ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["servers"]},". Mutually exclusive with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--match-mode"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--ignore-cookies"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["boolean"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Ignore cookie-based checks (useful for logs exported without cookies). Default: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--ignore-headers"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Comma-separated header names to skip in undocumented-header checks. A trailing ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["*"]}," matches by prefix, for example ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["x-consumer-*"]},". Useful for headers a gateway or proxy adds that are not part of the API contract."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--max-findings"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["number"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Maximum findings shown in pretty output. Default: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["10"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--min-severity"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Discard findings below this severity from the report (all formats).",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Possible values:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["info"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["warning"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error"]},". Default: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["info"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--rules"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Comma-separated subset of builtin rules to run: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["undocumented-endpoint"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["schema-consistency"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["security-baseline"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["owasp-api-top10"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--output, -o"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Write the drift report (in the format selected with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--format"]},") to this file instead of stdout."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--coverage"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["boolean"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Print an ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"#api-coverage"},"children":["API coverage"]}," overview after the report: how many documented operations, parameters, schema properties, and response codes the traffic exercised. Default: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--coverage-output"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Write a detailed JSON ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"#api-coverage"},"children":["API coverage"]}," report to this file. Lists the covered and missing items of every operation."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--config"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Specify path to the ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/cli/v2/configuration"},"children":["configuration file"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--lint-config"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Specify the severity level for the configuration file.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Possible values:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["warn"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["off"]},". Default: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["warn"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--help"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["boolean"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Display help."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["owasp-api-top10"]}," rule is opt-in and only runs when included in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--rules"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"examples","__idx":4},"children":["Examples"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"validate-a-har-capture-against-a-single-description","__idx":5},"children":["Validate a HAR capture against a single description"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly drift ./traffic.har --api ./openapi.yaml\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"validate-a-folder-of-logs-against-a-folder-of-descriptions","__idx":6},"children":["Validate a folder of logs against a folder of descriptions"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly drift ./traffic-logs/ --api ./openapi/ --format json\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"declare-the-server-the-traffic-was-captured-against","__idx":7},"children":["Declare the server the traffic was captured against"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When the captured traffic does not carry the documented host or base path (for example, behind a gateway that adds ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api"]},"), use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--server"]}," to declare the actual server."," ","Only requests under it are considered, and the remaining path is matched against the description paths directly:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly drift ./traffic.har --api ./openapi.yaml --server localhost:9000\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"ignore-headers-added-by-a-gateway-or-proxy","__idx":8},"children":["Ignore headers added by a gateway or proxy"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A gateway such as Caddy often injects headers that are not part of the API contract (for example authentication or consumer-identity headers)."," ","Skip them so they don't show up as undocumented headers."," ","Use a trailing ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["*"]}," to match a family of headers by prefix:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly drift ./traffic.har --api ./openapi.yaml --ignore-headers \"x-caddy-auth-token,x-auth-intent,x-consumer-*\"\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"write-the-report-to-a-file","__idx":9},"children":["Write the report to a file"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly drift ./traffic.har --api ./openapi.yaml --format json -o ./drift-report.json\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"measure-api-coverage","__idx":10},"children":["Measure API coverage"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly drift ./traffic.har --api ./openapi.yaml --coverage --coverage-output ./coverage.json\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"api-coverage","__idx":11},"children":["API coverage"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Drift tells you where the traffic disagrees with the description."," ","Coverage tells you how much of the description the traffic exercised at all, so you know how far the drift findings can be trusted."," ","Coverage is measured the same way test runners measure code coverage: each documented item is either covered by at least one exchange or missing."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["With ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--coverage"]},", the command prints an overview after the drift report:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"API coverage\n  operations         ███████████████░░░░░   75%      3/4\n  parameters         ██████████░░░░░░░░░░   50%      2/4\n  schema properties  ████████░░░░░░░░░░░░   41%    16/39\n  response codes     ███████████░░░░░░░░░   57%      4/7\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Category"},"children":["Category"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Documented items"},"children":["Documented items"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Covered when"},"children":["Covered when"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["operations"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Every operation of the loaded descriptions."]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["At least one exchange matched the operation."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["parameters"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Every path, query, header, and cookie parameter of an operation."]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A matched exchange carried the parameter. Cookie parameters are skipped with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--ignore-cookies"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["schema properties"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Every property reachable from the JSON request and response body schemas."]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A matched exchange carried the property in its JSON body."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["response codes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Every response of an operation, including responses without content."]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A matched exchange returned the status. Status ranges such as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["2XX"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["default"]}," count as well."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Schema properties are collected from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["properties"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["items"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["allOf"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["oneOf"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["anyOf"]},"."," ","Properties marked ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["readOnly"]}," are not expected in requests and properties marked ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["writeOnly"]}," are not expected in responses, so they are not counted on that side."," ","A property declared in several ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["oneOf"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["anyOf"]}," branches is counted once, and a body covers it whenever it carries that field, whichever branch declares it."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If the report on stdout is machine-readable (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--format json"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["csv"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sarif"]}," without ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--output"]},"), the overview is printed to stderr so the report stays parseable."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["With ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--coverage-output"]},", the command writes a JSON report that lists, for every operation, the items the traffic covered and the items it never exercised:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"version\": 1,\n  \"meta\": {\n    \"spec\": \"./openapi.yaml\",\n    \"traffic\": \"./traffic.har\",\n    \"matchMode\": \"strict-host\",\n    \"exchanges\": { \"total\": 4, \"matched\": 4, \"withBody\": 4 }\n  },\n  \"totals\": {\n    \"operations\": { \"covered\": 3, \"total\": 4 },\n    \"parameters\": { \"covered\": 2, \"total\": 4 },\n    \"properties\": { \"covered\": 16, \"total\": 39 },\n    \"responses\": { \"covered\": 4, \"total\": 7 }\n  },\n  \"operations\": [\n    {\n      \"method\": \"GET\",\n      \"path\": \"/items\",\n      \"operationId\": \"listItems\",\n      \"missing\": [\n        { \"kind\": \"parameter\", \"name\": \"limit\", \"in\": \"query\" },\n        { \"kind\": \"property\", \"target\": \"response\", \"status\": \"200\", \"path\": \"[].tags\" },\n        { \"kind\": \"response\", \"status\": \"400\" }\n      ],\n      \"covered\": [\n        { \"kind\": \"operation\" },\n        { \"kind\": \"parameter\", \"name\": \"category\", \"in\": \"query\" },\n        { \"kind\": \"response\", \"status\": \"200\" },\n        { \"kind\": \"property\", \"target\": \"response\", \"status\": \"200\", \"path\": \"[].name\" }\n      ]\n    }\n  ]\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["meta.exchanges.withBody"]}," counts the matched exchanges that carried a JSON request or response body."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A property ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["path"]}," is relative to the body: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[]"]}," marks array items, so ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[].price.amount"]}," is the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["amount"]}," of the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["price"]}," of each element."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The coverage output is experimental and its shape may change."," ","Coverage does not affect the exit code."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"exit-codes","__idx":12},"children":["Exit codes"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["0"]},": no error-level findings."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["1"]},": error-level drift detected."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"related-commands","__idx":13},"children":["Related commands"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/cli/v2/commands/proxy"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["proxy"]}]}," captures live HTTP traffic into a HAR file that can be replayed through ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drift"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/cli/v2/commands/generate-spec"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["generate-spec"]}]}," infers an OpenAPI description from the same traffic formats."]}]}]},"frontmatter":{},"tagList":["admonition","html"],"title":"drift","lastModified":"2026-10-07T06:18:11.000Z"}