---
id: https://spec.openapis.org/oas/3.0/schema/2019-04-02
"$schema": http://json-schema.org/draft-04/schema#
description: Validation schema for OpenAPI Specification 3.0.X.
type: object
required:
- openapi
- info
- paths
properties:
  openapi:
    type: string
    pattern: "^3\\.0\\.\\d(-.+)?$"
  info:
    $ref: "#/definitions/Info"
  externalDocs:
    $ref: "#/definitions/ExternalDocumentation"
  servers:
    type: array
    items:
      $ref: "#/definitions/Server"
  security:
    type: array
    items:
      $ref: "#/definitions/SecurityRequirement"
  tags:
    type: array
    items:
      $ref: "#/definitions/Tag"
    ### disabled, see 
    ### test/unit/plugins/json-schema-validator/test-documents/tag-object-uniqueness.yaml 
    # uniqueItems: true 
  paths:
    $ref: "#/definitions/Paths"
  components:
    $ref: "#/definitions/Components"
patternProperties:
  "^x-": {}
additionalProperties: false
definitions:
  Reference:
    type: object
    required:
    - $ref
    properties:
      $ref:
        type: string
        format: uri-reference
  Info:
    type: object
    required:
    - title
    - version
    properties:
      title:
        type: string
      description:
        type: string
      termsOfService:
        type: string
        format: uri-reference
      contact:
        $ref: "#/definitions/Contact"
      license:
        $ref: "#/definitions/License"
      version:
        type: string
    patternProperties:
      "^x-": {}
    additionalProperties: false
  Contact:
    type: object
    properties:
      name:
        type: string
      url:
        type: string
        format: uri-reference
      email:
        type: string
        format: email
    patternProperties:
      "^x-": {}
    additionalProperties: false
  License:
    type: object
    required:
    - name
    properties:
      name:
        type: string
      url:
        type: string
        format: uri-reference
    patternProperties:
      "^x-": {}
    additionalProperties: false
  Server:
    type: object
    required:
    - url
    properties:
      url:
        type: string
      description:
        type: string
      variables:
        type: object
        additionalProperties:
          $ref: "#/definitions/ServerVariable"
    patternProperties:
      "^x-": {}
    additionalProperties: false
  ServerVariable:
    type: object
    required:
    - default
    properties:
      enum:
        type: array
        items:
          type: string
      default:
        type: string
      description:
        type: string
    patternProperties:
      "^x-": {}
    additionalProperties: false
  Components:
    type: object
    properties:
      schemas:
        type: object
        patternProperties:
          "^[a-zA-Z0-9\\.\\-_]+$":
            switch:
            - if:
                required: [$ref]
              then:
                $ref: "#/definitions/Reference"
            - then:
                $ref: "#/definitions/Schema"
      responses:
        type: object
        patternProperties:
          "^[a-zA-Z0-9\\.\\-_]+$":
            switch:
            - if:
                required: [$ref]
              then:
                $ref: "#/definitions/Reference"
            - then:
                $ref: "#/definitions/Response"
      parameters:
        type: object
        patternProperties:
          "^[a-zA-Z0-9\\.\\-_]+$":
            switch:
            - if:
                required: [$ref]
              then:
                $ref: "#/definitions/Reference"
            - then:
                $ref: "#/definitions/Parameter"
      examples:
        type: object
        patternProperties:
          "^[a-zA-Z0-9\\.\\-_]+$":
            switch:
            - if:
                required: [$ref]
              then:
                $ref: "#/definitions/Reference"
            - then:
                $ref: "#/definitions/Example"
      requestBodies:
        type: object
        patternProperties:
          "^[a-zA-Z0-9\\.\\-_]+$":
            switch:
            - if:
                required: [$ref]
              then:
                $ref: "#/definitions/Reference"
            - then:
                $ref: "#/definitions/RequestBody"
      headers:
        type: object
        patternProperties:
          "^[a-zA-Z0-9\\.\\-_]+$":
            switch:
            - if:
                required: [$ref]
              then:
                $ref: "#/definitions/Reference"
            - then:
                $ref: "#/definitions/Header"
      securitySchemes:
        type: object
        patternProperties:
          "^[a-zA-Z0-9\\.\\-_]+$":
            switch:
            - if:
                required: [$ref]
              then:
                $ref: "#/definitions/Reference"
            - then:
                $ref: "#/definitions/SecurityScheme"
      links:
        type: object
        patternProperties:
          "^[a-zA-Z0-9\\.\\-_]+$":
            switch:
            - if:
                required: [$ref]
              then:
                $ref: "#/definitions/Reference"
            - then:
                $ref: "#/definitions/Link"
      callbacks:
        type: object
        patternProperties:
          "^[a-zA-Z0-9\\.\\-_]+$":
            switch:
            - if:
                required: [$ref]
              then:
                $ref: "#/definitions/Reference"
            - then:
                $ref: "#/definitions/Callback"
    patternProperties:
      "^x-": {}
    additionalProperties: false
  Schema:
    type: object
    properties:
      title:
        type: string
      multipleOf:
        type: number
        minimum: 0
        exclusiveMinimum: true
      maximum:
        type: number
      exclusiveMaximum:
        type: boolean
        default: false
      minimum:
        type: number
      exclusiveMinimum:
        type: boolean
        default: false
      maxLength:
        type: integer
        minimum: 0
      minLength:
        type: integer
        minimum: 0
        default: 0
      pattern:
        type: string
        format: regex
      maxItems:
        type: integer
        minimum: 0
      minItems:
        type: integer
        minimum: 0
        default: 0
      uniqueItems:
        type: boolean
        default: false
      maxProperties:
        type: integer
        minimum: 0
      minProperties:
        type: integer
        minimum: 0
        default: 0
      required:
        type: array
        items:
          type: string
        minItems: 1
        uniqueItems: true
        errorMessage: 
          type: "should be an array of property names required within an object schema"
      enum:
        type: array
        items: {}
        minItems: 1
        uniqueItems: false
      type:
        type: string
        enum:
        - array
        - boolean
        - integer
        - number
        - object
        - string
      not:
        switch:
          - if:
              required: [$ref]
            then:
              $ref: "#/definitions/Reference"
          - then:
              $ref: "#/definitions/Schema"
      allOf:
        type: array
        items:
          switch:
          - if:
              required: [$ref]
            then:
              $ref: "#/definitions/Reference"
          - then:
              $ref: "#/definitions/Schema"
      oneOf:
        type: array
        items:
          switch:
          - if:
              required: [$ref]
            then:
              $ref: "#/definitions/Reference"
          - then:
              $ref: "#/definitions/Schema"
      anyOf:
        type: array
        items:
          switch:
          - if:
              required: [$ref]
            then:
              $ref: "#/definitions/Reference"
          - then:
              $ref: "#/definitions/Schema"
      items:
        switch:
        - if:
            required: [$ref]
          then:
            $ref: "#/definitions/Reference"
        - then:
            $ref: "#/definitions/Schema"
      properties:
        type: object
        additionalProperties:
          switch:
          - if:
              required: [$ref]
            then:
              $ref: "#/definitions/Reference"
          - then:
              $ref: "#/definitions/Schema"
      additionalProperties:
        default: true
        switch:
        - if:
            type: object
            required: [$ref]
          then:
            $ref: "#/definitions/Reference"
        - if: 
            type: object
          then:
            $ref: "#/definitions/Schema"
        - then: 
            type: boolean
            errorMessage: "should be a Reference Object, Schema Object, or boolean value"
      description:
        type: string
      format:
        type: string
      default: {}
      nullable:
        type: boolean
        default: false
      discriminator:
        $ref: "#/definitions/Discriminator"
      readOnly:
        type: boolean
        default: false
      writeOnly:
        type: boolean
        default: false
      example: {}
      externalDocs:
        $ref: "#/definitions/ExternalDocumentation"
      deprecated:
        type: boolean
        default: false
      xml:
        $ref: "#/definitions/XML"
    patternProperties:
      "^x-": {}
    additionalProperties: false
  Discriminator:
    type: object
    required:
    - propertyName
    properties:
      propertyName:
        type: string
      mapping:
        type: object
        additionalProperties:
          type: string
  XML:
    type: object
    properties:
      name:
        type: string
      namespace:
        type: string
        format: uri
      prefix:
        type: string
      attribute:
        type: boolean
        default: false
      wrapped:
        type: boolean
        default: false
    patternProperties:
      "^x-": {}
    additionalProperties: false
  Response:
    type: object
    required:
    - description
    properties:
      description:
        type: string
      headers:
        type: object
        additionalProperties:
          switch:
          - if:
              required: [$ref]
            then:
              $ref: "#/definitions/Reference"
          - then:
              $ref: "#/definitions/Header"
      content:
        type: object
        additionalProperties:
          $ref: "#/definitions/MediaType"
      links:
        type: object
        additionalProperties:
          switch:
          - if:
              required: [$ref]
            then:
              $ref: "#/definitions/Reference"
          - then:
              $ref: "#/definitions/Link"
    patternProperties:
      "^x-": {}
    additionalProperties: false
  MediaType:
    type: object
    properties:
      schema:
        switch:
        - if:
            required: [$ref]
          then:
            $ref: "#/definitions/Reference"
        - then:
            $ref: "#/definitions/Schema"
      example: {}
      examples:
        type: object
        additionalProperties:
          switch:
          - if:
              required: [$ref]
            then:
              $ref: "#/definitions/Reference"
          - then:
              $ref: "#/definitions/Example"
      encoding:
        type: object
        additionalProperties:
          $ref: "#/definitions/Encoding"
    patternProperties:
      "^x-": {}
    additionalProperties: false
    allOf:
    - $ref: "#/definitions/ExampleXORExamples"
  Example:
    type: object
    properties:
      summary:
        type: string
      description:
        type: string
      value: {}
      externalValue:
        type: string
        format: uri-reference
    patternProperties:
      "^x-": {}
    additionalProperties: false
  Header:
    type: object
    properties:
      description:
        type: string
      required:
        type: boolean
        default: false
      deprecated:
        type: boolean
        default: false
      allowEmptyValue:
        type: boolean
        default: false
      style:
        type: string
        enum:
        - simple
        default: simple
      explode:
        type: boolean
      allowReserved:
        type: boolean
        default: false
      schema:
        switch:
        - if:
            required: [$ref]
          then:
            $ref: "#/definitions/Reference"
        - then:
            $ref: "#/definitions/Schema"
      content:
        type: object
        additionalProperties:
          $ref: "#/definitions/MediaType"
        minProperties: 1
        maxProperties: 1
      example: {}
      examples:
        type: object
        additionalProperties:
          switch:
          - if:
              required: [$ref]
            then:
              $ref: "#/definitions/Reference"
          - then:
              $ref: "#/definitions/Example"
    patternProperties:
      "^x-": {}
    additionalProperties: false
    allOf:
    - $ref: "#/definitions/ExampleXORExamples"
    - $ref: "#/definitions/SchemaXORContent"
  Paths:
    type: object
    patternProperties:
      "^\\/":
        $ref: "#/definitions/PathItem"
      "^x-": {}
    additionalProperties: false
    errorMessage:
      additionalProperties: "should only have path names that start with `/`"
  PathItem:
    type: object
    properties:
      $ref:
        type: string
      summary:
        type: string
      description:
        type: string
      servers:
        type: array
        items:
          $ref: "#/definitions/Server"
      parameters:
        type: array
        items:
          switch:
          - if:
              required: [$ref]
            then:
              $ref: "#/definitions/Reference"
          - then:
              $ref: "#/definitions/Parameter"
        uniqueItems: true
    patternProperties:
      "^(get|put|post|delete|options|head|patch|trace)$":
        $ref: "#/definitions/Operation"
      "^x-": {}
    additionalProperties: false
  Operation:
    type: object
    required:
    - responses
    properties:
      tags:
        type: array
        items:
          type: string
      summary:
        type: string
      description:
        type: string
      externalDocs:
        $ref: "#/definitions/ExternalDocumentation"
      operationId:
        type: string
      parameters:
        type: array
        items:
          switch:
          - if:
              required: [$ref]
            then:
              $ref: "#/definitions/Reference"
          - then:
              $ref: "#/definitions/Parameter"
        uniqueItems: true
      requestBody:
        switch:
        - if:
            required: [$ref]
          then:
            $ref: "#/definitions/Reference"
        - then:
            $ref: "#/definitions/RequestBody"
      responses:
        $ref: "#/definitions/Responses"
      callbacks:
        type: object
        additionalProperties:
          switch:
          - if:
              required: [$ref]
            then:
              $ref: "#/definitions/Reference"
          - then:
              $ref: "#/definitions/Callback"
      deprecated:
        type: boolean
        default: false
      security:
        type: array
        items:
          $ref: "#/definitions/SecurityRequirement"
      servers:
        type: array
        items:
          $ref: "#/definitions/Server"
    patternProperties:
      "^x-": {}
    additionalProperties: false
  Responses:
    type: object
    properties:
      default:
        switch:
        - if:
            required: [$ref]
          then:
            $ref: "#/definitions/Reference"
        - then:
            $ref: "#/definitions/Response"
    patternProperties:
      "^[1-5](?:\\d{2}|XX)$":
        switch: 
        - if:
            required: [$ref]
          then:
            $ref: "#/definitions/Reference"
        - then:
            $ref: "#/definitions/Response"
      "^x-": {}
    minProperties: 1
    additionalProperties: false
    not:
      type: object
      minProperties: 1
      additionalProperties: false
      patternProperties:
        "^x-": {}
    errorMessage:
      minProperties: "should define at least one response"
      not: "should define at least one response, in addition to any vendor extension (`x-*`) fields"
      additionalProperties: "should only have three-digit status codes, `default`, and vendor extensions (`x-*`) as properties"
  SecurityRequirement:
    type: object
    additionalProperties:
      type: array
      items:
        type: string
  Tag:
    type: object
    required:
    - name
    properties:
      name:
        type: string
      description:
        type: string
      externalDocs:
        $ref: "#/definitions/ExternalDocumentation"
    patternProperties:
      "^x-": {}
    additionalProperties: false
  ExternalDocumentation:
    type: object
    required:
    - url
    properties:
      description:
        type: string
      url:
        type: string
        format: uri-reference
    patternProperties:
      "^x-": {}
    additionalProperties: false
  ExampleXORExamples:
    description: Example and examples are mutually exclusive
    errorMessage: "should not have both `example` and `examples`, as they are mutually exclusive"
    not:
      required:
      - example
      - examples
  SchemaXORContent:
    description: Schema and content are mutually exclusive, at least one is required
    switch:
    - if:
        # fails mutual exclusion of `schema` and `content` 
        required:
        - schema
        - content
      then: false
    - if:
        required: [schema]
      then: true
    - if:
        required: [content]
      then:
        description: Some properties are not allowed if content is present
        errorMessage: "should not have `style`, `explode`, `allowReserved`, `example`, or `examples` when `content` is present"
        allOf:
        - not:
            required:
            - style
        - not:
            required:
            - explode
        - not:
            required:
            - allowReserved
        - not:
            required:
            - example
        - not:
            required:
            - examples
    - then:
        required: [schema, content]
    errorMessage: "should have either a `schema` or `content` property"
  Parameter:
    type: object
    properties:
      name:
        type: string
      in:
        type: string
      description:
        type: string
      required:
        type: boolean
        default: false
      deprecated:
        type: boolean
        default: false
      allowEmptyValue:
        type: boolean
        default: false
      style:
        type: string
      explode:
        type: boolean
      allowReserved:
        type: boolean
        default: false
      schema:
        switch:
        - if:
            required: [$ref]
          then:
            $ref: "#/definitions/Reference"
        - then:
            $ref: "#/definitions/Schema"
      content:
        type: object
        additionalProperties:
          $ref: "#/definitions/MediaType"
        minProperties: 1
        maxProperties: 1
      example: {}
      examples:
        type: object
        additionalProperties:
          switch:
          - if:
              required: [$ref]
            then:
              $ref: "#/definitions/Reference"
          - then:
              $ref: "#/definitions/Example"
    patternProperties:
      "^x-": {}
    additionalProperties: false
    required:
    - name
    - in
    allOf:
    - $ref: "#/definitions/ExampleXORExamples"
    - $ref: "#/definitions/SchemaXORContent"
    - $ref: "#/definitions/ParameterLocation"
  ParameterLocation:
    description: Parameter location
    switch:
    - if:
        required: [in]
        properties: { in: { enum: [path] } }
      then:
        description: Parameter in path
        required:
        - required
        properties:
          style:
            enum:
            - matrix
            - label
            - simple
            default: simple
          required:
            enum:
            - true
    - if:
        required: [in]
        properties: { in: { enum: [query] } }
      then:
        description: Parameter in query
        properties:
          style:
            enum:
            - form
            - spaceDelimited
            - pipeDelimited
            - deepObject
            default: form
    - if:
        required: [in]
        properties: { in: { enum: [header] } }
      then:
        description: Parameter in header
        properties:
          style:
            enum:
            - simple
            default: simple
    - if:
        required: [in]
        properties: { in: { enum: [cookie] } }
      then:
        description: Parameter in cookie
        properties:
          style:
            enum:
            - form
            default: form
    - then:
        required: [in]
        properties:
          in:
            enum: [path, query, header, cookie]
  RequestBody:
    type: object
    required:
    - content
    properties:
      description:
        type: string
      content:
        type: object
        additionalProperties:
          $ref: "#/definitions/MediaType"
      required:
        type: boolean
        default: false
    patternProperties:
      "^x-": {}
    additionalProperties: false
  SecurityScheme:
    type: object
    switch:
    - if:
        required: [type]
        properties:
          type:
            enum: [apiKey]
      then:
        $ref: "#/definitions/APIKeySecurityScheme"
    - if:
        required: [type]
        properties:
          type:
            enum: [http]
      then:
        $ref: "#/definitions/HTTPSecurityScheme"
    - if:
        required: [type]
        properties:
          type:
            enum: [oauth2]
      then:
        $ref: "#/definitions/OAuth2SecurityScheme"
    - if:
        required: [type]
        properties:
          type:
            enum: [openIdConnect]
      then:
        $ref: "#/definitions/OpenIdConnectSecurityScheme"
    - then:
        required: [type]
        properties:
          type:
            type: string
            enum: [apiKey, http, oauth2, openIdConnect]
  APIKeySecurityScheme:
    type: object
    required:
    - type
    - name
    - in
    properties:
      type:
        type: string
        enum:
        - apiKey
      name:
        type: string
      in:
        type: string
        enum:
        - header
        - query
        - cookie
      description:
        type: string
    patternProperties:
      "^x-": {}
    additionalProperties: false
  HTTPSecurityScheme:
    type: object
    required:
    - scheme
    - type
    properties:
      scheme:
        type: string
      bearerFormat:
        type: string
      description:
        type: string
      type:
        type: string
        enum:
        - http
    patternProperties:
      "^x-": {}
    switch:
    # the inverse (no `bearerFormat` in properties + using a switch to add it
    # in the case of `scheme: bearer`) doesn't work because of `switch`'s
    # limitations, so this is the best we can do.
    - if:
        not:
          required: [scheme]
          properties: { scheme: { enum: [bearer] } }
      then:
        properties:
          bearerFormat:
            enum: [null]
        errorMessage: "should NOT have a `bearerFormat` property without `scheme: bearer` being set"
    additionalProperties: false
  OAuth2SecurityScheme:
    type: object
    required:
    - type
    - flows
    properties:
      type:
        type: string
        enum:
        - oauth2
      flows:
        $ref: "#/definitions/OAuthFlows"
      description:
        type: string
    patternProperties:
      "^x-": {}
    additionalProperties: false
  OpenIdConnectSecurityScheme:
    type: object
    required:
    - type
    - openIdConnectUrl
    properties:
      type:
        type: string
        enum:
        - openIdConnect
      openIdConnectUrl:
        type: string
        format: uri-reference
      description:
        type: string
    patternProperties:
      "^x-": {}
    additionalProperties: false
  OAuthFlows:
    type: object
    properties:
      implicit:
        $ref: "#/definitions/ImplicitOAuthFlow"
      password:
        $ref: "#/definitions/PasswordOAuthFlow"
      clientCredentials:
        $ref: "#/definitions/ClientCredentialsFlow"
      authorizationCode:
        $ref: "#/definitions/AuthorizationCodeOAuthFlow"
    patternProperties:
      "^x-": {}
    additionalProperties: false
  ImplicitOAuthFlow:
    type: object
    required:
    - authorizationUrl
    - scopes
    properties:
      authorizationUrl:
        type: string
        format: uri-reference
      refreshUrl:
        type: string
        format: uri-reference
      scopes:
        type: object
        additionalProperties:
          type: string
    patternProperties:
      "^x-": {}
    additionalProperties: false
  PasswordOAuthFlow:
    type: object
    required:
    - tokenUrl
    properties:
      tokenUrl:
        type: string
        format: uri-reference
      refreshUrl:
        type: string
        format: uri-reference
      scopes:
        type: object
        additionalProperties:
          type: string
    patternProperties:
      "^x-": {}
    additionalProperties: false
  ClientCredentialsFlow:
    type: object
    required:
    - tokenUrl
    properties:
      tokenUrl:
        type: string
        format: uri-reference
      refreshUrl:
        type: string
        format: uri-reference
      scopes:
        type: object
        additionalProperties:
          type: string
    patternProperties:
      "^x-": {}
    additionalProperties: false
  AuthorizationCodeOAuthFlow:
    type: object
    required:
    - authorizationUrl
    - tokenUrl
    properties:
      authorizationUrl:
        type: string
        format: uri-reference
      tokenUrl:
        type: string
        format: uri-reference
      refreshUrl:
        type: string
        format: uri-reference
      scopes:
        type: object
        additionalProperties:
          type: string
    patternProperties:
      "^x-": {}
    additionalProperties: false
  Link:
    type: object
    properties:
      operationId:
        type: string
      operationRef:
        type: string
        format: uri-reference
      parameters:
        type: object
        additionalProperties: {}
      requestBody: {}
      description:
        type: string
      server:
        $ref: "#/definitions/Server"
    patternProperties:
      "^x-": {}
    additionalProperties: false
    not:
      description: Operation Id and Operation Ref are mutually exclusive
      required:
      - operationId
      - operationRef
  Callback:
    type: object
    additionalProperties:
      $ref: "#/definitions/PathItem"
    patternProperties:
      "^x-": {}
  Encoding:
    type: object
    properties:
      contentType:
        type: string
      headers:
        type: object
        additionalProperties:
          $ref: "#/definitions/Header"
      style:
        type: string
        enum:
        - form
        - spaceDelimited
        - pipeDelimited
        - deepObject
      explode:
        type: boolean
      allowReserved:
        type: boolean
        default: false
    additionalProperties: false
