{"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"apply-overlays","__idx":0},"children":["Apply overlays"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["An ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"https://spec.openapis.org/overlay/latest.html"},"children":["Overlay"]}," is a file that describes changes to an API description, such as removing internal operations or replacing the servers."," ","The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bundle"]}," command applies overlays while it creates the bundle, so you can publish several versions of an API from a single source."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"We recommend decorators for most tasks"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/cli/v2/decorators"},"children":["decorators"]}," for most changes to an API description."," ","Built-in decorators, such as ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/cli/v2/decorators/remove-x-internal"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["remove-x-internal"]}]},", ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/cli/v2/decorators/filter-out"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["filter-out"]}]},", and ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/cli/v2/decorators/info-override"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["info-override"]}]},", cover the common tasks."," ","Decorators select nodes by type, such as every operation, so they keep working when you restructure the API description, while an overlay's JSONPath targets depend on where each node sits."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use overlays for changes that come from other tools, such as the code samples that ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["generate-client"]}," writes, or that other tools supporting the Overlay Specification must also apply."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"prerequisites","__idx":1},"children":["Prerequisites"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/cli/v2/installation"},"children":["Install Redocly CLI"]}," version 2.x."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["An API description to change."," ","The examples use an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["openapi.yaml"]}," file whose ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/tickets"]}," path item lives in a separate ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paths/tickets.yaml"]}," file."," ","Its ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["get"]}," operation has ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tags: [tickets]"]},", and its ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["post"]}," operation is marked ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["x-internal: true"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"write-an-overlay","__idx":2},"children":["Write an overlay"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["An overlay has a list of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["actions"]},"."," ","Each action selects nodes in the API description with a ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"https://www.rfc-editor.org/rfc/rfc9535"},"children":["JSONPath"]}," expression in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["target"]},", and then either removes them, merges an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["update"]}," value into them, or merges a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["copy"]}," of another node into them."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["overlays/public.yaml"]}," file with the following content:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"yaml","header":{"controls":{"copy":{}}},"source":"overlay: 1.1.0\ninfo:\n  title: Public Museum API\n  version: 1.0.0\nactions:\n  - target: $.paths.*[?@['x-internal'] == true]\n    description: Hide internal operations.\n    remove: true\n  - target: $.servers[*]\n    description: Remove the staging server.\n    remove: true\n  - target: $.servers\n    description: Add the production server.\n    update:\n      - url: https://api.example.com\n  - target: $.paths['/tickets'].get\n    update:\n      description: Returns the tickets available for purchase.\n","lang":"yaml"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The actions run in order, and each one works on the result of the previous one."," ","The second and third actions replace the servers: an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["update"]}," adds to an existing list, so the list is emptied first."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"apply-the-overlay","__idx":3},"children":["Apply the overlay"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Pass the overlay to the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bundle"]}," command:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly bundle openapi.yaml --overlay=overlays/public.yaml -o dist/public.yaml\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The bundle no longer has the internal operation, and it lists the production server:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"yaml","header":{"controls":{"copy":{}}},"source":"openapi: 3.1.0\ninfo:\n  title: Museum API\n  version: 1.0.0\nservers:\n  - url: https://api.example.com\npaths:\n  /tickets:\n    get:\n      summary: List tickets\n      operationId: listTickets\n      tags:\n        - tickets\n      responses:\n        '200':\n          description: OK\n      description: Returns the tickets available for purchase.\ncomponents: {}\n","lang":"yaml"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["$.paths['/tickets'].get"]}," target reaches the operation even though it lives in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paths/tickets.yaml"]},"."," ","Overlays are applied to the bundled API description."," ","Write targets against the output of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["redocly bundle openapi.yaml"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To apply several overlays, repeat the option."," ","They are applied in the order you list them."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"reuse-actions-and-files","__idx":4},"children":["Reuse actions and files"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Overlay 1.2 lets you define an action once under ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["components.actions"]}," and apply it to several targets."," ","A ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["$ref"]}," in an overlay value can also point to a file."," ","The path is relative to the overlay file."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The following ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["overlays/errors.yaml"]}," overlay adds the same ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["404"]}," response to two operations:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"yaml","header":{"controls":{"copy":{}}},"source":"overlay: 1.2.0\ninfo:\n  title: Error responses\n  version: 1.0.0\ncomponents:\n  actions:\n    notFound:\n      description: Adds a 404 response to an operation.\n      fields:\n        update:\n          '404':\n            $ref: ./responses/NotFound.yaml\nactions:\n  - $ref: '#/components/actions/notFound'\n    target: $.paths['/tickets'].get.responses\n  - $ref: '#/components/actions/notFound'\n    target: $.paths['/tickets'].post.responses\n","lang":"yaml"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bundle"]}," command pulls ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["overlays/responses/NotFound.yaml"]}," into the bundle, like any other referenced file, and both operations point to it:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"yaml","header":{"controls":{"copy":{}}},"source":"paths:\n  /tickets:\n    get:\n      responses:\n        '200':\n          description: OK\n        '404':\n          $ref: '#/components/responses/NotFound'\n    post:\n      responses:\n        '201':\n          description: Created\n        '404':\n          $ref: '#/components/responses/NotFound'\n","lang":"yaml"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"combine-overlays-with-decorators","__idx":5},"children":["Combine overlays with decorators"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Overlays are applied before ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/cli/v2/decorators"},"children":["decorators"]},", so decorators see the changes an overlay makes."," ","For example, an overlay can mark operations as internal, and the ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/cli/v2/decorators/remove-x-internal"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["remove-x-internal"]}]}," decorator then removes them."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["overlays/mark-internal.yaml"]}," overlay:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"yaml","header":{"controls":{"copy":{}}},"source":"overlay: 1.1.0\ninfo:\n  title: Mark internal operations\n  version: 1.0.0\nactions:\n  - target: $.paths['/tickets'].post\n    update:\n      x-internal: true\n","lang":"yaml"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Then turn on the decorator for the API that uses the overlay:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"yaml","header":{"controls":{"copy":{}}},"source":"apis:\n  public:\n    root: openapi.yaml\n    overlays:\n      - overlays/mark-internal.yaml\n    decorators:\n      remove-x-internal: on\n","lang":"yaml"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When you run ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["redocly bundle public"]},", the bundle doesn't include the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /tickets"]}," operation."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"add-code-samples-from-a-generated-client","__idx":6},"children":["Add code samples from a generated client"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["With ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["codeSamples: true"]}," in the ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/cli/v2/configuration/reference/client"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["client"]}]}," configuration, the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["generate-client"]}," command writes an overlay next to the client that adds ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["x-codeSamples"]}," to each operation."," ","Apply it like any other overlay, for example after the overlay that prepares the public version:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly bundle openapi.yaml --overlay=overlays/public.yaml --overlay=src/api/client.code-samples.yaml -o dist/public.yaml\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"configure-overlays-for-each-api","__idx":7},"children":["Configure overlays for each API"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To publish an internal and a public version of the same API every time you bundle, list the overlays in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["apis"]}," section of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["redocly.yaml"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"yaml","header":{"controls":{"copy":{}}},"source":"apis:\n  internal:\n    root: openapi.yaml\n    output: dist/internal.yaml\n  public:\n    root: openapi.yaml\n    output: dist/public.yaml\n    overlays:\n      - overlays/public.yaml\n","lang":"yaml"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Paths in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["overlays"]}," are relative to the configuration file."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Run ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bundle"]}," without arguments to create both files:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"redocly bundle\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--overlay"]}," option replaces the overlays from the configuration file, which is handy for trying out an overlay before you add it to the configuration."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"fix-overlay-problems","__idx":8},"children":["Fix overlay problems"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If an action can't be applied, the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bundle"]}," command shows where the problem is in the overlay file and doesn't create the bundle."," ","For example, the following action tries to merge an object into the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tags"]}," list of an operation:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"yaml","header":{"controls":{"copy":{}}},"source":"overlay: 1.1.0\ninfo:\n  title: Broken\n  version: 1.0.0\nactions:\n  - target: $.paths['/tickets'].get\n    update:\n      tags:\n        name: public\n","lang":"yaml"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The command reports the problem and points to the action:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"text","header":{"controls":{"copy":{}}},"source":"[1] overlays/broken.yaml:8:7 at #/actions/0/update\n\nCannot apply object to array at $['paths']['/tickets']['get']['tags'].\n\n 6 | - target: $.paths['/tickets'].get\n 7 |   update:\n 8 |     tags:\n   |     ^^^^^\n 9 |       name: public\n   |       ^^^^^^^^^^^^\n10 |\n\nError was generated by the overlay rule.\n\n❌ Errors encountered while bundling openapi.yaml: bundle not created (use --force to ignore errors).\n","lang":"text"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To add a tag instead, make the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["update"]}," value a list: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tags: [public]"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If an action's target matches nothing, the action changes nothing and isn't reported."," ","If an overlay seems to have no effect, run ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["redocly bundle"]}," without it and check that the targets match the output."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To check that an overlay file itself is valid, lint it with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["redocly lint"]},"."," ","See ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/cli/v2/guides/lint-overlay"},"children":["Lint Overlay with Redocly CLI"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"resources","__idx":9},"children":["Resources"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/cli/v2/commands/bundle#apply-overlays"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bundle"]}," command"]}," reference describes how overlays work with the other bundle options."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/cli/v2/configuration/reference/apis"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["apis"]}," configuration"]}," reference lists the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["overlays"]}," option."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"https://spec.openapis.org/overlay/latest.html"},"children":["Overlay Specification"]}," has more examples of actions."]}]}]},"frontmatter":{"seo":{"title":"Apply Overlays with Redocly CLI","description":"Apply Overlay files to an API description when you bundle it with Redocly CLI."}},"tagList":["admonition"],"title":"Apply Overlays with Redocly CLI","lastModified":"2026-09-29T07:29:49.000Z"}