---
title: Rule Catalogue
description: Complete catalogue of all 45 Specdiff rules — JSON Schema rules, OpenAPI-only rules, direction-dependent severity, and how to configure overrides.
url: https://pr-1-ff84656b4b8a.thally.app/specdiff/rules
---

# Rule Catalogue

Complete catalogue of all 45 Specdiff rules — JSON Schema rules, OpenAPI-only rules, direction-dependent severity, and how to configure overrides.

Specdiff ships 45 built-in rules for detecting changes between JSON Schema and OpenAPI documents. Each rule has a code, a default severity, and a description. Rules are split into two groups: 24 rules that apply to JSON Schema (and also fire inside OpenAPI schemas), and 21 rules that apply only to OpenAPI documents.

## Severity levels

Every change detected by Specdiff is assigned one of three severity levels:

- **breaking** -- A change that will break existing consumers. Examples: removing an endpoint, adding a required property, or tightening a constraint.
- **warning** -- A change that may affect consumers but is not guaranteed to break them. Examples: changing a format, modifying a default value, or deprecating a field.
- **info** -- A change that is safe for consumers. Examples: adding an optional property, relaxing a constraint, or updating a description.

## JSON Schema rules

These 24 rules apply to standalone JSON Schema documents and also fire when comparing schemas embedded inside OpenAPI documents.

| Code | Default severity | Description |
|---|---|---|
| `type-changed` | breaking | The `type` keyword was changed |
| `property-removed` | breaking | A property was removed from the schema |
| `property-added` | info | A new property was added to the schema |
| `required-property-added` | breaking | A new property that is also marked as required was added |
| `required-added` | breaking | An entry was added to the `required` array |
| `required-removed` | info | An entry was removed from the `required` array |
| `enum-value-removed` | breaking | A value was removed from an `enum` |
| `enum-value-added` | info | A value was added to an `enum` |
| `additional-properties-restricted` | breaking | `additionalProperties` was tightened (e.g. set to `false`) |
| `additional-properties-relaxed` | info | `additionalProperties` was relaxed (e.g. set to `true`) |
| `constraint-tightened` | breaking | A numeric, string, or array constraint was made stricter |
| `constraint-relaxed` | info | A numeric, string, or array constraint was made looser |
| `format-changed` | warning | The `format` keyword was changed |
| `nullable-removed` | breaking | Nullability was removed (nullable set to false or null removed from type) |
| `nullable-added` | info | Nullability was added (nullable set to true or null added to type) |
| `default-changed` | warning | The `default` value was changed |
| `description-changed` | info | The `description` was changed |
| `composition-variant-removed` | breaking | A variant was removed from `allOf`, `anyOf`, or `oneOf` |
| `composition-variant-added` | info | A variant was added to `allOf`, `anyOf`, or `oneOf` |
| `items-changed` | breaking | The `items` or `prefixItems` schema was changed |
| `const-changed` | breaking | The `const` value was changed |
| `deprecated-added` | warning | The `deprecated` flag was added |
| `readonly-writeonly-changed` | warning | The `readOnly` or `writeOnly` flags were changed |
| `unresolved-ref` | warning | A `$ref` could not be resolved (remote or missing reference) |

## OpenAPI-only rules

These 21 rules apply only when comparing OpenAPI 3.x documents.

| Code | Default severity | Description |
|---|---|---|
| `endpoint-removed` | breaking | An entire path was removed |
| `endpoint-added` | info | A new path was added |
| `operation-removed` | breaking | An operation (HTTP method) was removed from a path |
| `operation-added` | info | A new operation was added to a path |
| `operation-id-changed` | warning | The `operationId` of an operation was changed |
| `parameter-removed` | breaking | A parameter was removed from an operation |
| `required-parameter-added` | breaking | A new required parameter was added |
| `optional-parameter-added` | info | A new optional parameter was added |
| `parameter-required-changed` | breaking | A parameter's `required` flag was changed |
| `request-body-required-added` | breaking | The request body was made required |
| `request-body-media-type-removed` | breaking | A media type was removed from the request body |
| `request-body-media-type-added` | info | A new media type was added to the request body |
| `response-removed` | breaking | A response status code was removed |
| `response-added` | info | A new response status code was added |
| `response-media-type-removed` | breaking | A media type was removed from a response |
| `response-media-type-added` | info | A new media type was added to a response |
| `security-requirement-added` | breaking | A security requirement was added to an operation |
| `security-requirement-removed` | info | A security requirement was removed from an operation |
| `server-removed` | warning | A server entry was removed |
| `server-added` | info | A new server entry was added |
| `deprecated-operation` | warning | An operation was marked as deprecated |

## Direction-dependent severity

Twelve rules change their severity depending on whether the schema appears in a request body, a response body, or a neutral context. When diffing OpenAPI documents, Specdiff automatically determines direction from position. When diffing standalone JSON Schema documents, you can set the direction via `DiffOptions.direction` (default: `"neutral"`).

| Rule | request | response | neutral (default) |
|---|---|---|---|
| `required-added` | breaking | info | breaking |
| `required-property-added` | breaking | info | breaking |
| `required-removed` | info | breaking | info |
| `enum-value-added` | info | warning | info |
| `enum-value-removed` | breaking | info | breaking |
| `constraint-tightened` | breaking | info | breaking |
| `constraint-relaxed` | info | warning | info |
| `additional-properties-restricted` | breaking | info | breaking |
| `nullable-added` | info | breaking | info |
| `nullable-removed` | breaking | info | breaking |
| `composition-variant-added` | info | warning | info |
| `composition-variant-removed` | breaking | info | breaking |

All rules not listed in this table keep their default severity regardless of direction. For example, `property-removed`, `type-changed`, and `const-changed` are breaking in every direction.

## Severity overrides

You can override the severity of any rule using the `overrides` option in `DiffOptions`:

```ts
import { diffDocuments } from "@specdiff/core";

const result = diffDocuments(before, after, {
  overrides: {
    "format-changed": "breaking",
    "default-changed": "info",
  },
});
```

Overrides replace the severity for all changes produced by that rule, regardless of direction. To suppress a rule entirely, use `ignoreRules` instead:

```ts
const result = diffDocuments(before, after, {
  ignoreRules: ["description-changed", "deprecated-added"],
});
```

You can also filter out changes under specific JSON Pointer paths using `ignorePaths`:

```ts
const result = diffDocuments(before, after, {
  ignorePaths: ["#/paths/~1internal"],
});
```

## Inspecting rules programmatically

Use the rule functions from `@specdiff/core` to look up rule details at runtime:

```ts
import { explainRule, listRules, isRuleCode, severityFor } from "@specdiff/core";

// Get details for a single rule
const info = explainRule("required-added");
// info.defaultSeverity === "breaking"

// Check if a string is a valid rule code
isRuleCode("required-added"); // true
isRuleCode("made-up-rule");   // false

// Get direction-aware severity
severityFor("required-added", "response"); // "info"
severityFor("required-added", "request");  // "breaking"

// List all 45 rules
const allRules = listRules();
```