openapi: 3.0.3
info:
  title: Match (CAMARA)
  description: |
    Match verifies identity attributes linked to a customer's mobile phone number. This creates a high trust and low friction method for verifying identity online.
  version: 0.2.1

servers:
  - url: https://api-sandbox.vf-dmp.engineering.vodafone.com
    description: "Sandbox"
  - url: https://api.vf-dmp.engineering.vodafone.com
    description: "Production"

paths:

  /openIDConnectCIBA/v1/bc-authorize:
    post:
      # security:
      #   - BasicAuth: []
      tags:
        - Authentication Flow
      description: The SP makes a request to Vodafone’s Backchannel Authentication Endpoint to ask for end-user authorization. Vodafone validates the MSISDN is a Vodafone MSISDN. If successful, it passes the request to the VF IDGW for processing. Once VF IDGW processing is successful, an “auth_req_id” is provided in the response to the SP.
      operationId: authenticationRequest
      parameters:
        - $ref: "#/components/parameters/authorization-basic"
        - $ref: "#/components/parameters/X-Correlator"

        
      requestBody:
        description: |
          The SP makes a request to Vodafone’s Backchannel Authentication Endpoint to ask for end-user authorization. Vodafone validates the MSISDN is a Vodafone MSISDN. If successful, it passes the request to the VF IDGW for processing. Once VF IDGW processing is successful, an “auth_req_id” is provided in the response to the SP.
        content :
          application/x-www-form-urlencoded:
            schema:
              $ref: "#/components/schemas/AuthorizeReq"
        required: true
      responses:
        "200":
          description: | 
            **OK** If the authorization request is successfully completed (i.e. without error), an authorization id (auth_req_id) is returned by ID Gateway, in an HTTP 200 response in json payload with parameters.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthenticationResp"

        "400":
          $ref: "#/components/responses/AuthError400"
        "401":
          $ref: "#/components/responses/AuthError401"
        "403":
          $ref: "#/components/responses/AuthError403"
        "406":
          $ref: "#/components/responses/AuthError406"
        "415":
          $ref: "#/components/responses/AuthError415"
        "500":
          $ref: "#/components/responses/AuthError500"
        "502":
          $ref: "#/components/responses/AuthError502"
        "503":
          $ref: "#/components/responses/AuthError503"

        # '400' :
        #   description: |
        #       **Bad request**
        #   content:
        #     application/json:
        #       examples:
        #         login_hint missing:
        #           value: {
        #                   "error": "invalid_request",
        #                   "error_description": "The request is missing a mandatory parameter login_hint"
        #                   }
        #         scope missing:
        #           value: {
        #                   "error": "invalid_request",
        #                   "error_description": "The request is missing a mandatory parameter scope"
        #                   }
        #         same param multiple time:
        #           value: {
        #                   "error": "invalid_request",
        #                   "error_description": "Request contains same parameter multiple times"
        #                   }
        #         invalid vf-trace-transaction-id:
        #           value: {
        #                   "error": "invalid_request",
        #                   "error_description": "The request parameter vf-trace-transaction-id is invalid"
        #                   }
        #         invalid X-Correlator:
        #           value: {
        #                   "error": "invalid_request",
        #                   "error_description": "The request parameter X-Correlator is invalid"
        #                   }
        #         invalid MSISDN:
        #           value: {
        #                   "error": "invalid_request",
        #                   "error_description": "The request parameter login_hint is invalid"
        #                   }
        #         invalid scope:
        #           value: {
        #                   "error": "invalid_request",
        #                   "error_description": "The request parameter scope is invalid"
        #                   }

        # '401' : 
        #   description: |
        #       **Unauthorized**
        #   content:
        #     application/json:
        #       examples:
        #         invalid_client:
        #           value: {
        #             "error": "invalid_client",
        #             "error_description": "Client Authentication failed"
        #           }
        # '403' : 
        #   description: |
        #       **Forbidden**
        #   content:
        #     application/json:
        #       examples:
        #         login_hint Not whitelisted:
        #           value: {
        #             "error": "access_denied",
        #             "error_description": "The service is not whitelisted for the requested country"
        #           }
        #         invalid request IP:
        #           value: {
        #             "error": "access_denied",
        #             "error_description": "The access is denied"
        #           }

        # '406' :
        #   description: |
        #       **Not Acceptable**
        #   content:
        #     application/json:
        #       examples:
        #         Not Acceptable:
        #           value: {
        #             "error": "Not Acceptable",
        #             "error_description": "The Accept header is invalid ",
        #           }
                  

        # '415' :
        #   description: |
        #       **Unsupported Media Type**
        #   content:
        #     application/json:
        #       examples:
        #         Unsupported Media Type:
        #           value: {
        #             "error": "invalid_request",
        #             "error_description": "The value of the Content-Type header is invalid",
        #           }
                  
        # '500' : 
        #   description: |
        #       **Internal Server Error**
        #   content:
        #     application/json:
        #       examples:
        #         internal processing fail:
        #           value: {
        #             "error": "server_error",
        #             "error_description": "The authorization server encountered an unexpected condition that prevented it from fulfilling the request"
        #           }
        #         config param not extracted:
        #           value: {
        #             "error": "server_error",
        #             "error_description": "Internal configuration error"
        #           }

        # '502' :
        #   description: |
        #       **Bad Gateway**
        #   content:
        #     application/json:
        #       examples:
        #         Bad Gateway:
        #           value: {
        #             "error": "server_error",
        #             "error_description": "Error connecting to an upstream server"
        #           }
                  
        # '503' :
        #   description: |
        #       **Service Unavailable**
        #   content:
        #     application/json:
        #       examples:
        #         Service Unavailable:
        #           value: {
        #             "error": "temporarily unavailable",
        #             "error_description": "An upstream server is unavailable"
        #           }

  /openIDConnectCIBA/v1/token:
    post:
      # security:
      #   - BasicAuth: []
      tags:
        - Authentication Flow
      description: | 
        The request to the token endpoint must be sent using the HTTP POST method and have parameters populated in accordance with the rules
      operationId: tokenRequest
      parameters:
        - $ref: "#/components/parameters/authorization-basic"
        - $ref: "#/components/parameters/X-Correlator"


      requestBody:
        description: |
          The request to the token endpoint must be sent using the HTTP POST method and have parameters populated in accordance with the rules.
        content :
          application/x-www-form-urlencoded:
            schema:
              $ref: "#/components/schemas/TokenReq"
        required: true
      responses:
        "200":
          description: | 
            **OK** If the token request is successfully completed (i.e. without error), an acess_token is returned by Gateway, in an HTTP 200 response in json payload with parameters.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TokenResp"
        "400":
          $ref: "#/components/responses/AuthError400"
        "401":
          $ref: "#/components/responses/AuthError401"
        "403":
          $ref: "#/components/responses/AuthError403"
        "406":
          $ref: "#/components/responses/AuthError406"
        "415":
          $ref: "#/components/responses/AuthError415"
        "500":
          $ref: "#/components/responses/AuthError500"
        "502":
          $ref: "#/components/responses/AuthError502"
        "503":
          $ref: "#/components/responses/AuthError503"
  
  /kyc-match/v0.2/match:
    post:
      tags:
        - Match
      summary: Matching a customer identity by checking a set of attributes related against the account data bound to their phone number.
      description: |-
        Verify matching of a number of attributes related to a customer identity against the verified data bound to their phone number in the Operator systems. Regardless of whether the `phoneNumber` is explicitly stated in the request body, at least one of the other fields must be provided, otherwise a `HTTP 400 - KNOW_YOUR_CUSTOMER.INVALID_PARAM_COMBINATION` error will be returned.

        In order to proceed with the match check, some Operators may have the requirement to perform an additional level of validation based on the `idDocument` property. This means that, in those cases, the `idDocument` is required and the provided value needs to match the one stored in the Operator system associated with the indicated `phoneNumber`. This validation will be done before proceeding with the match check of the rest of the properties. The following two rules apply only in the cases where the Operator have the requirement to validate the `idDocument`:
        - If no `idDocument` is provided, then a `HTTP 403 - KNOW_YOUR_CUSTOMER.ID_DOCUMENT_REQUIRED` error will be returned.
        - If the provided `idDocument` does not match the one stored in the Operator systems, then a `HTTP 403 - KNOW_YOUR_CUSTOMER.ID_DOCUMENT_MISMATCH` error will be returned.
        - There is a corner case where the Operator requires the `idDocument` to perform the match validation for the rest of the properties, but it also needs to be able to perform the validation only for the `idDocument` itself. In this case, if only the `idDocument` is provided along with the phoneNumber (either in the request body or extracted from the access token) then the match will be performed as with any other attribute and the response will contain the result of the match operation.

        The API will return the result of the matching process for each requested attribute. This means that the response will **only** contain the attributes for which validation has been requested. Possible values are:
          - **true**: the attribute provided matches with the one in the Operator systems.
          - **false**: the attribute provided does not match with the one in the Operator systems.
          - **not_available**: the attribute is not available to validate.
      operationId: KYC_Match

      # security:
      #   - openId:
      #     - kyc-match:match


      parameters:
        - $ref: "#/components/parameters/X-Correlator"
        - $ref: "#/components/parameters/authorization-bearer"
        
      requestBody:
        required: true
        content:
          application/json:

            schema:
              $ref: '#/components/schemas/KYC_MatchRequestBody'
            examples:
              KYC_MatchRequestBodyExample_UK:
                value:
                  phoneNumber: '+447772000001'
                  # idDocument: 66666666q
                  name: ROBYN HUNTER
                  givenName: ROBYN
                  familyName: HUNTER
                  # nameKanaHankaku: federica
                  # nameKanaZenkaku: Ｆｅｄｅｒｉｃａ
                  middleNames: Sanchez
                  # familyNameAtBirth: YYYY
                  address: '10 Downing Street'
                  streetName: 'Downing Street'
                  streetNumber: "10"
                  postalCode: "CA10 3LT"
                  region: United Kingdom
                  locality: London
                  # country: JP
                  # houseNumberExtension: VVVV
                  birthdate: '1991-03-05'
                  # email: abc@example.com
                  # gender: MALE
              KYC_MatchRequestBodyExample_NL:
                value:
                  phoneNumber: '+31777100001'
                  # idDocument: 66666666q
                  name: JOHN JENSEN
                  givenName: JOHN
                  familyName: JENSEN
                  # nameKanaHankaku: federica
                  # nameKanaZenkaku: Ｆｅｄｅｒｉｃａ
                  # middleNames: Sanchez
                  # familyNameAtBirth: YYYY
                  # address: Castlehill
                  # streetName: 10 Downing Street
                  streetNumber: "DAMRAK 34"
                  postalCode: "2431"
                  # region: United Kingdom
                  locality: AF AMSTERDAM 
                  country: NL
                  houseNumberExtension: 12B
                  birthdate: '1980-01-01'
                  # email: abc@example.com
                  # gender: MALE
                  
              KYC_MatchRequestBodyExample_DE:
                value:
                  phoneNumber: '+491722100001'
                  # idDocument: 66666666q
                  name: Alexander Boraczynski
                  givenName: Alexander
                  familyName: Boraczynski
                  # nameKanaHankaku: federica
                  # nameKanaZenkaku: Ｆｅｄｅｒｉｃａ
                  # middleNames: Sanchez
                  # familyNameAtBirth: YYYY
                  address: Musterstraße 12 10115 Berlin
                  streetName: Musterstraße
                  streetNumber: "12"
                  postalCode: "10115"
                  # region: United Kingdom
                  locality: Berlin
                  country: DE
                  # houseNumberExtension: VVVV
                  birthdate: '1978-08-22'
                  # email: abc@example.com
                  # gender: MALE
                  
              KYC_MatchRequestBodyExample_ES:
                value:
                  phoneNumber: '+34600080001'
                  idDocument: 66666666q
                  name: MAJLINDA PULACI MOISIU
                  givenName: MAJLINDA 
                  familyName: PULACI MOISIU
                  # nameKanaHankaku: federica
                  # nameKanaZenkaku: Ｆｅｄｅｒｉｃａ
                  # middleNames: Sanchez
                  # familyNameAtBirth: YYYY
                  # address: Castlehill
                  streetName: CL. GREMIOS
                  streetNumber: "3"
                  postalCode: "28037"
                  # region: United Kingdom
                  locality: Madrid
                  country: ES
                  # houseNumberExtension: VVVV
                  birthdate: '1961-10-01'
                  # email: abc@example.com
                  # gender: MALE

      responses:
        '200':
          description: OK
          headers:
            x-correlator:
              $ref: '#/components/headers/X-Correlator'

          content:
            application/json:

              schema:
                $ref: '#/components/schemas/KYC_MatchResponse'
              examples:
                KYC_Match200Example:
                  value:
                    nameMatch: 'true'
                    givenNameMatch: 'true'
                    familyNameMatch: 'true'
                    middleNamesMatch: 'true'
                    addressMatch: 'true'
                    streetNameMatch: 'true'
                    streetNumberMatch: 'not_available'
                    postalCodeMatch: 'true'
                    regionMatch: 'true'
                    localityMatch: 'true'
                    birthdateMatch: 'false'
                    birthdateMatchScore: 87


        '400':
          $ref: '#/components/responses/Generic400'

        '401':
          $ref: '#/components/responses/Generic401'

        '403':
          $ref: '#/components/responses/Generic403'

        '404':
          $ref: '#/components/responses/Generic404'

        '500':
          $ref: '#/components/responses/Generic500'

        '503':
          $ref: '#/components/responses/Generic503'

        '504':
          $ref: '#/components/responses/Generic504'


  /kyc-match/v0.2/ping:
    get:
      tags:
        - Monitoring
      summary: Check the upstream system is up and running.
      description: |-
        This API is to check the upstream system is up and running.

      # security:
      #   - oAuth2ClientCredentials: []

      operationId: getPing

      parameters:
        - $ref: "#/components/parameters/vf-trace-transaction-id"

      responses:
        "200":
          description: "**OK**"
          content:
            application/json:
              examples:
                success_response:
                  value: {
                            "suffix": "/ping",
                            "client": "35.191.13.203",
                            "startTime": "2023-06-05T19:47:16.794Z",
                            "endTime": "2023-06-05T19:47:16.888Z",
                            "responseTime": 94,
                            "message": "PONG"
                          }
        '400' :
          description: |
              **Bad request**
          content:
            application/json:
              examples:
                Unknown user:
                  value: {
                           "error": "invalid_request",
                           "error_description": "The request parameter is invalid",
                          }
        '401' : 
          description: |
              **Unauthorized**
          content:
            application/json:
              examples:
                invalid_client:
                  value: {
                    "error": "invalid_client",
                    "error_description": "Invalid Access Token"
                  }


