Spotlight Rules · API Governance Rules

Spotlight Rules API Rules

Spectral linting rules defining API design standards and conventions for Spotlight Rules.

332 Rules error 223 warn 95 info 5
View Rules File View on GitHub

Rule Categories

array avoid boolean cache channel collection component contact created createdby custom default delete deletedby description document error example examples filter fingerprint gateway get head header headers id info integer jwt leanix license limit location message messages modified modifiedby name no number oauth object ok operation operations optional options orgid pagination parameter parameters patch path paths post prefer properties property put query ref request requestid require required response responses schema server servers sort spec status string success tag tags throttled uri use version write

Rules

warn
path-segments-kebab-case
All YAML/JSON paths MUST follow kebab-case. It requires the targeted value to match the pattern `^/([a-z0-9]+(-[a-z0-9]+)*)?(/[a-z0-9]+(-[a-z0-9]+)*|/{.+})*$` (evaluated at `$.paths[*]~`). Severity: warn.
$.paths[*]~
warn
path-parameters-camel-case
Path parameters MUST follow camelCase. It requires the targeted value to match the pattern `^[a-z][a-zA-Z0-9]+$` (evaluated at `$..parameters[?(@.in == 'path')].name`). Severity: warn.
$..parameters[?(@.in == 'path')].name
error
schema-definitions-camel-case
All YAML/JSON definitions MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`. It requires the targeted value to match the pattern `/^[a-z$_]{1}[A-Z09$_]*/` (evaluated at `$.definitions[*]~`). Severity: error.
$.definitions[*]~
error
schema-properties-camel-case
All JSON Schema properties MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`. It requires the targeted value to match the pattern `/^[a-z$_]{1}[A-Z09$_]*/` (evaluated at `$.definitions..properties[*]~`). Severity: error.
$.definitions..properties[*]~
error
header-names-hyphenated-pascal-case
All `HTTP` headers MUST use `Hyphenated-Pascal-Case` notation. It requires the targeted value to match the pattern `/^([A-Z][a-z0-9]-)*([A-Z][a-z0-9])+/` (evaluated at `$..parameters[?(@.in == 'header')].name`). Severity: error.
$..parameters[?(@.in == 'header')].name
error
request-support-json-media-type
Every request MUST support `application/json` media type. It requires the targeted value to be absent or empty (evaluated at `$.paths.[*].requestBody.content[?(@property.indexOf('json') === -1)]^`). Severity: error.
$.paths.[*].requestBody.content[?(@property.indexOf('json') === -1)]^
error
require-https-servers
ALL requests MUST go through `https` protocol only. It requires the targeted value to match the pattern `/^https:/` (evaluated at `$.servers..url`). Severity: error.
$.servers..url
error
success-response-use-hal-json
All success responses MUST be of media type `application/hal+json`. It requires the targeted value to be one of ["application/hal+json"] (evaluated at `$.paths..responses[?( @property >= 201 && @property < 300 && @property != 204)].content[*]~`). Severity: error.
$.paths..responses[?( @property >= 201 && @property < 300 && @property != 204)].content[*]~
error
ok-response-use-hal-or-problem-json
All success responses MUST be of media type `application/hal+json` or `application/problem+json`. It requires the targeted value to be one of ["application/hal+json","application/problem+json"] (evaluated at `$.paths..responses[?( @property == 200 )].content[*]~`). Severity: error.
$.paths..responses[?( @property == 200 )].content[*]~
error
success-response-match-hal-schema
All success responses MUST follow `application/hal+json` schema. It validates the `schema` field against a JSON Schema (evaluated at `$.paths..responses[?( @property == 200 && @property < 300 && @property != 204)].content[?(@property === "application/hal+json")]`). Severity: error.
$.paths..responses[?( @property == 200 && @property < 300 && @property != 204)].content[?(@property === "application/hal+json")]
error
get-no-request-body
GET requests MUST NOT have a request body. It requires the targeted value to be absent or empty (evaluated at `$.paths[*].get.requestBody`). Severity: error.
$.paths[*].get.requestBody
error
post-not-for-retrieval
POST requests SHOULD NOT be used for retrieving information. Use GET instead. It requires the `summary` field not to match `(retrieve|fetch|get|read)` (evaluated at `$.paths[*].post`). Severity: error.
$.paths[*].post
error
put-require-request-body
PUT requests MUST have a request body. It requires the `requestBody` field to be present and non-empty (evaluated at `$.paths[*].put`). Severity: error.
$.paths[*].put
error
delete-no-request-body
DELETE requests MUST NOT have a request body. It requires the targeted value to be absent or empty (evaluated at `$.paths[*].delete.requestBody`). Severity: error.
$.paths[*].delete.requestBody
warn
paths-no-verbs
API paths MUST be resource-focused and MUST NOT include verbs like 'get', 'update', 'create', or 'delete'. It requires the targeted value not to match `/\b(get|update|create|delete|fetch|retrieve)\b/` (evaluated at `$.paths[*]~`). Severity: warn.
$.paths[*]~
warn
require-realistic-examples
API design SHOULD include real-like examples for request and response definitions. It requires the `example` field to be present and non-empty (evaluated at `$..[?(@.example || @.examples)]`). Severity: warn.
$..[?(@.example || @.examples)]
error
version-semantic-and-stable
The API contract MUST have a stable version and MUST follow semantic versioning (e.g., '1.0.0'). Words like 'SNAPSHOT' or 'RELEASE' are not allowed. It requires the targeted value to match the pattern `^(?!.*\b(SNAPSHOT|RELEASE)\b)(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$` (evaluated at `$.info.version`). Severity: error.
$.info.version
error
require-root-security
The API contract MUST include a 'security' section at the root level. It requires the `security` field to be present and non-empty (evaluated at `$`). Severity: error.
$
error
require-components-section
The API contract MUST include a 'components' section. It requires the `components` field to be present and non-empty (evaluated at `$`). Severity: error.
$
error
require-security-schemes
The API contract MUST include a 'securitySchemes' subsection under the 'components' section. It requires the `securitySchemes` field to be present and non-empty (evaluated at `$.components`). Severity: error.
$.components
warn
info-require-leanix-id
The API contract SHOULD include a custom field 'x-leanixid' in the 'info' section. It requires the `x-leanixid` field to be present and non-empty (evaluated at `$.info`). Severity: warn.
$.info
warn
leanix-id-valid-uuid
The API contract SHOULD include a custom field 'x-leanixid' containing a valid UUID. It requires the targeted value to match the pattern `^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$` (evaluated at `$.info.x-leanixid`). Severity: warn.
$.info.x-leanixid
warn
info-require-gateway
The API contract SHOULD include a custom field 'x-gateway' in the 'info' section. It requires the `x-gateway` field to be present and non-empty (evaluated at `$.info`). Severity: warn.
$.info
warn
gateway-from-allowed-list
The 'x-gateway' property, if present, MUST have a value in the enumeration: kong, nginx, aws, akamai, sap, other. It requires the `x-gateway` field to be one of ["kong","nginx","aws","akamai","sap","other"] (evaluated at `$`). Severity: warn.
$
hint
responses-include-hypermedia-links
The API contract MAY include hypermedia links to represent the state of resources and be navigable. It requires the `links` field to be present and non-empty (evaluated at `$.paths[*][*].responses[*]`). Severity: hint.
$.paths[*][*].responses[*]
error
uri-versioning-single-version
CAN use correct URI versioning [115a]. It requires the targeted value to match the pattern `^((?!.*\/v\d+(\/.*)?\/v\d+)\/.*)$` (evaluated at `$.paths.*~`). Severity: error.
$.paths.*~
error
property-names-camel-case
MUST property names must be ASCII camelCase [118a]. It requires the targeted value to match the pattern `^[a-z]+((\d)|([A-Z0-9][a-z0-9]+))*([A-Z])?$` (evaluated at `$.paths.*.*[responses,requestBody]..content..schema..properties.*~`). Severity: error.
$.paths.*.*[responses,requestBody]..content..schema..properties.*~
error
use-standard-status-codes
MUST use standard HTTP status codes [150a]. It requires the targeted value to be one of ["100","101","200","201","202","203","204","205","206","207","300","301","302","303","304","305","307","400","401","402","403","404","405","406","407","408","409","410","411","412","413","414","415","416","417","422","423","426","428","429","431","500","501","502","503","504","505","511","default"] (evaluated at `$.paths.*.*.responses.*~`). Severity: error.
$.paths.*.*.responses.*~
warn
prefer-400-over-422
MUST use standard HTTP status codes [150a]. It requires the `422` field to be defined (evaluated at `$.paths.*.*.responses.422`). Severity: warn.
$.paths.*.*.responses.422
warn
operation-well-understood-status-codes
MUST use standard HTTP status codes [150]. It applies a custom validation to the targeted value (evaluated at `$.paths.*`). Severity: warn.
$.paths.*
error
require-tracing-headers
MUST use b3 or w3c tracing [233a]. It applies a custom validation to the targeted value (evaluated at `$.paths.*`). Severity: error.
$.paths.*
error
info-require-audience
MUST provide API audience [219]. It requires the `x-audience` field to be present and non-empty, and requires the `x-audience` field to match the pattern `^(team-internal|domain-internal|company-internal|external-partner|external-public)$` (evaluated at `$.info`). Severity: error.
$.info
error
query-parameters-camel-case
MUST query parameter names must be ASCII camelCase [130a]. It requires the targeted value to match the pattern `^[a-z]+((\d)|([A-Z0-9][a-z0-9]+))*([A-Z])?$` (evaluated at `$.paths.*.*.parameters[?(@ && @.in=='query')].name`). Severity: error.
$.paths.*.*.parameters[?(@ && @.in=='query')].name
error
responses-include-ratelimit-headers
Response must include ratelimit-x headers. It requires the `headers.ratelimit-limit` field to be present and non-empty, and requires the `headers.ratelimit-remaining` field to be present and non-empty, and requires the `headers.ratelimit-reset` field to be present and non-empty (evaluated at `$..responses.*`). Severity: error.
$..responses.*
error
properties-require-examples
Object properties must include examples. It applies a custom validation to the targeted value (evaluated at `$..properties..properties.*`). Severity: error.
$..properties..properties.*
error
parameters-require-examples
Parameters must include examples. It requires exactly one of ["example","examples"] to be present (evaluated at `$..parameters.*`). Severity: error.
$..parameters.*
error
headers-require-examples
Headers must include examples. It applies a custom validation to the targeted value (evaluated at `$..headers.*`). Severity: error.
$..headers.*
error
operations-use-ref
Endpoint must be a $ref. It requires the `$ref` field to be present and non-empty (evaluated at `$.paths.*.*`). Severity: error.
$.paths.*.*
error
paths-include-version
Path must include the version. It requires the targeted value to match the pattern `^(/v[12]/.*|/api/v[12]/.*)$` (evaluated at `$.paths[?(@property!='/')]~`). Severity: error.
$.paths[?(@property!='/')]~
error
operation-ref-resource-file
Endpoint must a $ref to a file in resources/. It requires the targeted value to match the pattern `^resources/.*yml$` (evaluated at `$.paths.*.$ref`). Severity: error.
$.paths.*.$ref
error
responses-define-401
Responses should contain common response - 401 (unauthorized). It requires the `401` field to be present and non-empty (evaluated at `$.paths..responses`). Severity: error.
$.paths..responses
error
responses-define-404
Responses should contain common response - 404 (not found). It requires the `404` field to be present and non-empty (evaluated at `$.paths[?(@property.match(/.*\/{.*}.*/))]..responses`). Severity: error.
$.paths[?(@property.match(/.*\/{.*}.*/))]..responses
error
responses-define-429
Responses should contain common response - 429 (too many requests). It requires the `429` field to be present and non-empty (evaluated at `$.paths..responses`). Severity: error.
$.paths..responses
error
responses-define-500
Responses should contain common response - 500 (server error). It requires the `500` field to be present and non-empty (evaluated at `$.paths..responses`). Severity: error.
$.paths..responses
error
array-properties-typed-items
Array properties must have an items attribute with a type. It applies a custom validation to the targeted value (evaluated at `$..*.properties[*]`). Severity: error.
$..*.properties[*]
error
array-parameters-typed-items
Array parameters must have an items attribute with a type. It applies a custom validation to the targeted value (evaluated at `$..*.parameters[*]`). Severity: error.
$..*.parameters[*]
error
schema-keys-snake-case
schema key must be snake cased (e.g. snake_case). It applies a custom validation to the targeted value (evaluated at `$.components['schemas'].*~`). Severity: error.
$.components['schemas'].*~
error
parameter-keys-snake-case
parameter key must be snake cased (e.g. snake_case). It applies a custom validation to the targeted value (evaluated at `$.components['parameters'].*~`). Severity: error.
$.components['parameters'].*~
error
example-keys-snake-case
example key must be snake cased (e.g. snake_case). It applies a custom validation to the targeted value (evaluated at `$.components['examples'].*~`). Severity: error.
$.components['examples'].*~
error
response-keys-snake-case
response key must be snake cased (e.g. snake_case). It applies a custom validation to the targeted value (evaluated at `$.components['responses'].*~`). Severity: error.
$.components['responses'].*~
error
schema-properties-require-type
Schema properties must have a type defined. It applies a custom validation to the targeted value (evaluated at `$..properties.*`). Severity: error.
$..properties.*
error
operation-require-security
Check operation security is defined. It requires the `security` field to be present and non-empty (evaluated at `$.paths.*.*`). Severity: error.
$.paths.*.*
error
operation-security-use-defined-scheme
Check operation security uses a defined security scheme. It validates the targeted value against a JSON Schema (evaluated at `$.paths[*][*]..security.*`). Severity: error.
$.paths[*][*]..security.*
warn
info-microcks-extension-valid
x-microcks extension must be valid. It validates the targeted value against a JSON Schema (evaluated at `$.info.x-microcks`). Severity: warn.
$.info.x-microcks
warn
operation-microcks-extension-valid
x-microcks-operation extension must be valid. It validates the targeted value against a JSON Schema (evaluated at `$.paths.*.*.x-microcks-operation`, `$.channels.*.[publish,subscribe].x-microcks-operation`, `$.operations.*.x-microcks-operation`). Severity: warn.
$.paths.*.*.x-microcks-operation$.channels.*.[publish,subscribe].x-microcks-operation$.operations.*.x-microcks-operation
warn
required-parameters-require-examples
Required param must have examples. It requires the `examples` field to be present and non-empty (evaluated at `$..parameters[?(@ && @.required == true)]`). Severity: warn.
$..parameters[?(@ && @.required == true)]
info
optional-parameters-include-examples
Optional param should have examples. It requires the `examples` field to be present and non-empty (evaluated at `$..parameters[?(@ && @.required != true)]`). Severity: info.
$..parameters[?(@ && @.required != true)]
warn
request-content-require-examples
Request with content must have examples. It requires the `examples` field to be present and non-empty (evaluated at `$.paths..requestBody..content.*`). Severity: warn.
$.paths..requestBody..content.*
warn
response-content-require-examples
Response with content must have examples. It requires the `examples` field to be present and non-empty (evaluated at `$.paths..responses..content.*`). Severity: warn.
$.paths..responses..content.*
warn
examples-form-complete-mocks
Response example must match required params examples to form full mocks. It applies a custom validation to the targeted value (evaluated at `$.paths.*.*`). Severity: warn.
$.paths.*.*
warn
messages-require-examples
Message must have examples. It requires the `examples` field to be present and non-empty (evaluated at `$.channels.*.[publish,subscribe].message`). Severity: warn.
$.channels.*.[publish,subscribe].message
warn
component-messages-require-examples
Message must have examples. It requires the `examples` field to be present and non-empty (evaluated at `$.components.messages.*`). Severity: warn.
$.components.messages.*
warn
channel-parameters-require-examples
Parameter must have examples. It requires the `examples` field to be present and non-empty (evaluated at `$.channels.*.parameters.*.schema`). Severity: warn.
$.channels.*.parameters.*.schema
warn
message-examples-form-complete-mocks
Message example must match params examples to form full mocks. It applies a custom validation to the targeted value (evaluated at `$.channels.*`). Severity: warn.
$.channels.*
error
info-require-description
Info section is missing a description. It requires the `description` field to be present and non-empty (evaluated at `$.info`). Severity: error.
$.info
error
operation-id-url-safe
OperationId must use URL friendly characters. It requires the `operationId` field to match the pattern `^[A-Za-z0-9-._~:/?#\[\]@!\$&'()*+,;=]*$` (evaluated at `$.paths[*][*]`). Severity: error.
$.paths[*][*]
error
path-parameters-not-empty
Path parameter declarations must not be empty ex. `/api/{}` is invalid. It requires the targeted value not to match `{}` (evaluated at `$.paths`). Severity: error.
$.paths
warn
paths-no-trailing-slash
Path must not end with a slash. It requires the targeted value not to match `.+\/$` (evaluated at `$.paths`). Severity: warn.
$.paths
error
paths-no-query-string
Path must not include query string. It requires the targeted value not to match `\?` (evaluated at `$.paths`). Severity: error.
$.paths
warn
document-cache-control-parameter
Cache usage SHOULD be extensively detailed in the `description` property to avoid data leaks or the usage of stale data. This rule should ensure in some way that the api provider documented extensively the cache usage to avoid data leaks or usage of stale data. For now this ruleset tests: * the presence of following keywords in the `description`: `max-age`, `private`, `no-store`, `no-cache`. * that one and only one between Expires and Cache-Control is used. `Cache-Control` and `Expires` should not be used in conjuction, because `Cache-Control` overrides `Expires` when `max-age` is set. Instead if neither `Cache-Control` or `Expires` are set, clients MAY use euristic cache like described in RFC7234. It requires the `description` field to be present and non-empty, and requires the `description` field to match the pattern `.*(max-age|private|no-store|no-cache).*` (evaluated at `$..[parameters][?(@.in == "header" && @.name.match(/Cache-Control/i))]`). Severity: warn.
$..[parameters][?(@.in == "header" && @.name.match(/Cache-Control/i))]
info
document-cache-response-headers
Cache usage SHOULD be extensively detailed in the `description` property to avoid data leaks or the usage of stale data. This rule should ensure in some way that the api provider documented extensively the cache usage to avoid data leaks or usage of stale data. For now this ruleset tests: * the presence of following keywords in the `description`: `max-age`, `private`, `no-store`, `no-cache`. * that one and only one between Expires and Cache-Control is used. `Cache-Control` and `Expires` should not be used in conjuction, because `Cache-Control` overrides `Expires` when `max-age` is set. Instead if neither `Cache-Control` or `Expires` are set, clients MAY use euristic cache like described in RFC7234. It requires the `description` field to be present and non-empty, and requires the `description` field to match the pattern `.*(max-age|private|no-store|no-cache).*` (evaluated at `$.[responses][?(@property[0] == "2" )][headers].[?(@property.match(/Cache-Control|Expires/i))]]`). Severity: info.
$.[responses][?(@property[0] == "2" )][headers].[?(@property.match(/Cache-Control|Expires/i))]]
info
cache-headers-no-conflict
Cache usage SHOULD be extensively detailed in the `description` property to avoid data leaks or the usage of stale data. This rule should ensure in some way that the api provider documented extensively the cache usage to avoid data leaks or usage of stale data. For now this ruleset tests: * the presence of following keywords in the `description`: `max-age`, `private`, `no-store`, `no-cache`. * that one and only one between Expires and Cache-Control is used. `Cache-Control` and `Expires` should not be used in conjuction, because `Cache-Control` overrides `Expires` when `max-age` is set. Instead if neither `Cache-Control` or `Expires` are set, clients MAY use euristic cache like described in RFC7234. It requires exactly one of ["Expires","Cache-Control"] to be present (evaluated at `$.[responses][?(@property[0] == "2" )][headers]`). Severity: info.
$.[responses][?(@property[0] == "2" )][headers]
warn
path-segments-kebab-case-2
Paths should be kebab-case. See Italian recommendation RAC_REST_NAME_002. It requires the targeted value to match the pattern `^(/[a-z0-9-.]+|/{[a-zA-Z0-9_]+})+$` (evaluated at `$.paths[*]~`). Severity: warn.
$.paths[*]~
hint
request-header-names-pascal-case
Headers should be pascal-case. See Italian recommendation RAC_REST_NAME_003. It requires pascal casing on the targeted value (evaluated at `$.[parameters][?(@.in=="header")].name`). Severity: hint.
$.[parameters][?(@.in=="header")].name
hint
response-header-names-pascal-case
Headers should be pascal-case. See Italian recommendation RAC_REST_NAME_003. It requires pascal casing on the targeted value (evaluated at `$.[responses][*].headers.*~`). Severity: hint.
$.[responses][*].headers.*~
error
no-forbidden-http-headers
OAS do not allow using the following HTTP headers in a specification file: Authorization, Content-Type and Accept. You MUST use the associate functionalities provided by OAS, instead. It requires the targeted value not to match `/^(accept|content-type|authorization)$/i` (evaluated at `$..parameters[?(@.in == 'header')].name`, `$.[responses][*].headers.*~`). Severity: error.
$..parameters[?(@.in == 'header')].name$.[responses][*].headers.*~
warn
headers-no-x-prefix
'HTTP' headers SHOULD NOT start with 'X-' RFC6648. It requires the targeted value to match the pattern `/^([^x]|.[^-])|RateLimit-/i` (evaluated at `$..parameters[?(@.in == 'header')].name`). Severity: warn.
$..parameters[?(@.in == 'header')].name
warn
response-headers-no-x-prefix
'HTTP' headers SHOULD NOT start with 'X-' RFC6648. It requires the targeted value to match the pattern `/^([^x]|.[^-])|RateLimit-/i` (evaluated at `$.[responses][*].headers.*~`). Severity: warn.
$.[responses][*].headers.*~
error
server-require-description
Servers must have a description. It requires the `description` field to be present and non-empty (evaluated at `$.servers[*]`, `$.paths..servers`). Severity: error.
$.servers[*]$.paths..servers
error
require-https-servers-2
Servers must use https to ensure the origin of the responses and protect the integrity and the confidentiality of the communication. You can use `http://` only on sandboxes environment. Use `x-sandbox: true` to skip this kind of check. It requires the `url` field to match the pattern `^https://.*` (evaluated at `$.servers[?(@["x-sandbox"] != true)]`, `$.paths..servers[?(@["x-sandbox"] != true)]`). Severity: error.
$.servers[?(@["x-sandbox"] != true)]$.paths..servers[?(@["x-sandbox"] != true)]
error
info-require-summary
The `#/info/x-summary` can be used to specify a brief, one-liner description of your API: this is very useful for catalog purposes (eg. this can be shown as your API subtitle in catalogs and developer portals). In OAS3.1 you can use the standard `#/info/summary` field. It requires the `info.x-summary` field to be present and non-empty (evaluated at `$`). Severity: error.
$
error
info-require-terms-of-service
API MUST reference the URL of the Terms of Service in `#/info/termsOfService`. It requires the `info.termsOfService` field to be present and non-empty (evaluated at `$`). Severity: error.
$
error
info-require-contact
API MUST reference a contact, either url or email in #/info/contact. It requires the `info.contact` field to be present and non-empty (evaluated at `$`). Severity: error.
$
error
info-require-api-identifier
The `#/info/x-api-id` field can be used to associate an identifier to an API. This is useful to track an API even when its `#/info/title` changes. It requires the `info.x-api-id` field to be present and non-empty (evaluated at `$`). Severity: error.
$
error
version-must-be-semver
The API version field should follow [semantic versioning](https://semver.org/#semantic-versioning-specification-semver). It requires the targeted value to match the pattern `^[0-9]+.[0-9]+.[0-9]+(-[a-z0-9+.-]+)?` (evaluated at `$.info.version`). Severity: error.
$.info.version
error
number-require-format
Schema of type number or integer must specify a format to express the associated datatype, eg. `int32`, `int64`, ... You can express similar requirements using the `minimum` and `maximum` properties. See recommendation RAC_REST_FORMAT_004. It requires the `format` field to be present and non-empty (evaluated at `$.[?(@.type=="number")]`). Severity: error.
$.[?(@.type=="number")]
error
integer-require-format
Schema of type number or integer must specify a format to express the associated datatype, eg. `int32`, `int64`, ... You can express similar requirements using the `minimum` and `maximum` properties. See recommendation RAC_REST_FORMAT_004. It requires the `format` field to be present and non-empty (evaluated at `$.[?(@.type=="integer")] `). Severity: error.
$.[?(@.type=="integer")]
hint
integer-format-allowed-values
To improve interoperability, integer and number formats are constrained to a shared subset. See recommendation RAC_REST_FORMAT_004. It requires the `format` field to be one of ["int32","int64"] (evaluated at `$.[?(@.type=="integer")] `). Severity: hint.
$.[?(@.type=="integer")]
hint
number-format-allowed-values
To improve interoperability, integer and number formats are constrained to a shared subset. See recommendation RAC_REST_FORMAT_004. It requires the `format` field to be one of ["decimal32","decimal64","float","double","decimal128"] (evaluated at `$.[?(@.type=="number")] `). Severity: hint.
$.[?(@.type=="number")]
error
patch-media-type-not-plain-json
The PATCH specification explicits that the request body contains a "patch document" describing the changes to be applied to the target resource. To avoid confusion, [this errata](https://www.rfc-editor.org/errata/eid3169) explains that `application/json` is not an appropriate media-type for `PATCH`. A correct example of PATCH using eg. `application/json-patch+json` media-type defined in RFC6902. ``` paths: /books/{book_id}: patch: requestBody: content: application/json-patch+json: schema: type: object example: [{ "op": "add", "path": "/baz", "value": "qux" }] ```. It requires the `application/json` field to be absent or empty (evaluated at `$.[patch][requestBody][content]`). Severity: error.
$.[patch][requestBody][content]
error
require-status-health-check-path
You must define a `/status` path that can be used to health-check the API. Using this path avoids the arbitrary usage of a server URL for health-check scope. The `/status` endpoint should return a `application/problem+json` response containing a successful status code if the service is working correctly. The service provider is free to define the implementation logic for this path. It requires the `paths./status.get.responses.200` field to be present and non-empty (evaluated at `$`). Severity: error.
$
error
status-path-return-problem-type
"/status" must return a Problem object. It requires the targeted value to be one of ["application/problem+xml","application/problem+json"] (evaluated at `$.paths.'/status'.get.responses.200.content.*~`). Severity: error.
$.paths.'/status'.get.responses.200.content.*~
warn
status-path-problem-schema-fields
"/status" schema is not a Problem object. It requires the `properties.status` field to be present and non-empty, and requires the `properties.title` field to be present and non-empty, and requires the `properties.detail` field to be present and non-empty (evaluated at `$.paths.'/status'.get.responses.200.content.[[schema]]`). Severity: warn.
$.paths.'/status'.get.responses.200.content.[[schema]]
hint
path-no-http-method-names
When you design a REST API, you don't usually need to mention terms like `get`, `delete` and so on in your `paths`, because this information is conveyed by the HTTP method. Instead of using ``` POST /books/1234/delete HTTP/1.1 Host: api.example ``` You can simply call ``` DELETE /books/1234 HTTP/1.1 Host: api.example ``` Similarly you don't need verbs like `list` or `create` because the HTTP Semantics RFC7231 supports this kind of actions natively with proper methods and status code. Instead of ``` POST /create/user HTTP/1.1 Host: api.example Content-Type: application/json {"given_name": "Mario"} ``` You can use ``` POST /create/user HTTP/1.1 Host: api.example Content-Type: application/json {"given_name": "Mario"} ``` returning a proper response ``` HTTP/1.1 201 Created Location: /users/1234 ``` This simplifies securing your API as you know beforehand the kind of action which is going to be performed. It requires the `@key` field to be undefined (evaluated at `$.paths[?(@property.match( /\/(get|post|put|delete|patch)[\/A-Z_\-]?/ ))]~`, `$.paths[?(@property.match( /\/(create|remove|list)[\/A-Z_\-]?/ ))]~`). Severity: hint.
$.paths[?(@property.match( /\/(get|post|put|delete|patch)[\/A-Z_\-]?/ ))]~$.paths[?(@property.match( /\/(create|remove|list)[\/A-Z_\-]?/ ))]~
error
error-response-use-problem-type
Error management is a key enabler of a resilient API ecosystem. Enforcing a consistent schema for errors between different APIs, enables client to properly implement an error management strategy, with positive impacts for users. Error responses should return one of the media-type defined in RFC 9457: - `application/problem+json` - `application/problem+xml` An example of a valid response: ``` responses: "503": content: application/problem+json: schema: ... ```. It requires the targeted value to be one of ["application/problem+xml","application/problem+json"] (evaluated at `$.paths.[*].responses[?(@property.match(/^(4|5|default)/))].content.*~`). Severity: error.
$.paths.[*].responses[?(@property.match(/^(4|5|default)/))].content.*~
hint
error-response-match-problem-schema
WARN: This rule is under implementation and just provides an hint. Error management is a key enabler of a resilient API ecosystem. Enforcing a consistent schema for errors between different APIs, enables client to properly implement an error management strategy, with positive impacts for users. This rule inspects the schema returned by an error response and verifies whether it contains the main properties defined in RFC 9457: `status`, `title` and `detail`. An example of a valid payload is ``` { "title": "Not Found", "status": 404, "detail": "Book does not exist; id: 123" } ``` See recommendation RAC_REST_NAME_007. It validates the targeted value against a JSON Schema (evaluated at `$.paths.[*].responses[?(@property.match(/^(4|5|default)/))][[schema]]`). Severity: hint.
$.paths.[*].responses[?(@property.match(/^(4|5|default)/))][[schema]]
hint
error-schema-problem-property-names
WARN: This rule is under implementation and just provides an hint. Error management is a key enabler of a resilient API ecosystem. Enforcing a consistent schema for errors between different APIs, enables client to properly implement an error management strategy, with positive impacts for users. Errors should return RFC 9457 objects. Instead, this schema seems to use non standard properties such as: `message`, `msg` and `code`. An error of the following form ``` { "msg": "Book with id: 123 does not exist.", "code": 6063 } ``` can be expressed in RFC 9457 with ``` { "detail": "Book with id: 123 does not exist.", "type": "https://api.example/v1/errors/6063", "status": 404, "title": "Not Found" } ``` Returning an URI in `type`, instead of an opaque `code` can help the client in better identifying the error; moreover the URI though it should not be dereferenced automatically, can return an actual resource providing guidance in addressing the issue. See recommendation RAC_REST_NAME_007. It requires the `@key` field not to match `message|code|msg` (evaluated at `$.[responses][?(@property.match(/^(4|5|default)/))][[schema]][properties].*~`). Severity: hint.
$.[responses][?(@property.match(/^(4|5|default)/))][[schema]][properties].*~
warn
throttled-response-require-retry-after
When a client is either: * throttled out with a 429 status code; * warned about a temporary server issue with a 503 status code; the server should explicitly communicate how long to wait before issuing further requests using the Retry-After header. Retry-After is defined in RFC7231. It requires the `Retry-After` field to be present and non-empty (evaluated at `$.[responses][?(@property == "429" || @property == "503" )][headers]`). Severity: warn.
$.[responses][?(@property == "429" || @property == "503" )][headers]
warn
success-response-require-ratelimit-headers
Ratelimiting API preserves a service and limits attack scenario [see API4:2019 Lack of Resources & Rate Limiting](https://owasp.org/www-project-api-security). APIs should use the following headers at least on successful responses: - `X-RateLimit-Limit`: number of total requests in a give time window - `X-RateLimit-Remaining`: remaining requests in the current window - `X-RateLimit-Reset`: number of seconds before the window resets An example set of headers is the following ``` X-Ratelimit-Limit: 100 X-Ratelimit-Remaining: 40 X-Ratelimit-Reset: 12 ``` A standardization proposal for ratelimit headers is ongoning inside the IETF HTTPAPI Workgroup. See [the draft](https://datatracker.ietf.org/doc/draft-ietf-httpapi-ratelimit-headers/). It requires exactly one of ["X-RateLimit-Limit","RateLimit-Limit"] to be present, and requires exactly one of ["X-RateLimit-Remaining","RateLimit-Remaining"] to be present, and requires exactly one of ["X-RateLimit-Reset","RateLimit-Reset"] to be present (evaluated at `$.[responses][?(@property[0] == "2" )][headers]`). Severity: warn.
$.[responses][?(@property[0] == "2" )][headers]
warn
array-require-min-max-items
Array size should be limited to mitigate resource exhaustion attacks. This can be done using `maxItems` and `minItems`, like in the example below. ``` Limited: type: array maxItems: 10 items: type: string format: date ``` You should ensure that the schema referenced in `items` is constrained too. If you delegate input validation to a library or framework, be sure to test it thoroughly and ensure that it verifies `maxItems`. It requires the `maxItems` field to be defined, and requires the `minItems` field to be defined (evaluated at `$.[?(@.type=="array")]`). Severity: warn.
$.[?(@.type=="array")]
warn
number-require-min-max
Numeric values should be limited in size to mitigate resource exhaustion using `maximum` and `minimum`. If you delegate input validation to a library or framework, be sure to test it thoroughly. It requires the `maximum` field to be defined, and requires the `minimum` field to be defined (evaluated at `$.[?(@.type=="number")]`, `$.[?(@.type=="integer")]`). Severity: warn.
$.[?(@.type=="number")]$.[?(@.type=="integer")]
warn
object-disallow-additional-properties
By default, jsonschema allows additionalProperties. This means that schema validators can be bypassed using further, unspecified fields. While forbidding additionalProperties can create rigidity and hinder the evolution of an API - eg making it hard to accept new parameters or fields - it is possible that this flexibility can be used to bypass the schema validator and force the application to process unwanted information. Disable `additionalProperties` with `false` ``` Person: type: object additionalProperties: false properties: given_name: type: string pattern: [a-zA-Z ]{24} ``` Or constraint them using `maxProperties` ``` Person: type: object additionalProperties: type: string pattern: /+39[0-9]{,14}/ maxProperties: 3 properties: given_name: type: string pattern: [a-zA-Z ]{24} ``` - no additionalProperties - constrained additionalProperties. It requires the `additionalProperties` field to be absent or empty (evaluated at `$.[?(@.type=="object" && @.additionalProperties==true)]`). Severity: warn.
$.[?(@.type=="object" && @.additionalProperties==true)]
warn
object-set-additional-properties
By default, jsonschema allows additionalProperties. This means that schema validators can be bypassed using further, unspecified fields. While forbidding additionalProperties can create rigidity and hinder the evolution of an API - eg making it hard to accept new parameters or fields - it is possible that this flexibility can be used to bypass the schema validator and force the application to process unwanted information. Disable `additionalProperties` with `false` ``` Person: type: object additionalProperties: false properties: given_name: type: string pattern: [a-zA-Z ]{24} ``` Or constraint them using `maxProperties` ``` Person: type: object additionalProperties: type: string pattern: /+39[0-9]{,14}/ maxProperties: 3 properties: given_name: type: string pattern: [a-zA-Z ]{24} ``` - no additionalProperties - constrained additionalProperties. It requires the `additionalProperties` field to be defined (evaluated at `$.[?(@.type=="object" && ! @.additionalProperties)]`). Severity: warn.
$.[?(@.type=="object" && ! @.additionalProperties)]
warn
object-constrain-additional-properties
By default, jsonschema allows additionalProperties. This means that schema validators can be bypassed using further, unspecified fields. While forbidding additionalProperties can create rigidity and hinder the evolution of an API - eg making it hard to accept new parameters or fields - it is possible that this flexibility can be used to bypass the schema validator and force the application to process unwanted information. Disable `additionalProperties` with `false` ``` Person: type: object additionalProperties: false properties: given_name: type: string pattern: [a-zA-Z ]{24} ``` Or constraint them using `maxProperties` ``` Person: type: object additionalProperties: type: string pattern: /+39[0-9]{,14}/ maxProperties: 3 properties: given_name: type: string pattern: [a-zA-Z ]{24} ``` - no additionalProperties - constrained additionalProperties. It requires the `maxProperties` field to be defined (evaluated at `$.[?(@.type=="object" && @.additionalProperties && @.additionalProperties!=true && @.additionalProperties!=false )]`). Severity: warn.
$.[?(@.type=="object" && @.additionalProperties && @.additionalProperties!=true && @.additionalProperties!=false )]
info
get-operation-require-security
Your API should be protected by a `security` rule either at global or operation level. Operations should be protected specially when they are tied to non-idempotent HTTP methods like `POST`, `PUT`, `PATCH` and `DELETE`. This is done with one or more non-empty `security` rules. Security rules are defined in the `securityScheme` section. An example of a security rule applied at global level. ``` security: - BasicAuth: [] paths: /books: {} /users: {} securitySchemes: BasicAuth: scheme: http type: basic ``` An example of a security rule applied at operation level, which eventually overrides the global one ``` paths: /books: post: security: - AccessToken: [] securitySchemes: BasicAuth: scheme: http type: basic AccessToken: scheme: http type: bearer bearerFormat: JWT ```. It validates the `security` field against a JSON Schema (evaluated at `$.paths.*.get`). Severity: info.
$.paths.*.get
error
write-operation-require-security
Your API should be protected by a `security` rule either at global or operation level. Operations should be protected specially when they are tied to non-idempotent HTTP methods like `POST`, `PUT`, `PATCH` and `DELETE`. This is done with one or more non-empty `security` rules. Security rules are defined in the `securityScheme` section. An example of a security rule applied at global level. ``` security: - BasicAuth: [] paths: /books: {} /users: {} securitySchemes: BasicAuth: scheme: http type: basic ``` An example of a security rule applied at operation level, which eventually overrides the global one ``` paths: /books: post: security: - AccessToken: [] securitySchemes: BasicAuth: scheme: http type: basic AccessToken: scheme: http type: bearer bearerFormat: JWT ```. It validates the `security` field against a JSON Schema (evaluated at `$.paths.*[?(@property.match(/^(post|put|patch|delete)/))]`). Severity: error.
$.paths.*[?(@property.match(/^(post|put|patch|delete)/))]
warn
oauth-scheme-require-description
Json Web Tokens RFC7519 is a compact, URL-safe means of representing claims to be transferred between two parties. JWT can be enclosed in encrypted or signed tokens like JWS and JWE. The [JOSE IANA registry](https://www.iana.org/assignments/jose/jose.xhtml) provides algorithms information. RFC8725 describes common pitfalls in the JWx specifications and in their implementations, such as: - the ability to ignore algorithms, eg. `{"alg": "none"}`; - using insecure algorithms like `RSASSA-PKCS1-v1_5` eg. `{"alg": "RS256"}`. An API using JWT should explicit in the `description` that the implementation conforms to RFC8725. ``` components: securitySchemes: JWTBearer: type: http scheme: bearer bearerFormat: JWT description: |- A bearer token in the format of a JWS and conformato to the specifications included in RFC8725. ```. It requires the `description` field to be present and non-empty, and requires the `description` field to match the pattern `.*RFC8725.*` (evaluated at `$.[securitySchemes][?(@.type=="oauth2")]`). Severity: warn.
$.[securitySchemes][?(@.type=="oauth2")]
warn
jwt-scheme-require-description
Json Web Tokens RFC7519 is a compact, URL-safe means of representing claims to be transferred between two parties. JWT can be enclosed in encrypted or signed tokens like JWS and JWE. The [JOSE IANA registry](https://www.iana.org/assignments/jose/jose.xhtml) provides algorithms information. RFC8725 describes common pitfalls in the JWx specifications and in their implementations, such as: - the ability to ignore algorithms, eg. `{"alg": "none"}`; - using insecure algorithms like `RSASSA-PKCS1-v1_5` eg. `{"alg": "RS256"}`. An API using JWT should explicit in the `description` that the implementation conforms to RFC8725. ``` components: securitySchemes: JWTBearer: type: http scheme: bearer bearerFormat: JWT description: |- A bearer token in the format of a JWS and conformato to the specifications included in RFC8725. ```. It requires the `description` field to be present and non-empty, and requires the `description` field to match the pattern `.*RFC8725.*` (evaluated at `$.[securitySchemes][?(@.bearerFormat=="jwt" || @.bearerFormat=="JWT")]`). Severity: warn.
$.[securitySchemes][?(@.bearerFormat=="jwt" || @.bearerFormat=="JWT")]
error
oauth-endpoints-require-https
OAuth2 endpoints must use `https://`. It requires the `value` field to match the pattern `^https://` (evaluated at `$.[securitySchemes][?(@.type=="oauth2")][*].[?(@property.match(/url$/i))]`). Severity: error.
$.[securitySchemes][?(@.type=="oauth2")][*].[?(@property.match(/url$/i))]
error
oauth-disallow-insecure-flows
The OAuth2 authorization framework defines various [grant types](https://tools.ietf.org/html/rfc6749#section-1.3), most notably the [AuthorizationCode](https://tools.ietf.org/html/rfc6749#section-1.3.1) and the [Client Credentials](https://tools.ietf.org/html/rfc6749#section-1.3.4). Some grant types are now considered insecure and MUST not be used, including `implicit` and `password`. The new [OAuth2.1](https://tools.ietf.org/html/draft-ietf-oauth-v2-1-01) still in draft, removes them and suggests to replace the `implicit` with `authorizationCode` + PKCE defined in RFC7636. It requires the `implicit` field to be absent or empty, and requires the `password` field to be absent or empty (evaluated at `$.[?(@.type=="oauth2")].flows`). Severity: error.
$.[?(@.type=="oauth2")].flows
warn
string-require-max-length
String length should be limited to avoid an attacker to send very long strings to your service. You can do this in different ways: - specify a `maxLength` - constraint the possible values with an `enum` - use a constrained `format` like `date` or `date-time`. A constrained string using the `date` format. ``` ConstrainedString: type: string format: date ``` Another constrained string using `maxLength`. You can always add further constraints using a `pattern` or a `format`. ``` ZipCode: type: string maxLength: 5 pattern: '[0-9]{5}' ``` For further security, you can always limit string length even in conjunction with `format` and `pattern`. It requires the `maxLength` field to be defined (evaluated at `$.[?(@.type=="string" && !@.enum && @.format!="date" && @.format !="date-time" )]`). Severity: warn.
$.[?(@.type=="string" && !@.enum && @.format!="date" && @.format !="date-time" )]
hint
string-require-pattern-or-format
String length should be limited to avoid an attacker to send very long strings to your service. You can do this in different ways: - specify a `maxLength` - constraint the possible values with an `enum` - use a constrained `format` like `date` or `date-time`. A constrained string using the `date` format. ``` ConstrainedString: type: string format: date ``` Another constrained string using `maxLength`. You can always add further constraints using a `pattern` or a `format`. ``` ZipCode: type: string maxLength: 5 pattern: '[0-9]{5}' ``` For further security, you can always limit string length even in conjunction with `format` and `pattern`. It validates the targeted value against a JSON Schema (evaluated at `$.[?(@.type=="string" && !@.enum && @.format!="date" && @.format !="date-time" )]`). Severity: hint.
$.[?(@.type=="string" && !@.enum && @.format!="date" && @.format !="date-time" )]
warn
server-url-meet-standards
API URLs should meet the Trimble API Standards. It applies a custom validation to the targeted value (evaluated at `$.servers`). Severity: warn.
$.servers
warn
server-url-include-version
API URLs versions should meet the Trimble API Standards. It applies a custom validation to the targeted value (evaluated at `$.servers`). Severity: warn.
$.servers
error
schema-properties-camel-case-2
Ensuring that schema property names are camel case. It requires the `@key` field to match the pattern `^[a-z][a-zA-Z0-9]*$` (evaluated at `$..properties.`). Severity: error.
$..properties.
warn
path-no-http-verbs
HTTP verbs should be not be in URL paths. It applies a custom validation to the `@key` field (evaluated at `$.paths`). Severity: warn.
$.paths
error
write-response-support-json
All APIs returning structured data SHOULD support JSON as the default format. It applies a custom validation to the targeted value (evaluated at `$.paths.*.`). Severity: error.
$.paths.*.
warn
get-response-support-json
All APIs returning structured data SHOULD support JSON as the default format. It applies a custom validation to the targeted value (evaluated at `$.paths.*.`). Severity: warn.
$.paths.*.
warn
response-code-must-be-valid
All APIs should return a valid http response code. It applies a custom validation to the `@key` field (evaluated at `$..responses`). Severity: warn.
$..responses
warn
path-require-query-parameter
Check if the given resource path has queryparameter. It applies a custom validation to the `@key` field (evaluated at `$.paths`). Severity: warn.
$.paths
warn
path-require-valid-http-verb
All APIs MUST have a valid http verb. It applies a custom validation to the `@key` field (evaluated at `$.paths.*`). Severity: warn.
$.paths.*
error
spec-must-not-be-empty
Spec should not be empty. It applies a custom validation to the targeted value (evaluated at `$`). Severity: error.
$
warn
tag-no-pascal-case
Tag names cannot use Pascal Case. Please rename {{value}}. It requires the targeted value not to match `/[A-Z][a-z]+[A-Z][a-z]+$/g` (evaluated at `$.tags[*].name`, `$.paths[*][*].tags[*]`). Severity: warn.
$.tags[*].name$.paths[*][*].tags[*]
warn
tag-no-camel-case
Detects a tag with camelCase (personalItem) text within it. It requires the targeted value not to match `/^[a-z]+[A-Z][a-z]+$/g` (evaluated at `$.tags[*].name`, `$.paths[*][*].tags[*]`). Severity: warn.
$.tags[*].name$.paths[*][*].tags[*]
warn
tag-no-version-info
Tag names cannot have version information {{value}}. Consider versioning your API. It requires the targeted value not to match `/(V|v)\s?[0-9]+/g` (evaluated at `$.tags[*].name`, `$.paths[*][*].tags[*]`). Severity: warn.
$.tags[*].name$.paths[*][*].tags[*]
warn
operation-summary-description-differ
Operation summaries and description should not match. It applies a custom validation to the targeted value (evaluated at `$.paths[*].[get,post,put,patch,delete]`). Severity: warn.
$.paths[*].[get,post,put,patch,delete]
error
delete-require-204-response
All DELETE methods MUST have a 204 response. It requires the `204` field to be present and non-empty (evaluated at `$.paths[*].delete.responses`). Severity: error.
$.paths[*].delete.responses
error
post-require-201-or-202-response
All POST methods MUST have a 201 or 202 response. It applies a custom validation to the targeted value (evaluated at `$.paths[*].post.responses`). Severity: error.
$.paths[*].post.responses
error
response-400-require-body
All 400 responses must include a response body. It requires the `content` field to be present and non-empty (evaluated at `$.paths.*.*.responses['400']`). Severity: error.
$.paths.*.*.responses['400']
warn
response-206-require-content-range
Check if the get response code 206 has content-type and content-range. It applies a custom validation to the targeted value (evaluated at `$.paths.*.`). Severity: warn.
$.paths.*.
error
error-response-standard-payload
All 4XX and 5XX response codes must follow Trimble API Standard. It applies a custom validation to the targeted value (evaluated at `$.paths.*.*.responses.`). Severity: error.
$.paths.*.*.responses.
warn
error-response-require-description
Check if the response description is appropriate for all requests. It applies a custom validation to the targeted value (evaluated at `$.paths.*.*.responses.`). Severity: warn.
$.paths.*.*.responses.
warn
success-response-require-description
Check if the response description is appropriate for all requests. It applies a custom validation to the targeted value (evaluated at `$.paths.*.`). Severity: warn.
$.paths.*.
error
write-response-require-content-type
All API responses MUST include the Content-Type header in all responses. It applies a custom validation to the targeted value (evaluated at `$.paths[*].post.responses`, `$.paths[*].put.responses`). Severity: error.
$.paths[*].post.responses$.paths[*].put.responses
error
path-params-declared-in-block
Check for the path parameter in the parameter block. It applies a custom validation to the targeted value (evaluated at `$.paths.`). Severity: error.
$.paths.
error
operation-require-response
Check if every request has their respective responses. It applies a custom validation to the targeted value (evaluated at `$.paths.*`). Severity: error.
$.paths.*
warn
delete-no-response-body
Check if the delete response does not have any body. It applies a custom validation to the targeted value (evaluated at `$.paths.*.`). Severity: warn.
$.paths.*.
error
path-no-invalid-symbols
Check if the given endpoint has queryparameter. It applies a custom validation to the `@key` field (evaluated at `$.paths.`). Severity: error.
$.paths.
error
no-http-basic-auth
Consider a more secure alternative to HTTP Basic. It requires the `scheme` field not to match `basic` (evaluated at `$.components.securitySchemes[*]`). Severity: error.
$.components.securitySchemes[*]
warn
collection-response-support-paging
Response bodies from collection endpoints SHOULD offer paging capability. It requires the `paging` field to be present and non-empty, and requires the `paging` field to match the pattern `object`, and requires the `paging.type` field to match the pattern `object` (evaluated at `$.paths[?(!@property.match(/.*\/\{[^}]+\}.*$/))].get.responses['200'].content.application/json.schema.properties`). Severity: warn.
$.paths[?(!@property.match(/.*\/\{[^}]+\}.*$/))].get.responses['200'].content.application/json.schema.properties
error
collection-require-results-array
Response bodies must have a root element called results and is an array of objects. It requires the `type` field to match the pattern `array`, and requires the `items.type` field to match the pattern `object` (evaluated at `$.paths[?(!@property.match(/.*\/\{[^}]+\}$/))].get.responses['200'].content.application/json.schema.properties.results`). Severity: error.
$.paths[?(!@property.match(/.*\/\{[^}]+\}$/))].get.responses['200'].content.application/json.schema.properties.results
warn
collection-require-pagination-params
Collection GET endpoints SHOULD support pagination using query parameters. Offset or cursor based pagination is required. It validates the `parameters` field against a JSON Schema (evaluated at `$.paths[?(!@property.match(/.*\/\{[^}]+\}\/*.*/))].get`). Severity: warn.
$.paths[?(!@property.match(/.*\/\{[^}]+\}\/*.*/))].get
error
post-collection-require-paging-object
POST collection endpoints MUST have a request body schema that includes paging parameters. It requires the `type` field to match the pattern `object` (evaluated at `$.paths[?(!@property.match(/.*\/\{[^}]+\}$/))].post.requestBody.content.application/json.schema.properties.paging`). Severity: error.
$.paths[?(!@property.match(/.*\/\{[^}]+\}$/))].post.requestBody.content.application/json.schema.properties.paging
warn
no-id-query-parameter
Resource identifier filtering is not allowed as a query parameter. Use the resource identifier in the URL path. It requires the `name` field not to match `^id$` (evaluated at `$.paths..get.parameters.[?(@.in=='query' && @.name=='id')]`). Severity: warn.
$.paths..get.parameters.[?(@.in=='query' && @.name=='id')]
error
filter-param-only-on-get
Only GET-based endpoints SHOULD have have the query parameter 'filter'. It requires the targeted value to be absent or empty (evaluated at `$.paths.*[?(@property!='get')].parameters.[?(@.in=='query' && @.name=='filter')].name`). Severity: error.
$.paths.*[?(@property!='get')].parameters.[?(@.in=='query' && @.name=='filter')].name
error
no-hybrid-and-root-filtering
Hybrid filtering MAY be offered on multiple attributes, but MUST never exist if a root "filter" query parameter is present. It validates the targeted value against a JSON Schema (evaluated at `$.paths..get.parameters^`). Severity: error.
$.paths..get.parameters^
error
sort-param-only-on-get
Non-GET endpoints MUST NOT have sorting query parameters. Parameter names such as sort, sorting, orderBy, etc. It requires the `name` field not to match `^sort|sorting|sortBy|order|ordering|orderBy$` (evaluated at `$.paths.*[?(@property!='get')].parameters.[?(@.in=='query')]`). Severity: error.
$.paths.*[?(@property!='get')].parameters.[?(@.in=='query')]
error
error-response-use-problem-type-2
Every error response SHOULD support RFC 9457. It requires the targeted value to be one of ["application/problem+xml","application/problem+json"] (evaluated at `$.paths...responses[?(@property.match(/^(4|5)/))].content.*~`). Severity: error.
$.paths...responses[?(@property.match(/^(4|5)/))].content.*~
warn
property-no-language-keywords
Names that may conflict with keywords in common programming languages SHOULD NOT be used. It requires the targeted value not to match `^(abstract|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|volatile|const|float|native|super|while)$` (evaluated at `$..properties.*~`). Severity: warn.
$..properties.*~
error
property-names-camel-case-2
Property names and acronyms MUST be in camelCase. It requires the targeted value to match the pattern `^[a-z][a-z0-9]*(([A-Z]{2}|[A-Z])[a-z0-9]+)*$` (evaluated at `$..properties.*~`). Severity: error.
$..properties.*~
warn
property-no-prepositions
Property names SHOULD NOT include prepositions (e.g. "for", "during", "at", etc.). It requires the targeted value not to match `(^(about|above|across|after|against|among|around|at|before|behind|below|beside|between|down|during|for|from|in|inside|into|near|of|off|on|out|over|through|to|toward|under|up|with|as|but|like|since|than|till|unlike|until|upon|within|without)([A-Z]|$)|.*(About|Above|Across|After|Against|Among|Around|At|Before|Behind|Below|Beside|Between|Down|During|For|From|In|Inside|Into|Near|Of|Off|On|Out|Over|Through|To|Toward|Under|Up|With|As|But|Like|Since|Than|Till|Unlike|Until|Upon|Within|Without)([A-Z]|$)).*` (evaluated at `$..properties.*~`). Severity: warn.
$..properties.*~
warn
boolean-no-prefix
Boolean properties SHOULD NOT use is, has, or another prefix. It requires the targeted value not to match `^(is|has|was|will|needs|uses|should|can)([A-Z]|$).*` (evaluated at `$..properties[?(@ && @.type == 'boolean')]~`). Severity: warn.
$..properties[?(@ && @.type == 'boolean')]~
error
ref-property-require-format
Property with the name 'ref' MUST use a format 'sps-ref'. It requires the `format` field to be present and non-empty, and requires the `format` field to match the pattern `^sps-ref$` (evaluated at `$..properties..[?((@property=== "ref" || @property === "Ref") && @.$ref == null && @.allOf == null && @.oneOf == null && @.type != null)]`). Severity: error.
$..properties..[?((@property=== "ref" || @property === "Ref") && @.$ref == null && @.allOf == null && @.oneOf == null && @.type != null)]
error
ref-property-standard-schema
Properties following 'sps-ref' format MUST use the standardized schema - maxLength (255), minLength(7), pattern (includes 'sps'), type (string). It validates the targeted value against a JSON Schema, and requires the `pattern` field to match the pattern `sps`, and requires the `type` field to match the pattern `^string$` (evaluated at `$..[?(@property=== "format" && @ == "sps-ref")]^`). Severity: error.
$..[?(@property=== "format" && @ == "sps-ref")]^
warn
id-property-must-be-string
id SHOULD use a data type of 'string'. It requires the targeted value to match the pattern `^string$` (evaluated at `$..[?(@property === "id")].type`). Severity: warn.
$..[?(@property === "id")].type
warn
use-id-not-identifier
Use abbreviations instead of long form names, i.e. identifier SHOULD BE id. It requires the targeted value not to match `^identifier$` (evaluated at `$..properties.*~`). Severity: warn.
$..properties.*~
warn
use-org-not-organization
Use abbreviations instead of long form names, i.e. organization SHOULD BE org. It requires the targeted value not to match `(^organization([A-Z]|$)|Organization([A-Z]|$))` (evaluated at `$..properties.*~`). Severity: warn.
$..properties.*~
error
ref-property-must-be-string
ref MUST use a data type of 'string'. It requires the targeted value to match the pattern `^string$` (evaluated at `$..[?(@property === "ref")].type`). Severity: error.
$..[?(@property === "ref")].type
error
orgid-property-must-be-string
orgId MUST use a data type of 'string'. It requires the targeted value to match the pattern `^string$` (evaluated at `$..[?(@property === "orgId")].type`). Severity: error.
$..[?(@property === "orgId")].type
error
name-property-must-be-string
name MUST use a data type of 'string'. It requires the targeted value to match the pattern `^string$` (evaluated at `$..[?(@property === "name")].type`). Severity: error.
$..[?(@property === "name")].type
error
description-property-must-be-string
description MUST use a data type of 'string'. It requires the targeted value to match the pattern `^string$` (evaluated at `$..[?(@property === "description")].type`). Severity: error.
$..[?(@property === "description")].type
error
requestid-property-must-be-string
requestId MUST use a data type of 'string'. It requires the targeted value to match the pattern `^string$` (evaluated at `$..[?(@property === "requestId")].type`). Severity: error.
$..[?(@property === "requestId")].type
error
created-datetime-must-be-date-time
createdDateTime MUST use a data type of 'string' with the format 'date-time'. It requires the `type` field to match the pattern `^string$`, and requires the `format` field to be present and non-empty, and requires the `format` field to match the pattern `^date-time$` (evaluated at `$..properties.createdDateTime`). Severity: error.
$..properties.createdDateTime
error
createdby-property-must-be-string
createdBy MUST use a data type of 'string'. It requires the targeted value to match the pattern `^string$` (evaluated at `$..[?(@property === "createdBy")].type`). Severity: error.
$..[?(@property === "createdBy")].type
error
modified-datetime-must-be-date-time
modifiedDateTime MUST use a data type of 'string' with the format 'date-time'. It requires the `type` field to match the pattern `^string$`, and requires the `format` field to be present and non-empty, and requires the `format` field to match the pattern `^date-time$` (evaluated at `$..properties.modifiedDateTime`). Severity: error.
$..properties.modifiedDateTime
error
modifiedby-property-must-be-string
modifiedBy MUST use a data type of 'string'. It requires the targeted value to match the pattern `^string$` (evaluated at `$..[?(@property === "modifiedBy")].type`). Severity: error.
$..[?(@property === "modifiedBy")].type
error
deletedby-property-must-be-string
deletedBy MUST use a data type of 'string'. It requires the targeted value to match the pattern `^string$` (evaluated at `$..[?(@property === "deletedBy")].type`). Severity: error.
$..[?(@property === "deletedBy")].type
error
fingerprint-property-must-be-string
Fingerprint values MUST use a data type of `string`. It requires the targeted value to match the pattern `^string$` (evaluated at `$..[?(@property === "fingerprint")].type`). Severity: error.
$..[?(@property === "fingerprint")].type
error
use-fingerprint-not-hash
Rather than property names refering to the implementation for 'hash' or 'hashkey', you MUST use the property name 'fingerprint'. It requires the targeted value not to match `^hashkey|hashKey|hash$` (evaluated at `$.components.schemas..properties.*~`). Severity: error.
$.components.schemas..properties.*~
error
response-body-must-be-object
Response bodies must be an object type. It requires the targeted value to match the pattern `object` (evaluated at `$.paths[*][*].responses[*].content.application/json.schema.type`). Severity: error.
$.paths[*][*].responses[*].content.application/json.schema.type
error
use-standard-status-codes-2
An API MUST return HTTP response codes in conformance with RFC-2616 and common usage. It requires the targeted value to be one of ["200","201","202","204","400","401","403","404","405","406","409","412","415","428","429","500"] (evaluated at `$.paths...responses.*~`). Severity: error.
$.paths...responses.*~
warn
operation-define-500-response
Every endpoint SHOULD have a 500 response. It requires the `responses.500` field to be present and non-empty (evaluated at `$.paths[*][*]`). Severity: warn.
$.paths[*][*]
warn
no-x-prefixed-request-headers
Do not use headers with X-. It requires the targeted value not to match `^(x|X)-` (evaluated at `$..parameters.[?(@.in === 'header')].name`). Severity: warn.
$..parameters.[?(@.in === 'header')].name
warn
no-x-prefixed-response-headers
Do not use headers with X-. It requires the targeted value not to match `^(x|X)-` (evaluated at `$..headers.*~`). Severity: warn.
$..headers.*~
error
location-header-only-on-201
Location header MUST NOT be present in non-201 responses. It requires the `Location` field to be absent or empty (evaluated at `$.paths[*][*].responses[?(@property !== '201')].headers`). Severity: error.
$.paths[*][*].responses[?(@property !== '201')].headers
error
require-root-security-scheme
Security field MUST be present at the root of the spec with at least one item (ie. HTTPBearer, Token, APIKey, etc.). It validates the `security` field against a JSON Schema (evaluated at `$`). Severity: error.
$
error
default-content-language-en-us
Content-Language is optional but MUST default locale to en-US when none provided. It requires the targeted value to match the pattern `en-US` (evaluated at `$.paths[*][*].responses[*].headers.Content-Language.schema.default`). Severity: error.
$.paths[*][*].responses[*].headers.Content-Language.schema.default
warn
no-operational-headers-in-spec
Access-Control-*, Content-Type, and Accept Headers SHOULD NOT be specified explicitly in a spec as it an operational concern. It requires the targeted value not to match `^(Access-Control-.*|Content-Type|Accept)$` (evaluated at `$.paths[*][*].responses[*].headers`). Severity: warn.
$.paths[*][*].responses[*].headers
error
custom-header-naming-format
Custom headers MUST NOT be longer than 50 chars, and MUST only contain alphanumeric and dash chars, and MUST begin with Sps- not X-. It requires the targeted value to match the pattern `^(Sps-[a-zA-Z0-9-]{1,50}|Accept|Access-Control.*|Authorization|Cache-Control|Content-Disposition|Content-Language|Content-Length|Content-Type|Date|ETag|Host|If-Match|If-None-Match|Location|Origin|User-Agent)$` (evaluated at `$.paths[*][*].responses[*].headers.*~`). Severity: error.
$.paths[*][*].responses[*].headers.*~
error
no-sensitive-data-in-headers
Headers MUST NOT contain sensitive data. It requires the targeted value not to match `^(SPS-Token|SPS-Password|SPS-Identity|Password)$` (evaluated at `$.paths[*][*].responses[*].headers.*~`). Severity: error.
$.paths[*][*].responses[*].headers.*~
error
no-format-extensions-in-paths
Request and Response media type formats MUST NOT be implied using extensions on resources (i.e. .json or .xml). Instead, use the standard resource path with the appropriate Content-Type header. It requires the targeted value not to match `\.json|\.xml|\.yml|\.yaml` (evaluated at `$.paths.*~`). Severity: error.
$.paths.*~
error
use-standard-mime-types
MIME types MUST be standard (application/json, application/problem+json, application/problem+xml) or use custom format application/vnd.*. It requires the targeted value to match the pattern `^application/(json|problem\+json|problem\+xml|vnd\..*)$` (evaluated at `$.paths[*][*].responses[*].content.*~`). Severity: error.
$.paths[*][*].responses[*].content.*~
error
use-standard-http-methods
Operations MUST use only the common HTTP methods as outlined in the standards guide, and must be in lower-case. It requires the `method` field to be one of ["get","post","put","patch","delete","head","options"] (evaluated at `$.paths[*].*~`). Severity: error.
$.paths[*].*~
error
get-must-not-have-request-body
A `GET` request MUST NOT accept a request body. It requires the targeted value to be undefined (evaluated at `$.paths[*][get].requestBody`). Severity: error.
$.paths[*][get].requestBody
error
get-must-return-response-body
A `GET` operation must return a response body. It requires the `content` field to be present and non-empty (evaluated at `$.paths[*].get.responses[*]`). Severity: error.
$.paths[*].get.responses[*]
warn
get-response-codes-allowed
GET operations should not use status codes 201, 202, 204, 409, 412. It requires the `@key` field not to match `^(201|202|204|409|412)$` (evaluated at `$.paths[*].get.responses`). Severity: warn.
$.paths[*].get.responses
error
get-must-return-200
GET operations must always return 200 status code. It requires the `200` field to be present and non-empty (evaluated at `$.paths[*].get.responses`). Severity: error.
$.paths[*].get.responses
warn
post-response-codes-allowed
POST operations should not return 412 status codes. It requires the `@key` field not to match `412` (evaluated at `$.paths[*].post.responses`). Severity: warn.
$.paths[*].post.responses
warn
put-response-codes-allowed
PUT operations should not return 200 or 201 status codes. It requires the `@key` field not to match `^(200|201)$` (evaluated at `$.paths[*].put.responses`). Severity: warn.
$.paths[*].put.responses
warn
delete-response-codes-allowed
DELETE operations should not return 200 or 201 status codes. It requires the `@key` field not to match `^(200|201)$` (evaluated at `$.paths[*].delete.responses`). Severity: warn.
$.paths[*].delete.responses
error
delete-must-not-have-request-body
DELETE operations must not accept a request body. It requires the targeted value to be undefined (evaluated at `$.paths[*].delete.requestBody`). Severity: error.
$.paths[*].delete.requestBody
error
delete-must-not-return-body
DELETE operations must not have a response body. It requires the targeted value to be absent or empty (evaluated at `$.paths.*.delete.responses[202,204].content`). Severity: error.
$.paths.*.delete.responses[202,204].content
warn
patch-response-codes-allowed
PATCH operations should not return 201 status code. It requires the `@key` field not to match `^201$` (evaluated at `$.paths[*].patch.responses`). Severity: warn.
$.paths[*].patch.responses
error
patch-must-have-request-body
PATCH operations must have a request body. It validates the `requestBody` field against a JSON Schema (evaluated at `$.paths[*].patch`). Severity: error.
$.paths[*].patch
warn
head-response-codes-allowed
HEAD operations should not return 201, 202, 204, 409, 412 status codes. It requires the `@key` field not to match `^(201|202|204|409|412)$` (evaluated at `$.paths[*].head.responses`). Severity: warn.
$.paths[*].head.responses
error
head-must-not-have-request-body
A `HEAD` request MUST NOT accept a request body. It requires the targeted value to be undefined (evaluated at `$.paths[*][head].requestBody`). Severity: error.
$.paths[*][head].requestBody
error
head-must-not-return-body
HEAD operations should not return a response body for success. It requires the targeted value to be absent or empty (evaluated at `$.paths.*.head.responses[200].content`). Severity: error.
$.paths.*.head.responses[200].content
warn
options-response-codes-allowed
OPTIONS operations should not return 201, 202, 409, 412 status codes. It requires the `@key` field not to match `^(201|202|409|412)$` (evaluated at `$.paths[*].options.responses`). Severity: warn.
$.paths[*].options.responses
error
options-must-not-have-request-body
An `OPTIONS` request MUST NOT accept a request body. It requires the targeted value to be undefined (evaluated at `$.paths[*][options].requestBody`). Severity: error.
$.paths[*][options].requestBody
error
options-must-not-return-body
OPTIONS operations should not return a response body for success. It requires the targeted value to be absent or empty (evaluated at `$.paths.*.options.responses[200, 204].content`). Severity: error.
$.paths.*.options.responses[200, 204].content
error
request-support-json-media-type-2
Every request MUST support `application/json` media type. It validates the targeted value against a JSON Schema (evaluated at `$.paths[*][*].requestBody.content`). Severity: error.
$.paths[*][*].requestBody.content
warn
avoid-integer-id-parameters
Avoid exposing IDs as an integer, UUIDs or other interoperable strings are preferred. It validates the targeted value against a JSON Schema (evaluated at `$.paths..parameters[*].[?(@property === "name" && (@ === "id" || @ === "ID" || @ === "Id"))]^.schema`). Severity: warn.
$.paths..parameters[*].[?(@property === "name" && (@ === "id" || @ === "ID" || @ === "Id"))]^.schema
warn
version-must-use-semver
Version should use semantic versioning. {{value}} is not a valid version. It requires the targeted value to match the pattern `^([0-9]+.[0-9]+.[0-9]+)$` (evaluated at `$.info.version`). Severity: warn.
$.info.version
warn
schema-names-pascal-case
Schema names SHOULD be written in PascalCase. It requires the targeted value to match the pattern `^[A-Z][a-zA-Z0-9]*$` (evaluated at `$.components.schemas.*~`). Severity: warn.
$.components.schemas.*~
warn
response-names-pascal-case
Response names SHOULD be written in PascalCase. It requires the targeted value to match the pattern `^[A-Z][a-zA-Z0-9]*$` (evaluated at `$.components.responses.*~`). Severity: warn.
$.components.responses.*~
warn
limit-path-length
APIs SHOULD NOT expand their total URL length beyond a few hundred characters. It constrains the length of the targeted value and at most 100 (evaluated at `$.paths.*~`). Severity: warn.
$.paths.*~
error
servers-must-use-https
Servers MUST be https and no other protocol is allowed unless using localhost. It requires the targeted value to match the pattern `^(https:|http://localhost)` (evaluated at `$.servers..url`). Severity: error.
$.servers..url
warn
server-url-must-be-lowercase
Server URL SHOULD BE lowercase. It requires the targeted value to match the pattern `^[^A-Z]*$` (evaluated at `$.servers..url`). Severity: warn.
$.servers..url
warn
servers-on-approved-domain
APIs SHOULD be accessible under api.spscommerce.com. It requires the targeted value to match the pattern `api.spscommerce.com|api.sps-internal.com|localhost` (evaluated at `$.servers..url`). Severity: warn.
$.servers..url
error
no-environment-names-in-paths
API paths MUST NOT indicate environment names. It requires the targeted value not to match `/prod/|/preprod/|/dev/|/test/|/integration/|/stage/` (evaluated at `$.paths.*~`). Severity: error.
$.paths.*~
error
servers-must-not-specify-port
Port MUST NOT be specified or required to use the API, except for 'localhost' testing in a spec. It requires the targeted value not to match `(?!https?://localhost)(https?://.*):(\d*)\/?(.*)` (evaluated at `$.servers..url`). Severity: error.
$.servers..url
error
no-technology-leak-in-paths
A resource MUST NOT leak or expose format or technology-specific information at any point in the path. It requires the targeted value not to match `(.php|.asp|.jsp|.cgi|.psp|.json|.xml)` (evaluated at `$.paths.*~`). Severity: error.
$.paths.*~
warn
no-file-extension-in-paths
A resource SHOULD NOT make use of an extension at any point in the path. It requires the targeted value not to match `\.` (evaluated at `$.paths.*~`). Severity: warn.
$.paths.*~
error
path-segments-kebab-case-3
A resource containing multiple words MUST be separated using kebab-case (lower case and separated with hyphens). It requires the targeted value not to match `(\/[a-z]+_.)|(\/([a-z]|[A-Z])+[A-Z])` (evaluated at `$.paths[?(/^((?!_webhooks).)*$/i.test(@property))]~`). Severity: error.
$.paths[?(/^((?!_webhooks).)*$/i.test(@property))]~
error
no-trailing-slash-in-paths
A resource MUST be addressable without a trailing slash on the path. It requires the targeted value not to match `/$` (evaluated at `$.paths.*~`). Severity: error.
$.paths.*~
error
no-api-prefix-in-paths
A resource SHOULD NOT contain 'api' as a prefix in or a part of the path. It requires the targeted value not to match `/api|/api/|-api/` (evaluated at `$.paths.*~`). Severity: error.
$.paths.*~
error
no-empty-path-segments
A resource MUST use normalized paths without empty path segments. It requires the targeted value not to match `//` (evaluated at `$.paths.*~`). Severity: error.
$.paths.*~
warn
limit-path-parameters
The URL path should not contain more than 3 dynamic path parameters. It requires the targeted value not to match `^(.*{{1}.*){4,}` (evaluated at `$.paths.*~`). Severity: warn.
$.paths.*~
warn
limit-nested-sub-resources
The hierarchy of nested resources SHOULD NOT contain more than 8 resource names in the path. It requires the targeted value not to match `^([^/]*/){9,}` (evaluated at `$.paths.*~`). Severity: warn.
$.paths.*~
error
no-http-methods-in-paths
A resource SHOULD NOT contain HTTP methods. It requires the targeted value not to match `(\/get|\/post|\/put|\/delete|\/patch)` (evaluated at `$.paths.*~`). Severity: error.
$.paths.*~
error
path-parameters-camel-case-2
Path parameter keys MUST use camelCase. It requires camel casing on the targeted value (evaluated at `$.paths.*.*.parameters[?(@.in=='path')].name`). Severity: error.
$.paths.*.*.parameters[?(@.in=='path')].name
error
query-parameter-allowed-characters
Query parameter keys MUST include only alpha-numeric characters and periods: [Aa0-Zz9]'. It requires the targeted value to match the pattern `^[A-Za-z0-9\.]+$` (evaluated at `$.paths.*.*.parameters[?(@.in=='query')].name`). Severity: error.
$.paths.*.*.parameters[?(@.in=='query')].name
error
query-parameters-camel-case-2
Query parameter keys MUST use camelCase. It requires camel casing on the targeted value (evaluated at `$.paths.*.*.parameters[?(@.in=='query')].name`). Severity: error.
$.paths.*.*.parameters[?(@.in=='query')].name
error
query-parameters-must-be-optional
Query parameters MUST be optional. It requires the targeted value to be absent or empty (evaluated at `$.paths.*.*.parameters[?(@.in=='query')].required`). Severity: error.
$.paths.*.*.parameters[?(@.in=='query')].required
error
no-api-keys-in-query-parameters
Query parameters MUST not contain sensitive information, like API tokens or keys. It requires the targeted value not to match `apiKey|token` (evaluated at `$.paths.*.*.parameters[?(@.in=='query')].name`). Severity: error.
$.paths.*.*.parameters[?(@.in=='query')].name
warn
no-query-strings-in-paths
Paths SHOULD NOT have query parameters in them. They should be defined separately in the OpenAPI. It requires the targeted value not to match `\?` (evaluated at `$.paths.*~`). Severity: warn.
$.paths.*~
error
response-must-use-json-content-type
API responses should use application/json as the primary content type. Analysis of 773 specs shows application/json is used by 92% of APIs, making it the universal standard for modern REST APIs. It requires the `application/json` field to be present and non-empty (evaluated at `$.paths.*[get,post,put,patch,delete].responses[*].content`). Severity: error.
$.paths.*[get,post,put,patch,delete].responses[*].content
error
request-body-must-use-json-content-type
Request bodies should use application/json as the primary content type for consistency across API operations and client implementations. It requires the `application/json` field to be present and non-empty (evaluated at `$.paths.*[post,put,patch].requestBody.content`). Severity: error.
$.paths.*[post,put,patch].requestBody.content
error
info-description-no-eval-tag
Eval functions MUST not be included in the description of an API, keeping descriptions to just the text that is needed, and relying on the rest of the OpenAPI to describe what is possible. It requires the `description` field not to match `^\b(
$.info
error
info-description-length-limit
Having a restriction on the length of the API description expressed as the OpenAPI info description helps provide constraints for consumers when adding a description, and keeps portals, landing pages, documentation, and discovery results more consistent. It constrains the length of the `description` field and at most 500 (evaluated at `$.info`). Severity: error.
$.info
error
info-description-no-script-tag
Script tags MUST not be included in the description of an API, keeping descriptions to just the text that is needed, and relying on the rest of the OpenAPI to describe what is possible. It requires the `description` field not to match `^\b(
$.info
error
info-require-title
Having a intuitive and helpful title for your API using the OpenAPI info title is the first impression you will make on the consumers of your API. It requires the `title` field to be present and non-empty (evaluated at `$.info`). Severity: error.
$.info
error
info-title-max-length
Having a limitation on the length of the title for your API helps provide constraints for teams naming it, but also keep consistent with other APIs from across teams. It constrains the length of the `title` field and at most 50 (evaluated at `$.info`). Severity: error.
$.info
error
info-title-capitalized
Having a consistent casing for the title for your API helps provide constraints for teams naming the API, but also keep consistent with other APIs from across teams. It requires the targeted value to match the pattern `[A-Z]\w*` (evaluated at `$.info.title`). Severity: error.
$.info.title
warn
operation-description-max-length
Having a length limitation for each description of each API operation helps apply constraints to how you describe your APIs, while helping drive consistency across APIs when it comes to search, documentation, and other ways an API is made available. It constrains the length of the `description` field and at most 250 (evaluated at `$.paths.*[get,post,patch,put,delete]`). Severity: warn.
$.paths.*[get,post,patch,put,delete]
error
operation-require-summary
Having short and intuitive summary for each API operation helps API consumers understand what is possible with each API request. It requires the `summary` field to be present and non-empty (evaluated at `$.paths.*[get,post,patch,put,delete]`). Severity: error.
$.paths.*[get,post,patch,put,delete]
warn
operation-summary-max-length
Apply length constraints to the operation summary helps keep them consistent for publishing in documentation. It constrains the length of the `summary` field and at most 50 (evaluated at `$.paths.*[get,post,patch,put,delete]`). Severity: warn.
$.paths.*[get,post,patch,put,delete]
error
operation-summary-no-period
Operation summaries should not have a period, keeping the primary summary for each API as consistent as possible for publishing in documentation. It requires the targeted value not to match `\.$` (evaluated at `$.paths[*][*].summary`). Severity: error.
$.paths[*][*].summary
error
operation-require-tags
Having tags applied to each API operations helps organize and group APIs in portals, documentation, search, and other ways in which APIs are made available. It requires the `tags` field to be present and non-empty (evaluated at `$.paths.*[get,post,patch,put,delete]`). Severity: error.
$.paths.*[get,post,patch,put,delete]
error
operation-require-one-tag
Having tags applied to each API operations helps organize and group APIs in portals, documentation, search, and other ways in which APIs are made available. It constrains the length of the `tags` field to at least 1 (evaluated at `$.paths.*[get,post,patch,put,delete]`). Severity: error.
$.paths.*[get,post,patch,put,delete]
error
operation-tags-title-case
Having the first letter of each word applied as a tag to API operations helps keep a consistent layout when published via search, documentation, and other ways APIs are made available. It requires the targeted value to match the pattern `[A-Z]\w*` (evaluated at `$.paths.*[get,post,patch,put,delete].tags.*`). Severity: error.
$.paths.*[get,post,patch,put,delete].tags.*
error
schema-require-description
Schema should have descriptions that provide a narrative of what a schema object is for, and how it can be used, leaving examples to demonstrate what can actually be expected. It requires the `description` field to be present and non-empty (evaluated at `$.components.schemas.*`). Severity: error.
$.components.schemas.*
error
schema-description-max-length
Schema should have a length limit applied, restricting how long schema descriptions can be, helping keep them concise and consistent. It constrains the length of the `description` field and at most 250 (evaluated at `$.components.schemas.*`). Severity: error.
$.components.schemas.*
error
schema-require-name
Schema names, keeping the naming of them consistent across APIs, standardizing how consumers can use in their applications. It requires the `@key` field to be present and non-empty (evaluated at `$.components.schemas`). Severity: error.
$.components.schemas
error
schema-name-max-length
Schema should have a length limit applied keeping the names of schema consistent across APIs. It constrains the length of the `@key` field and at most 25 (evaluated at `$.components.schemas`). Severity: error.
$.components.schemas
error
get-define-401-response
GET operations should define a 401 Unauthorized response. Analysis of 773 specs shows 401 is the second most common response code with 4805 occurrences, confirming authentication errors must be documented. It requires the `401` field to be present and non-empty (evaluated at `$.paths[*].get.responses`). Severity: error.
$.paths[*].get.responses
error
post-define-400-response
POST operations should define a 400 Bad Request response for input validation errors. Analysis shows 400 is the 4th most common response code across 2516 operations. It requires the `400` field to be present and non-empty (evaluated at `$.paths[*].post.responses`). Severity: error.
$.paths[*].post.responses
error
post-define-401-response
POST operations should define a 401 Unauthorized response to document authentication requirements for write operations. It requires the `401` field to be present and non-empty (evaluated at `$.paths[*].post.responses`). Severity: error.
$.paths[*].post.responses
error
put-define-401-response
PUT operations should define a 401 Unauthorized response to document authentication requirements for update operations. It requires the `401` field to be present and non-empty (evaluated at `$.paths[*].put.responses`). Severity: error.
$.paths[*].put.responses
error
delete-define-401-response
DELETE operations should define a 401 Unauthorized response to document authentication requirements for destructive operations. It requires the `401` field to be present and non-empty (evaluated at `$.paths[*].delete.responses`). Severity: error.
$.paths[*].delete.responses
error
patch-define-200-response
PATCH operations should define a 200 OK response for successful partial updates. Analysis shows PATCH is used in 17.7% of APIs. It requires the `200` field to be present and non-empty (evaluated at `$.paths[*].patch.responses`). Severity: error.
$.paths[*].patch.responses
error
patch-define-400-response
PATCH operations should define a 400 Bad Request response for validation errors on partial update payloads. It requires the `400` field to be present and non-empty (evaluated at `$.paths[*].patch.responses`). Severity: error.
$.paths[*].patch.responses
error
patch-define-404-response
PATCH operations should define a 404 Not Found response for cases where the resource to be updated does not exist. It requires the `404` field to be present and non-empty (evaluated at `$.paths[*].patch.responses`). Severity: error.
$.paths[*].patch.responses
error
operation-define-429-response
APIs should define a 429 Too Many Requests response to document rate limiting behavior. Analysis shows 429 appears in 671 operations, confirming rate limiting is a common API pattern. It requires the `429` field to be present and non-empty (evaluated at `$.paths.*[get,post,put,patch,delete].responses`). Severity: error.
$.paths.*[get,post,put,patch,delete].responses
error
contact-require-email
Having a contact email address associated with the technical contract ensures that anyone who comes across the API has someone to email and get more information. It requires the `email` field to be present and non-empty (evaluated at `$.info.contact`). Severity: error.
$.info.contact
error
info-require-contact-2
Having a contact object associated with the technical contract ensures that anyone who comes across the API has someone to contact and get more information. It requires the `contact` field to be present and non-empty (evaluated at `$.info`). Severity: error.
$.info
error
contact-require-name
Having a contact name associated with the technical contract ensures that anyone who comes across the API knows who to contact. It requires the `name` field to be present and non-empty (evaluated at `$.info.contact`). Severity: error.
$.info.contact
error
contact-require-url
Having a contact url associated with the technical contract ensures that anyone who comes across the API knows where to go to contact someone. It requires the `url` field to be present and non-empty (evaluated at `$.info.contact`). Severity: error.
$.info.contact
error
require-info-object
Having an info object provides much of the metadata needed for the collection of APIs described in an OpenAPI. It requires the `info` field to be present and non-empty (evaluated at `$`). Severity: error.
$
error
info-require-version
Publishing a version for your OpenAPI technical contract helps you communicate change with consumers using Semantic or date-based versioning published to the info version property. It requires the `version` field to be present and non-empty (evaluated at `$.info`). Severity: error.
$.info
error
info-require-license
Having a license defined in the info object clarifies the terms under which the API can be used. Analysis shows only 44.4% of APIs define a license, but it is essential for API governance and compliance. It requires the `license` field to be present and non-empty (evaluated at `$.info`). Severity: error.
$.info
error
license-require-name
The license object should include a name property identifying the license type, such as Apache 2.0, MIT, or a proprietary license. It requires the `name` field to be present and non-empty (evaluated at `$.info.license`). Severity: error.
$.info.license
error
license-require-url
The license object should include a URL linking to the full license text so API consumers can review the terms. It requires the `url` field to be present and non-empty (evaluated at `$.info.license`). Severity: error.
$.info.license
error
info-require-terms-of-service-2
Having terms of service defined helps API consumers understand usage policies. Analysis shows 51.1% of APIs include terms of service, and it should be standard for any production API. It requires the `termsOfService` field to be present and non-empty (evaluated at `$.info`). Severity: error.
$.info
error
require-external-docs
Defining external documentation provides a link to detailed API guides, tutorials, and reference material beyond the OpenAPI spec. Analysis shows 57.1% of APIs include external docs. It requires the `externalDocs` field to be present and non-empty (evaluated at `$`). Severity: error.
$
error
path-segments-kebab-case-4
API path segments should use kebab-case (lowercase with hyphens). Consistent path naming reduces confusion and improves developer experience across API consumers and documentation. It requires the targeted value to match the pattern `^(/[a-z0-9{}][a-z0-9\-{}]*)*$` (evaluated at `$.paths`). Severity: error.
$.paths
error
paths-no-file-extensions
API paths should not include file extensions like .json or .xml. Content negotiation should be handled through Accept headers rather than path suffixes. It requires the targeted value not to match `\.(json|xml|html|yaml|yml|csv|pdf)$` (evaluated at `$.paths`). Severity: error.
$.paths
error
operation-require-operation-id
Every operation should have an operationId for SDK generation and documentation linking. Analysis shows operationId styles across 8878 operations with camelCase dominant at 92%. It requires the `operationId` field to be present and non-empty (evaluated at `$.paths.*[get,post,put,patch,delete]`). Severity: error.
$.paths.*[get,post,put,patch,delete]
error
schema-properties-camel-case-3
Schema property names should use camelCase. Analysis of 773 specs shows camelCase is the dominant convention at 65% (12958 properties), followed by snake_case at 33% (6661 properties). It requires the targeted value to match the pattern `^[a-z][a-zA-Z0-9]*$` (evaluated at `$.components.schemas[*].properties`). Severity: error.
$.components.schemas[*].properties
error
query-parameters-camel-case-3
Query parameter names should use camelCase for consistency. Analysis shows camelCase is the most common query parameter style at 54% (2519 parameters), followed by snake_case at 36%. It requires camel casing on the `name` field (evaluated at `$.paths[*][*].parameters[?(@.in == 'query')]`). Severity: error.
$.paths[*][*].parameters[?(@.in == 'query')]
error
operation-require-security-2
Each API operation should have a security definition referencing the central security scheme express for an OpenAPI. It requires the `security` field to be present and non-empty (evaluated at `$.paths.*[get,post,patch,put,delete]`). Severity: error.
$.paths.*[get,post,patch,put,delete]
error
operation-require-description
Having a paragraph or two description of each API operation helps API consumers understand what is possible with each API request. It requires the `description` field to be present and non-empty (evaluated at `$.paths.*[get,post,patch,put,delete]`). Severity: error.
$.paths.*[get,post,patch,put,delete]
error
operation-id-camel-case
Operation identifiers provide a unique way to identify each individual API, and requiring them to have consistent casing reduces friction when generating SDKs and automating around APIs. It requires the targeted value to match the pattern `^[a-z]+(?:[A-Z][a-z]+)*$` (evaluated at `$.paths.*[get,post,patch,put,delete].operationId`). Severity: error.
$.paths.*[get,post,patch,put,delete].operationId
error
operation-require-identifier
Operation identifiers provide a unique way to identify each individual API, which then used for SDK generation and other automation. It requires the `operationId` field to be present and non-empty (evaluated at `$.paths.*[get,post,patch,put,delete]`). Severity: error.
$.paths.*[get,post,patch,put,delete]
error
collection-require-limit-parameter
GET operations returning collections should include a limit parameter for pagination. Analysis shows limit is the most common pagination parameter (116 of 773 specs), used in 24% of APIs with pagination. It validates the targeted value against a JSON Schema (evaluated at `$.paths[*].get.parameters[*]`). Severity: error.
$.paths[*].get.parameters[*]
error
pagination-params-in-query
Pagination parameters like page, limit, offset, and cursor should be passed as query parameters, not in headers or path segments. Analysis confirms 100% of pagination parameters observed are query parameters. It requires the `in` field to match the pattern `query` (evaluated at `$.paths[*].get.parameters[?(@.name == 'page' || @.name == 'limit' || @.name == 'offset' || @.name == 'cursor' || @.name == 'per_page' || @.name == 'page_size')]`). Severity: error.
$.paths[*].get.parameters[?(@.name == 'page' || @.name == 'limit' || @.name == 'offset' || @.name == 'cursor' || @.name == 'per_page' || @.name == 'page_size')]
error
parameter-names-camel-case
Providing parameters with consistent naming helps make it easier for API consumers to understand how they are able to configure their API requests. It requires the `name` field not to match `^[a-z]+(?:[A-Z][a-z]+)*$`, and requires the `name` field to match the pattern `^[A-Z](([a-z0-9]+[A-Z]?)*)$` (evaluated at `$.components.parameters.*`). Severity: error.
$.components.parameters.*
warn
parameter-require-description
Having a parameters description provides more depth to what a parameter does and will be displayed via documentation, and other tooling used across the API lifecycle. It requires the `description` field to be present and non-empty (evaluated at `$.paths.*.*.parameters.*`). Severity: warn.
$.paths.*.*.parameters.*
warn
parameter-description-max-length
Limiting the length of parameters description forces us to be more concise in how we describe each parameter, while keeping our documentation and other ways descriptions show up in discovery and portals more consistent. It constrains the length of the `summary` field and at most 500 (evaluated at `$.components.parameters.*`). Severity: warn.
$.components.parameters.*
error
parameter-enum-upper-snake-case
Keeping parameters enumerator casing consistent across APIs helps reduce confusion by consumers, and can keep aligned with services and applications putting an API to work. It requires the targeted value not to match `^[A-Z]+(?:_[A-Z]+)*$` (evaluated at `$.components.parameters.*.enum.*`). Severity: error.
$.components.parameters.*.enum.*
warn
parameter-require-in
Providing an in property for parameters gets explicit about whether a parameter is in the path, query, or a header, making it clear to consumers where they can configure their request. It requires the `in` field to be present and non-empty (evaluated at `$.components.parameters.*`). Severity: warn.
$.components.parameters.*
error
parameter-require-name
Providing a simple, intuitive, and consistent names for your parameters helps make it easier for API consumers to understand how they are able to configure their API requests. It requires the `name` field to be present and non-empty (evaluated at `$.components.parameters.*`). Severity: error.
$.components.parameters.*
warn
parameter-name-max-length
Providing short and concise names for your parameters helps make it easier for API consumers to understand how they are able to configure their API requests. It constrains the length of the `summary` field and at most 25 (evaluated at `$.components.parameters[?(@.in=='path')].name`). Severity: warn.
$.components.parameters[?(@.in=='path')].name
error
parameter-require-required-flag
Providrequiredg an required property for parameters gets explicit about whether a parameter is required the path, query, or a header, making it clear to consumers where they can configure their request. It requires the `required` field to be present and non-empty (evaluated at `$.components.parameters.*`). Severity: error.
$.components.parameters.*
error
require-paths-declared
There must be a paths property and have paths declared, providing the minimum viable definition for an API. It requires the `@key` field not to match `{}` (evaluated at `$.paths`). Severity: error.
$.paths
error
path-max-nesting-depth
API paths should not exceed 4 levels of nesting depth. Analysis of 6627 paths across 773 specs shows an average depth of 3.04 segments, with deeper paths indicating overly complex resource hierarchies. It requires the targeted value not to match `^(/[^/]+){5,}` (evaluated at `$.paths`). Severity: error.
$.paths
warn
path-resources-plural
Resource names in paths should use plural nouns to maintain consistency and follow REST conventions for collection-oriented resource design. It requires the targeted value to match the pattern `^(/[a-z].*s(/\{[^}]+\})?)*$` (evaluated at `$.paths`). Severity: warn.
$.paths
error
delete-no-request-body-2
DELETE HTTP methods should not have a request body, keeping API requests compliant with the HTTP standard. It requires the `requestBody` field to be absent or empty (evaluated at `$.paths.*.delete`). Severity: error.
$.paths.*.delete
error
get-no-request-body-2
GET HTTP methods should not have a request body, keeping API requests compliant with the HTTP standard. It requires the `requestBody` field to be absent or empty (evaluated at `$.paths.*.get`). Severity: error.
$.paths.*.get
error
post-require-request-body
POST HTTP methods can have a request body, providing a structured payload for configuring each API request. It requires the `requestBody` field to be present and non-empty (evaluated at `$.paths.*.post`). Severity: error.
$.paths.*.post
error
put-require-request-body-2
PUT HTTP methods can have a request body, providing a structured payload for configuring each API request. It requires the `requestBody` field to be present and non-empty (evaluated at `$.paths.*.put`). Severity: error.
$.paths.*.put
info
delete-define-204-response
DELETE responses should have a 204 success HTTP status codes, communicating a success created response to consumers. It requires the `204` field to be present and non-empty (evaluated at `$.paths.*.delete.responses`). Severity: info.
$.paths.*.delete.responses
error
delete-404-use-schema-ref
DELETE 404 not found HTTP status codes have a schema references to standardize the response payload returned for the error response. It requires the `$ref` field to be absent or empty (evaluated at `$.paths.*.delete.responses.404`). Severity: error.
$.paths.*.delete.responses.404
error
delete-define-500-response
DELETE responses should have a 500 internal server erorr HTTP status code, communicating the API had a problem to consumers. It requires the `500` field to be present and non-empty (evaluated at `$.paths.*.delete.responses`). Severity: error.
$.paths.*.delete.responses
error
get-define-200-response
GET responses should have a 200 success HTTP status codes, communicating a successful response to consumers. It requires the `200` field to be present and non-empty (evaluated at `$.paths.*.get.responses`). Severity: error.
$.paths.*.get.responses
error
get-define-404-response
GET responses should have a 404 not found HTTP status code, communicating that nothing was found to consumers. It requires the `404` field to be present and non-empty (evaluated at `$.paths.*.get[?(@.properties)]`). Severity: error.
$.paths.*.get[?(@.properties)]
error
get-define-500-response
GET responses should have a 500 internal server erorr HTTP status code, communicating the API had a problem to consumers. It requires the `500` field to be present and non-empty (evaluated at `$.paths.*.get.responses`). Severity: error.
$.paths.*.get.responses
error
post-define-201-response
POST responses should have a 201 success HTTP status codes, communicating a success created response to consumers. It requires the `201` field to be present and non-empty (evaluated at `$.paths[*].post.responses`). Severity: error.
$.paths[*].post.responses
error
post-define-500-response
POST responses should have a 500 internal server erorr HTTP status code, communicating the API had a problem to consumers. It requires the `500` field to be present and non-empty (evaluated at `$.paths.*.post.responses`). Severity: error.
$.paths.*.post.responses
error
put-define-400-response
PUT responses should have a 400 not found HTTP status code, communicating nothing was found to consumers. It requires the `400` field to be present and non-empty (evaluated at `$.paths.*.put.responses`). Severity: error.
$.paths.*.put.responses
error
put-define-500-response
PUT responses should have a 500 internal server erorr HTTP status code, communicating the API had a problem to consumers. It requires the `500` field to be present and non-empty (evaluated at `$.paths.*.put.responses`). Severity: error.
$.paths.*.put.responses
warn
parameter-require-schema
Parameters must always possess a schema to help define the format and shape of the parameter, setting expections with consumers about what should be passed in. It requires the `schema` field to be present and non-empty (evaluated at `$.components.parameters.*`). Severity: warn.
$.components.parameters.*
error
parameter-schema-use-ref
Parameters must always use a schema reference that utilizes reusable schema that are defined as part of a centralized schema components library. It requires the `$ref` field to be absent or empty (evaluated at `$.components.parameters.*.schema`). Severity: error.
$.components.parameters.*.schema
error
parameter-schema-require-type
Parameters must always have their schema type defined, being precise about what type of data can be inputted and used to configure an API request. It requires the `type` field to be present and non-empty (evaluated at `$.components.parameters.*.schema`). Severity: error.
$.components.parameters.*.schema
error
schema-property-require-description
Schema properties should have descriptions that provide a narrative of the property contains, and how it can be used. It requires the `description` field to be present and non-empty (evaluated at `$.components.schemas.*.properties[?(@.type == 'string')]`). Severity: error.
$.components.schemas.*.properties[?(@.type == 'string')]
error
schema-property-description-max-length
Schema property descriptions should have a length limit applied, applying constraints to writing descriptions, and keeping consistent across APIs. It constrains the length of the `description` field and at most 250 (evaluated at `$.components.schemas.*.properties[?(@.type == 'string')]`). Severity: error.
$.components.schemas.*.properties[?(@.type == 'string')]
error
schema-property-enum-upper-snake-case
Schema property enumerators are consistent casing, keeping all entries upper snake case, and consistent across all APIs. It requires the targeted value to match the pattern `^[A-Z]+(?:_[A-Z]+)*$` (evaluated at `$.components.schemas.*.properties.*.enum.*`). Severity: error.
$.components.schemas.*.properties.*.enum.*
error
schema-property-names-camel-case
Schema property names are camel case, providing consistent casing across all the schema properties used by APIs. It requires the `@key` field not to match `^[A-Z][a-z0-9]*[A-Z0-9][a-z0-9]+[A-Za-z0-9]*$` (evaluated at `$.components.schemas.*.properties`). Severity: error.
$.components.schemas.*.properties
error
schema-property-names-length-limit
Schema property names have a length restriction applied, keeping names consistent, and avoiding being too long. It constrains the length of the `@key` field and at most 25 (evaluated at `$.components.schemas.*.properties`). Severity: error.
$.components.schemas.*.properties
error
schema-require-type
Schema should have a type defined, being explicit about type of data a schema describes and can be used to validate, helping standardize the type of data being made available. It requires the `type` field to be present and non-empty (evaluated at `$.components.schemas.*`). Severity: error.
$.components.schemas.*
error
parameter-array-require-items
Parameters that are of an array type should always have the items defined, being explicit about what is continued as part of the array. It requires the `items` field to be present and non-empty (evaluated at `$.components.parameters.schema[?(@.type=='array')]`). Severity: error.
$.components.parameters.schema[?(@.type=='array')]
warn
parameter-integer-require-maximum
Parameters that are of the integer schema type must have their maximum value set, defining the shape of parameter data passed in with a request. It requires the `maximum` field to be present and non-empty (evaluated at `$.apis.*.properties.*`, `$.common.*`). Severity: warn.
$.apis.*.properties.*$.common.*
warn
parameter-integer-require-minimum
Parameters that are of the integer schema type must have their minimum value set, defining the shape of parameter data passed in with a request. It requires the `minimum` field to be present and non-empty (evaluated at `$.apis.*.properties.*`, `$.common.*`). Severity: warn.
$.apis.*.properties.*$.common.*
warn
parameter-string-require-max-length
Parameters that are of the string schema type must have their maximum value set, defining the shape of parameter data passed in with a request. It requires the `maxLength` field to be present and non-empty (evaluated at `$.apis.*.properties.*`, `$.common.*`). Severity: warn.
$.apis.*.properties.*$.common.*
warn
parameter-string-require-min-length
Parameters that are of the string schema type must have their minimum value set, defining the shape of parameter data passed in with a request. It requires the `minLength` field to be present and non-empty (evaluated at `$.apis.*.properties.*`, `$.common.*`). Severity: warn.
$.apis.*.properties.*$.common.*
warn
parameter-string-require-pattern
Parameters that are of the string schema type must have a pattern set, using a regex to define the shape of parameter data passed in with a request. It requires the `pattern` field to be present and non-empty (evaluated at `$.apis.*.properties.*`, `$.common.*`). Severity: warn.
$.apis.*.properties.*$.common.*
error
schema-array-property-require-items
Schema properties that are of the type array must have an items property defined. It requires the `items` field to be present and non-empty (evaluated at `$.components.schemas.*.properties[?(@.type=="array")]`). Severity: error.
$.components.schemas.*.properties[?(@.type=="array")]
error
schema-array-property-require-max-items
Schema properties that are of the type array should have a max items property defined. It requires the `maxItems` field to be present and non-empty (evaluated at `$.components.schemas.*.properties[?(@.type=="array")]`). Severity: error.
$.components.schemas.*.properties[?(@.type=="array")]
error
schema-array-property-require-min-items
Schema properties that are of the type array should have a min items property defined. It requires the `minItems` field to be present and non-empty (evaluated at `$.components.schemas.*.properties[?(@.type=="array")]`). Severity: error.
$.components.schemas.*.properties[?(@.type=="array")]
error
schema-number-property-require-maximum
Schema properties that are of the type number should have a maximum property defined. It requires the `maximum` field to be defined (evaluated at `$.components.schemas.*.properties[?(@.type=="number")]`). Severity: error.
$.components.schemas.*.properties[?(@.type=="number")]
error
schema-number-property-require-minimum
Schema properties that are of the type number should have a minimum property defined. It requires the `minimum` field to be defined (evaluated at `$.components.schemas.*.properties[?(@.type=="number")]`). Severity: error.
$.components.schemas.*.properties[?(@.type=="number")]
error
schema-string-property-require-max-length
Schema properties that are of the string type have the max length applied defining the shape of the property. It requires the `maxLength` field to be present and non-empty (evaluated at `$.components.schemas.*.properties[?(@.type == 'string')]`). Severity: error.
$.components.schemas.*.properties[?(@.type == 'string')]
error
schema-string-property-require-min-length
Schema properties that are of the string type have the min length applied defining the shape of the property. It requires the `minLength` field to be present and non-empty (evaluated at `$.components.schemas.*.properties[?(@.type == 'string')]`). Severity: error.
$.components.schemas.*.properties[?(@.type == 'string')]
error
tags-require-description
Tags used as part of an OpenAPI should have descriptions, providing more of a narrative behind what a tag means when it is applied to an API. It requires the `description` field to be present and non-empty (evaluated at `$.tags[*]`). Severity: error.
$.tags[*]
error
tags-require-name
Tags used as part of an OpenAPI should have names, providing a simple key word or phrase that represents the tag being applied to APIs. It requires the `name` field to be present and non-empty (evaluated at `$.tags[*]`). Severity: error.
$.tags[*]
error
require-tags-object
There needs to be a central tags object applied to the OpenAPI, providing central tags that can be applied across all operations within an OpenAPI. It requires the `tags` field to be present and non-empty (evaluated at `$`). Severity: error.
$
error
require-at-least-one-tag
There needs to be at least one tag applied to an OpenAPI, providing a key word or phrase that can be applied to API operations. It constrains the length of the `tags` field to at least 1 (evaluated at `$`). Severity: error.
$
error
tag-names-title-case
The first letter of each word in a tag being applied to APIs needs to be capitalized, keeping the tags being applied across APIs the same look and feel for organizing and publishing to documentation. It requires the targeted value to match the pattern `[A-Z]\w*` (evaluated at `$.tags.*.name`). Severity: error.
$.tags.*.name
error
require-openapi-version-3x
APIs should use OpenAPI 3.x specification. Analysis of 773 API specs shows 97% use OpenAPI 3.x, with 86% on 3.1.0, making it the dominant standard for modern API definitions. It requires the `openapi` field to match the pattern `^3\.` (evaluated at `$`). Severity: error.
$
error
require-servers-defined
Every OpenAPI should define at least one server URL. Analysis shows 97.2% of APIs define servers, providing consumers with the base URL needed to make requests. It requires the `servers` field to be present and non-empty (evaluated at `$`). Severity: error.
$
error
server-url-require-https
API server URLs should use HTTPS to ensure encrypted communication between clients and servers, protecting sensitive data in transit. It requires the `url` field to match the pattern `^https://` (evaluated at `$.servers[*]`). Severity: error.
$.servers[*]
error
paths-no-version-segment
API paths should not contain version numbers like v1 or v2. API versioning should be handled through headers, query parameters, or server URLs rather than embedded in resource paths. It requires the targeted value not to match `/v[0-9]` (evaluated at `$.paths`). Severity: error.
$.paths

Spectral Ruleset

spotlight-rules-recommended.yml Raw ↑
# Spotlight Rules — spotlight-recommended ruleset (verbatim)
# generated: 
# method: searched
# source: https://raw.githubusercontent.com/api-commons/spotlight-validator/main/rules/spotlight-recommended.yaml
# note: Published by the Spotlight Rules project (api-commons/spotlight-validator, CNAME
#   validator.spotlight-rules.com). Compiled by Spotlight from public Spectral rulesets;
#   each rule carries source:* / category:* / format:* tags for attribution. Body below is
#   byte-for-byte as served; only these comment lines were prepended.
description: Spotlight best-of-breed API governance ruleset, compiled from
  public Spectral rulesets. Select rules with tags (source:*, category:*,
  format:*).
documentationUrl: https://github.com/api-commons/spotlight-validator
extends:
  - - spotlight:oas
    - recommended
rules:
  path-segments-kebab-case:
    description: "All YAML/JSON paths MUST follow kebab-case. It requires the
      targeted value to match the pattern
      `^/([a-z0-9]+(-[a-z0-9]+)*)?(/[a-z0-9]+(-[a-z0-9]+)*|/{.+})*$` (evaluated
      at `$.paths[*]~`). Severity: warn."
    severity: warn
    recommended: true
    message: "{{property}} is not kebab-case: {{error}}"
    given: $.paths[*]~
    then:
      function: pattern
      functionOptions:
        match: ^/([a-z0-9]+(-[a-z0-9]+)*)?(/[a-z0-9]+(-[a-z0-9]+)*|/{.+})*$
    tags:
      - source:adidas
      - format:openapi
      - spec:paths
      - experience:naming
      - experience:consistency
  path-parameters-camel-case:
    description: "Path parameters MUST follow camelCase. It requires the targeted
      value to match the pattern `^[a-z][a-zA-Z0-9]+$` (evaluated at
      `$..parameters[?(@.in == 'path')].name`). Severity: warn."
    severity: warn
    recommended: true
    message: "{{property}} path parameter is not camelCase: {{error}}"
    given: $..parameters[?(@.in == 'path')].name
    then:
      function: pattern
      functionOptions:
        match: ^[a-z][a-zA-Z0-9]+$
    tags:
      - source:adidas
      - format:openapi
      - spec:parameters
      - experience:naming
      - experience:consistency
  schema-definitions-camel-case:
    description: "All YAML/JSON definitions MUST follow fields-camelCase and be
      ASCII alphanumeric characters or `_` or `$`. It requires the targeted
      value to match the pattern `/^[a-z$_]{1}[A-Z09$_]*/` (evaluated at
      `$.definitions[*]~`). Severity: error."
    severity: error
    recommended: true
    message: "{{property}} MUST follow camelCase and be ASCII alphanumeric
      characters or `_` or `$`."
    given: $.definitions[*]~
    then:
      function: pattern
      functionOptions:
        match: /^[a-z$_]{1}[A-Z09$_]*/
    tags:
      - source:adidas
      - format:openapi
      - spec:document
      - experience:naming
      - experience:consistency
  schema-properties-camel-case:
    description: "All JSON Schema properties MUST follow fields-camelCase and be
      ASCII alphanumeric characters or `_` or `$`. It requires the targeted
      value to match the pattern `/^[a-z$_]{1}[A-Z09$_]*/` (evaluated at
      `$.definitions..properties[*]~`). Severity: error."
    severity: error
    recommended: true
    message: "{{property}} MUST follow camelCase and be ASCII alphanumeric
      characters or `_` or `$`."
    given: $.definitions..properties[*]~
    then:
      function: pattern
      functionOptions:
        match: /^[a-z$_]{1}[A-Z09$_]*/
    tags:
      - source:adidas
      - format:openapi
      - spec:schemas
      - experience:naming
      - experience:consistency
  header-names-hyphenated-pascal-case:
    description: "All `HTTP` headers MUST use `Hyphenated-Pascal-Case` notation. It
      requires the targeted value to match the pattern
      `/^([A-Z][a-z0-9]-)*([A-Z][a-z0-9])+/` (evaluated at `$..parameters[?(@.in
      == 'header')].name`). Severity: error."
    severity: error
    given: $..parameters[?(@.in == 'header')].name
    message: "'HTTP' headers MUST follow 'Hyphenated-Pascal-Case' notation"
    recommended: true
    type: style
    then:
      function: pattern
      functionOptions:
        match: /^([A-Z][a-z0-9]-)*([A-Z][a-z0-9])+/
    tags:
      - source:adidas
      - format:openapi
      - spec:parameters
      - spec:headers
      - experience:naming
      - experience:consistency
      - source:sps-commerce
  request-support-json-media-type:
    description: "Every request MUST support `application/json` media type. It
      requires the targeted value to be absent or empty (evaluated at
      `$.paths.[*].requestBody.content[?(@property.indexOf('json') === -1)]^`).
      Severity: error."
    formats:
      - oas3
    recommended: true
    severity: error
    message: "{{description}}: {{error}}"
    given: $.paths.[*].requestBody.content[?(@property.indexOf('json') === -1)]^
    then:
      function: falsy
    tags:
      - source:adidas
      - format:openapi
      - spec:paths
      - spec:request-body
      - spec:media-types
      - experience:consistency
      - experience:usability
  require-https-servers:
    description: "ALL requests MUST go through `https` protocol only. It requires
      the targeted value to match the pattern `/^https:/` (evaluated at
      `$.servers..url`). Severity: error."
    formats:
      - oas3
    recommended: true
    severity: error
    message: Servers MUST be https and no other protocol is allowed.
    given: $.servers..url
    then:
      function: pattern
      functionOptions:
        match: /^https:/
    tags:
      - source:adidas
      - format:openapi
      - spec:servers
      - experience:security
  success-response-use-hal-json:
    description: 'All success responses MUST be of media type
      `application/hal+json`. It requires the targeted value to be one of
      ["application/hal+json"] (evaluated at `$.paths..responses[?( @property >=
      201 && @property < 300 && @property != 204)].content[*]~`). Severity:
      error.'
    severity: error
    given: $.paths..responses[?( @property >= 201 && @property < 300 && @property !=
      204)].content[*]~
    recommended: true
    formats:
      - oas3
    message: "Response documents MUST be of application/hal+json media types: {{error}}"
    then:
      function: enumeration
      functionOptions:
        values:
          - application/hal+json
    tags:
      - source:adidas
      - format:openapi
      - spec:paths
      - spec:responses
      - spec:media-types
      - experience:consistency
      - experience:data-modeling
  ok-response-use-hal-or-problem-json:
    description: 'All success responses MUST be of media type `application/hal+json`
      or `application/problem+json`. It requires the targeted value to be one of
      ["application/hal+json","application/problem+json"] (evaluated at
      `$.paths..responses[?( @property == 200 )].content[*]~`). Severity:
      error.'
    severity: error
    given: $.paths..responses[?( @property == 200 )].content[*]~
    recommended: true
    formats:
      - oas3
    message: "Response documents MUST be of application/hal+json or
      application/problem+json media types: {{error}}"
    then:
      function: enumeration
      functionOptions:
        values:
          - application/hal+json
          - application/problem+json
    tags:
      - source:adidas
      - format:openapi
      - spec:paths
      - spec:responses
      - spec:media-types
      - experience:consistency
      - experience:data-modeling
  success-response-match-hal-schema:
    description: 'All success responses MUST follow `application/hal+json` schema.
      It validates the `schema` field against a JSON Schema (evaluated at
      `$.paths..responses[?( @property == 200 && @property < 300 && @property !=
      204)].content[?(@property === "application/hal+json")]`). Severity:
      error.'
    severity: error
    given: $.paths..responses[?( @property == 200 && @property < 300 && @property !=
      204)].content[?(@property === "application/hal+json")]
    recommended: true
    type: style
    formats:
      - oas3
    message: "Response documents MUST follow application/hal+json schema: {{error}}"
    then:
      field: schema
      function: schema
      functionOptions:
        schema:
          $ref: ./supermodel/adidas/api/HAL.yaml
    tags:
      - source:adidas
      - format:openapi
      - spec:paths
      - spec:responses
      - spec:media-types
      - experience:data-modeling
      - experience:consistency
  get-no-request-body:
    description: "GET requests MUST NOT have a request body. It requires the
      targeted value to be absent or empty (evaluated at
      `$.paths[*].get.requestBody`). Severity: error."
    severity: error
    recommended: true
    formats:
      - oas3
    given: $.paths[*].get.requestBody
    then:
      function: falsy
      message: "{{description}}: {{error}}"
    tags:
      - source:adidas
      - format:openapi
      - spec:paths
      - spec:operations
      - spec:request-body
      - experience:consistency
      - experience:usability
  post-not-for-retrieval:
    description: "POST requests SHOULD NOT be used for retrieving information. Use
      GET instead. It requires the `summary` field not to match
      `(retrieve|fetch|get|read)` (evaluated at `$.paths[*].post`). Severity:
      error."
    severity: error
    recommended: true
    formats:
      - oas3
    given: $.paths[*].post
    then:
      field: summary
      function: pattern
      functionOptions:
        notMatch: (retrieve|fetch|get|read)
      message: "{{description}}: {{error}}"
    tags:
      - source:adidas
      - format:openapi
      - spec:paths
      - spec:operations
      - experience:consistency
      - experience:usability
  put-require-request-body:
    description: "PUT requests MUST have a request body. It requires the
      `requestBody` field to be present and non-empty (evaluated at
      `$.paths[*].put`). Severity: error."
    severity: error
    recommended: true
    formats:
      - oas3
    given: $.paths[*].put
    then:
      field: requestBody
      function: truthy
      message: "{{description}}: {{error}}"
    tags:
      - source:adidas
      - format:openapi
      - spec:paths
      - spec:operations
      - experience:consistency
      - experience:usability
  delete-no-request-body:
    description: "DELETE requests MUST NOT have a request body. It requires the
      targeted value to be absent or empty (evaluated at
      `$.paths[*].delete.requestBody`). Severity: error."
    severity: error
    recommended: true
    formats:
      - oas3
    given: $.paths[*].delete.requestBody
    then:
      function: falsy
      message: "{{description}}: {{error}}"
    tags:
      - source:adidas
      - format:openapi
      - spec:paths
      - spec:operations
      - spec:request-body
      - experience:consistency
      - experience:usability
  paths-no-verbs:
    description: "API paths MUST be resource-focused and MUST NOT include verbs like
      'get', 'update', 'create', or 'delete'. It requires the targeted value not
      to match `/\\b(get|update|create|delete|fetch|retrieve)\\b/` (evaluated at
      `$.paths[*]~`). Severity: warn."
    severity: warn
    recommended: true
    formats:
      - oas3
    message: Path '{{path}}' includes a verb (e.g., 'get', 'update', 'create',
      'delete'). API paths SHOULD be resource-focused.
    given: $.paths[*]~
    then:
      function: pattern
      functionOptions:
        notMatch: /\b(get|update|create|delete|fetch|retrieve)\b/
    tags:
      - source:adidas
      - format:openapi
      - spec:paths
      - experience:naming
      - experience:consistency
  require-realistic-examples:
    description: "API design SHOULD include real-like examples for request and
      response definitions. It requires the `example` field to be present and
      non-empty (evaluated at `$..[?(@.example || @.examples)]`). Severity:
      warn."
    severity: warn
    recommended: true
    formats:
      - oas3
    message: The {{property}} SHOULD include a real-like example. Add realistic
      examples to improve API usability.
    given: $..[?(@.example || @.examples)]
    then:
      field: example
      function: truthy
    tags:
      - source:adidas
      - format:openapi
      - spec:examples
      - experience:documentation
      - experience:usability
  version-semantic-and-stable:
    description: "The API contract MUST have a stable version and MUST follow
      semantic versioning (e.g., '1.0.0'). Words like 'SNAPSHOT' or 'RELEASE'
      are not allowed. It requires the targeted value to match the pattern
      `^(?!.*\\b(SNAPSHOT|RELEASE)\\b)(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\
      \\d*)$` (evaluated at `$.info.version`). Severity: error."
    severity: error
    recommended: true
    formats:
      - oas3
    message: "{{description}}: {{error}}"
    given: $.info.version
    then:
      function: pattern
      functionOptions:
        match: ^(?!.*\b(SNAPSHOT|RELEASE)\b)(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$
    tags:
      - source:adidas
      - format:openapi
      - spec:info
      - experience:versioning
      - experience:consistency
  require-root-security:
    description: "The API contract MUST include a 'security' section at the root
      level. It requires the `security` field to be present and non-empty
      (evaluated at `$`). Severity: error."
    severity: error
    recommended: true
    formats:
      - oas3
    message: "{{description}}: {{error}}"
    given: $
    then:
      field: security
      function: truthy
    tags:
      - source:adidas
      - format:openapi
      - spec:document
      - experience:security
      - experience:governance
  require-components-section:
    description: "The API contract MUST include a 'components' section. It requires
      the `components` field to be present and non-empty (evaluated at `$`).
      Severity: error."
    severity: error
    recommended: true
    formats:
      - oas3
    message: "{{description}}: {{error}}"
    given: $
    then:
      field: components
      function: truthy
    tags:
      - source:adidas
      - format:openapi
      - spec:document
      - experience:consistency
      - experience:governance
  require-security-schemes:
    description: "The API contract MUST include a 'securitySchemes' subsection under
      the 'components' section. It requires the `securitySchemes` field to be
      present and non-empty (evaluated at `$.components`). Severity: error."
    severity: error
    recommended: true
    formats:
      - oas3
    message: "{{description}}: {{error}}"
    given: $.components
    then:
      field: securitySchemes
      function: truthy
    tags:
      - source:adidas
      - format:openapi
      - spec:components
      - experience:security
      - experience:governance
      - source:api-evangelist
  info-require-leanix-id:
    description: "The API contract SHOULD include a custom field 'x-leanixid' in the
      'info' section. It requires the `x-leanixid` field to be present and
      non-empty (evaluated at `$.info`). Severity: warn."
    severity: warn
    recommended: true
    formats:
      - oas3
    message: "{{description}}: {{error}}"
    given: $.info
    then:
      field: x-leanixid
      function: truthy
    tags:
      - source:adidas
      - format:openapi
      - spec:info
      - experience:governance
      - experience:discoverability
  leanix-id-valid-uuid:
    description: "The API contract SHOULD include a custom field 'x-leanixid'
      containing a valid UUID. It requires the targeted value to match the
      pattern
      `^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]\
      {12}$` (evaluated at `$.info.x-leanixid`). Severity: warn."
    severity: warn
    recommended: true
    formats:
      - oas3
    message: "{{description}}: {{error}}"
    given: $.info.x-leanixid
    then:
      function: pattern
      functionOptions:
        match: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$
    tags:
      - source:adidas
      - format:openapi
      - spec:info
      - experience:governance
      - experience:consistency
  info-require-gateway:
    description: "The API contract SHOULD include a custom field 'x-gateway' in the
      'info' section. It requires the `x-gateway` field to be present and
      non-empty (evaluated at `$.info`). Severity: warn."
    severity: warn
    recommended: true
    formats:
      - oas3
    message: "{{description}}: {{error}}"
    given: $.info
    then:
      field: x-gateway
      function: truthy
    tags:
      - source:adidas
      - format:openapi
      - spec:info
      - experience:governance
  gateway-from-allowed-list:
    description: "The 'x-gateway' property, if present, MUST have a value in the
      enumeration: kong, nginx, aws, akamai, sap, other. It requires the
      `x-gateway` field to be one of
      [\"kong\",\"nginx\",\"aws\",\"akamai\",\"sap\",\"other\"] (evaluated at
      `$`). Severity: warn."
    severity: warn
    recommended: true
    formats:
      - oas3
    given: $
    then:
      field: x-gateway
      function: enumeration
      functionOptions:
        values:
          - kong
          - nginx
          - aws
          - akamai
          - sap
          - other
    tags:
      - source:adidas
      - format:openapi
      - spec:document
      - experience:governance
      - experience:consistency
  responses-include-hypermedia-links:
    description: "The API contract MAY include hypermedia links to represent the
      state of resources and be navigable. It requires the `links` field to be
      present and non-empty (evaluated at `$.paths[*][*].responses[*]`).
      Severity: hint."
    severity: hint
    recommended: true
    formats:
      - oas3
    message: "{{description}}: {{error}}"
    given: $.paths[*][*].responses[*]
    then:
      field: links
      function: truthy
    tags:
      - source:adidas
      - format:openapi
      - spec:paths
      - spec:responses
      - experience:discoverability
      - experience:usability
  uri-versioning-single-version:
    message: Path can contain correct URI versioning
    description: "CAN use correct URI versioning [115a]. It requires the targeted
      value to match the pattern `^((?!.*\\/v\\d+(\\/.*)?\\/v\\d+)\\/.*)$`
      (evaluated at `$.paths.*~`). Severity: error."
    documentationUrl: https://github.com/baloise-incubator/spectral-ruleset/blob/main/doc/rules/can-use-correct-URI-versioning.test.md
    severity: error
    given: $.paths.*~
    then:
      function: pattern
      functionOptions:
        match: ^((?!.*\/v\d+(\/.*)?\/v\d+)\/.*)$
    tags:
      - source:baloise
      - format:openapi
      - spec:paths
      - experience:versioning
      - experience:consistency
  property-names-camel-case:
    message: Property name has to be ASCII camelCase
    description: "MUST property names must be ASCII camelCase [118a]. It requires
      the targeted value to match the pattern
      `^[a-z]+((\\d)|([A-Z0-9][a-z0-9]+))*([A-Z])?$` (evaluated at
      `$.paths.*.*[responses,requestBody]..content..schema..properties.*~`).
      Severity: error."
    documentationUrl: https://github.com/baloise-incubator/spectral-ruleset/blob/main/doc/rules/property-names-must-be-ascii-camel-case.md
    severity: error
    given: $.paths.*.*[responses,requestBody]..content..schema..properties.*~
    then:
      function: pattern
      functionOptions:
        match: ^[a-z]+((\d)|([A-Z0-9][a-z0-9]+))*([A-Z])?$
    tags:
      - source:baloise
      - format:openapi
      - spec:paths
      - spec:request-body
      - spec:responses
      - spec:media-types
      - spec:schemas
      - experience:naming
      - experience:consistency
  use-standard-status-codes:
    message: "{{property}} is not a standardized response code"
    description: 'MUST use standard HTTP status codes [150a]. It requires the
      targeted value to be one of
      ["100","101","200","201","202","203","204","205","206","207","300","301","302","303","304","305","307","400","401","402","403","404","405","406","407","408","409","410","411","412","413","414","415","416","417","422","423","426","428","429","431","500","501","502","503","504","505","511","default"]
      (evaluated at `$.paths.*.*.responses.*~`). Severity: error.'
    documentationUrl: https://github.com/baloise-incubator/spectral-ruleset/blob/main/doc/rules/must-use-additional-standard-http-status-codes.md
    severity: error
    given: $.paths.*.*.responses.*~
    then:
      function: enumeration
      functionOptions:
        values:
          - "100"
          - "101"
          - "200"
          - "201"
          - "202"
          - "203"
          - "204"
          - "205"
          - "206"
          - "207"
          - "300"
          - "301"
          - "302"
          - "303"
          - "304"
          - "305"
          - "307"
          - "400"
          - "401"
          - "402"
          - "403"
          - "404"
          - "405"
          - "406"
          - "407"
          - "408"
          - "409"
          - "410"
          - "411"
          - "412"
          - "413"
          - "414"
          - "415"
          - "416"
          - "417"
          - "422"
          - "423"
          - "426"
          - "428"
          - "429"
          - "431"
          - "500"
          - "501"
          - "502"
          - "503"
          - "504"
          - "505"
          - "511"
          - default
    tags:
      - source:baloise
      - format:openapi
      - spec:paths
      - spec:responses
      - experience:error-handling
      - experience:consistency
  prefer-400-over-422:
    message: Prefer 400 over 422 as response code
    description: "MUST use standard HTTP status codes [150a]. It requires the `422`
      field to be defined (evaluated at `$.paths.*.*.responses.422`). Severity:
      warn."
    documentationUrl: https://github.com/baloise-incubator/spectral-ruleset/blob/main/doc/rules/must-use-additional-standard-http-status-codes.md
    severity: warn
    given: $.paths.*.*.responses.422
    then:
      field: "422"
      function: defined
    tags:
      - source:baloise
      - format:openapi
      - spec:paths
      - spec:responses
      - experience:error-handling
      - experience:consistency
  operation-well-understood-status-codes:
    message: "{{error}}"
    description: "MUST use standard HTTP status codes [150]. It applies a custom
      validation to the targeted value (evaluated at `$.paths.*`). Severity:
      warn."
    documentationUrl: https://github.com/baloise-incubator/spectral-ruleset/blob/main/doc/rules/should-use-additional-well-understood-http-status-codes.md
    severity: warn
    given: $.paths.*
    then:
      function: baloise:assert-http-codes-for-operation
      functionOptions:
        wellUnderstood:
          "200":
            - ALL
          "201":
            - POST
            - PUT
          "202":
            - POST
            - PUT
            - DELETE
            - PATCH
          "204":
            - PUT
            - DELETE
            - PATCH
          "207":
            - POST
          "301":
            - ALL
          "303":
            - PATCH
            - POST
            - PUT
            - DELETE
          "304":
            - GET
            - HEAD
          "400":
            - ALL
          "401":
            - ALL
          "403":
            - ALL
          "404":
            - ALL
          "405":
            - ALL
          "406":
            - ALL
          "408":
            - ALL
          "409":
            - POST
            - PUT
            - DELETE
            - PATCH
          "410":
            - ALL
          "412":
            - PUT
            - DELETE
            - PATCH
          "415":
            - POST
            - PUT
            - DELETE
            - PATCH
          "422":
            - ALL
          "423":
            - PUT
            - DELETE
            - PATCH
          "428":
            - ALL
          "429":
            - ALL
          "500":
            - ALL
          "501":
            - ALL
          "503":
            - ALL
          default:
            - ALL
    tags:
      - source:baloise
      - format:openapi
      - spec:paths
      - experience:error-handling
      - experience:consistency
  require-tracing-headers:
    message: Header X-B3-Traceid, X-B3-Spanid or traceparent (w3c) missing
    description: "MUST use b3 or w3c tracing [233a]. It applies a custom validation
      to the targeted value (evaluated at `$.paths.*`). Severity: error."
    documentationUrl: https://github.com/baloise-incubator/spectral-ruleset/blob/main/doc/rules/requests-must-use-tracing.md
    severity: error
    given: $.paths.*
    then:
      function: baloise:validate-tracing
    tags:
      - source:baloise
      - format:openapi
      - spec:paths
      - experience:reliability
      - experience:governance
  info-require-audience:
    message: Missing or wrong `info.x-audience`.
    description: "MUST provide API audience [219]. It requires the `x-audience`
      field to be present and non-empty, and requires the `x-audience` field to
      match the pattern
      `^(team-internal|domain-internal|company-internal|external-partner|extern\
      al-public)$` (evaluated at `$.info`). Severity: error."
    documentationUrl: https://github.com/baloise-incubator/spectral-ruleset/blob/main/doc/rules/property-names-must-be-ascii-camel-case.md
    severity: error
    given: $.info
    then:
      - field: x-audience
        function: truthy
      - field: x-audience
        function: pattern
        functionOptions:
          match: ^(team-internal|domain-internal|company-internal|external-partner|external-public)$
    tags:
      - source:baloise
      - format:openapi
      - spec:info
      - experience:governance
      - experience:discoverability
  query-parameters-camel-case:
    message: Query parameter name has to be ASCII camelCase
    description: "MUST query parameter names must be ASCII camelCase [130a]. It
      requires the targeted value to match the pattern
      `^[a-z]+((\\d)|([A-Z0-9][a-z0-9]+))*([A-Z])?$` (evaluated at
      `$.paths.*.*.parameters[?(@ && @.in=='query')].name`). Severity: error."
    documentationUrl: https://github.com/baloise-incubator/spectral-ruleset/blob/main/doc/rules/query-parameter-names-must-be-ascii-camel-case.md
    severity: error
    given: $.paths.*.*.parameters[?(@ && @.in=='query')].name
    then:
      function: pattern
      functionOptions:
        match: ^[a-z]+((\d)|([A-Z0-9][a-z0-9]+))*([A-Z])?$
    tags:
      - source:baloise
      - format:openapi
      - spec:paths
      - spec:parameters
      - experience:naming
      - experience:consistency
  responses-include-ratelimit-headers:
    description: "Response must include ratelimit-x headers. It requires the
      `headers.ratelimit-limit` field to be present and non-empty, and requires
      the `headers.ratelimit-remaining` field to be present and non-empty, and
      requires the `headers.ratelimit-reset` field to be present and non-empty
      (evaluated at `$..responses.*`). Severity: error."
    message: "{{description}}; missing {{property}}"
    severity: error
    given: $..responses.*
    then:
      - field: headers.ratelimit-limit
        function: truthy
      - field: headers.ratelimit-remaining
        function: truthy
      - field: headers.ratelimit-reset
        function: truthy
    tags:
      - source:digitalocean
      - format:openapi
      - spec:responses
      - experience:reliability
      - experience:documentation
  properties-require-examples:
    description: "Object properties must include examples. It applies a custom
      validation to the targeted value (evaluated at
      `$..properties..properties.*`). Severity: error."
    given: $..properties..properties.*
    severity: error
    message: "{{description}}; {{property}}"
    then:
      function: digitalocean:ensurePropertiesExample
    tags:
      - source:digitalocean
      - format:openapi
      - spec:schemas
      - experience:documentation
      - experience:usability
  parameters-require-examples:
    description: 'Parameters must include examples. It requires exactly one of
      ["example","examples"] to be present (evaluated at `$..parameters.*`).
      Severity: error.'
    given: $..parameters.*
    severity: error
    message: "{{description}}; missing {{property}}"
    then:
      function: xor
      functionOptions:
        properties:
          - example
          - examples
    tags:
      - source:digitalocean
      - format:openapi
      - spec:parameters
      - experience:documentation
      - experience:usability
  headers-require-examples:
    description: "Headers must include examples. It applies a custom validation to
      the targeted value (evaluated at `$..headers.*`). Severity: error."
    given: $..headers.*
    severity: error
    message: "{{description}}; missing {{property}}"
    then:
      function: digitalocean:ensurePropertiesExample
    tags:
      - source:digitalocean
      - format:openapi
      - spec:headers
      - experience:documentation
      - experience:usability
  operations-use-ref:
    description: "Endpoint must be a $ref. It requires the `$ref` field to be
      present and non-empty (evaluated at `$.paths.*.*`). Severity: error."
    message: "{{description}}; {{property}} incorrect"
    severity: error
    resolved: false
    given: $.paths.*.*
    then:
      field: $ref
      function: truthy
    tags:
      - source:digitalocean
      - format:openapi
      - spec:paths
      - experience:consistency
      - experience:governance
  paths-include-version:
    description: "Path must include the version. It requires the targeted value to
      match the pattern `^(/v[12]/.*|/api/v[12]/.*)$` (evaluated at
      `$.paths[?(@property!='/<upload_url>')]~`). Severity: error."
    message: "{{description}}; {{property}} incorrect"
    severity: error
    resolved: false
    given: $.paths[?(@property!='/<upload_url>')]~
    then:
      function: pattern
      functionOptions:
        match: ^(/v[12]/.*|/api/v[12]/.*)$
    tags:
      - source:digitalocean
      - format:openapi
      - spec:paths
      - experience:versioning
      - experience:consistency
  operation-ref-resource-file:
    description: "Endpoint must a $ref to a file in resources/. It requires the
      targeted value to match the pattern `^resources/.*yml$` (evaluated at
      `$.paths.*.$ref`). Severity: error."
    message: "{{description}}; {{value}} incorrect"
    severity: error
    resolved: false
    given: $.paths.*.$ref
    then:
      function: pattern
      functionOptions:
        match: ^resources/.*yml$
    tags:
      - source:digitalocean
      - format:openapi
      - spec:paths
      - experience:consistency
      - experience:governance
  responses-define-401:
    description: "Responses should contain common response - 401 (unauthorized). It
      requires the `401` field to be present and non-empty (evaluated at
      `$.paths..responses`). Severity: error."
    message: "{{description}}. Missing {{property}}"
    severity: error
    given: $.paths..responses
    then:
      field: "401"
      function: truthy
    tags:
      - source:digitalocean
      - format:openapi
      - spec:paths
      - spec:responses
      - experience:error-handling
      - experience:documentation
  responses-define-404:
    description: "Responses should contain common response - 404 (not found). It
      requires the `404` field to be present and non-empty (evaluated at
      `$.paths[?(@property.match(/.*\\/{.*}.*/))]..responses`). Severity:
      error."
    message: "{{description}}. Missing {{property}}"
    severity: error
    given: $.paths[?(@property.match(/.*\/{.*}.*/))]..responses
    then:
      field: "404"
      function: truthy
    tags:
      - source:digitalocean
      - format:openapi
      - spec:paths
      - spec:responses
      - experience:error-handling
      - experience:documentation
  responses-define-429:
    description: "Responses should contain common response - 429 (too many
      requests). It requires the `429` field to be present and non-empty
      (evaluated at `$.paths..responses`). Severity: error."
    message: "{{description}}. Missing {{property}}"
    severity: error
    given: $.paths..responses
    then:
      field: "429"
      function: truthy
    tags:
      - source:digitalocean
      - format:openapi
      - spec:paths
      - spec:responses
      - experience:error-handling
      - experience:relia

# --- truncated at 32 KB (242 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/spotlight-rules/refs/heads/main/rules/spotlight-rules-recommended.yml

Work with this as data

Every ruleset here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for spectral rules

4 MCP tools reach this
  • find_rulesBrowse and filter every ruleset in the catalog.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This ruleset
curl "https://apis.io/api/v1/rules/spotlight-rules-recommended"
All spectral rules
curl "https://apis.io/api/v1/rules?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.