documentationUrl: https://spec.openlint.org/
functions:
- baloise-assert-http-codes-for-operation
- trimble-check-description-for-all-error-responses
- trimble-check-standard-for-error-payload
- trimble-operation-post-201-202-status-code
- trimble-valid-http-response
functionsDir: ./functions
rules:
  openapi-operation-define-429-response:
    description: 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.
    message: Operations MUST Have 429 Response
    severity: info
    given: $.paths.*[get,post,put,patch,delete].responses
    then:
      field: '429'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-operation-define-429-response
  openapi-operation-define-500-response:
    description: Every endpoint SHOULD have a 500 response.
    message: Every endpoint SHOULD have a 500 response.
    severity: info
    given: $.paths[*][*]
    then:
      field: responses.500
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-operation-define-500-response
  openapi-operation-well-understood-status-codes:
    description: MUST use standard HTTP status codes [150].
    message: '{{error}}'
    severity: info
    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
    documentationUrl: https://apicommons.org/rules/#openapi-operation-well-understood-status-codes
  openapi-response-400-require-body:
    description: All 400 responses must include a response body.
    message: All 400 responses must include a response body.
    severity: info
    given:
    - $.paths.*.*.responses['400']
    then:
      field: content
      function: truthy
    formats:
    - oas3
    documentationUrl: https://apicommons.org/rules/#openapi-response-400-require-body
  openapi-response-code-must-be-valid:
    description: All APIs should return a valid http response code.
    message: '{{error}}'
    severity: info
    given: $..responses
    then:
      field: '@key'
      function: trimble-valid-http-response
    documentationUrl: https://apicommons.org/rules/#openapi-response-code-must-be-valid
  openapi-response-define-401:
    description: Responses should contain common response - 401 (unauthorized).
    message: '{{description}}. Missing {{property}}'
    severity: info
    given: $.paths..responses
    then:
      field: '401'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-define-401
  openapi-response-define-404:
    description: Responses should contain common response - 404 (not found).
    message: '{{description}}. Missing {{property}}'
    severity: info
    given: $.paths[?(@property.match(/.*\/{.*}.*/))]..responses
    then:
      field: '404'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-define-404
  openapi-response-define-429:
    description: Responses should contain common response - 429 (too many requests).
    message: '{{description}}. Missing {{property}}'
    severity: info
    given: $.paths..responses
    then:
      field: '429'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-define-429
  openapi-response-define-500:
    description: Responses should contain common response - 500 (server error).
    message: '{{description}}. Missing {{property}}'
    severity: info
    given: $.paths..responses
    then:
      field: '500'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-define-500
  openapi-response-delete-404-use-schema-ref:
    description: DELETE 404 not found HTTP status codes have a schema references to standardize the response payload returned
      for the error response.
    message: DELETE 404 Responses MUST Use Schema Reference
    severity: info
    given: $.paths.*.delete.responses.404
    then:
      field: $ref
      function: falsy
    documentationUrl: https://apicommons.org/rules/#openapi-response-delete-404-use-schema-ref
  openapi-response-delete-codes-allowed:
    description: DELETE operations should not return 200 or 201 status codes.
    message: DELETE operations should not return 200 or 201 status codes.
    severity: info
    given: $.paths[*].delete.responses
    then:
      field: '@key'
      function: pattern
      functionOptions:
        notMatch: ^(200|201)$
    documentationUrl: https://apicommons.org/rules/#openapi-response-delete-codes-allowed
  openapi-response-delete-define-401:
    description: DELETE operations should define a 401 Unauthorized response to document authentication requirements for destructive
      operations.
    message: DELETE MUST Have 401 Response
    severity: info
    given: $.paths[*].delete.responses
    then:
      field: '401'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-delete-define-401
  openapi-response-delete-define-500:
    description: DELETE responses should have a 500 internal server erorr HTTP status code, communicating the API had a problem
      to consumers.
    message: DELETE Responses MUST Have 500 Status Codes
    severity: info
    given: $.paths.*.delete.responses
    then:
      field: '500'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-delete-define-500
  openapi-response-delete-require-204:
    description: All DELETE methods MUST have a 204 response.
    message: All DELETE methods MUST have a 204 response.
    severity: info
    given:
    - $.paths[*].delete.responses
    then:
      field: '204'
      function: truthy
    formats:
    - oas3
    documentationUrl: https://apicommons.org/rules/#openapi-response-delete-require-204
  openapi-response-error-match-problem-schema:
    description: '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.'
    message: Your schema doesn't seem to match RFC 9457. Are you sure it is ok? {{path}}
    severity: info
    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
    formats:
    - oas3
    documentationUrl: https://apicommons.org/rules/#openapi-response-error-match-problem-schema
  openapi-response-error-require-description:
    description: Check if the response description is appropriate for all requests.
    message: '{{error}}'
    severity: info
    given: $.paths.*.*.responses
    then:
      function: trimble-check-description-for-all-error-responses
    documentationUrl: https://apicommons.org/rules/#openapi-response-error-require-description
  openapi-response-error-schema-problem-property-names:
    description: '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.'
    message: Error response doesn't seem to match RFC 9457. Are you sure it is ok? {{path}}
    severity: info
    given: $.[responses][?(@property.match(/^(4|5|default)/))][[schema]][properties].*~
    then:
      field: '@key'
      function: pattern
      functionOptions:
        notMatch: message|code|msg
    formats:
    - oas3
    documentationUrl: https://apicommons.org/rules/#openapi-response-error-schema-problem-property-names
  openapi-response-error-standard-payload:
    description: All 4XX and 5XX response codes must follow Trimble API Standard.
    message: '{{error}}'
    severity: info
    given: $.paths.*.*.responses
    then:
      function: trimble-check-standard-for-error-payload
    documentationUrl: https://apicommons.org/rules/#openapi-response-error-standard-payload
  openapi-response-error-use-problem-json:
    description: All 4xx and 5xx error responses MUST use the `application/problem+json` media type (RFC 9457, which obsoleted
      RFC 7807).
    message: 'Error response documents MUST use the application/problem+json media type: {{error}}'
    severity: info
    given: $.paths..responses[?( @property >= 400 && @property < 600)].content[*]~
    then:
      function: enumeration
      functionOptions:
        values:
        - application/problem+json
    formats:
    - oas3
    documentationUrl: https://apicommons.org/rules/#openapi-response-error-use-problem-json
  openapi-response-error-use-problem-type:
    description: '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: ... ```.'
    message: Error responses should support RFC 9457 in {{path}}.
    severity: info
    given: $.paths.[*].responses[?(@property.match(/^(4|5|default)/))].content.*~
    then:
      function: enumeration
      functionOptions:
        values:
        - application/problem+xml
        - application/problem+json
    formats:
    - oas3
    documentationUrl: https://apicommons.org/rules/#openapi-response-error-use-problem-type
  openapi-response-error-use-problem-type-2:
    formats:
    - oas3
    description: Every error response SHOULD support RFC 9457.
    message: Every error response SHOULD support RFC 9457.
    severity: info
    given: $.paths...responses[?(@property.match(/^(4|5)/))].content.*~
    then:
      function: enumeration
      functionOptions:
        values:
        - application/problem+xml
        - application/problem+json
    documentationUrl: https://apicommons.org/rules/#openapi-response-error-use-problem-type-2
  openapi-response-get-codes-allowed:
    description: GET operations should not use status codes 201, 202, 204, 409, 412.
    message: GET operations should not use status codes 201, 202, 204, 409, 412.
    severity: info
    given: $.paths[*].get.responses
    then:
      field: '@key'
      function: pattern
      functionOptions:
        notMatch: ^(201|202|204|409|412)$
    documentationUrl: https://apicommons.org/rules/#openapi-response-get-codes-allowed
  openapi-response-get-define-401:
    description: 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.
    message: GET MUST Have 401 Response
    severity: info
    given: $.paths[*].get.responses
    then:
      field: '401'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-get-define-401
  openapi-response-get-define-500:
    description: GET responses should have a 500 internal server erorr HTTP status code, communicating the API had a problem
      to consumers.
    message: GET Responses MUST Have 500 Status Code
    severity: info
    given: $.paths.*.get.responses
    then:
      field: '500'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-get-define-500
  openapi-response-get-must-return-200:
    description: GET operations must always return 200 status code.
    message: GET operations must always return 200 status code.
    severity: info
    given: $.paths[*].get.responses
    then:
    - field: '200'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-get-must-return-200
  openapi-response-head-codes-allowed:
    description: HEAD operations should not return 201, 202, 204, 409, 412 status codes.
    message: HEAD operations should not return 201, 202, 204, 409, 412 status codes.
    severity: info
    given: $.paths[*].head.responses
    then:
      field: '@key'
      function: pattern
      functionOptions:
        notMatch: ^(201|202|204|409|412)$
    documentationUrl: https://apicommons.org/rules/#openapi-response-head-codes-allowed
  openapi-response-location-header-only-on-201:
    description: Location header MUST NOT be present in non-201 responses.
    message: Location header MUST NOT be present in non-201 responses.
    severity: info
    given: $.paths[*][*].responses[?(@property !== '201')].headers
    then:
      field: Location
      function: falsy
    documentationUrl: https://apicommons.org/rules/#openapi-response-location-header-only-on-201
  openapi-response-options-codes-allowed:
    description: OPTIONS operations should not return 201, 202, 409, 412 status codes.
    message: OPTIONS operations should not return 201, 202, 409, 412 status codes.
    severity: info
    given: $.paths[*].options.responses
    then:
      field: '@key'
      function: pattern
      functionOptions:
        notMatch: ^(201|202|409|412)$
    documentationUrl: https://apicommons.org/rules/#openapi-response-options-codes-allowed
  openapi-response-patch-codes-allowed:
    description: PATCH operations should not return 201 status code.
    message: PATCH operations should not return 201 status code.
    severity: info
    given: $.paths[*].patch.responses
    then:
      field: '@key'
      function: pattern
      functionOptions:
        notMatch: ^201$
    documentationUrl: https://apicommons.org/rules/#openapi-response-patch-codes-allowed
  openapi-response-patch-define-200:
    description: PATCH operations should define a 200 OK response for successful partial updates. Analysis shows PATCH is
      used in 17.7% of APIs.
    message: PATCH MUST Have 200 Response
    severity: info
    given: $.paths[*].patch.responses
    then:
      field: '200'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-patch-define-200
  openapi-response-patch-define-400:
    description: PATCH operations should define a 400 Bad Request response for validation errors on partial update payloads.
    message: PATCH MUST Have 400 Response
    severity: info
    given: $.paths[*].patch.responses
    then:
      field: '400'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-patch-define-400
  openapi-response-patch-define-404:
    description: PATCH operations should define a 404 Not Found response for cases where the resource to be updated does not
      exist.
    message: PATCH MUST Have 404 Response
    severity: info
    given: $.paths[*].patch.responses
    then:
      field: '404'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-patch-define-404
  openapi-response-post-codes-allowed:
    description: POST operations should not return 412 status codes.
    message: POST operations should not return 412 status codes.
    severity: info
    given: $.paths[*].post.responses
    then:
      field: '@key'
      function: pattern
      functionOptions:
        notMatch: '412'
    documentationUrl: https://apicommons.org/rules/#openapi-response-post-codes-allowed
  openapi-response-post-define-400:
    description: 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.
    message: POST MUST Have 400 Response
    severity: info
    given: $.paths[*].post.responses
    then:
      field: '400'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-post-define-400
  openapi-response-post-define-401:
    description: POST operations should define a 401 Unauthorized response to document authentication requirements for write
      operations.
    message: POST MUST Have 401 Response
    severity: info
    given: $.paths[*].post.responses
    then:
      field: '401'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-post-define-401
  openapi-response-post-define-500:
    description: POST responses should have a 500 internal server erorr HTTP status code, communicating the API had a problem
      to consumers.
    message: POST Responses MUST Have 500 Status Codes
    severity: info
    given: $.paths.*.post.responses
    then:
      field: '500'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-post-define-500
  openapi-response-post-require-201-or-202:
    description: All POST methods MUST have a 201 or 202 response.
    message: All POST methods MUST have a 201 or 202 response.
    severity: info
    given:
    - $.paths[*].post.responses
    then:
      function: trimble-operation-post-201-202-status-code
    formats:
    - oas3
    documentationUrl: https://apicommons.org/rules/#openapi-response-post-require-201-or-202
  openapi-response-prefer-400-over-422:
    description: MUST use standard HTTP status codes [150a].
    message: Prefer 400 over 422 as response code
    severity: info
    given: $.paths.*.*.responses.422
    then:
      field: '422'
      function: defined
    documentationUrl: https://apicommons.org/rules/#openapi-response-prefer-400-over-422
  openapi-response-put-codes-allowed:
    description: PUT operations should not return 200 or 201 status codes.
    message: PUT operations should not return 200 or 201 status codes.
    severity: info
    given: $.paths[*].put.responses
    then:
      field: '@key'
      function: pattern
      functionOptions:
        notMatch: ^(200|201)$
    documentationUrl: https://apicommons.org/rules/#openapi-response-put-codes-allowed
  openapi-response-put-define-400:
    description: PUT responses should have a 400 not found HTTP status code, communicating nothing was found to consumers.
    message: PUT Responses MUST Have 400 Status Codes
    severity: info
    given: $.paths.*.put.responses
    then:
      field: '400'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-put-define-400
  openapi-response-put-define-401:
    description: PUT operations should define a 401 Unauthorized response to document authentication requirements for update
      operations.
    message: PUT MUST Have 401 Response
    severity: info
    given: $.paths[*].put.responses
    then:
      field: '401'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-put-define-401
  openapi-response-put-define-500:
    description: PUT responses should have a 500 internal server erorr HTTP status code, communicating the API had a problem
      to consumers.
    message: PUT Responses MUST Have 500 Status Codes
    severity: info
    given: $.paths.*.put.responses
    then:
      field: '500'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-response-put-define-500
  openapi-response-status-path-problem-schema-fields:
    formats:
    - oas3
    description: '"/status" schema is not a Problem object.'
    message: '{{error}} {{path}}'
    severity: info
    given: $.paths.'/status'.get.responses.200.content.[[schema]]
    then:
    - function: truthy
      field: properties.status
    - function: truthy
      field: properties.title
    - function: truthy
      field: properties.detail
    documentationUrl: https://apicommons.org/rules/#openapi-response-status-path-problem-schema-fields
  openapi-response-status-path-problem-schema-fields-oas2:
    formats:
    - oas2
    description: '"/status" schema is not a Problem object.'
    message: '{{error}} {{path}}'
    severity: info
    given: $.paths.'/status'.get.responses.200.schema
    then:
    - function: truthy
      field: properties.status
    - function: truthy
      field: properties.title
    - function: truthy
      field: properties.detail
    documentationUrl: https://apicommons.org/rules/#openapi-response-status-path-problem-schema-fields-oas2
  openapi-response-status-path-return-problem-type:
    formats:
    - oas3
    description: '"/status" must return a Problem object.'
    message: '{{error}}'
    severity: info
    given: $.paths.'/status'.get.responses.200.content.*~
    then:
      function: enumeration
      functionOptions:
        values:
        - application/problem+xml
        - application/problem+json
    documentationUrl: https://apicommons.org/rules/#openapi-response-status-path-return-problem-type
  openapi-response-status-path-return-problem-type-oas2:
    formats:
    - oas2
    description: '"/status" must be produced as a Problem media type.'
    message: '{{error}}'
    severity: info
    given: $.paths.'/status'.get.produces[*]
    then:
      function: enumeration
      functionOptions:
        values:
        - application/problem+xml
        - application/problem+json
    documentationUrl: https://apicommons.org/rules/#openapi-response-status-path-return-problem-type-oas2
  openapi-response-throttled-require-retry-after:
    description: '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.'
    message: 'Missing ratelimit header: {{property}} in {{path}}'
    severity: info
    given: $.[responses][?(@property == "429" || @property == "503"  )][headers]
    then:
      field: Retry-After
      function: truthy
    formats:
    - oas3
    documentationUrl: https://apicommons.org/rules/#openapi-response-throttled-require-retry-after
  openapi-response-use-standard-status-codes:
    description: MUST use standard HTTP status codes [150a].
    message: '{{property}} is not a standardized response code'
    severity: info
    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
    documentationUrl: https://apicommons.org/rules/#openapi-response-use-standard-status-codes
  openapi-response-use-standard-status-codes-2:
    description: An API MUST return HTTP response codes in conformance with RFC-2616 and common usage.
    message: An API MUST return HTTP response codes in conformance with RFC-2616 and common usage.
    severity: info
    given: $.paths...responses.*~
    then:
      function: enumeration
      functionOptions:
        values:
        - '200'
        - '201'
        - '202'
        - '204'
        - '400'
        - '401'
        - '403'
        - '404'
        - '405'
        - '406'
        - '409'
        - '412'
        - '415'
        - '428'
        - '429'
        - '500'
    documentationUrl: https://apicommons.org/rules/#openapi-response-use-standard-status-codes-2
  openapi-schema-get-define-404-response:
    description: GET responses should have a 404 not found HTTP status code, communicating that nothing was found to consumers.
    message: GET Responses MUST Have 404 Status Code
    severity: info
    given: $.paths.*.get[?(@.properties)]
    then:
      field: '404'
      function: truthy
    documentationUrl: https://apicommons.org/rules/#openapi-schema-get-define-404-response
