{"templateId":"markdown","versions":[{"version":"v1","label":"1.x (archive)","link":"/docs/cli/v1/commands/generate-spec","default":false,"active":false,"folderId":"6f4800fc"},{"version":"v2","label":"2.x (current)","link":"/docs/cli/commands/generate-spec","default":true,"active":true,"folderId":"6f4800fc"}],"sharedDataIds":{"sidebar":"sidebar-docs-cli.sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["admonition"]},"redocly_category":"Redocly CLI","type":"markdown"},"seo":{"title":"generate-spec","description":"OpenAPI-generated documentation tool with 24k+ stars on Github - make APIs your company's superpower.","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":"Heading","attributes":{"level":1,"id":"generate-spec","__idx":0},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["generate-spec"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["generate-spec"]}," command infers an OpenAPI description from recorded HTTP traffic."," ","The command reads a traffic log (or a folder of logs), builds a deterministic baseline description from the observed exchanges, and can optionally refine that baseline with an AI provider."]},{"$$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":["generate-spec"]}," command generates OpenAPI 3.1 descriptions only."]}]},{"$$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":["Traffic parsing is shared with the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/cli/commands/drift"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drift"]}]}," command, so any log that works with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drift"]}," works here too."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"how-it-works","__idx":2},"children":["How it works"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The baseline description is inferred directly from the recorded exchanges: identifier-like path segments become named path parameters, request and response schemas are merged across all observations, repeated object shapes are extracted into ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["components/schemas"]},", and consistently formatted string values get ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["format"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["enum"]}," hints."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A description inferred from traffic alone is a hypothesis: types are coarse and there are no descriptions, enums, or examples beyond what was observed."," ","With ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--with-ai"]},", the command sends each operation together with sample exchanges to an AI provider, which narrows types and adds formats, enums, descriptions, and examples."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The AI's answer is never trusted blindly: a refined operation is only accepted when it keeps the operation's path, method, and observed response status codes, and passes validation with the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["spec"]}," ruleset."," ","Rejected refinements keep their baseline version, and if refinement fails entirely the command falls back to the baseline description."," ","The validation uses the built-in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["spec"]}," ruleset, not your project's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["redocly.yaml"]}," — lint the generated description with your own configuration afterward."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"Data sharing"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--with-ai"]}," sends samples of the recorded traffic (URLs, query strings, request and response bodies) to the selected AI provider."," ","Make sure the traffic contains no secrets or personal data you are not allowed to share."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"ai-providers","__idx":3},"children":["AI providers"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Refinement runs a locally installed AI CLI in non-interactive mode: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["claude"]}," (Claude Code), ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["codex"]}," (Codex CLI), or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cursor"]}," (Cursor CLI)."," ","The selected CLI must be installed and authenticated on the machine running the command."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The provider runs in isolation: project context the CLIs normally load (such as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CLAUDE.md"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AGENTS.md"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".cursor/rules"]},") and settings like a configured model do not apply."," ","Use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--ai-model"]}," to choose a model, or the provider's default is used."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"usage","__idx":4},"children":["Usage"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly generate-spec <traffic>\nredocly generate-spec <traffic> [--traffic-format=<option>] [--server=<url>]\nredocly generate-spec <traffic> [--title=<string>] [--output=<file>]\nredocly generate-spec <traffic> --with-ai [--ai-provider=<option>] [--ai-model=<string>] [--ai-concurrency=<number>]\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"options","__idx":5},"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":["--type"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Target API description type.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Possible values:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["openapi"]},". Default value is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["openapi"]},"."]}]},{"$$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 value is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["auto"]},"."]}]},{"$$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, the rest of their URL is treated as the API path, and it becomes the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["servers"]}," URL of the generated description."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--title"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Title for the generated API description. Default value is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Generated API"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--with-ai"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["boolean"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Refine the inferred description with an AI provider. Default value is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--ai-provider"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["AI provider used with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--with-ai"]},". Runs the corresponding CLI in non-interactive mode.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Possible values:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["claude"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["codex"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cursor"]},". Default value is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["claude"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--ai-model"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Model passed to the selected AI provider. If not set, the provider's default model is used."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--ai-concurrency"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["number"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Number of operations refined in parallel with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--with-ai"]},". Default value is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["4"]},"."]}]},{"$$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 generated description to this file instead of stdout."]}]},{"$$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":"MarkdownLink","attributes":{"href":"/docs/cli/configuration"},"children":["configuration file"]},"."]}]},{"$$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":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["--version"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["boolean"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Display version number."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"examples","__idx":6},"children":["Examples"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"generate-a-description-from-a-har-capture","__idx":7},"children":["Generate a description from a HAR capture"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly generate-spec ./traffic.har -o ./openapi.yaml\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"scope-the-traffic-to-a-server","__idx":8},"children":["Scope the traffic to a server"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When the capture contains traffic for more than one host, or the API lives behind a base path (for example, a gateway that adds ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api"]},"), use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--server"]}," to declare the server the traffic was captured against."," ","Only requests under it are considered, and the remaining path becomes the API path:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly generate-spec ./traffic.har --server https://api.example.com/api -o ./openapi.yaml\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"refine-the-description-with-ai","__idx":9},"children":["Refine the description with AI"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly generate-spec ./traffic.har --with-ai --ai-provider claude -o ./openapi.yaml\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"speed-up-refinement-for-large-apis","__idx":10},"children":["Speed up refinement for large APIs"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For descriptions with many operations, raise the concurrency and pick a faster model to shorten the run:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly generate-spec ./traffic-logs/ --with-ai --ai-concurrency 12 --ai-model claude-sonnet-5 -o ./openapi.yaml\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"capture-traffic-and-generate-a-description","__idx":11},"children":["Capture traffic and generate a description"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly proxy --target https://api.example.com --har ./capture.har\n# point your client at http://127.0.0.1:4040, then press Ctrl+C to stop\nredocly generate-spec ./capture.har -o ./openapi.yaml\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"related-commands","__idx":12},"children":["Related commands"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/cli/commands/proxy"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["proxy"]}]}," captures live HTTP traffic into a HAR file that can be fed into ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["generate-spec"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/cli/commands/drift"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["drift"]}]}," detects drift between recorded HTTP traffic and an existing OpenAPI description."]}]}]},"headings":[{"value":"generate-spec","id":"generate-spec","depth":1},{"value":"Supported traffic formats","id":"supported-traffic-formats","depth":2},{"value":"How it works","id":"how-it-works","depth":2},{"value":"AI providers","id":"ai-providers","depth":3},{"value":"Usage","id":"usage","depth":2},{"value":"Options","id":"options","depth":2},{"value":"Examples","id":"examples","depth":2},{"value":"Generate a description from a HAR capture","id":"generate-a-description-from-a-har-capture","depth":3},{"value":"Scope the traffic to a server","id":"scope-the-traffic-to-a-server","depth":3},{"value":"Refine the description with AI","id":"refine-the-description-with-ai","depth":3},{"value":"Speed up refinement for large APIs","id":"speed-up-refinement-for-large-apis","depth":3},{"value":"Capture traffic and generate a description","id":"capture-traffic-and-generate-a-description","depth":3},{"value":"Related commands","id":"related-commands","depth":2}],"frontmatter":{"seo":{"title":"generate-spec"}},"lastModified":"2026-07-21T09:36:41.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/docs/cli/commands/generate-spec","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}