On this page
When to use it
On every pull request that changes the spec file, including specs generated from code. If your spec is generated, make the build write it to a file and review that file’s diff: a renamed property in a C# or Java class is easy to miss in code and obvious in the spec.
Step 1: get the diff a reviewer can read
A YAML diff shows lines; it does not tell you which lines break clients. Run a breaking-change diff first, so the review starts from a list instead of from 400 changed lines. oasdiff is free and reads the base version straight from git:
oasdiff breaking main:openapi.yaml openapi.yaml
oasdiff changelog main:openapi.yaml openapi.yamlbreaking shows errors and warnings; changelog shows every change.To get the same output on every pull request without anyone running it, oasdiff publishes a GitHub Action. This is its quick start:
name: oasdiff
on:
pull_request:
branches: [ "main" ]
permissions:
contents: read
pull-requests: write
jobs:
breaking-changes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- run: git fetch --depth=1 origin ${{ github.base_ref }}
- uses: oasdiff/oasdiff-action/breaking@v0
with:
base: 'origin/${{ github.base_ref }}:openapi.yaml'
revision: 'HEAD:openapi.yaml'
fail-on: WARN
github-token: ${{ github.token }}fail-on: WARN fails the job on any warning or error; leave it out to report without failing.Where the specs go
By default, when it finds changes, the action uploads both specs, encrypted in CI, to link a side-by-side review. If your specs must not leave your runners, its review input turns that off. The CLI commands above run on your machine.
Step 2: the reviewer checklist
Read the breaking list, not just the YAML
Start from the oasdiff output. Every error-level line needs a reason in the pull request description. If the author cannot say why it has to break, it probably does not.
Look for removals
Endpoints, response fields, success status codes and accepted enum values. Removing an optional response field is quiet in oasdiff (info), but clients that read it still break; check it by hand.
Look for new requirements
A new required parameter or request field, a parameter or field that became required, or a request body that became required. Every existing caller sends the old request.
Look for changed types and narrowed limits
A number that became a string, a lower
maxLength, a higherminimum, a stricterpattern, a shorterenum. A value that was valid yesterday is rejected today.Look at responses from the client’s side
A new enum value in a response breaks clients with an exhaustive switch; oasdiff counts it as breaking. A response field that became optional means clients now need a null check.
Decide the warnings
A removed request parameter or field is a warning: old clients keep sending it. Fine if the server ignores unknown input, breaking if it rejects it. Write down which.
Name the consumers
For each changed endpoint, write down the teams that call it and how to reach them. “Everyone” is not an answer, and an endpoint with no known consumer is a blind spot, not a safe change.
Tell them before the merge
Link the pull request in their channel, with what changes, when it ships and what they need to do. A breaking change found in review is still a comment; after release it is an incident on another team.
What each rule looks like in a spec, with before and after snippets, is in the OpenAPI breaking changes reference.
Step 3: copy the template
Paste this into the pull request description, or save it as a pull request template. GitHub reads .github/pull_request_template.md, docs/pull_request_template.md or pull_request_template.md in the repository root, once it is on the default branch. To keep it separate from your normal template, put it in a .github/PULL_REQUEST_TEMPLATE/ folder and open the pull request with ?template=api-change.md in the URL.
## API change review
Spec: openapi.yaml Compared with: main
### 1. The diff
- [ ] Ran: oasdiff breaking main:openapi.yaml openapi.yaml
- [ ] Output pasted below, or "no breaking changes"
### 2. Breaking changes (oasdiff error)
| Endpoint | Change | Why it cannot be additive |
|----------|--------|---------------------------|
| | | |
### 3. Reviewer checks
- [ ] Nothing removed: endpoints, response fields, success status codes,
accepted enum values
- [ ] Nothing newly required: parameters, request fields, request body
- [ ] No changed types, no narrowed limits (maxLength, minimum, pattern, enum)
- [ ] No response field became optional
- [ ] New response enum values: clients handle unknown values (or none added)
- [ ] Removed request parameters or fields (oasdiff warning): the server
ignores input it does not know, so old clients still work
### 4. Who is affected
| Endpoint | Consumer team | Contact | Told on (date) |
|----------|---------------|---------|----------------|
| | | | |
- [ ] Endpoints with no known consumer are listed as "unknown", not "none"
### 5. Plan
- [ ] Additive option considered first (new field, new endpoint, new version)
- [ ] Old behaviour kept until: ____ (or: no transition, because ____)
- [ ] Changelog or release note written
- [ ] Reviewer sign-off: ____.github/PULL_REQUEST_TEMPLATE/api-change.md.The hard part: section 4
Sections 1 to 3 are mechanical: a tool finds the change and the reviewer reads it. Section 4 is where most reviews stop, because the author and the reviewer are on the team that owns the API, and the teams that call it work in other repositories. Searching your own code finds your own callers. A wiki page of consumers is out of date the week after it is written.
Whatever you use, keep the list next to the endpoint, keep it owned by the consumers rather than by the API team, and treat a blank row as “we do not know yet”.
Where Graphwake fits
Graphwake fills in section 4 from the consumer teams’ own subscriptions, and tells those teams while the change is still a pull request. Its CI step sends the spec and never blocks the build.
- Check out code2s
- Run tests41s
- Graphwake spec check1s
- graphwake: spec sent (pull request #1284)
- Build1m 12s
If Graphwake can’t be reached, the step logs it and exits cleanly. The build carries on.
Who is affected, per endpoint
Consumer teams subscribe to the endpoints they call, so the affected teams for a pull request come from that map, not from memory.
Told while it is still a pull request
On a pull request build the spec is stored as a draft. With alerts on open pull requests turned on in settings, the teams that use the changed endpoints hear about the breaking changes before the merge, in Slack, Microsoft Teams or email.
Impact score before the merge
Each pull request gets a 0-100 impact score with its parts shown, including blind spots: endpoints nobody subscribes to.
Open pull requests in one place
The dashboard lists open pull requests by impact score, and an AI assistant connected to Graphwake can ask which open pull requests break an endpoint.
When the checklist alone is enough
- Every caller of the API is in the same repository, so a search answers section 4.
- The API has a handful of known consumers and a short list in the README stays correct.
- You want the pull request to stop on a breaking change until someone approves it: oasdiff’s action can fail the job.
Next steps
- Every rule from the checklist with a before/after snippet: OpenAPI breaking changes.
- How to route the alert once you know who to tell: API breaking change alerts.
- Setting up the oasdiff Action, input by input: the oasdiff GitHub Action, step by step.
- Compare the two tools: oasdiff vs Graphwake.
Questions
What should a reviewer check in a pull request that changes an API?
Run a breaking-change diff, then check for removals, new requirements, changed types, narrowed limits and new response enum values. Then name the teams that call each changed endpoint and tell them before the merge.
Should a breaking change fail the pull request build?
That is a team choice. oasdiff’s GitHub Action can fail the job on a breaking change. Some teams prefer a visible report and a human decision, because some breaking changes are intended.
What does Graphwake add to this checklist?
Section 4. Graphwake keeps the list of consumer teams from their subscriptions, scores each pull request’s impact and tells those teams, before the merge when alerts on open pull requests are on. The rest of the checklist works with any breaking-change diff.
What if the spec is generated from code?
Generate it in the build, write it to a file and diff that file against the default branch. Reviewing the generated spec catches renames and type changes that are easy to miss in code.
Pick an endpoint. See who it reaches. 7-day free trial. Cancel before day 7 and you pay nothing.
Start free trialSources and last verified
- github.com/oasdiff/oasdiff
- github.com/oasdiff/oasdiff-action
- oasdiff.com/docs/breaking-changes
- docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository
- oasdiff and its name belong to its authors. Graphwake is not affiliated with the oasdiff project.
Sources checked on 2026-11-09.