How to Use OpenAPI Overlays #
The OpenAPI Overlay Specification provides a structured way to apply changes to an OpenAPI document without touching the original file. Instead of maintaining several diverging copies of the same document for different audiences or environments, you maintain one canonical OpenAPI description and one or more overlay files that describe the differences. This guide walks through every option available in an overlay document and shows a working example for each.
For background on why overlays exist and the problems they solve, see What is the OpenAPI Overlay Specification?.
The Building Blocks of an Overlay Document #
An overlay document is a YAML or JSON file with the following top-level fields:
| Field | Required | Description |
|---|---|---|
overlay | Yes | The version of the Overlay Specification being used, e.g. 1.1.0. |
info | Yes | Metadata about the overlay: title, version, and an optional description (added in 1.1.0, CommonMark supported). |
extends | No | A URI reference (absolute or relative) identifying the specific OpenAPI document the overlay is designed to update, e.g. ./tictactoe.yaml. |
actions | Yes | An ordered list of overlay actions to apply. |
Each entry in actions supports:
| Field | Description |
|---|---|
target | A JSONPath expression identifying which part(s) of the OpenAPI document to modify. As of version 1.1.0, this must be fully RFC 9535-compliant JSONPath. |
update | An object, array, or primitive value to deep-merge into the matched node(s). |
remove | A boolean (true) that deletes the matched node(s). |
copy | A JSONPath expression selecting a node in the same document to copy into the matched node(s) — added in version 1.1.0. |
description | An optional human-readable note explaining what the action does. |
Only one of update, remove, or copy should be set per action — if both update and copy are present, update is ignored.
Step 1: Declare the Overlay and What It Targets #
Start with the overlay version and info block, optionally pointing at the base document with extends:
overlay: 1.1.0
info:
title: Public API Overlay
version: 1.0.0
description: Strips internal-only endpoints and rewrites the public description.
extends: ./api.yaml
actions: []
Step 2: Target Nodes With JSONPath #
Every action needs a target expression to select the node(s) it applies to. Some common patterns:
$.info # the info object
$.paths.* # every path item
$.paths.*.*.responses # every response object, across all operations
$.components.schemas.User # the User schema component
$.paths['/orders'].post.summary # the summary of the POST /orders operation
$.paths.*.get.tags[?@ == 'dummy'] # a specific tag value inside an array
Because target expressions must be RFC 9535-compliant, some filter expressions may need extra parentheses depending on your tooling’s JSONPath implementation, e.g. parameters[?(@.name=='filter')] instead of parameters[?@.name=='filter'].
Step 3: Choose an Action #
update — Add or Replace Values
#
update performs a deep merge into the matched node, similar to JSON Merge Patch (RFC 7396). Keys not mentioned are preserved.
overlay: 1.1.0
info:
title: Update info and one operation
version: 1.0.0
actions:
- target: $.info
update:
description: "This is the public-facing version of our API."
- target: $.paths['/users/{id}'].get
update:
summary: "Retrieve a user by their unique identifier"
x-internal-note: "Cached for 60 seconds"
Since version 1.1.0, update also works directly against primitive-valued nodes:
- target: $.paths['/foo'].get.description
update: This is the new description
remove — Delete Nodes
#
remove deletes the matched node entirely. It is commonly used to strip internal or administrative endpoints before publishing public documentation:
overlay: 1.1.0
info:
title: Remove an internal endpoint
version: 1.0.0
actions:
- target: $.paths['/internal/admin']
remove: true
Since version 1.1.0, remove also works against a single primitive entry inside an array, such as one tag among several:
- target: $.paths.*.get.tags[?@ == 'dummy']
remove: true
copy — Duplicate or Move Nodes
#
copy, introduced in version 1.1.0, merges in a value selected from elsewhere in the same document instead of a literal value written in the overlay. This is what makes renaming or moving a node possible with overlays alone:
overlay: 1.1.0
info:
title: Rename the items path
version: 1.0.0
actions:
- target: '$.paths'
update: { "/new-items": {} }
- target: '$.paths["/new-items"]'
copy: '$.paths["/items"]'
- target: '$.paths["/items"]'
remove: true
description: 'moves (renames) the "items" path item to "new-items"'
This sequence follows the general recipe for any move or rename: ensure the destination exists, copy the source into it, then remove the source. Actions run in the order they appear, so the update action that creates /new-items must come before the copy action that fills it in.
Putting It All Together #
A single overlay file can combine update, remove, and copy freely, since actions are just applied in sequence against the base document:
overlay: 1.1.0
info:
title: Public documentation overlay
version: 1.2.0
description: Prepares the internal API description for external publication.
extends: ./internal-api.yaml
actions:
- target: $.info
update:
description: "This is the public-facing version of our API."
- target: $.paths['/internal/metrics']
remove: true
- target: '$.paths'
update: { "/orders-v2": {} }
- target: '$.paths["/orders-v2"]'
copy: '$.paths["/orders"]'
- target: $.paths['/orders-v2'].post.summary
update: "Create an order (v2 endpoint)"
Applying an Overlay #
Overlays are typically applied with a CLI tool as part of a build or CI/CD step, rather than by hand. Tools with documented support include:
- Redocly CLI — one of the earliest tools to ship the
overlaycommand. - Bump.sh CLI and Speakeasy CLI — overlay support as part of broader documentation/SDK workflows.
- overlays-js and overlay-jvm — libraries for applying overlays programmatically from JavaScript or the JVM.
- apigee-go-gen, openapi-format, and oas-patch — CLI transformation toolchains that include overlay support.
Check the OAI Overlay Specification repository for the current list of tools and their supported Overlay Specification version, since copy, primitive update/remove, and the RFC 9535 requirement were only added in version 1.1.0.
Related Reading #
- What is the OpenAPI Overlay Specification?
- How can I use OpenAPI overlays to remove internal endpoints before publishing documentation?
- How can I use OpenAPI overlays to add examples to an existing OpenAPI document?
- How can I use OpenAPI overlays to copy or move elements in an OpenAPI document?
- How can I use OpenAPI overlays to test and validate changes before publishing?
Last updated on August 7, 2026.