Skip to main content

SpecShift

CI PyPI version Python versions License: MIT

SpecShift detects changes in OpenAPI and Swagger contracts, classifies each one as breaking, warning, or info, and can optionally summarize them in plain language.

When an API changes from one version to the next, the real question isn't "what changed" but "will this break me". SpecShift is built to answer exactly that: it takes two specifications, evaluates every difference between them individually, and tells you which ones actually matter.

$ specshift diff examples/old_api.yaml examples/new_api.yaml

Bookstore API : 1.0.0 -> 2.0.0
13 breaking, 2 warning, 3 info changes found.

[BREAKING] DELETE /books/{bookId} :: HTTP method removed
[BREAKING] GET /books > parameter 'category' :: Parameter 'category' is now required
[BREAKING] GET /books > response 200 > field 'author' :: field removed from response
...

Result: 13 breaking change(s) make this update risky.

Why SpecShift

Every team that keeps evolving its API eventually hits the same problem: a field gets removed, a parameter becomes required, an enum value disappears, and nobody notices until a client breaks in production. Most existing diff tools just show you a raw JSON diff and leave it up to you to figure out what actually matters.

SpecShift doesn't do that. It evaluates every change based on its context:

  • Removing a field from a response is breaking, because clients may depend on it being there.
  • Removing the same field from a request body is usually just a warning, because clients that send it are simply ignored, not broken.
  • Adding a new required field to a request is breaking, but adding a new field to a response is just informational.

These context-aware rules are the core of SpecShift, and they work completely free, with no API key required. The optional AI-powered natural-language summary is an additional layer on top, never a requirement.

Features

  • Comprehensive structural diff: deep comparison at the path, HTTP method, parameter, request body, response, and schema level.
  • Context-aware classification: the same change is weighted differently depending on whether it occurs in a request or a response.
  • $ref resolution and allOf merging: correctly follows the reference and composition patterns common in real-world specifications.
  • Detects enum, format, nullable, and security scheme changes.
  • Works entirely for free: no API key or paid service is required.
  • Optional AI summary: can generate a natural-language summary using Groq, the Gemini free tier, or any OpenAI-compatible endpoint. If no key is set, it automatically falls back to a rule-based summary and never stops working.
  • CI/CD integration: the specshift check command compares the current specification against a branch and fails the build if a breaking change is found.
  • Live monitoring: the specshift watch command periodically checks a remote API's specification and sends a Slack or Discord notification when it changes.
  • Three output formats: a colored console table, a Markdown report (ideal for PR comments), and JSON (for integrating with other tools).

Installation

pip install specshift

For colored console output (optional, works fine without it too):

pip install "specshift[pretty]"

Installing from source:

git clone https://github.com/Lethe044/specshift.git
cd specshift
pip install -e .

Quick start

Compare two specifications directly:

specshift diff old_openapi.yaml new_openapi.yaml

You can also compare specifications from URLs:

specshift diff https://api.example.com/v1/openapi.json https://api.example.com/v2/openapi.json

To use it in CI, create a configuration file in your repo:

specshift init

This produces a .specshift.yml file similar to:

spec_path: openapi.yaml
base_ref: main
fail_on: breaking

Then, in your CI pipeline:

specshift check

This command compares the current openapi.yaml file against its version on the main branch and returns exit code 1 if a breaking change is found.

AI summary (optional)

SpecShift can use free-tier AI services to generate a natural-language summary of the changes. This never requires any payment:

export GROQ_API_KEY="your-groq-api-key"
specshift diff old.yaml new.yaml --ai

You can also use Google Gemini's free tier instead of Groq:

export GEMINI_API_KEY="your-gemini-api-key"
specshift diff old.yaml new.yaml --ai --ai-provider gemini

If you want to use a more powerful (paid) model, you can connect any OpenAI-compatible endpoint:

export SPECSHIFT_API_KEY="your-api-key"
export SPECSHIFT_OPENAI_BASE_URL="https://api.openai.com/v1"
specshift diff old.yaml new.yaml --ai --ai-provider openai_compatible --ai-model gpt-4o-mini

If no key is configured, the --ai flag still works, it simply produces a rule-based summary instead of waiting on a network call. AI support is an optional enhancement, never a requirement.

Commands

specshift diff <old> <new>

Compares two specifications. <old> and <new> can be a file path, an http(s) URL, or raw JSON/YAML text.

