{"templateId":"../@theme/templates/BlogPost","sharedDataIds":{"blog-latest-posts":"blog-latest-posts"},"props":{"metadata":{"markdoc":{"tagList":["admonition"]},"redocly_category":"Blog","type":"markdown","template":"../@theme/templates/BlogPost","title":"Catch API drift with the new proxy and drift commands","description":"Record real HTTP traffic with the proxy command, then let the drift command tell you where your API and your OpenAPI description disagree.","seo":{"title":"Catch API drift with the new proxy and drift commands","description":"Record real HTTP traffic with the proxy command, then let the drift command tell you where your API and your OpenAPI description disagree."},"author":{"id":"adam-sobaniec","name":"Adam Sobaniec","authorBIO":"Software Engineer, Redocly","image":"/assets/sobaniec.d72cecde632c015ce4db05cc559e1f27ccae55d6e5977f816362afb23a1a56a7.978384e4.png"},"publishedDate":"2026-07-08","categories":[{"category":{"id":"redocly","label":"Redocly"},"subcategory":{"id":"redocly-cli","label":"Redocly CLI"}},{"category":{"id":"redocly","label":"Redocly"},"subcategory":{"id":"product-updates","label":"Product updates"}},{"category":{"id":"api-testing","label":"API testing"},"subcategory":{"id":"integration-testing","label":"Integration testing"}}],"slug":"/blog/catch-api-drift"},"seo":{"title":"Catch API drift with the new proxy and drift commands","description":"Record real HTTP traffic with the proxy command, then let the drift command tell you where your API and your OpenAPI description disagree.","siteUrl":"https://redocly.com","image":"/assets/redocly-card.f670aae34a39545a5ea633a540cb3a4a333a1f23bb2ed3c4a1b17a5fbcf0ac85.db81178d.png","lang":"en-US"},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Your OpenAPI description says one thing."," ","Your API does another."," ","Nobody notices, because nothing fails - until an SDK generated from that description breaks in a customer's build, or a partner integration chokes on a field that was \"documented\" but never returned."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The gap between what you describe and what you ship has a name: drift."," ","It accumulates quietly, one hotfix and one forgotten field at a time."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Redocly CLI ships two commands that work together to close this gap: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["proxy"]}," records what your API actually does, and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drift"]}," compares it against what your OpenAPI description claims."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"record-first-judge-later","__idx":0},"children":["Record first, judge later"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["proxy"]}," command starts a local reverse proxy in front of your API."," ","Point any client at it - a browser, a test suite, a curl script - and every request and response that passes through is captured into a standard HAR file."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drift"]}," command takes that traffic and replays it against your OpenAPI description."," ","It matches each exchange to a documented operation and reports the discrepancies: undocumented endpoints, undocumented parameters, missing required fields, response bodies that don't match their schemas."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Because the two commands meet at a plain HAR file, you don't have to use them together."," ","Traffic exported from browser DevTools, Kong, or Nginx/Apache JSON logs works with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drift"]}," too."," ","And if you prefer immediate feedback, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["proxy"]}," accepts an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--api"]}," flag and validates traffic live, as it flows."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"HAR files record everything"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A HAR file is a full capture: request and response headers, cookies, tokens, and bodies all land in it verbatim."," ","Run ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["proxy"]}," and handle the recorded HAR files in closed sandboxes - a local machine or an isolated e2e environment exercised with synthetic accounts and test credentials - so no real user data or production secrets end up in the recording."," ","If you do record traffic that touches real credentials, treat the HAR file like a secret: keep it out of version control, redact it before sharing, and delete it when you're done."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"put-it-in-your-test-pipeline","__idx":1},"children":["Put it in your test pipeline"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here is the setup we like most: you probably already have e2e or integration tests that exercise your API."," ","That traffic is a free, realistic sample of how your API actually behaves - you're just letting it evaporate after every run."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Instead, start ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["proxy"]}," before the test run, route the tests through it, and stop it when they finish."," ","The proxy sits between your tests and the API: requests and responses pass through it unchanged, and every exchange is captured on the way."]},{"$$mdtype":"Tag","name":"Diagram","attributes":{"data-language":"mermaid","align":"center","diagramType":"mermaid","diagramSource":"flowchart TD\n    tests[\"E2E / integration tests\"] -->|\"connects to http://localhost:4040\"| proxy[\"redocly proxy\"]\n    proxy -->|\"proxies to http://localhost:9000\"| target[\"Your API\"]\n    proxy -.->|\"records\"| har[\"test-traffic.har\"]\n    har --> drift[\"redocly drift\"]\n    openapi[\"openapi.yaml\"] --> drift\n    drift -->|\"produces\"| report[\"✨ Drift report&nbsp;&nbsp;\"]\n","diagramHtml":"<svg id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26\" width=\"100%\" xmlns=\"http://www.w3.org/2000/svg\" class=\"flowchart\" style=\"max-width: 604.3125px;\" viewBox=\"0 0 604.3125 606\" role=\"graphics-document document\" aria-roledescription=\"flowchart-v2\"><style>#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26{font-family:\"Redocly Mermaid Sans\",sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .error-icon{fill:#552222;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .error-text{fill:#552222;stroke:#552222;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .edge-thickness-normal{stroke-width:1px;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .edge-thickness-thick{stroke-width:3.5px;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .edge-pattern-solid{stroke-dasharray:0;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .edge-thickness-invisible{stroke-width:0;fill:none;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .edge-pattern-dashed{stroke-dasharray:3;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .edge-pattern-dotted{stroke-dasharray:2;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .marker{fill:#333333;stroke:#333333;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .marker.cross{stroke:#333333;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 svg{font-family:\"Redocly Mermaid Sans\",sans-serif;font-size:16px;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 p{margin:0;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .label{font-family:\"Redocly Mermaid Sans\",sans-serif;color:#333;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .cluster-label text{fill:#333;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .cluster-label span{color:#333;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .cluster-label span p{background-color:transparent;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .label text,#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 span{fill:#333;color:#333;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .node rect,#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .node circle,#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .node ellipse,#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .node polygon,#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .rough-node .label text,#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .node .label text,#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .image-shape .label,#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .icon-shape .label{text-anchor:middle;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .rough-node .label,#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .node .label,#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .image-shape .label,#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .icon-shape .label{text-align:center;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .node.clickable{cursor:pointer;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .arrowheadPath{fill:#333333;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .edgePath .path{stroke:#333333;stroke-width:1px;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .flowchart-link{stroke:#333333;fill:none;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .cluster text{fill:#333;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .cluster span{color:#333;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"Redocly Mermaid Sans\",sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 rect.text{fill:none;stroke-width:0;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .icon-shape,#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .icon-shape p,#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .icon-shape .label rect,#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 .node .neo-node{stroke:#9370DB;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 [data-look=\"neo\"].node rect,#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 [data-look=\"neo\"].cluster rect,#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 [data-look=\"neo\"].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 [data-look=\"neo\"].node path{stroke:#9370DB;stroke-width:1px;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 [data-look=\"neo\"].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 [data-look=\"neo\"].node .neo-line path{stroke:#9370DB;filter:none;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 [data-look=\"neo\"].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 [data-look=\"neo\"].node circle .state-start{fill:#000000;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 [data-look=\"neo\"].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 [data-look=\"neo\"].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 :root{--mermaid-font-family:\"Redocly Mermaid Sans\",sans-serif;}#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26 :root{--mermaid-font-family:\"Redocly Mermaid Sans\",sans-serif;}</style><g><marker id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-pointEnd\" class=\"marker flowchart-v2\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" class=\"arrowMarkerPath\" style=\"stroke-width: 1; stroke-dasharray: 1, 0;\"></path></marker><marker id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-pointStart\" class=\"marker flowchart-v2\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" class=\"arrowMarkerPath\" style=\"stroke-width: 1; stroke-dasharray: 1, 0;\"></path></marker><marker id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-pointEnd-margin\" class=\"marker flowchart-v2\" viewBox=\"0 0 11.5 14\" refX=\"11.5\" refY=\"7\" markerUnits=\"userSpaceOnUse\" markerWidth=\"10.5\" markerHeight=\"14\" orient=\"auto\"><path d=\"M 0 0 L 11.5 7 L 0 14 z\" class=\"arrowMarkerPath\" style=\"stroke-width: 0; stroke-dasharray: 1, 0;\"></path></marker><marker id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-pointStart-margin\" class=\"marker flowchart-v2\" viewBox=\"0 0 11.5 14\" refX=\"1\" refY=\"7\" markerUnits=\"userSpaceOnUse\" markerWidth=\"11.5\" markerHeight=\"14\" orient=\"auto\"><polygon points=\"0,7 11.5,14 11.5,0\" class=\"arrowMarkerPath\" style=\"stroke-width: 0; stroke-dasharray: 1, 0;\"></polygon></marker><marker id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-circleEnd\" class=\"marker flowchart-v2\" viewBox=\"0 0 10 10\" refX=\"11\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"11\" markerHeight=\"11\" orient=\"auto\"><circle cx=\"5\" cy=\"5\" r=\"5\" class=\"arrowMarkerPath\" style=\"stroke-width: 1; stroke-dasharray: 1, 0;\"></circle></marker><marker id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-circleStart\" class=\"marker flowchart-v2\" viewBox=\"0 0 10 10\" refX=\"-1\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"11\" markerHeight=\"11\" orient=\"auto\"><circle cx=\"5\" cy=\"5\" r=\"5\" class=\"arrowMarkerPath\" style=\"stroke-width: 1; stroke-dasharray: 1, 0;\"></circle></marker><marker id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-circleEnd-margin\" class=\"marker flowchart-v2\" viewBox=\"0 0 10 10\" refY=\"5\" refX=\"12.25\" markerUnits=\"userSpaceOnUse\" markerWidth=\"14\" markerHeight=\"14\" orient=\"auto\"><circle cx=\"5\" cy=\"5\" r=\"5\" class=\"arrowMarkerPath\" style=\"stroke-width: 0; stroke-dasharray: 1, 0;\"></circle></marker><marker id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-circleStart-margin\" class=\"marker flowchart-v2\" viewBox=\"0 0 10 10\" refX=\"-2\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"14\" markerHeight=\"14\" orient=\"auto\"><circle cx=\"5\" cy=\"5\" r=\"5\" class=\"arrowMarkerPath\" style=\"stroke-width: 0; stroke-dasharray: 1, 0;\"></circle></marker><marker id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-crossEnd\" class=\"marker cross flowchart-v2\" viewBox=\"0 0 11 11\" refX=\"12\" refY=\"5.2\" markerUnits=\"userSpaceOnUse\" markerWidth=\"11\" markerHeight=\"11\" orient=\"auto\"><path d=\"M 1,1 l 9,9 M 10,1 l -9,9\" class=\"arrowMarkerPath\" style=\"stroke-width: 2; stroke-dasharray: 1, 0;\"></path></marker><marker id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-crossStart\" class=\"marker cross flowchart-v2\" viewBox=\"0 0 11 11\" refX=\"-1\" refY=\"5.2\" markerUnits=\"userSpaceOnUse\" markerWidth=\"11\" markerHeight=\"11\" orient=\"auto\"><path d=\"M 1,1 l 9,9 M 10,1 l -9,9\" class=\"arrowMarkerPath\" style=\"stroke-width: 2; stroke-dasharray: 1, 0;\"></path></marker><marker id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-crossEnd-margin\" class=\"marker cross flowchart-v2\" viewBox=\"0 0 15 15\" refX=\"17.7\" refY=\"7.5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"12\" markerHeight=\"12\" orient=\"auto\"><path d=\"M 1,1 L 14,14 M 1,14 L 14,1\" class=\"arrowMarkerPath\" style=\"stroke-width: 2.5;\"></path></marker><marker id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-crossStart-margin\" class=\"marker cross flowchart-v2\" viewBox=\"0 0 15 15\" refX=\"-3.5\" refY=\"7.5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"12\" markerHeight=\"12\" orient=\"auto\"><path d=\"M 1,1 L 14,14 M 1,14 L 14,1\" class=\"arrowMarkerPath\" style=\"stroke-width: 2.5; stroke-dasharray: 1, 0;\"></path></marker><g class=\"root\"><g class=\"clusters\"></g><g class=\"edgePaths\"><path d=\"M205.105,62L205.105,70.167C205.105,78.333,205.105,94.667,205.105,110.333C205.105,126,205.105,141,205.105,148.5L205.105,156\" id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26-L_tests_proxy_0\" class=\"edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link\" style=\";\" data-edge=\"true\" data-et=\"edge\" data-id=\"L_tests_proxy_0\" data-points=\"W3sieCI6MjA1LjEwNTQ2ODc1LCJ5Ijo2Mn0seyJ4IjoyMDUuMTA1NDY4NzUsInkiOjExMX0seyJ4IjoyMDUuMTA1NDY4NzUsInkiOjE2MH1d\" data-look=\"classic\" marker-end=\"url(#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-pointEnd)\"></path><path d=\"M170.607,214L160.173,222.167C149.738,230.333,128.869,246.667,118.435,262.333C108,278,108,293,108,300.5L108,308\" id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26-L_proxy_target_0\" class=\"edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link\" style=\";\" data-edge=\"true\" data-et=\"edge\" data-id=\"L_proxy_target_0\" data-points=\"W3sieCI6MTcwLjYwNzQ3MzI3MzAyNjMsInkiOjIxNH0seyJ4IjoxMDgsInkiOjI2M30seyJ4IjoxMDgsInkiOjMxMn1d\" data-look=\"classic\" marker-end=\"url(#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-pointEnd)\"></path><path d=\"M239.603,214L250.038,222.167C260.473,230.333,281.342,246.667,291.776,262.333C302.211,278,302.211,293,302.211,300.5L302.211,308\" id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26-L_proxy_har_0\" class=\"edge-thickness-normal edge-pattern-dotted edge-thickness-normal edge-pattern-solid flowchart-link\" style=\";\" data-edge=\"true\" data-et=\"edge\" data-id=\"L_proxy_har_0\" data-points=\"W3sieCI6MjM5LjYwMzQ2NDIyNjk3MzcsInkiOjIxNH0seyJ4IjozMDIuMjEwOTM3NSwieSI6MjYzfSx7IngiOjMwMi4yMTA5Mzc1LCJ5IjozMTJ9XQ==\" data-look=\"classic\" marker-end=\"url(#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-pointEnd)\"></path><path d=\"M302.211,366L302.211,370.167C302.211,374.333,302.211,382.667,310.166,390.708C318.121,398.749,334.031,406.499,341.986,410.374L349.941,414.248\" id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26-L_har_drift_0\" class=\"edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link\" style=\";\" data-edge=\"true\" data-et=\"edge\" data-id=\"L_har_drift_0\" data-points=\"W3sieCI6MzAyLjIxMDkzNzUsInkiOjM2Nn0seyJ4IjozMDIuMjEwOTM3NSwieSI6MzkxfSx7IngiOjM1My41MzY4MDg4OTQyMzA4LCJ5Ijo0MTZ9XQ==\" data-look=\"classic\" marker-end=\"url(#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-pointEnd)\"></path><path d=\"M515.727,366L515.727,370.167C515.727,374.333,515.727,382.667,507.772,390.708C499.817,398.749,483.907,406.499,475.952,410.374L467.997,414.248\" id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26-L_openapi_drift_0\" class=\"edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link\" style=\";\" data-edge=\"true\" data-et=\"edge\" data-id=\"L_openapi_drift_0\" data-points=\"W3sieCI6NTE1LjcyNjU2MjUsInkiOjM2Nn0seyJ4Ijo1MTUuNzI2NTYyNSwieSI6MzkxfSx7IngiOjQ2NC40MDA2OTExMDU3NjkyLCJ5Ijo0MTZ9XQ==\" data-look=\"classic\" marker-end=\"url(#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-pointEnd)\"></path><path d=\"M408.969,470L408.969,476.167C408.969,482.333,408.969,494.667,408.969,506.333C408.969,518,408.969,529,408.969,534.5L408.969,540\" id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26-L_drift_report_0\" class=\"edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link\" style=\";\" data-edge=\"true\" data-et=\"edge\" data-id=\"L_drift_report_0\" data-points=\"W3sieCI6NDA4Ljk2ODc1LCJ5Ijo0NzB9LHsieCI6NDA4Ljk2ODc1LCJ5Ijo1MDd9LHsieCI6NDA4Ljk2ODc1LCJ5Ijo1NDR9XQ==\" data-look=\"classic\" marker-end=\"url(#diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26_flowchart-v2-pointEnd)\"></path></g><g class=\"edgeLabels\"><g class=\"edgeLabel\" transform=\"translate(205.10546875, 111)\"><g class=\"label\" data-id=\"L_tests_proxy_0\" transform=\"translate(-100, -24)\"><foreignObject width=\"200\" height=\"48\"><div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"labelBkg\" style=\"display: table; white-space: break-spaces; line-height: 1.5; max-width: 200px; text-align: center; width: 200px;\"><span class=\"edgeLabel\"><p>connects to http://localhost:4040</p></span></div></foreignObject></g></g><g class=\"edgeLabel\" transform=\"translate(108, 263)\"><g class=\"label\" data-id=\"L_proxy_target_0\" transform=\"translate(-100, -24)\"><foreignObject width=\"200\" height=\"48\"><div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"labelBkg\" style=\"display: table; white-space: break-spaces; line-height: 1.5; max-width: 200px; text-align: center; width: 200px;\"><span class=\"edgeLabel\"><p>proxies to http://localhost:9000</p></span></div></foreignObject></g></g><g class=\"edgeLabel\" transform=\"translate(302.2109375, 263)\"><g class=\"label\" data-id=\"L_proxy_har_0\" transform=\"translate(-28.0625, -12)\"><foreignObject width=\"56.125\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"labelBkg\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"edgeLabel\"><p>records</p></span></div></foreignObject></g></g><g class=\"edgeLabel\"><g class=\"label\" data-id=\"L_har_drift_0\" transform=\"translate(0, 0)\"><foreignObject width=\"0\" height=\"0\"><div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"labelBkg\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"edgeLabel\"></span></div></foreignObject></g></g><g class=\"edgeLabel\"><g class=\"label\" data-id=\"L_openapi_drift_0\" transform=\"translate(0, 0)\"><foreignObject width=\"0\" height=\"0\"><div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"labelBkg\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"edgeLabel\"></span></div></foreignObject></g></g><g class=\"edgeLabel\" transform=\"translate(408.96875, 507)\"><g class=\"label\" data-id=\"L_drift_report_0\" transform=\"translate(-34.765625, -12)\"><foreignObject width=\"69.53125\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"labelBkg\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"edgeLabel\"><p>produces</p></span></div></foreignObject></g></g></g><g class=\"nodes\"><g class=\"node default\" id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26-flowchart-tests-0\" data-look=\"classic\" transform=\"translate(205.10546875, 35)\"><rect class=\"basic label-container\" style=\"\" x=\"-111.1875\" y=\"-27\" width=\"222.375\" height=\"54\"></rect><g class=\"label\" style=\"\" transform=\"translate(-81.1875, -12)\"><rect></rect><foreignObject width=\"162.375\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"nodeLabel\"><p>E2E / integration tests</p></span></div></foreignObject></g></g><g class=\"node default\" id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26-flowchart-proxy-1\" data-look=\"classic\" transform=\"translate(205.10546875, 187)\"><rect class=\"basic label-container\" style=\"\" x=\"-80.171875\" y=\"-27\" width=\"160.34375\" height=\"54\"></rect><g class=\"label\" style=\"\" transform=\"translate(-50.171875, -12)\"><rect></rect><foreignObject width=\"100.34375\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"nodeLabel\"><p>redocly proxy</p></span></div></foreignObject></g></g><g class=\"node default\" id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26-flowchart-target-3\" data-look=\"classic\" transform=\"translate(108, 339)\"><rect class=\"basic label-container\" style=\"\" x=\"-61.28125\" y=\"-27\" width=\"122.5625\" height=\"54\"></rect><g class=\"label\" style=\"\" transform=\"translate(-31.28125, -12)\"><rect></rect><foreignObject width=\"62.5625\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"nodeLabel\"><p>Your API</p></span></div></foreignObject></g></g><g class=\"node default\" id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26-flowchart-har-5\" data-look=\"classic\" transform=\"translate(302.2109375, 339)\"><rect class=\"basic label-container\" style=\"\" x=\"-82.9296875\" y=\"-27\" width=\"165.859375\" height=\"54\"></rect><g class=\"label\" style=\"\" transform=\"translate(-52.9296875, -12)\"><rect></rect><foreignObject width=\"105.859375\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"nodeLabel\"><p>test-traffic.har</p></span></div></foreignObject></g></g><g class=\"node default\" id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26-flowchart-drift-7\" data-look=\"classic\" transform=\"translate(408.96875, 443)\"><rect class=\"basic label-container\" style=\"\" x=\"-75\" y=\"-27\" width=\"150\" height=\"54\"></rect><g class=\"label\" style=\"\" transform=\"translate(-45, -12)\"><rect></rect><foreignObject width=\"90\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"nodeLabel\"><p>redocly drift</p></span></div></foreignObject></g></g><g class=\"node default\" id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26-flowchart-openapi-8\" data-look=\"classic\" transform=\"translate(515.7265625, 339)\"><rect class=\"basic label-container\" style=\"\" x=\"-80.5859375\" y=\"-27\" width=\"161.171875\" height=\"54\"></rect><g class=\"label\" style=\"\" transform=\"translate(-50.5859375, -12)\"><rect></rect><foreignObject width=\"101.171875\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"nodeLabel\"><p>openapi.yaml</p></span></div></foreignObject></g></g><g class=\"node default\" id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26-flowchart-report-11\" data-look=\"classic\" transform=\"translate(408.96875, 571)\"><rect class=\"basic label-container\" style=\"\" x=\"-81.3125\" y=\"-27\" width=\"162.625\" height=\"54\"></rect><g class=\"label\" style=\"\" transform=\"translate(-51.3125, -12)\"><rect></rect><foreignObject width=\"102.625\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"nodeLabel\"><p>✨ Drift report&nbsp;&nbsp;</p></span></div></foreignObject></g></g></g></g></g><defs><filter id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26-drop-shadow\" height=\"130%\" width=\"130%\"><feDropShadow dx=\"4\" dy=\"4\" stdDeviation=\"0\" flood-opacity=\"0.06\" flood-color=\"#000000\"></feDropShadow></filter></defs><defs><filter id=\"diagram-477f22da8e7911fb7e8cb011d66ffd877c93570a701e919426786239270d6f26-drop-shadow-small\" height=\"150%\" width=\"150%\"><feDropShadow dx=\"2\" dy=\"2\" stdDeviation=\"0\" flood-opacity=\"0.06\" flood-color=\"#000000\"></feDropShadow></filter></defs></svg>","diagramHtmlDark":"<svg id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902\" width=\"100%\" xmlns=\"http://www.w3.org/2000/svg\" class=\"flowchart\" style=\"max-width: 604.3125px;\" viewBox=\"0 0 604.3125 606\" role=\"graphics-document document\" aria-roledescription=\"flowchart-v2\"><style>#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902{font-family:\"Redocly Mermaid Sans\",sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .error-icon{fill:#a44141;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .error-text{fill:#ddd;stroke:#ddd;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .edge-thickness-normal{stroke-width:1px;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .edge-thickness-thick{stroke-width:3.5px;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .edge-pattern-solid{stroke-dasharray:0;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .edge-thickness-invisible{stroke-width:0;fill:none;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .edge-pattern-dashed{stroke-dasharray:3;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .edge-pattern-dotted{stroke-dasharray:2;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .marker{fill:lightgrey;stroke:lightgrey;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .marker.cross{stroke:lightgrey;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 svg{font-family:\"Redocly Mermaid Sans\",sans-serif;font-size:16px;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 p{margin:0;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .label{font-family:\"Redocly Mermaid Sans\",sans-serif;color:#ccc;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .cluster-label text{fill:#F9FFFE;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .cluster-label span{color:#F9FFFE;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .cluster-label span p{background-color:transparent;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .label text,#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 span{fill:#ccc;color:#ccc;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .node rect,#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .node circle,#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .node ellipse,#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .node polygon,#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .rough-node .label text,#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .node .label text,#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .image-shape .label,#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .icon-shape .label{text-anchor:middle;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .rough-node .label,#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .node .label,#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .image-shape .label,#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .icon-shape .label{text-align:center;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .node.clickable{cursor:pointer;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .arrowheadPath{fill:lightgrey;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .edgePath .path{stroke:lightgrey;stroke-width:1px;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .flowchart-link{stroke:lightgrey;fill:none;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .cluster text{fill:#F9FFFE;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .cluster span{color:#F9FFFE;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"Redocly Mermaid Sans\",sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 rect.text{fill:none;stroke-width:0;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .icon-shape,#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .icon-shape p,#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .icon-shape .label rect,#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .image-shape .label rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 .node .neo-node{stroke:#ccc;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 [data-look=\"neo\"].node rect,#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 [data-look=\"neo\"].cluster rect,#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 [data-look=\"neo\"].node polygon{stroke:url(#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 [data-look=\"neo\"].node path{stroke:url(#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-gradient);stroke-width:1px;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 [data-look=\"neo\"].node .outer-path{filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 [data-look=\"neo\"].node .neo-line path{stroke:#ccc;filter:none;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 [data-look=\"neo\"].node circle{stroke:url(#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 [data-look=\"neo\"].node circle .state-start{fill:#000000;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 [data-look=\"neo\"].icon-shape .icon{fill:url(#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 [data-look=\"neo\"].icon-shape .icon-neo path{stroke:url(#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 :root{--mermaid-font-family:\"Redocly Mermaid Sans\",sans-serif;}#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902 :root{--mermaid-font-family:\"Redocly Mermaid Sans\",sans-serif;}</style><g><marker id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-pointEnd\" class=\"marker flowchart-v2\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 0 L 10 5 L 0 10 z\" class=\"arrowMarkerPath\" style=\"stroke-width: 1; stroke-dasharray: 1, 0;\"></path></marker><marker id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-pointStart\" class=\"marker flowchart-v2\" viewBox=\"0 0 10 10\" refX=\"4.5\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\"><path d=\"M 0 5 L 10 10 L 10 0 z\" class=\"arrowMarkerPath\" style=\"stroke-width: 1; stroke-dasharray: 1, 0;\"></path></marker><marker id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-pointEnd-margin\" class=\"marker flowchart-v2\" viewBox=\"0 0 11.5 14\" refX=\"11.5\" refY=\"7\" markerUnits=\"userSpaceOnUse\" markerWidth=\"10.5\" markerHeight=\"14\" orient=\"auto\"><path d=\"M 0 0 L 11.5 7 L 0 14 z\" class=\"arrowMarkerPath\" style=\"stroke-width: 0; stroke-dasharray: 1, 0;\"></path></marker><marker id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-pointStart-margin\" class=\"marker flowchart-v2\" viewBox=\"0 0 11.5 14\" refX=\"1\" refY=\"7\" markerUnits=\"userSpaceOnUse\" markerWidth=\"11.5\" markerHeight=\"14\" orient=\"auto\"><polygon points=\"0,7 11.5,14 11.5,0\" class=\"arrowMarkerPath\" style=\"stroke-width: 0; stroke-dasharray: 1, 0;\"></polygon></marker><marker id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-circleEnd\" class=\"marker flowchart-v2\" viewBox=\"0 0 10 10\" refX=\"11\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"11\" markerHeight=\"11\" orient=\"auto\"><circle cx=\"5\" cy=\"5\" r=\"5\" class=\"arrowMarkerPath\" style=\"stroke-width: 1; stroke-dasharray: 1, 0;\"></circle></marker><marker id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-circleStart\" class=\"marker flowchart-v2\" viewBox=\"0 0 10 10\" refX=\"-1\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"11\" markerHeight=\"11\" orient=\"auto\"><circle cx=\"5\" cy=\"5\" r=\"5\" class=\"arrowMarkerPath\" style=\"stroke-width: 1; stroke-dasharray: 1, 0;\"></circle></marker><marker id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-circleEnd-margin\" class=\"marker flowchart-v2\" viewBox=\"0 0 10 10\" refY=\"5\" refX=\"12.25\" markerUnits=\"userSpaceOnUse\" markerWidth=\"14\" markerHeight=\"14\" orient=\"auto\"><circle cx=\"5\" cy=\"5\" r=\"5\" class=\"arrowMarkerPath\" style=\"stroke-width: 0; stroke-dasharray: 1, 0;\"></circle></marker><marker id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-circleStart-margin\" class=\"marker flowchart-v2\" viewBox=\"0 0 10 10\" refX=\"-2\" refY=\"5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"14\" markerHeight=\"14\" orient=\"auto\"><circle cx=\"5\" cy=\"5\" r=\"5\" class=\"arrowMarkerPath\" style=\"stroke-width: 0; stroke-dasharray: 1, 0;\"></circle></marker><marker id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-crossEnd\" class=\"marker cross flowchart-v2\" viewBox=\"0 0 11 11\" refX=\"12\" refY=\"5.2\" markerUnits=\"userSpaceOnUse\" markerWidth=\"11\" markerHeight=\"11\" orient=\"auto\"><path d=\"M 1,1 l 9,9 M 10,1 l -9,9\" class=\"arrowMarkerPath\" style=\"stroke-width: 2; stroke-dasharray: 1, 0;\"></path></marker><marker id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-crossStart\" class=\"marker cross flowchart-v2\" viewBox=\"0 0 11 11\" refX=\"-1\" refY=\"5.2\" markerUnits=\"userSpaceOnUse\" markerWidth=\"11\" markerHeight=\"11\" orient=\"auto\"><path d=\"M 1,1 l 9,9 M 10,1 l -9,9\" class=\"arrowMarkerPath\" style=\"stroke-width: 2; stroke-dasharray: 1, 0;\"></path></marker><marker id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-crossEnd-margin\" class=\"marker cross flowchart-v2\" viewBox=\"0 0 15 15\" refX=\"17.7\" refY=\"7.5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"12\" markerHeight=\"12\" orient=\"auto\"><path d=\"M 1,1 L 14,14 M 1,14 L 14,1\" class=\"arrowMarkerPath\" style=\"stroke-width: 2.5;\"></path></marker><marker id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-crossStart-margin\" class=\"marker cross flowchart-v2\" viewBox=\"0 0 15 15\" refX=\"-3.5\" refY=\"7.5\" markerUnits=\"userSpaceOnUse\" markerWidth=\"12\" markerHeight=\"12\" orient=\"auto\"><path d=\"M 1,1 L 14,14 M 1,14 L 14,1\" class=\"arrowMarkerPath\" style=\"stroke-width: 2.5; stroke-dasharray: 1, 0;\"></path></marker><g class=\"root\"><g class=\"clusters\"></g><g class=\"edgePaths\"><path d=\"M205.105,62L205.105,70.167C205.105,78.333,205.105,94.667,205.105,110.333C205.105,126,205.105,141,205.105,148.5L205.105,156\" id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-L_tests_proxy_0\" class=\"edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link\" style=\";\" data-edge=\"true\" data-et=\"edge\" data-id=\"L_tests_proxy_0\" data-points=\"W3sieCI6MjA1LjEwNTQ2ODc1LCJ5Ijo2Mn0seyJ4IjoyMDUuMTA1NDY4NzUsInkiOjExMX0seyJ4IjoyMDUuMTA1NDY4NzUsInkiOjE2MH1d\" data-look=\"classic\" marker-end=\"url(#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-pointEnd)\"></path><path d=\"M170.607,214L160.173,222.167C149.738,230.333,128.869,246.667,118.435,262.333C108,278,108,293,108,300.5L108,308\" id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-L_proxy_target_0\" class=\"edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link\" style=\";\" data-edge=\"true\" data-et=\"edge\" data-id=\"L_proxy_target_0\" data-points=\"W3sieCI6MTcwLjYwNzQ3MzI3MzAyNjMsInkiOjIxNH0seyJ4IjoxMDgsInkiOjI2M30seyJ4IjoxMDgsInkiOjMxMn1d\" data-look=\"classic\" marker-end=\"url(#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-pointEnd)\"></path><path d=\"M239.603,214L250.038,222.167C260.473,230.333,281.342,246.667,291.776,262.333C302.211,278,302.211,293,302.211,300.5L302.211,308\" id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-L_proxy_har_0\" class=\"edge-thickness-normal edge-pattern-dotted edge-thickness-normal edge-pattern-solid flowchart-link\" style=\";\" data-edge=\"true\" data-et=\"edge\" data-id=\"L_proxy_har_0\" data-points=\"W3sieCI6MjM5LjYwMzQ2NDIyNjk3MzcsInkiOjIxNH0seyJ4IjozMDIuMjEwOTM3NSwieSI6MjYzfSx7IngiOjMwMi4yMTA5Mzc1LCJ5IjozMTJ9XQ==\" data-look=\"classic\" marker-end=\"url(#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-pointEnd)\"></path><path d=\"M302.211,366L302.211,370.167C302.211,374.333,302.211,382.667,310.166,390.708C318.121,398.749,334.031,406.499,341.986,410.374L349.941,414.248\" id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-L_har_drift_0\" class=\"edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link\" style=\";\" data-edge=\"true\" data-et=\"edge\" data-id=\"L_har_drift_0\" data-points=\"W3sieCI6MzAyLjIxMDkzNzUsInkiOjM2Nn0seyJ4IjozMDIuMjEwOTM3NSwieSI6MzkxfSx7IngiOjM1My41MzY4MDg4OTQyMzA4LCJ5Ijo0MTZ9XQ==\" data-look=\"classic\" marker-end=\"url(#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-pointEnd)\"></path><path d=\"M515.727,366L515.727,370.167C515.727,374.333,515.727,382.667,507.772,390.708C499.817,398.749,483.907,406.499,475.952,410.374L467.997,414.248\" id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-L_openapi_drift_0\" class=\"edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link\" style=\";\" data-edge=\"true\" data-et=\"edge\" data-id=\"L_openapi_drift_0\" data-points=\"W3sieCI6NTE1LjcyNjU2MjUsInkiOjM2Nn0seyJ4Ijo1MTUuNzI2NTYyNSwieSI6MzkxfSx7IngiOjQ2NC40MDA2OTExMDU3NjkyLCJ5Ijo0MTZ9XQ==\" data-look=\"classic\" marker-end=\"url(#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-pointEnd)\"></path><path d=\"M408.969,470L408.969,476.167C408.969,482.333,408.969,494.667,408.969,506.333C408.969,518,408.969,529,408.969,534.5L408.969,540\" id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-L_drift_report_0\" class=\"edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link\" style=\";\" data-edge=\"true\" data-et=\"edge\" data-id=\"L_drift_report_0\" data-points=\"W3sieCI6NDA4Ljk2ODc1LCJ5Ijo0NzB9LHsieCI6NDA4Ljk2ODc1LCJ5Ijo1MDd9LHsieCI6NDA4Ljk2ODc1LCJ5Ijo1NDR9XQ==\" data-look=\"classic\" marker-end=\"url(#diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902_flowchart-v2-pointEnd)\"></path></g><g class=\"edgeLabels\"><g class=\"edgeLabel\" transform=\"translate(205.10546875, 111)\"><g class=\"label\" data-id=\"L_tests_proxy_0\" transform=\"translate(-100, -24)\"><foreignObject width=\"200\" height=\"48\"><div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"labelBkg\" style=\"display: table; white-space: break-spaces; line-height: 1.5; max-width: 200px; text-align: center; width: 200px;\"><span class=\"edgeLabel\"><p>connects to http://localhost:4040</p></span></div></foreignObject></g></g><g class=\"edgeLabel\" transform=\"translate(108, 263)\"><g class=\"label\" data-id=\"L_proxy_target_0\" transform=\"translate(-100, -24)\"><foreignObject width=\"200\" height=\"48\"><div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"labelBkg\" style=\"display: table; white-space: break-spaces; line-height: 1.5; max-width: 200px; text-align: center; width: 200px;\"><span class=\"edgeLabel\"><p>proxies to http://localhost:9000</p></span></div></foreignObject></g></g><g class=\"edgeLabel\" transform=\"translate(302.2109375, 263)\"><g class=\"label\" data-id=\"L_proxy_har_0\" transform=\"translate(-28.0625, -12)\"><foreignObject width=\"56.125\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"labelBkg\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"edgeLabel\"><p>records</p></span></div></foreignObject></g></g><g class=\"edgeLabel\"><g class=\"label\" data-id=\"L_har_drift_0\" transform=\"translate(0, 0)\"><foreignObject width=\"0\" height=\"0\"><div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"labelBkg\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"edgeLabel\"></span></div></foreignObject></g></g><g class=\"edgeLabel\"><g class=\"label\" data-id=\"L_openapi_drift_0\" transform=\"translate(0, 0)\"><foreignObject width=\"0\" height=\"0\"><div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"labelBkg\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"edgeLabel\"></span></div></foreignObject></g></g><g class=\"edgeLabel\" transform=\"translate(408.96875, 507)\"><g class=\"label\" data-id=\"L_drift_report_0\" transform=\"translate(-34.765625, -12)\"><foreignObject width=\"69.53125\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"labelBkg\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"edgeLabel\"><p>produces</p></span></div></foreignObject></g></g></g><g class=\"nodes\"><g class=\"node default\" id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-flowchart-tests-0\" data-look=\"classic\" transform=\"translate(205.10546875, 35)\"><rect class=\"basic label-container\" style=\"\" x=\"-111.1875\" y=\"-27\" width=\"222.375\" height=\"54\"></rect><g class=\"label\" style=\"\" transform=\"translate(-81.1875, -12)\"><rect></rect><foreignObject width=\"162.375\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"nodeLabel\"><p>E2E / integration tests</p></span></div></foreignObject></g></g><g class=\"node default\" id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-flowchart-proxy-1\" data-look=\"classic\" transform=\"translate(205.10546875, 187)\"><rect class=\"basic label-container\" style=\"\" x=\"-80.171875\" y=\"-27\" width=\"160.34375\" height=\"54\"></rect><g class=\"label\" style=\"\" transform=\"translate(-50.171875, -12)\"><rect></rect><foreignObject width=\"100.34375\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"nodeLabel\"><p>redocly proxy</p></span></div></foreignObject></g></g><g class=\"node default\" id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-flowchart-target-3\" data-look=\"classic\" transform=\"translate(108, 339)\"><rect class=\"basic label-container\" style=\"\" x=\"-61.28125\" y=\"-27\" width=\"122.5625\" height=\"54\"></rect><g class=\"label\" style=\"\" transform=\"translate(-31.28125, -12)\"><rect></rect><foreignObject width=\"62.5625\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"nodeLabel\"><p>Your API</p></span></div></foreignObject></g></g><g class=\"node default\" id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-flowchart-har-5\" data-look=\"classic\" transform=\"translate(302.2109375, 339)\"><rect class=\"basic label-container\" style=\"\" x=\"-82.9296875\" y=\"-27\" width=\"165.859375\" height=\"54\"></rect><g class=\"label\" style=\"\" transform=\"translate(-52.9296875, -12)\"><rect></rect><foreignObject width=\"105.859375\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"nodeLabel\"><p>test-traffic.har</p></span></div></foreignObject></g></g><g class=\"node default\" id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-flowchart-drift-7\" data-look=\"classic\" transform=\"translate(408.96875, 443)\"><rect class=\"basic label-container\" style=\"\" x=\"-75\" y=\"-27\" width=\"150\" height=\"54\"></rect><g class=\"label\" style=\"\" transform=\"translate(-45, -12)\"><rect></rect><foreignObject width=\"90\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"nodeLabel\"><p>redocly drift</p></span></div></foreignObject></g></g><g class=\"node default\" id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-flowchart-openapi-8\" data-look=\"classic\" transform=\"translate(515.7265625, 339)\"><rect class=\"basic label-container\" style=\"\" x=\"-80.5859375\" y=\"-27\" width=\"161.171875\" height=\"54\"></rect><g class=\"label\" style=\"\" transform=\"translate(-50.5859375, -12)\"><rect></rect><foreignObject width=\"101.171875\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"nodeLabel\"><p>openapi.yaml</p></span></div></foreignObject></g></g><g class=\"node default\" id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-flowchart-report-11\" data-look=\"classic\" transform=\"translate(408.96875, 571)\"><rect class=\"basic label-container\" style=\"\" x=\"-81.3125\" y=\"-27\" width=\"162.625\" height=\"54\"></rect><g class=\"label\" style=\"\" transform=\"translate(-51.3125, -12)\"><rect></rect><foreignObject width=\"102.625\" height=\"24\"><div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;\"><span class=\"nodeLabel\"><p>✨ Drift report&nbsp;&nbsp;</p></span></div></foreignObject></g></g></g></g></g><defs><filter id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-drop-shadow\" height=\"130%\" width=\"130%\"><feDropShadow dx=\"4\" dy=\"4\" stdDeviation=\"0\" flood-opacity=\"0.06\" flood-color=\"#FFFFFF\"></feDropShadow></filter></defs><defs><filter id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-drop-shadow-small\" height=\"150%\" width=\"150%\"><feDropShadow dx=\"2\" dy=\"2\" stdDeviation=\"0\" flood-opacity=\"0.06\" flood-color=\"#FFFFFF\"></feDropShadow></filter></defs><linearGradient id=\"diagram-a4d5a64595058269169dbbbfef0101c16d13b4821e0182aa1240691eccfeb902-gradient\" gradientUnits=\"objectBoundingBox\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\"><stop offset=\"0%\" stop-color=\"#cccccc\" stop-opacity=\"1\"></stop><stop offset=\"100%\" stop-color=\"hsl(180, 0%, 18.3529411765%)\" stop-opacity=\"1\"></stop></linearGradient></svg>"},"children":["flowchart TD\n    tests[\"E2E / integration tests\"] -->|\"connects to http://localhost:4040\"| proxy[\"redocly proxy\"]\n    proxy -->|\"proxies to http://localhost:9000\"| target[\"Your API\"]\n    proxy -.->|\"records\"| har[\"test-traffic.har\"]\n    har --> drift[\"redocly drift\"]\n    openapi[\"openapi.yaml\"] --> drift\n    drift -->|\"produces\"| report[\"✨ Drift report&nbsp;&nbsp;\"]\n"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["In a script, the whole setup fits in a few lines:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly proxy --target http://localhost:9000 --har ./test-traffic.har &\nPROXY_PID=$!\n# run your e2e or integration tests against http://localhost:4040\nkill \"$PROXY_PID\" && wait \"$PROXY_PID\"\nredocly drift ./test-traffic.har --api ./openapi.yaml\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["kill"]}," step matters: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["proxy"]}," streams captured exchanges to a temporary file and assembles the final HAR only on a clean shutdown, so ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drift"]}," finds nothing to read until the proxy has stopped."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drift"]}," command exits with a non-zero code when it finds error-level problems, so it slots into CI as a gate."," ","Every test run now doubles as a contract check, with zero extra test code to maintain."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"try-it-on-the-cafe-api","__idx":2},"children":["Try it on the Cafe API"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You don't need your own API to see it work."," ","Redocly Cafe is our public demo API, and its OpenAPI description is published along with the docs."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Start a proxy in front of the live Cafe API:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly proxy --target https://api.cafe.redocly.com --har ./cafe.har\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"Proxy listening on http://localhost:4040 → forwarding to https://api.cafe.redocly.com/\nRecording traffic to ./cafe.har\nPress Ctrl+C to stop.\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Send some traffic through it:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl http://localhost:4040/menu\ncurl \"http://localhost:4040/menu?category=dessert\"\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Press ",{"$$mdtype":"Tag","name":"kbd","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Ctrl"]}]}," + ",{"$$mdtype":"Tag","name":"kbd","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["C"]}]}," and the proxy writes the HAR file:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"Captured 2 exchange(s) to ./cafe.har\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Now grab the Cafe OpenAPI description:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl -s https://cafe.redocly.com/page-data/shared/oas-openapi/cafe.yaml.json \\\n  | jq .definition > cafe-openapi.json\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To simulate drift, open ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cafe-openapi.json"]}," and make the description lie:"," ","in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Page"]}," schema, change the type of the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["total"]}," property from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["integer"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["string"]},"."," ","Then replay the recorded traffic against it:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly drift ./cafe.har --api ./cafe-openapi.json\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"┃ Exchanges: total=2 documented=2 undocumented=0\n┃ Findings: total=3 error=2 warning=1 info=0\n\n✖ ERROR ×2 → Response field \"page.total\" must be string.\n  ↳ sample exchange=0 GET /menu (200) listMenuItems\n    expected: type \"string\"\n    actual: 5\n\n▲ WARN → Undocumented query parameter in traffic: \"category\"\n  ↳ sample exchange=1 GET /menu (200) listMenuItems\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The error is the discrepancy we planted: the API returns a number where the description now promises a string."," ","The warning is a bonus we didn't plant at all."," ","The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["category"]}," query parameter we sent isn't documented anywhere in the Cafe description."," ","Two requests of traffic, and drift already surfaced something real."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"more-than-schemas","__idx":3},"children":["More than schemas"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Findings come from built-in rules that you can select with the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--rules"]}," flag:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["undocumented-endpoint"]}," flags traffic that doesn't match any documented operation."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["schema-consistency"]}," validates parameters, headers, and request/response bodies against your schemas."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["security-baseline"]}," checks that requests actually satisfy the security requirements your description declares, and flags things like credentials sent over plain HTTP."," ","Loopback hosts such as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["localhost"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["127.0.0.1"]}," are exempt from the transport check, so sandboxed recordings against a local target stay warning-free."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["owasp-api-top10"]}," scans recorded traffic with heuristics based on the OWASP API Security Top 10 - enable it with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--rules owasp-api-top10"]},". It looks for credential-like query parameters, insecure CORS (wildcard origin with credentials enabled), weak cookie attributes, sensitive-looking fields in response payloads, and large unpaginated responses."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["One caveat before you wire ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["owasp-api-top10"]}," into a CI gate: it inspects each exchange in isolation."," ","It has no notion of user identity or ownership across requests, so it cannot detect authorization logic flaws like Broken Object Level Authorization."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Reports come out as human-readable text, JSON, CSV, or SARIF, so the same run can feed a terminal, a dashboard, or a code-scanning integration."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"Experimental"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Both commands are experimental."," ","Flags, output formats, and behavior may change - including breaking changes - in upcoming releases while we shape them with your feedback."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"get-started","__idx":4},"children":["Get started"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["proxy"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drift"]}," commands are available now in the latest ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://redocly.com/docs/cli"},"children":["Redocly CLI"]},"."," ","Check out the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://redocly.com/docs/cli/commands/drift"},"children":["drift"]}," and ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://redocly.com/docs/cli/commands/proxy"},"children":["proxy"]}," command references, run them against your own traffic, and tell us what you find - feedback and ideas are welcome on the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://github.com/Redocly/redocly-cli/issues"},"children":["Redocly CLI GitHub repository"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Your API and its description should tell the same story."," ","Now you can check."]}]},"headings":[{"value":"Record first, judge later","id":"record-first-judge-later","depth":2},{"value":"Put it in your test pipeline","id":"put-it-in-your-test-pipeline","depth":2},{"value":"Try it on the Cafe API","id":"try-it-on-the-cafe-api","depth":2},{"value":"More than schemas","id":"more-than-schemas","depth":2},{"value":"Get started","id":"get-started","depth":2}],"frontmatter":{"template":"../@theme/templates/BlogPost","title":"Catch API drift with the new proxy and drift commands","description":"Record real HTTP traffic with the proxy command, then let the drift command tell you where your API and your OpenAPI description disagree.","seo":{"title":"Catch API drift with the new proxy and drift commands","description":"Record real HTTP traffic with the proxy command, then let the drift command tell you where your API and your OpenAPI description disagree."},"author":"adam-sobaniec","publishedDate":"2026-07-08","categories":["redocly:redocly-cli","redocly:product-updates","api-testing:integration-testing"]},"lastModified":"2026-07-21T13:09:30.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/blog/catch-api-drift","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}