# OpenAPI Breaking Change Detector (`afkdigital/openapi-breaking-change-detector`) Actor

Compare OpenAPI 3.0 contracts with directional request/response rules, breaking-change evidence, JSON/CSV and summary reports. No endpoint probes. $0.15 per successful comparison.

- **URL**: https://apify.com/afkdigital/openapi-breaking-change-detector.md
- **Developed by:** [AFK Digital](https://apify.com/afkdigital) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.15 / successfully completed comparison

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## OpenAPI Breaking Change Detector

Compare two OpenAPI contracts before shipping a release. Find removed operations, new required inputs, type and enum changes, response-contract changes and authentication changes, with JSON-pointer evidence for every finding.

**Version 1.0 • OpenAPI 3.0.0–3.0.4 only • $0.15 per successfully completed comparison.**
A successful comparison with **zero findings is also charged $0.15**. Finding count, exports and internal retries within the same run do not add charges. Platform usage is included. Invalid input and unsuccessful analysis are not charged a comparison event. Starting a separate run is a new comparison.

### Quick start

The prefilled example compares two realistic Order API versions and runs without credentials or external services.

1. Paste the baseline document into `oldSpec` and the candidate into `newSpec` as JSON or YAML **text strings**.
2. Select `old-to-new` to check existing clients against the new service.
3. Run the Actor. Review both the findings and the summary counts, especially if a filter or result limit is active.
4. Download JSON, CSV and the Markdown report from Output.

Alternatively, supply `oldSpecUrl` and/or `newSpecUrl`. Clear the corresponding inline field first: exactly one source is required for each side. The inline text fields also accept a safe HTTPS document URL as their entire value. No API key is required.

Example API input (documents are strings):

```json
{
  "oldSpec": "{\"openapi\":\"3.0.3\",\"info\":{\"title\":\"Example\",\"version\":\"1\"},\"paths\":{\"/health\":{\"get\":{\"responses\":{\"200\":{\"description\":\"OK\"}}}}}}",
  "newSpec": "{\"openapi\":\"3.0.3\",\"info\":{\"title\":\"Example\",\"version\":\"2\"},\"paths\":{}}",
  "comparisonDirection": "old-to-new",
  "severityFilter": ["high", "warning", "info"],
  "maxFindings": 200
}
```

### Comparison direction

| Direction | Baseline | Target | Request check | Response check |
|---|---|---|---|---|
| `old-to-new` | oldSpec | newSpec | Previously valid requests must remain accepted | Target responses must fit baseline client expectations |
| `new-to-old` | newSpec | oldSpec | Requests built for newSpec checked against oldSpec | oldSpec responses checked against newSpec client expectations |

For example, adding an enum value to a **request** is an expansion and normally safe under the enum rule; adding an enum value to a **response** can break an exhaustive client. Reversing direction reverses these roles. `old_value`, `new_value` and evidence pointers always refer to the original input documents, even in reverse mode.

### Rules and severity

`high` = breaking under a documented rule; `warning` = manual review needed; `info` = nonbreaking under the evaluated rule. These labels are not an exploit severity rating.

| Contract area | Implemented rule |
|---|---|
| Operations | Removed path/method: high. Added path/method: info. Paths are matched literally; a renamed template is treated as removal/addition. |
| Parameters | Merge path-level and operation-level parameters by location/name; operation overrides path-level. Added required parameter or optional→required: high. Added optional parameter: info. Removal: warning because unknown-parameter handling is not specified. |
| Request bodies/media | Optional→required: high. Removed accepted media type: high; added request media: info. |
| Types/nullability | Requests must not shrink accepted types; responses must not expand possible types. Integer is a subset of number. No coercion is assumed. |
| Enums | Requests must retain baseline values; responses must not add values outside baseline enum. Unconstrained and constrained enums are distinguished. |
| Object properties | Requests must not gain required fields; responses must preserve guaranteed fields. Project readOnly out of requests and writeOnly out of responses. Removed optional response property: warning. Adding a request property to a previously open object: warning because it can constrain previously arbitrary values. |
| Additional properties | Boolean open/closed changes use directional variance. Schema-valued policies and property transitions are recursively compared. Mixed boolean/schema policy changes: warning; this release does not prove all additional-property language relationships. |
| Bounds/arrays | minimum/maximum, length/item/property limits, exclusive bounds, uniqueItems and recursive item schemas use directional variance. Interacting constraints can require manual review. |
| Responses | Compare matching response media and schemas; response status additions/removals, status ranges/default coverage and response-header availability: warning. |
| Security | Apply global/operation override including empty security. Alternatives are OR; schemes/scopes within each alternative are AND. Each baseline credential alternative must still satisfy a target alternative. Authentication scheme definition changes: high. |
| Serialization/codegen | Parameter style/explode/allowReserved/allowEmptyValue, media encoding, format/pattern/multipleOf, operationId and read/write annotation changes: warning. |
| Composition/unsupported | allOf/oneOf/anyOf/not/discriminator and unrecognized schema keywords: warning even when unchanged. Callbacks and operation/path server routing also require review. |

Local `$ref` values are resolved in memory with original-document evidence. Recursive object schemas are compared using active reference pairs and bounded traversal. Pure chains of references with no concrete schema, missing references and external references are rejected. OpenAPI 3.0 reference siblings are ignored, consistent with Reference Object behavior.

### Inputs

| Field | Meaning |
|---|---|
| oldSpec / newSpec | Inline JSON/YAML document text, or a safe HTTPS document URL |
| oldSpecUrl / newSpecUrl | Alternate HTTPS source; do not also provide the corresponding inline value |
| comparisonDirection | old-to-new (default) or new-to-old |
| severityFilter | Nonempty array of high, warning, info; default all three |
| maxFindings | 1–1000; default 200 |

### Outputs

The default Dataset contains findings with:

`change_id, path, method, change_type, severity, compatibility_direction, old_value, new_value, explanation, source_pointer`

Additional `old_exists/new_exists` flags distinguish a missing value from JSON null. `source_pointer` has separate `old` and `new` JSON pointers. A pointer on the absent side identifies where the value would occur; it need not exist. Resolved references point to their target definitions. Large evidence values over 4,096 characters are replaced with a marked preview; use the pointer and original document for full detail.

Key-value store exports:

- `OUTPUT`: filtered and limited findings in JSON, including an empty array for a clean comparison.
- `OUTPUT.csv`: same rows; nested values encoded as JSON, spreadsheet formula prefixes escaped.
- `SUMMARY`: counts **before** filtering/limiting, assessment, hashes, rule version, duration and truncation status.
- `REPORT.md`: human-readable summary report.

The limit caps returned rows, not billed events. Counts still cover the completed supported-rule analysis. Returned rows are deterministic; selection is by contract traversal, then the selected rows are sorted by severity. A filter can hide all rows while the summary still reports breaking changes. Always check `SUMMARY`.

### Security and limits

- 2 MiB per UTF-8 document; maximum tree depth 80; 100,000 document-tree nodes.
- At most 2,000 operations per document and 30,000 schema-pair comparisons.
- 120-second analysis deadline, 100-second comparison deadline, 300-second default platform timeout.
- SafeLoader-derived YAML parser: no object constructors, aliases or merge keys; duplicate keys rejected. Boolean resolution limited to true/false; timestamp-like scalars stay strings. Integer mapping keys are normalized to strings for common YAML response codes. Quote ambiguous YAML scalars.
- HTTPS port 443 only, no credentials, query string or fragment. Only globally routable public IPs. All DNS results checked and the connection pinned to a checked IP with verified TLS and original hostname SNI.
- Redirects and compressed downloads refused; download deadline 15 seconds per document.
- No external `$ref` fetches. Bundle multi-file documents before submitting.
- **The Actor never calls endpoints, servers, authentication URLs or callbacks described by the contracts.** Only explicitly provided document URLs are downloaded.
- No proxy, AI model or third-party comparison API is used.

Input is stored in your Apify run and output contains contract excerpts. Use Apify access controls and avoid submitting credentials or secrets embedded in documents.

### Scope and limitations

This is a **static, explicitly bounded rule engine**, not a complete OpenAPI validator, a formal proof of language inclusion, or a guarantee of actual service behavior. Structural validation rejects malformed supported inputs, but not every OpenAPI semantic rule is validated. OpenAPI 3.1, Swagger 2, external references and arbitrary JSON Schema dialects are unsupported. Documentation-only changes and unused component changes are generally omitted. Component changes matter when reachable from compared operations. Complex composition always produces review warnings; no overall runtime compatibility guarantee is made. A clean result means no breaking change was found **under these supported rules**, not that every client or deployment will work.

### Pricing details

The only billable event is `comparison-completed` at **$0.15**, configured once per run. There are no start, per-finding or per-Dataset-row charges. Exports are produced before the event. Retry charging uses an idempotency key plus the platform's one-time-event setting; a resumed completed run reuses its checkpoint. Set a spending limit of at least $0.15. Platform usage is included in the event price. A new independently started comparison run is charged separately.

### Dependencies and verification sources

Checked 2026-11-06:

- [OpenAPI 3.0.4 specification](https://spec.openapis.org/oas/v3.0.4.html)
- [Apify Python SDK 4.2 documentation](https://docs.apify.com/sdk/python/docs/concepts/pay-per-event) — Apache-2.0.
- [PyYAML 6.0.3 project and license](https://pypi.org/project/PyYAML/6.0.3/) — MIT; [SafeLoader documentation](https://pyyaml.org/wiki/PyYAMLDocumentation).
- [Apify pay-per-event pricing](https://docs.apify.com/actors/monetize/pay-per-event).
- [Swagger Petstore official sample](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml) used for real contract testing.

Third-party license texts and the pinned dependency inventory are included in the build. The comparison engine is original AFK Digital code.

# Actor input Schema

## `oldSpec` (type: `string`):

JSON/YAML text for OpenAPI 3.0.0–3.0.4, or safe HTTPS document URL. Clear this if using the separate URL field. Max 2 MiB.

## `oldSpecUrl` (type: `string`):

Optional alternative to inline spec. Public HTTPS port 443, no query/fragment/credentials/redirects. Clear corresponding inline field.

## `newSpec` (type: `string`):

JSON/YAML text for OpenAPI 3.0.0–3.0.4, or safe HTTPS document URL. Clear this if using the separate URL field. Max 2 MiB.

## `newSpecUrl` (type: `string`):

Optional alternative to inline spec. Public HTTPS port 443, no query/fragment/credentials/redirects. Clear corresponding inline field.

## `comparisonDirection` (type: `string`):

old-to-new checks existing clients against the new service; new-to-old reverses baseline and target.

## `severityFilter` (type: `array`):

Nonempty list. high = breaking; warning = manual review; info = nonbreaking under supported rules. Summary counts ignore this filter.

## `maxFindings` (type: `integer`):

Output cap only; total counts and truncation are reported. Finding count does not change the $0.15 comparison price.

## Actor input object example

```json
{
  "oldSpec": "{\n  \"openapi\": \"3.0.3\",\n  \"info\": {\n    \"title\": \"Order API\",\n    \"version\": \"1.0\"\n  },\n  \"paths\": {\n    \"/orders/{id}\": {\n      \"parameters\": [\n        {\n          \"name\": \"id\",\n          \"in\": \"path\",\n          \"required\": true,\n          \"schema\": {\n            \"type\": \"string\"\n          }\n        }\n      ],\n      \"get\": {\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"type\": \"object\",\n                  \"required\": [\n                    \"id\",\n                    \"status\"\n                  ],\n                  \"properties\": {\n                    \"id\": {\n                      \"type\": \"string\"\n                    },\n                    \"status\": {\n                      \"type\": \"string\",\n                      \"enum\": [\n                        \"open\",\n                        \"paid\"\n                      ]\n                    }\n                  }\n                }\n              }\n            }\n          }\n        }\n      },\n      \"post\": {\n        \"requestBody\": {\n          \"required\": true,\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"type\": \"object\",\n                \"required\": [\n                  \"status\"\n                ],\n                \"properties\": {\n                  \"status\": {\n                    \"type\": \"string\",\n                    \"enum\": [\n                      \"open\",\n                      \"paid\"\n                    ]\n                  }\n                }\n              }\n            }\n          }\n        },\n        \"responses\": {\n          \"204\": {\n            \"description\": \"Updated\"\n          }\n        }\n      }\n    }\n  }\n}",
  "newSpec": "{\n  \"openapi\": \"3.0.3\",\n  \"info\": {\n    \"title\": \"Order API\",\n    \"version\": \"2.0\"\n  },\n  \"paths\": {\n    \"/orders/{id}\": {\n      \"parameters\": [\n        {\n          \"name\": \"id\",\n          \"in\": \"path\",\n          \"required\": true,\n          \"schema\": {\n            \"type\": \"string\"\n          }\n        }\n      ],\n      \"get\": {\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"type\": \"object\",\n                  \"required\": [\n                    \"id\",\n                    \"status\"\n                  ],\n                  \"properties\": {\n                    \"id\": {\n                      \"type\": \"string\"\n                    },\n                    \"status\": {\n                      \"type\": \"string\",\n                      \"enum\": [\n                        \"open\",\n                        \"paid\",\n                        \"refunded\"\n                      ]\n                    }\n                  }\n                }\n              }\n            }\n          }\n        },\n        \"parameters\": [\n          {\n            \"name\": \"X-Tenant\",\n            \"in\": \"header\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          }\n        ]\n      },\n      \"post\": {\n        \"requestBody\": {\n          \"required\": true,\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"type\": \"object\",\n                \"required\": [\n                  \"status\"\n                ],\n                \"properties\": {\n                  \"status\": {\n                    \"type\": \"string\",\n                    \"enum\": [\n                      \"open\"\n                    ]\n                  }\n                }\n              }\n            }\n          }\n        },\n        \"responses\": {\n          \"202\": {\n            \"description\": \"Queued\"\n          }\n        }\n      }\n    },\n    \"/health\": {\n      \"get\": {\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Healthy\"\n          }\n        }\n      }\n    }\n  }\n}",
  "comparisonDirection": "old-to-new",
  "severityFilter": [
    "high",
    "warning",
    "info"
  ],
  "maxFindings": 200
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `json` (type: `string`):

No description

## `csv` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `report` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "oldSpec": `{
  "openapi": "3.0.3",
  "info": {
    "title": "Order API",
    "version": "1.0"
  },
  "paths": {
    "/orders/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "status"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "open",
                        "paid"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "status"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "open",
                      "paid"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Updated"
          }
        }
      }
    }
  }
}`,
    "newSpec": `{
  "openapi": "3.0.3",
  "info": {
    "title": "Order API",
    "version": "2.0"
  },
  "paths": {
    "/orders/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "status"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "open",
                        "paid",
                        "refunded"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-Tenant",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "post": {
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "status"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "open"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Queued"
          }
        }
      }
    },
    "/health": {
      "get": {
        "responses": {
          "200": {
            "description": "Healthy"
          }
        }
      }
    }
  }
}`,
    "severityFilter": [
        "high",
        "warning",
        "info"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("afkdigital/openapi-breaking-change-detector").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "oldSpec": """{
  \"openapi\": \"3.0.3\",
  \"info\": {
    \"title\": \"Order API\",
    \"version\": \"1.0\"
  },
  \"paths\": {
    \"/orders/{id}\": {
      \"parameters\": [
        {
          \"name\": \"id\",
          \"in\": \"path\",
          \"required\": true,
          \"schema\": {
            \"type\": \"string\"
          }
        }
      ],
      \"get\": {
        \"responses\": {
          \"200\": {
            \"description\": \"OK\",
            \"content\": {
              \"application/json\": {
                \"schema\": {
                  \"type\": \"object\",
                  \"required\": [
                    \"id\",
                    \"status\"
                  ],
                  \"properties\": {
                    \"id\": {
                      \"type\": \"string\"
                    },
                    \"status\": {
                      \"type\": \"string\",
                      \"enum\": [
                        \"open\",
                        \"paid\"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      },
      \"post\": {
        \"requestBody\": {
          \"required\": true,
          \"content\": {
            \"application/json\": {
              \"schema\": {
                \"type\": \"object\",
                \"required\": [
                  \"status\"
                ],
                \"properties\": {
                  \"status\": {
                    \"type\": \"string\",
                    \"enum\": [
                      \"open\",
                      \"paid\"
                    ]
                  }
                }
              }
            }
          }
        },
        \"responses\": {
          \"204\": {
            \"description\": \"Updated\"
          }
        }
      }
    }
  }
}""",
    "newSpec": """{
  \"openapi\": \"3.0.3\",
  \"info\": {
    \"title\": \"Order API\",
    \"version\": \"2.0\"
  },
  \"paths\": {
    \"/orders/{id}\": {
      \"parameters\": [
        {
          \"name\": \"id\",
          \"in\": \"path\",
          \"required\": true,
          \"schema\": {
            \"type\": \"string\"
          }
        }
      ],
      \"get\": {
        \"responses\": {
          \"200\": {
            \"description\": \"OK\",
            \"content\": {
              \"application/json\": {
                \"schema\": {
                  \"type\": \"object\",
                  \"required\": [
                    \"id\",
                    \"status\"
                  ],
                  \"properties\": {
                    \"id\": {
                      \"type\": \"string\"
                    },
                    \"status\": {
                      \"type\": \"string\",
                      \"enum\": [
                        \"open\",
                        \"paid\",
                        \"refunded\"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        \"parameters\": [
          {
            \"name\": \"X-Tenant\",
            \"in\": \"header\",
            \"required\": true,
            \"schema\": {
              \"type\": \"string\"
            }
          }
        ]
      },
      \"post\": {
        \"requestBody\": {
          \"required\": true,
          \"content\": {
            \"application/json\": {
              \"schema\": {
                \"type\": \"object\",
                \"required\": [
                  \"status\"
                ],
                \"properties\": {
                  \"status\": {
                    \"type\": \"string\",
                    \"enum\": [
                      \"open\"
                    ]
                  }
                }
              }
            }
          }
        },
        \"responses\": {
          \"202\": {
            \"description\": \"Queued\"
          }
        }
      }
    },
    \"/health\": {
      \"get\": {
        \"responses\": {
          \"200\": {
            \"description\": \"Healthy\"
          }
        }
      }
    }
  }
}""",
    "severityFilter": [
        "high",
        "warning",
        "info",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("afkdigital/openapi-breaking-change-detector").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "oldSpec": "{\\n  \\"openapi\\": \\"3.0.3\\",\\n  \\"info\\": {\\n    \\"title\\": \\"Order API\\",\\n    \\"version\\": \\"1.0\\"\\n  },\\n  \\"paths\\": {\\n    \\"/orders/{id}\\": {\\n      \\"parameters\\": [\\n        {\\n          \\"name\\": \\"id\\",\\n          \\"in\\": \\"path\\",\\n          \\"required\\": true,\\n          \\"schema\\": {\\n            \\"type\\": \\"string\\"\\n          }\\n        }\\n      ],\\n      \\"get\\": {\\n        \\"responses\\": {\\n          \\"200\\": {\\n            \\"description\\": \\"OK\\",\\n            \\"content\\": {\\n              \\"application/json\\": {\\n                \\"schema\\": {\\n                  \\"type\\": \\"object\\",\\n                  \\"required\\": [\\n                    \\"id\\",\\n                    \\"status\\"\\n                  ],\\n                  \\"properties\\": {\\n                    \\"id\\": {\\n                      \\"type\\": \\"string\\"\\n                    },\\n                    \\"status\\": {\\n                      \\"type\\": \\"string\\",\\n                      \\"enum\\": [\\n                        \\"open\\",\\n                        \\"paid\\"\\n                      ]\\n                    }\\n                  }\\n                }\\n              }\\n            }\\n          }\\n        }\\n      },\\n      \\"post\\": {\\n        \\"requestBody\\": {\\n          \\"required\\": true,\\n          \\"content\\": {\\n            \\"application/json\\": {\\n              \\"schema\\": {\\n                \\"type\\": \\"object\\",\\n                \\"required\\": [\\n                  \\"status\\"\\n                ],\\n                \\"properties\\": {\\n                  \\"status\\": {\\n                    \\"type\\": \\"string\\",\\n                    \\"enum\\": [\\n                      \\"open\\",\\n                      \\"paid\\"\\n                    ]\\n                  }\\n                }\\n              }\\n            }\\n          }\\n        },\\n        \\"responses\\": {\\n          \\"204\\": {\\n            \\"description\\": \\"Updated\\"\\n          }\\n        }\\n      }\\n    }\\n  }\\n}",
  "newSpec": "{\\n  \\"openapi\\": \\"3.0.3\\",\\n  \\"info\\": {\\n    \\"title\\": \\"Order API\\",\\n    \\"version\\": \\"2.0\\"\\n  },\\n  \\"paths\\": {\\n    \\"/orders/{id}\\": {\\n      \\"parameters\\": [\\n        {\\n          \\"name\\": \\"id\\",\\n          \\"in\\": \\"path\\",\\n          \\"required\\": true,\\n          \\"schema\\": {\\n            \\"type\\": \\"string\\"\\n          }\\n        }\\n      ],\\n      \\"get\\": {\\n        \\"responses\\": {\\n          \\"200\\": {\\n            \\"description\\": \\"OK\\",\\n            \\"content\\": {\\n              \\"application/json\\": {\\n                \\"schema\\": {\\n                  \\"type\\": \\"object\\",\\n                  \\"required\\": [\\n                    \\"id\\",\\n                    \\"status\\"\\n                  ],\\n                  \\"properties\\": {\\n                    \\"id\\": {\\n                      \\"type\\": \\"string\\"\\n                    },\\n                    \\"status\\": {\\n                      \\"type\\": \\"string\\",\\n                      \\"enum\\": [\\n                        \\"open\\",\\n                        \\"paid\\",\\n                        \\"refunded\\"\\n                      ]\\n                    }\\n                  }\\n                }\\n              }\\n            }\\n          }\\n        },\\n        \\"parameters\\": [\\n          {\\n            \\"name\\": \\"X-Tenant\\",\\n            \\"in\\": \\"header\\",\\n            \\"required\\": true,\\n            \\"schema\\": {\\n              \\"type\\": \\"string\\"\\n            }\\n          }\\n        ]\\n      },\\n      \\"post\\": {\\n        \\"requestBody\\": {\\n          \\"required\\": true,\\n          \\"content\\": {\\n            \\"application/json\\": {\\n              \\"schema\\": {\\n                \\"type\\": \\"object\\",\\n                \\"required\\": [\\n                  \\"status\\"\\n                ],\\n                \\"properties\\": {\\n                  \\"status\\": {\\n                    \\"type\\": \\"string\\",\\n                    \\"enum\\": [\\n                      \\"open\\"\\n                    ]\\n                  }\\n                }\\n              }\\n            }\\n          }\\n        },\\n        \\"responses\\": {\\n          \\"202\\": {\\n            \\"description\\": \\"Queued\\"\\n          }\\n        }\\n      }\\n    },\\n    \\"/health\\": {\\n      \\"get\\": {\\n        \\"responses\\": {\\n          \\"200\\": {\\n            \\"description\\": \\"Healthy\\"\\n          }\\n        }\\n      }\\n    }\\n  }\\n}",
  "severityFilter": [
    "high",
    "warning",
    "info"
  ]
}' |
apify call afkdigital/openapi-breaking-change-detector --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,afkdigital/openapi-breaking-change-detector"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/JwJI12bTTu8iMRjlt/builds/UMIGdcPC6TI8lmhS1/openapi.json
