---
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