components:

  # securitySchemes:
  #   BasicAuth:
  #       type: http
  #       scheme: basic
  #   BearerAuth:
  #     type: http
  #     scheme: bearer
    
  
  parameters:

    authorization-basic:
      name: Authorization
      in: header
      required: true
      description: |
        “Basic “ + base_64_encode (client_id + “:” + client_secret)
      schema:
        type: string
        example: | 
          Basic d3lCOHF1R0RPWTdXTnUyVUV2eGF5Sk9aNVpTSU1KM1Y6V2ZHQUJqSUJpRDIySg==
          
    authorization-bearer:
      name: Authorization
      in: header
      required: true
      description: |
        “Bearer ” concatenated with the access token obtained from the token endpoint response.
      schema:
        type: string
        example: | 
          Bearer dUk4Bs0qgKQKujbGxQDvIdXkI6Bz
  
    X-Correlator:
      name: X-Correlator
      in: header
      required: false
      description: Correlation id for the different services ie 42da5b19-457a-4d30-a5c4-038c62dccbb0.
      schema:
        type: string
        # example: A111123e4567-e89b-12d3-a456-426614174000111
    vf-trace-transaction-id:
      name: vf-trace-transaction-id
      in: header
      required: false
      description: A unique identifier for each request (typically a GUID).  This is not defined as part of the standard, but it can be used by the Service Provider to set a value which could assist in troubleshooting.  Note - if this header is not set in the request, Vodafone generates this value upon receipt of the message and returns the value in the response as a header.
      schema:
        type: string


  headers:
    X-Correlator:
      description: Correlation id for the different services
      schema:
        type: string
  schemas:
  
    AuthorizeReq:
      type: object
      required:
        - login_hint
        - scope
      properties:
        login_hint: 
          type: string
          example : "tel:+447772000001"
          description: | 
           End-user for whom the authentication is being requested. This is MSISDN in the format    “tel:+{MSISDN}”, where +" prefix is optional. Examples for UK: “tel:+447772000001” or “tel:447772000001”, for NL +31777100001, for DE +491722100001 and for ES +34600080001.
        scope: 
          type: string
          enum:
            - openid kyc-match:match
          example: openid kyc-match:match
          description: | 
            Authorization request MUST contain the scope value.
    AuthenticationResp:
      type: object
      properties:
        interval: 
          type: number
          format: number
          example: 0
          description: | 
            The time required to wait between receiving the authorization endpoint response and making the polling endpoint request (in seconds). This value can be ignored.
        auth_req_id: 
          type: string
          format: UUID
          example: 39da5b19-457a-4d30-a5c4-047c62dcca3b
          description: |
            Unique Id of this authorization (to be used in the token request).
        expires_in: 
          type: number
          format: number
          example: 300
          description: | 
            The timeout available to make a request to the token endpoint. i.e. The request must be made before the “expires_in” time is reached.

    
    TokenReq:
      type: object
      required:
        - auth_req_id
        - grant_type
      properties:
        auth_req_id: 
          type: string
          example : "39da5b19-457a-4d30-a5c4-047c62dcca3b"
          description: | 
           The auth_req_id received in the successful authorization endpoint response.
        grant_type: 
          type: string
          example: urn:openid:params:grant-type:ciba
          description: | 
            For all token requests the value of the grant_type parameter MUST have the value: "urn:openid:params:grant-type:ciba" (Note: must be url encoded)
    TokenResp:
      type: object
      properties:
        access_token: 
          type: string
          example: dUk4Bs0qgKQKujbGxQDvIdXkI6Bz
          description: |
            OAuth 2.0 access_token used to gain access to the end-user information. This token CANNOT can be reused
        token_type: 
          type: string
          example: Always "Bearer"
          description: | 
            The timeout available to make a request to the token endpoint. i.e. The request must be made before the “expires_in” time is reached.
        expires_in: 
          type: number
          format: number
          example: 3599
          description: | 
            Expiration time of the Access Token in seconds since the response was generated.
        id_token: 
          type: string
          example: "eyJraWQiOiJ0ZXN0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYeyJpc3MiOiJodHRwczovL2FwaXN0YWdpbmdyZWYuZGV2ZWxvcGVyLnZvZGFmb25lLmNvbSIsInN1YiI6ImRhNTNhOWRlLTljMmQtNGZkYy1hODY1LWE4OWZiZThmZGE2MyIsImF1ZCI6ImJSdlJKZVBHaGlMQndmelJSdEx3Z3REVFZ4UFdSQU1BIiwiZXhwIjoxNjA2OTE2Mzc2LCJpYXQiOjE2MDY5MTI3NzYsImF1dGhfdGltZSI6MTYwNjkxMjc1Niwibm9uY2UiOiI0NTI1OTUtOWRhMS00NDZiLWE0MmEtMWJkZmJmMTRhOGJjIiwiYXRfaGFzaCI6Ik9FRkZRVFpCTURCQ09FTkJRVVZFT0RnMU1qRTRSalJCUXpaQ1FUVXdRa1E0TWtRM1JFSTVSamsyT1RVMVJEbERPRE5GUkVFM05qa3hOVFl4UWpjM09BPT0iLCJhY3IiOiIwIiwiYW1yIjpbIk5PX0FVVEhOIl0sImF6cCI6IjU0NjEyNTk1LTlkYTAtNDQ2Yi1hNDJhLTFiZGZiZjE0YThhZiIsImhhc2hlZF9sb2dpbl9oaW50IjoiQUVBNkEwMEI4Q0FBRUQ4ODUyMThGNEFDNkJBNTBCRDgyRDdEQjlGOTY5NTVEOUM4M0VEQTc2OTE1NjFCNzc4In0.8Y4SArYeLdwyVUF7zjW9hyWTULiANn_MbvfXkxk62mKdPEeTI0HNOAG9tsItR1KVhHQdotAZOcoTNLRn66w4TMphQ1K2wfRcWTWKrTXtUA3Xuyx_bhZTkm7Zkz8k944JgpxejWgCjVUejlOiaQJZhu23UWufpd1An4x8UY7JU1LsKJj_OFMleESuM4xoJru0fPUkMMcNKB9D76sfBeSaZeMdqUARBhoWLyO_cb79sFfpu1Uf9V8SFB3NLRuktu0KANwqipwc_5c4LtxzP_rw3A_hWcaGpT67Qk1-tisW6ITCvrFKzZ5aqn8qWPEcte-XGoCXwd7pp0HKzgd1G8xw"
          description: | 
            This token is not used in CAMARA CIBA flows at this stage and can be ignored.
  

    
    PhoneNumber:
      type: string
      pattern: '^\+?[0-9]{5,15}$'
      example: '+346661113334'
      description: Subscriber number in E.164 format (starting with country code). Optionally prefixed with '+'.
    
    
    KYC_MatchRequestBody:
      type: object
      description: Payload to validate the customer data.

      properties:
        phoneNumber:
          type: string
          pattern: '^\+[1-9]\d{1,14}$' # Regex for E.164 format
          example: "+14155552671" # Example of a valid E.164 phone number
          description: A public identifier addressing a telephone subscription. In mobile networks it corresponds to the MSISDN (Mobile Station International Subscriber Directory Number). In order to be globally unique it has to be formatted in international format, according to E.164 standard, prefixed with '+'.


        idDocument:
          type: string
          minLength: 1      # Minimum length of 1 characters
          maxLength: 20       # Maximum length of 20 characters
          example: "user123"  # Example username
          description: Id number associated to the official identity document in the country. It may contain alphanumeric characters with string max length 20.

        name:
          minLength: 1      # Minimum length of 1 characters
          maxLength: 40       # Maximum length of 40 characters
          type: string
          description: Complete name of the customer, usually composed of first/given name and last/family/sur- name in a country.  Depending on the country, the order of first/give name and last/family/sur- name varies, and middle name could be included.  It can use givenName, middleNames, familyName and/or familyNameAtBirth. For example, in ESP, name+familyName; in NLD, it can be name+middleNames+familyName or name+middleNames+familyNameAtBirth, etc.

        givenName:
          type: string
          minLength: 1      # Minimum length of 1 characters
          maxLength: 20       # Maximum length of 20 characters
          description: First/given name or compound first/given name of the customer.
          
        familyName:
          type: string
          minLength: 1      # Minimum length of 1 characters
          maxLength: 20       # Maximum length of 20 characters
          description: Last name, family name, or surname of the customer.
          
        nameKanaHankaku:
          type: string
          description: Complete name of the customer in Hankaku-Kana format (reading of name) for Japan.

        nameKanaZenkaku:
          type: string
          description: Complete name of the customer in Zenkaku-Kana format (reading of name) for Japan.

        middleNames:
          type: string
          description: Middle name/s of the customer.

        familyNameAtBirth:
          type: string
          minLength: 1      # Minimum length of 1 characters
          maxLength: 20       # Maximum length of 20 characters
          description: Last/family/sur- name at birth of the customer.

        address:
          type: string
          minLength: 1      # Minimum length of 1 characters
          maxLength: 80       # Maximum length of 30 characters
          description: Complete address of the customer.  For some countries, it is built following the usual concatenation of parameters in a country, but for other countries, this is not the case.  For some countries, it can use streetName, streetNumber and/or houseNumberExtension. For example, in ESP, streetName+streetNumber; in NLD, it can be streetName+streetNumber or streetName+streetNumber+houseNumberExtension.
          
        streetName:
          minLength: 1      # Minimum length of 1 characters
          maxLength: 80       # Maximum length of 80 characters
          type: string
          description: Name of the street of the customer's address. It should not include the type of the street.

        streetNumber:
          type: string
          minLength: 1      # Minimum length of 1 characters
          maxLength: 20       # Maximum length of 20 characters
          description: The street number of the customer's address.  Number identifying a specific property on the 'streetName'.

        postalCode:
          minLength: 1      # Minimum length of 1 characters
          maxLength: 10       # Maximum length of 10 characters
          type: string
          description: Zip code or postal code

        region:
          minLength: 1      # Minimum length of 1 characters
          maxLength: 20       # Maximum length of 20 characters
          type: string
          description: Region/prefecture of the customer's address

        locality:
          minLength: 1      # Minimum length of 1 characters
          maxLength: 20       # Maximum length of 20 characters
          type: string
          description: Locality of the customer's address

        country:
          type: string
          pattern: '^[A-Z]{2}$' # Regex pattern for ISO 3166-1 alpha-2
          example: "US" # Example of a valid ISO 3166-1 alpha-2 code
          description: Country of the customer's address. Format ISO 3166-1 alpha-2 (two uppercase letters).

        houseNumberExtension:
          type: string
          description: Specific identifier of the house needed depending on the property type. For example, number of apartment in an apartment building.

        birthdate:
          type: string
          format: date # This indicates the date format YYYY-MM-DD
          description: The birthdate of the customer, in ISO 8601 calendar date format (YYYY-MM-DD).

        email:
          type: string
          minLength: 1      # Minimum length of 1 characters
          maxLength: 40       # Maximum length of 40 characters
          format: email # Indicates the property should be an email
          pattern: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$' # Regex for email validation
          example: "customer@example.com" # Example of a valid email address
          description: Email address of the customer in the RFC specified format (local-part@domain).

        gender:
          type: string
          description: Gender of the customer (Male/Female/Other).
          enum:
            - MALE
            - FEMALE
            - OTHER

    MatchResult:
      type: string
      enum:
          - 'true'
          - 'false'
          - 'not_available'

    MatchScoreResult:
      type: integer
      description: Indicates the similarity score assigned to the input value when it does not exactly match the value stored in the operator's system. This property shall only be returned when the value of the corresponding match field is `false`.
      minimum: 0
      maximum: 100

    KYC_MatchResponse:
      type: object
      properties:
        idDocumentMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether Id number associated to the ID document of the customer matches with the one on the Operator's system.
        nameMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether the complete name of the customer matches with the one on the Operator's system.
        nameMatchScore:
          $ref: '#/components/schemas/MatchScoreResult'
        givenNameMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether First name/given name of the customer matches with the one on the Operator's system.
        givenNameMatchScore:
          $ref: '#/components/schemas/MatchScoreResult'
        familyNameMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether last name/ family name/ surname of the customer matches with the one on the Operator's system.
        familyNameMatchScore:
          $ref: '#/components/schemas/MatchScoreResult'
        nameKanaHankakuMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether complete name of the customer in Hankaku-Kana format (reading of name) for Japan matches with the one on the Operator's system.
        nameKanaHankakuMatchScore:
          $ref: '#/components/schemas/MatchScoreResult'
        nameKanaZenkakuMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether complete name of the customer in Zenkaku-Kana format (reading of name) for Japan matches with the one on the Operator's system.
        nameKanaZenkakuMatchScore:
          $ref: '#/components/schemas/MatchScoreResult'
        middleNamesMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether the middle names of the customer matches with the one on the Operator's system.
        middleNamesScore:
          $ref: '#/components/schemas/MatchScoreResult'
        familyNameAtBirthMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether the Family Name At Birth of the customer matches with the one on the Operator's system.
        familyNameAtBirthMatchScore:
          $ref: '#/components/schemas/MatchScoreResult'
        addressMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether complete address of the customer matches with the one on the Operator's system.
        addressMatchScore:
          $ref: '#/components/schemas/MatchScoreResult'
        streetNameMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether the street name of the customer matches with the one on the Operator's system.
        streetNameMatchScore:
          $ref: '#/components/schemas/MatchScoreResult'
        streetNumberMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether the street number of the customer matches with the one on the Operator's system.
        streetNumberMatchScore:
          $ref: '#/components/schemas/MatchScoreResult'
        postalCodeMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether the postal code / zip code of the customer matches with the one on the Operator's system.
        regionMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether the region of the customer's address matches with the one on the Operator's system.
        regionMatchScore:
          $ref: '#/components/schemas/MatchScoreResult'
        localityMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether the locality of the customer's address matches with the one on the Operator's system.
        localityMatchScore:
          $ref: '#/components/schemas/MatchScoreResult'
        countryMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether the country of the customer's address matches with the one on the Operator's system.
        houseNumberExtensionMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether the house number extension of the customer's address with the one on the Operator's system.
        birthdateMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether the birthdate of the customer matches with the one on the Operator's system.
        emailMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether the email address of the customer matches with the one on the Operator's system.
        emailMatchScore:
          $ref: '#/components/schemas/MatchScoreResult'
        genderMatch:
          allOf:
            - $ref: '#/components/schemas/MatchResult'
            - description: Indicates whether the gender of the customer matches with the one on the Operator's system.    
    
    

    ErrorInfo:
      type: object
      required:
        - status
        - code
        - message
      properties:
        status:
          type: integer
          description: HTTP response status code
        code:
          type: string
          description: Code given to this error
        message:
          type: string
          description: Detailed error description
          
    AuthErrorInfo:
      type: object
      required:
        - status
        - code
        - message
      properties:
        error:
          type: integer
          description: HTTP response status code
        error_description:
          type: string
          description: Detailed error description
    # CreateCheckSimSwap:
    #   type: object
    #   required:
    #     - phoneNumber
    #   properties:
    #     # phoneNumber:
    #     #   $ref: "#/components/schemas/PhoneNumber"
    #     maxAge:
    #       type: integer
    #       example: 240
    #       description: |
    #         Time period in hours to check mobile account for SIM Swap.Minimum value: 1 (hours) Maximum value: 2400 (hours) If not provided, default value used is 240 (hours).
    #       format: int32
    #       minimum: 1
    #       maximum: 2400
    #       default: 240
    # CreateSimSwapDate:
    #   type: object
    #   required:
    #     - phoneNumber
    #   properties:
    #     phoneNumber:
    #       $ref: "#/components/schemas/PhoneNumber"





  responses:
    Generic400:
      description: |
        **Bad Request**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            invalid argument:
              value:
                status: 400
                code: INVALID_ARGUMENT
                message: Client specified an invalid argument, request body or query param
    Generic401:
      description: |
        **Unauthorized**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            invalid creds:
              value:
                status: 401
                code: UNAUTHENTICATED
                message: Request not authenticated due to missing, invalid, or expired credentials
    Generic403:
      description: |
        **Forbidden**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            permission denied:
              value:
                status: 403
                code: PERMISSION_DENIED
                message: Client does not have sufficient permissions to perform this action
    Generic404:
      description: |
        **Not Found**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:

              NOT_FOUND:
                value: {
                          "status": 404,
                          "code" : "NOT_FOUND",
                          "message": "The specified resource is not found."
                        }
              UNKNOWN_PHONE_NUMBER:
                value: {
                          "status": 404,
                          "code" : "SIM_SWAP.UNKNOWN_PHONE_NUMBER",
                          "message": "SIM Swap can't be checked because the phone number is unknown."
                        }
    Generic405:
      description: |
        **Method Not Allowed**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            METHOD_NOT_ALLOWED:
              value:
                status: 405
                code: METHOD_NOT_ALLOWED
                message: The requested method is not allowed/supported on
                      the target resource"
    Generic406:
      description: |
        **Not Acceptable**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            Not Acceptable:
              value:
                status: 406
                code: Not Acceptable
                message: The server cannot produce a response matching
                          the content requested by the client through Accept-* headers."
    Generic415:
      description: |
        **Unsupported Media Type**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            UNSUPPORTED_MEDIA_TYPE:
              value:
                status: 415
                code: UNSUPPORTED_MEDIA_TYPE
                message: The server refuses to accept the request because
                      the payload format is in an unsupported format
                      
    Generic429:
      description: |
        **Too Many Requests**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
              SpikeArrestViolation:
                value: {
                          "status": 429,
                          "code" : "TOO_MANY_REQUESTS",
                          "message": "Spike Arrest Violation."
                        }
              QuotaViolation:
                value: {
                          "status": 429,
                          "code" : "TOO_MANY_REQUESTS",
                          "message": "API/App/Country Quota limit reached."
                        }
                        
    Generic500:
      description: |
        **Internal Server Error**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            Internal_Server_Error:
              value:
                status: 500
                code: INTERNAL
                message: The server encountered an unexpected condition
                      that prevented it from fulfilling the request
    Generic502:
      description: |
        **Bad Gateway**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            Bad_Gateway:
              value:
                status: 502
                code: BAD_GATEWAY
                message: An upstream internal service cannot be reached

    Generic503:
      description: |
        **UNAVAILABLE**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            UNAVAILABLE:
              value:
                status: 503
                code: UNAVAILABLE
                message: Request timeout exceeded
    Generic504:
      description: |
        **Gateway Timeout**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            TIMEOUT:
              value:
                status: 504
                code: TIMEOUT
                message: Request timeout exceeded. 
            
    AuthError400:
      description: | 
        **Bad Request**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/AuthErrorInfo'
          examples:
            login_hint missing:
              value: {
                        "error": "invalid_request",
                        "error_description": "The request is missing a mandatory parameter login_hint"
                      }
            scope missing:
              value: {
                        "error": "invalid_request",
                        "error_description": "The request is missing a mandatory parameter scope"
                      }
            same param multiple time:
                  value: {
                           "error": "invalid_request",
                           "error_description": "Request contains same parameter multiple times"
                          }
            invalid vf-trace-transaction-id:
                  value: {
                           "error": "invalid_request",
                           "error_description": "The request parameter vf-trace-transaction-id is invalid"
                          }
            invalid X-Correlator:
                  value: {
                           "error": "invalid_request",
                           "error_description": "The request parameter X-Correlator is invalid"
                          }
            invalid MSISDN:
                  value: {
                           "error": "invalid_request",
                           "error_description": "The request parameter login_hint is invalid"
                          }
            invalid scope:
                  value: {
                           "error": "invalid_request",
                           "error_description": "The request parameter scope is invalid"
                          }
    AuthError401:
      description: |
        **Unauthorized**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/AuthErrorInfo'
          examples:
            auth header invalid:
              value: {
                        "error": "invalid_client",
                        "error_description": "Client Authentication failed"
                      }
    AuthError403:
      description: | 
        **Forbidden**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/AuthErrorInfo'
          examples:
            login_hint not whitelisted:
              value: {
                        "error": "access_denied",
                        "error_description": "The service is not whitelisted for the requested country"
                      }
            invalid request IP:
              value: {
                        "error": "access_denied",
                        "error_description": "The access is denied"
                      }

    AuthError406:
      description: |
        **Not Acceptable**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/AuthErrorInfo'
          examples:
            Invalid Accept Header:
              value: {
                        "error": "server_error",
                        "error_description": "The Accept header is invalid"
                      }

    AuthError415:
      description: |
        **Unsupported Media Type**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/AuthErrorInfo'
          examples:
            Invalid Content-Type :
              value: {
                        "error": "server_error",
                        "error_description": "The value of the Content-Type header is invalid"
                      }

    AuthError500:
      description: | 
        **Internal Server Error**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/AuthErrorInfo'
          examples:
            Config Param Error:
              value: {
                        "error": "server_error",
                        "error_description": "Internal configuration error"
                      }
            Internal Processing Fail:
              value: {
                        "error": "server_error",
                        "error_description": "The authorization server encountered an unexpected condition that prevented it from fulfilling the request"
                      }

    AuthError502:
      description: | 
        **Bad Gateway**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/AuthErrorInfo'
          examples:
            Bad Gateway:
              value: {
                        "error": "server_error",
                        "error_description": "Error connecting to an upstream server"
                      }
    AuthError503:
      description: | 
        **Service Unavailiable**
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/AuthErrorInfo'
          examples:
            Service Unavailiable:
              value: {
                        "error": "temporarily unavailable",
                        "error_description": "An upstream server is unavailable"
                      }