Useful options:

Option Description
--format console|markdown|json Output format (default: console)
--output <file> Writes the output to a file
--ai Adds a natural-language summary
--ai-provider groq|gemini|openai_compatible Chooses the AI provider
--fail-on breaking|warning|none Determines at which level exit code 1 is returned
--quiet Only prints the summary line

specshift check

Designed for CI/CD. Compares the current specification file against a git reference (branch, tag, or commit) defined in .specshift.yml.

specshift check --spec openapi.yaml --base-ref origin/main

specshift watch <url>

Periodically checks a remote specification, compares it against the previous snapshot, and sends a notification if a difference is found.

specshift watch https://api.example.com/openapi.json \
  --interval 600 \
  --slack-webhook "$SLACK_WEBHOOK_URL"

specshift init

Creates a sample .specshift.yml file.

Using it with GitHub Actions

The workflow below checks your API contract against the main branch on every pull request and fails the build if a breaking change is found:

name: API Contract Check

on:
  pull_request:
    paths:
      - "openapi.yaml"

jobs:
  contract-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - run: pip install specshift

      - run: specshift check --base-ref origin/${{ github.base_ref }}

If you want to add AI-powered PR comments, you can generate a Markdown report with specshift check --ai --format markdown --output report.md and post it as a PR comment using an action like peter-evans/create-or-update-comment.

Configuration file (.specshift.yml)

spec_path: openapi.yaml
base_ref: main
fail_on: breaking

# optional
ai_provider: groq
ai_model: llama-3.3-70b-versatile
slack_webhook: https://hooks.slack.com/services/...
discord_webhook: https://discord.com/api/webhooks/...
ignore_paths: []

When SpecShift calls something breaking

The table below summarizes which severity level applies in the most common scenarios:

Change In a request In a response
Field removed Warning Breaking
New required field added Breaking Info
New optional field added Info Info
Field no longer required Info Breaking
Field became required Breaking Info
Data type changed Breaking Breaking
Enum value removed Breaking Breaking
Endpoint or method removed Breaking Breaking

Comparison with other tools

SpecShift Raw JSON/YAML diff oasdiff / openapi-diff style tools
Context-aware classification Yes No Partially
Natural-language summary Yes (optional) No No
Free to use Fully free Free Usually free
CI integration Built-in (check) Manual Varies
Live URL monitoring Built-in (watch) No Rarely

Roadmap

This project is under active development. Some planned areas:

  • Support for gRPC/Protobuf contracts
  • GraphQL schema diffing
  • An official GitHub Action for posting automatic PR comments
  • A web-based result viewer
  • More semantic rules (path parameter pattern changes, content-type changes, etc.)

Feel free to open an issue if you have a feature request.

Contributing

See CONTRIBUTING.md for the contribution guide. Bug reports, feature requests, and pull requests are always welcome.

License

This project is licensed under the MIT License.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

specshift-1.0.0.tar.gz (26.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

specshift-1.0.0-py3-none-any.whl (24.1 kB view details)

Uploaded Python 3

File details

Details for the file specshift-1.0.0.tar.gz.

File metadata

  • Download URL: specshift-1.0.0.tar.gz
  • Upload date:
  • Size: 26.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for specshift-1.0.0.tar.gz
Algorithm Hash digest
SHA256 9b9c6da651da304747bad82bf820e19bb450e43943b9eab076b95fc6f9cfa931
MD5 df8db809ba9b1f1848cd5735d337bf13
BLAKE2b-256 e36a54e9517b3914e4aabc0f0f656c9dcc86f7b352050f6e54bf290592f727b7

See more details on using hashes here.

Provenance

The following attestation bundles were made for specshift-1.0.0.tar.gz:

Publisher: publish.yml on Lethe044/SpecShift

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file specshift-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: specshift-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 24.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for specshift-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2db4ce666c16c0a72d0d388e1a6814d3c4c9fe2c42bfcc117757c13ae3d9c35e
MD5 3c49978a6abde2b6d26ae2a4f5800436
BLAKE2b-256 3c9add8cee810e7bb669a68e1526e3e61aa8ec1497c84e9c6553ed4a4bb372ad

See more details on using hashes here.

Provenance

The following attestation bundles were made for specshift-1.0.0-py3-none-any.whl:

Publisher: publish.yml on Lethe044/SpecShift

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page