# harvested from https://github.com/BBVA/apicheck/blob/8f455e8d3863c56ed75fc5d68df0a52830c7749b/tools-edge/oas-checker/spectral.yml on 2026-10-09 — a Spectral ruleset published in the provider's own GitHub repository (BBVA/apicheck); found by GitHub code search, fetched verbatim x-method: harvested x-stamped: 2026-10-09 x-source-url: https://github.com/BBVA/apicheck/blob/8f455e8d3863c56ed75fc5d68df0a52830c7749b/tools-edge/oas-checker/spectral.yml # # See technical recommendations on Italian Guidelines # in https://github.com/italia/api-oas-checker for discussing rules. # # extends: spectral:oas # Skipping has-x-summary: off # Skipping has-x-api-id: off # Skipping number-format: off # Skipping integer-format: off # Skipping allowed-integer-format: off # Skipping allowed-number-format: off rules: paths-kebab-case: description: | Paths should be kebab-case. message: "{{property}} is not kebab-case: {{error}}" severity: warn recommended: true given: $.paths[*]~ then: function: pattern functionOptions: match: ^(/[a-z0-9-.]+|/{[a-zA-Z0-9_]+})+$ request-headers-pascal-case: description: | Headers should be pascal-case. message: "{{value}} {{error}} in {{path}}" severity: hint recommended: true given: - $.[parameters][?(@.in=="header")].name then: function: casing functionOptions: type: pascal separator: char: "-" response-headers-pascal-case: description: | Headers should be pascal-case. message: "Header {{error}}: {{path}}" severity: hint recommended: true given: - $.[responses][*].headers.*~ then: function: casing functionOptions: type: pascal separator: char: "-" no-forbidden-headers: description: OAS do not allow using Authorization, Content-Type and Accept in the spec. message: "{{error}} in {{path}} {{value}}" severity: error given: - $..parameters[?(@.in == 'header')].name - $.[responses][*].headers.*~ then: function: pattern functionOptions: notMatch: /^(accept|content-type|authorization)$/i no-x-headers-request: description: All 'HTTP' headers SHOULD NOT include 'X-' headers (https://tools.ietf.org/html/rfc6648). severity: warn given: - $..parameters[?(@.in == 'header')].name message: HTTP header '{{value}}' SHOULD NOT include 'X-' prefix in {{path}} recommended: true type: style then: function: pattern functionOptions: match: /^([^x]|.[^-])|RateLimit-/i no-x-headers-response: description: All 'HTTP' headers SHOULD NOT include 'X-' headers (https://tools.ietf.org/html/rfc6648). severity: warn given: - $.[responses][*].headers.*~ message: HTTP response header SHOULD NOT include 'X-' prefix in {{path}} recommended: true type: style then: function: pattern functionOptions: match: /^([^x]|.[^-])|RateLimit-/i servers-description: description: Servers must have a description. message: Server {{path}} must have a description. given: $.servers[*] severity: error recommended: true then: field: description function: truthy servers-use-https: description: Servers must use https message: "Non-sandbox url {{value}} {{error}}. Add `x-sandbox: true` to declare the server as a sandbox." given: $.servers[?(@["x-sandbox"] != true)] severity: error recommended: true then: field: url function: pattern functionOptions: match: ^https://.* has-termsOfService: description: "API MUST reference the URL of the Terms of Service in #/info/termsOfService" given: $ severity: error recommended: true type: style formats: - oas3 then: field: info.termsOfService function: truthy has-contact: description: "API MUST reference a contact, either url or email in #/info/contact" given: $ severity: error recommended: true type: style formats: - oas3 then: field: info.contact function: truthy use-semver: severity: error recommended: true message: |- Specs should follow semantic versioning. {{value}} is not a valid version. See https://semver.org/#semantic-versioning-specification-semver given: $.info.version then: function: pattern functionOptions: match: ^[0-9]+.[0-9]+.[0-9]+(-[a-z0-9+.-]+)? oas2: false no-swagger-2: description: Swagger 2 files are not allowed. Use OpenAPI >= 3.0 given: $ severity: error recommended: true type: style formats: - oas2 then: field: swagger function: falsy patch-media-type: description: application/json is not an appropriate media-type for PATCH. message: application/json is not an appropriate media-type for PATCH. {{path}} See https://www.rfc-editor.org/errata/eid3169 formats: - oas3 severity: error recommended: true given: $.[patch][requestBody][content] then: field: application/json function: falsy use-problem-json-for-errors: description: "Error responses should support [RFC 7807](https://tools.ietf.org/html/rfc7807) " message: Error responses should support [RFC 7807](https://tools.ietf.org/html/rfc7807) in {{path}}. formats: - oas3 severity: error given: $.paths.[*].responses[?(@property.match(/^(4|5|default)/))].content.*~ then: function: enumeration functionOptions: values: - application/problem+xml - application/problem+json use-problem-schema: description: >- WARN: This rule is under implementation. Your problem schema doesn't seem to match RFC7807. Are you sure it is ok? message: Your schema doesn't seem to match RFC7807. Are you sure it is ok? {{path}} formats: - oas3 severity: hint recommended: false given: $.paths.[*].responses[?(@property.match(/^(4|5|default)/))][[schema]] then: function: schema functionOptions: schema: type: object properties: status: type: integer title: type: string detail: type: string hint-problem-schema: description: Your problem schema doesn't seem to match RFC7807. Are you sure it is ok? message: Error response doesn't seem to match RFC7807. Are you sure it is ok? {{path}} formats: - oas3 severity: hint recommended: true given: $.[responses][?(@property.match(/^(4|5|default)/))][[schema]][properties].*~ then: field: "@key" function: pattern functionOptions: notMatch: message|code|msg missing-retry-after: description: APIs should use Retry-After on 429 and 503 responses. message: "Missing ratelimit header: {{property}} in {{path}}" formats: - oas3 severity: warn recommended: true given: $.[responses][?(@property == "429" || @property == "503" )][headers] then: field: Retry-After function: truthy missing-ratelimit: description: APIs should use ratelimit headers at least on successful responses. message: Missing ratelimit headers. {{property}} {{error}} {{path}} formats: - oas3 severity: warn recommended: true given: $.[responses][?(@property[0] == "2" )][headers] then: - functionOptions: properties: - X-RateLimit-Limit - RateLimit-Limit function: xor - functionOptions: properties: - X-RateLimit-Remaining - RateLimit-Remaining function: xor - functionOptions: properties: - X-RateLimit-Reset - RateLimit-Reset function: xor # # Extra security rule # response-with-json-object: message: JSON responses must use json objects (eg "{}"), not {{value}}. {{path}} severity: warn recommended: true given: $.[responses][*][content][?(@property.match("json$"))][schema] then: field: type function: pattern functionOptions: match: object array-boundaries: description: Arrays should be limited. message: Schema of type array must specify maxItems and minItems. {{path}} {{error}} formats: - oas3 severity: warn recommended: true given: - $.[?(@.type=="array")] then: - field: maxItems function: defined - field: minItems function: defined number-boundaries: description: Schema of type number or integer must specify a maximum and a minimum. message: Schema of type number or integer must specify a maximum and a minimum. {{path}} {{error}} formats: - oas3 severity: warn recommended: true given: - $.[?(@.type=="number")] - $.[?(@.type=="integer")] then: - field: maximum function: defined - field: minimum function: defined string-maxlength: description: String length should be limited. message: Strings (non enum) must specify a maximum length. {{path}} {{error}} formats: - oas3 severity: warn recommended: true given: - $.[?(@.type=="string" && !@.enum )] then: - field: maxLength function: defined string-pattern-or-format-or-enum: description: String values should be constrained. message: Strings (non enum) must specify a pattern or a format. {{path}} formats: - oas3 severity: hint recommended: true given: - $.[[?( @.type == "string" && !@.enum )]] then: function: schema functionOptions: schema: type: object anyOf: - required: - pattern - required: - format additionalProperties: true