openapi: 3.0.3
info:
  title: Token Management 3SKey API
  description: |
    API to support digital signing and authentication for 3SKey
  version: 1.0.0
  contact:
    email: developer-support@swift.com 
    name: Developer Hub
  license:
    name: API Restricted License
    url: https://developer.swift.com/api-license

servers:
  - description: Live Environment
    url: https://api.swift.com/swift-token-management/v1

tags:
  - name: Signing
    description: Concerning the request for and retrieval of signatures
  - name: Authentication
    description: Concerning the request to be authenticated and retreival of authentication status

security: 
  - oauthBearerToken: []

paths:
  /digital-token/signature:
    post:
      tags:
        - Signing
      summary: Request a Signature.
      description: Submits request for signature to Swift systems.
      operationId: submitForSignature
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignatureRequest'
            examples:
              Request:
                $ref: '#/components/examples/SignatureRequest'
        required: true
      responses:
        '202':
          description: Request submitted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DigitalTokenResponse'
              examples:
                Response:
                  $ref: '#/components/examples/SignatureOrAuthenticationResponse'
        '400':
          description: >-
            A 400 Bad Request response status is returned for validation or other business errors.
            
            Additionally, Swift API Gateway uses the 400 status code for the following failure cases: 

              - SwAP510 - The API method does not support non-repudiation.

              - SwAP509 - Missing mandatory signature on the non-repudiation API transaction.

              - SwAP504 - Text is custom to the schema error
        
              - SwAP504 - Invalid Service.

              - SwAP504 - JSON request body does not conform to policy.

              - SwAP505 - XML request body does not conform to policy.

              - SwAP501 - API request is malformed.
          headers:
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage'
              examples: 
                400-CAPE01:
                  $ref: '#/components/examples/400-CAPE01'
                400-SwAP510:
                  $ref: '#/components/examples/400-SwAP510'
                400-SwAP509:
                  $ref: '#/components/examples/400-SwAP509'
                400-SwAP504-txt:
                  $ref: '#/components/examples/400-SwAP504-txt'
                400-SwAP504-svc:
                  $ref: '#/components/examples/400-SwAP504-svc'
                400-SwAP504:
                  $ref: '#/components/examples/400-SwAP504'
                400-SwAP505:
                  $ref: '#/components/examples/400-SwAP505'
                400-SwAP501:
                  $ref: '#/components/examples/400-SwAP501'
        '401':
          $ref: '#/components/responses/401-Unauthorized'
        '403':
          $ref: '#/components/responses/403-Forbidden'
        '404':
          $ref: '#/components/responses/404-NotFound'
        '429':
          $ref: '#/components/responses/429-TooManyRequests'
        '500':
          $ref: '#/components/responses/500-InternalServerError'
        '503':
          $ref: '#/components/responses/503-ServiceUnavailable'
        '504':
          $ref: '#/components/responses/504-GatewayTimeout'
        default:
          $ref: '#/components/responses/500-InternalServerError'
        
  /digital-token/authentication:
    post:
      tags:
        - Authentication
      summary: Request an Authentication.
      description: Submits request for authentication to Swift systems.
      operationId: submitForAuthentication
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AuthenticationRequest'
            examples:
              Request:
                $ref: '#/components/examples/AuthenticationRequest'
        required: true
      responses:
        '202':
          description: Request submitted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DigitalTokenResponse'
              examples:
                Response:
                  $ref: '#/components/examples/SignatureOrAuthenticationResponse'
        '400':
          description: >-
            A 400 Bad Request response status is returned for validation or other business errors.
            
            Additionally, Swift API Gateway uses the 400 status code for the following failure cases: 

              - SwAP510 - The API method does not support non-repudiation.

              - SwAP509 - Missing mandatory signature on the non-repudiation API transaction.

              - SwAP504 - Text is custom to the schema error

              - SwAP504 - Invalid Service.

              - SwAP504 - JSON request body does not conform to policy.

              - SwAP505 - XML request body does not conform to policy.

              - SwAP501 - API request is malformed.
          headers:
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage'
              examples: 
                400-CAPE01:
                  $ref: '#/components/examples/400-CAPE01'
                400-SwAP510:
                  $ref: '#/components/examples/400-SwAP510'
                400-SwAP509:
                  $ref: '#/components/examples/400-SwAP509'
                400-SwAP504-txt:
                  $ref: '#/components/examples/400-SwAP504-txt'
                400-SwAP504-svc:
                  $ref: '#/components/examples/400-SwAP504-svc'
                400-SwAP504:
                  $ref: '#/components/examples/400-SwAP504'
                400-SwAP505:
                  $ref: '#/components/examples/400-SwAP505'
                400-SwAP501:
                  $ref: '#/components/examples/400-SwAP501'
        '401':
          $ref: '#/components/responses/401-Unauthorized'
        '403':
          $ref: '#/components/responses/403-Forbidden'
        '404':
          $ref: '#/components/responses/404-NotFound'
        '429':
          $ref: '#/components/responses/429-TooManyRequests'
        '500':
          $ref: '#/components/responses/500-InternalServerError'
        '503':
          $ref: '#/components/responses/503-ServiceUnavailable'
        '504':
          $ref: '#/components/responses/504-GatewayTimeout'
        default:
          $ref: '#/components/responses/500-InternalServerError'  
  /digital-token/{session_id}:
    get:
      tags:
        - Signing
        - Authentication
      summary: Retrieve Signature or Authentication Status.
      description: Checks the status of a request in Swift systems.
      operationId: getStatus
      parameters:
        - name: session_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
          example: de305d54-75b4-431b-adb2-eb6b9e546014
      responses:
        '200':
          description: Request Status.
          headers:
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DigitalTokenResponse'
              examples:
                Status_PENDING:
                  $ref: '#/components/examples/SignatureOrAuthenticationResponse_PENDING'
                Status_COMPLETE:
                  $ref: '#/components/examples/SignatureOrAuthenticationResponse_REFUSED'
                Status_ERROR:
                  $ref: '#/components/examples/SignatureOrAuthenticationResponse_COMPLETE'
        '400':
          description: >-
            A 400 Bad Request response status is returned for validation or other business errors.
            
            Additionally, Swift API Gateway uses the 400 status code for the following failure cases: 

              - SwAP510 - The API method does not support non-repudiation.

              - SwAP509 - Missing mandatory signature on the non-repudiation API transaction.

              - SwAP504 - Text is custom to the schema error

              - SwAP504 - Invalid Service.

              - SwAP504 - JSON request body does not conform to policy.

              - SwAP505 - XML request body does not conform to policy.

              - SwAP501 - API request is malformed.
          headers:
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage'
              examples: 
                400-CAPE01:
                  $ref: '#/components/examples/400-CAPE01'
                400-SwAP510:
                  $ref: '#/components/examples/400-SwAP510'
                400-SwAP509:
                  $ref: '#/components/examples/400-SwAP509'
                400-SwAP504-txt:
                  $ref: '#/components/examples/400-SwAP504-txt'
                400-SwAP504-svc:
                  $ref: '#/components/examples/400-SwAP504-svc'
                400-SwAP504:
                  $ref: '#/components/examples/400-SwAP504'
                400-SwAP505:
                  $ref: '#/components/examples/400-SwAP505'
                400-SwAP501:
                  $ref: '#/components/examples/400-SwAP501'
        '401':
          $ref: '#/components/responses/401-Unauthorized'
        '403':
          $ref: '#/components/responses/403-Forbidden'
        '404':
          $ref: '#/components/responses/404-NotFound'
        '429':
          $ref: '#/components/responses/429-TooManyRequests'
        '500':
          $ref: '#/components/responses/500-InternalServerError'
        '503':
          $ref: '#/components/responses/503-ServiceUnavailable'
        '504':
          $ref: '#/components/responses/504-GatewayTimeout'
        default:
          $ref: '#/components/responses/500-InternalServerError'
        
  
components:
  securitySchemes:
    oauthBearerToken:
      type: http
      scheme: bearer
      bearerFormat: Signed JWT
  parameters:
    X-Request-ID:
      name: X-Request-ID
      in: header
      description: End to end tracking ID. This value will be returned to the caller as a response header of the same name. If no header is assigned by the caller, then one will be assigned by Swift.
      required: false
      schema:
        type: string
        maxLength: 75
      example: rrt-1130311210763048898-c-geu2-21394-2055157-17
  headers:
    X-Request-ID:
      description: End to end tracking ID. This value identifies the callers request in the Swift API Platform.
      schema:
        type: string
        maxLength: 75
      example: nlartp03-2674166-324389-2

  schemas:
    SignatureRequest:
      type: object
      additionalProperties: false
      properties:
        requester_bic:
          maxLength: 8
          minLength: 8
          type: string
          example: TESTBIC8
        requester_service:
          type: string
          example: Test Bank Portal
        user_id:
          type: string
          example: corp12345678
        digest:
          type: array
          minItems: 1
          maxItems: 100
          items:
            type: string
            maxLength: 100
          example: ['Pwo3e6CkpGDsthb2UHzg2M+j5wQCXU/aPtDFygVGhyg=']
        digest_algorithm:
          type: string
          enum: 
            - SHA256
          example: SHA256
        user_preferred_method:
          type: string
          example: SSSKEY_DIGITAL
          enum:
            - SSSKEY_DIGITAL
        required_security_level:
          type: string
          example: EASY
          enum:
            - EASY
            - AVERAGE
            - COMPLEX
        message:
          type: string
          maxLength: 200
          minLength: 0
          example: 'Authenticate to Payment system'
      required:
        - requester_bic
        - requester_service
        - user_id
        - digest
        - digest_algorithm
    
    AuthenticationRequest:
      type: object
      additionalProperties: false
      properties:
        requester_bic:
          maxLength: 8
          minLength: 8
          type: string
          example: TESTBIC8
        requester_service:
          type: string
          example: Test Application
        user_id:
          type: string
          example: corp12345678
        challenge:
          type: string
          example: Pwo3e6CkpGDsthb2UHzg2M+j5wQCXU/aPtDFygVGhyg=
        user_preferred_method:
          type: string
          example: SSSKEY_DIGITAL
          enum:
            - SSSKEY_DIGITAL
        required_security_level:
          type: string
          example: EASY
          enum:
            - EASY
            - AVERAGE
            - COMPLEX
        message:
          type: string
          maxLength: 200
          minLength: 0
          example: 'currency: euro, value: 250, ...'
      required:
        - requester_bic
        - requester_service
        - user_id
        - challenge

    DigitalTokenResponse:
      type: object
      additionalProperties: false
      properties:
        session_id:
          type: string
          format: uuid
          example: de305d54-75b4-431b-adb2-eb6b9e546014
        verification_code:
          type: string
          example: '8691'
        dn:
          type: string
          example: CN=corp04367121,OU=section_7,OU=personalid,O=swift,C=ww
        signature:
          type: array
          minItems: 1
          maxItems: 100
          items:
            type: string
            maxLength: 1200
          example: ['B+C9XVjIAZnCHH9vfBSv...']
        certificate:
          type: string
          maxLength: 3000
          example: B+C9XVjIAZnCHH9vfBSv...
        pkcs7:
          type: array
          minItems: 1
          maxItems: 100
          items:
            type: string
            maxLength: 3000
          example: ['B+C9XVjIAZnCHH9vfBSv...']
        state:
          type: string
          example: COMPLETE
          enum:
            - PENDING
            - COMPLETE
            - ERROR
        result:
          type: string
          example: USER_REFUSED
    ErrorMessage: 
      type: object
      additionalProperties: false
      properties:
        severity:
          description: |
            The category of error.
              * Fatal means the failure is permanent and the request should not be retried.
              * Transient means the failure is temporary and the request can be retried after a suitable interval.
              * Logic is a legacy code and should not be used. 
          type: string
          enum:
            - Fatal
            - Transient
            - Logic
        code: 
          description: A unique string which should identify the error and the system or service where it originated.          
          type: string
          maxLength: 50
        text:
          description: free-text field which should describe the problem and any recovery or remediation steps which can be taken.
          type: string
          maxLength: 1000
      required:
        - severity
        - code
        - text
      
  responses: 
    406-NotAcceptable:
      description: Not Acceptable
      headers:
        X-Request-ID: 
          $ref: '#/components/headers/X-Request-ID' 
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorMessage'
          examples:
            406-Encoding:
              $ref: '#/components/examples/406-Encoding'
            406-Language:
              $ref: '#/components/examples/406-Language'
              
    415-UnsupportedMediaType:
      description: Unsupported Media Type
      headers:
        X-Request-ID: 
          description: End to end tracking ID. This value identifies the callers request in the Swift API Platform.
          schema:
            type: string
            maxLength: 75
          example: nlartp03-2674166-324389-2 
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorMessage'
          examples:
            415-UnsupportedMediaType:
              $ref: '#/components/examples/415-UnsupportedMediaType'
    
    401-Unauthorized:
      description: >-
        Covers the following scenarios:
        
        * SwAP502 - Invalid Signing Certificate. The certificate cannot be used for doing the API transaction.
        
        * SwAP502 - Invalid OAuth access token.
        
        * SwAP508 - OAuth access token not provided.
        
        * SwAP509 - Customer number not defined.
      headers:
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorMessage' 
          examples:
            401-SwAP502-cert:
              $ref: '#/components/examples/401-SwAP502-cert'
            401-SwAP502-token:
              $ref: '#/components/examples/401-SwAP502-token'
            401-SwAP508:
              $ref: '#/components/examples/401-SwAP508'
            401-SwAP509:
              $ref: '#/components/examples/401-SwAP509'
            
    403-Forbidden:
      description: >-
        Covers the following scenarios:

        - SwAP503 - OAuth access token has insufficient scope for the requested service. 
      headers:
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorMessage' 
          examples:
            403-SwAP503:
              $ref: '#/components/examples/403-SwAP503'
    
    404-NotFound:
      description: >-
        Covers the following scenarios:

        - SwAP506 - Resource does not exist.
      headers:
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorMessage' 
          examples:
            404-SwAP506:
              $ref: '#/components/examples/404-SwAP506'

    429-TooManyRequests:
      description: >-
        Covers the following scenarios:

        - SwAP507 - Request cannot be processed at this time. Please try again..
      headers:
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorMessage' 
          examples:
            429-SwAP507:
              $ref: '#/components/examples/429-SwAP507'

    503-ServiceUnavailable:
      description: >-
        Covers the following scenarios:

        - SwAP590 - Service is temporarily unavailable.
      headers:
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorMessage' 
          examples:
            503-SwAP590:
              $ref: '#/components/examples/503-SwAP590'

    504-GatewayTimeout:
      description: >-
        Covers the following scenarios:

        - SwAP591 - Service Provider time out.
      headers:
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorMessage' 
          examples:
            504-SwAP591:
              $ref: '#/components/examples/504-SwAP591'

    # Default error response #
    500-InternalServerError: 
      description: 'Internal Server Error'
      headers:
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorMessage'      
          examples:
            500-InternalServerError:
              $ref: '#/components/examples/500-InternalServerError'  

  examples:
    406-Encoding:
      summary: Unsupported encoding
      value:
        severity: Fatal
        code: <error code> 
        text: Encoding must be UTF-8. Other encodings are not supported. 
        
    406-Language:
      summary: Unsupported language
      value:
        severity: Fatal
        code: <error code> 
        text: Language <language> is not supported. 
    
    415-UnsupportedMediaType:
      summary: Unsupported Media Type
      value:
        severity: Fatal
        code: <error code> 
        text: Media type <media-type> is not supported. 

    400-AppRevoked:
      summary: >-
        Client App is revoked
      value:
        severity: Fatal
        code: <enter code here> 
        text: The action is unsupported because this Client App is in the revoked state.

    400-SwAP510:
      summary: >-
        SwAP510: The API method does not support non-repudiation.
      value:
        severity: Fatal
        code: SwAP510 
        text: The API method does not support non-repudiation.
    400-SwAP509:
      summary: >-
        SwAP509: Missing mandatory signature on the non-repudiation API transaction.
      value:
        severity: Fatal
        code: SwAP509 
        text: Missing mandatory signature on the non-repudiation API transaction.
    400-SwAP504-txt:
      summary: >-
        SwAP504: Text is custom to the schema error
      value:
        severity: Fatal
        code: SwAP504 
        text: Text is custom to the schema error
    400-SwAP504-svc:
      summary: >-
        SwAP504: Invalid Service.
      value:
        severity: Fatal
        code: SwAP504 
        text: Invalid Service.
    400-SwAP504:
      summary: >-
        SwAP504: JSON request body does not conform to policy.
      value:
        severity: Fatal
        code: SwAP504 
        text: JSON request body does not conform to policy.
    400-SwAP505:
      summary: >-
        SwAP505: XML request body does not conform to policy.
      value:
        severity: Fatal
        code: SwAP505 
        text: XML request body does not conform to policy.
    400-SwAP501:
      summary: >-
        SwAP501: API request is malformed.
      value:
        severity: Fatal
        code: SwAP501 
        text: API request is malformed.

    400-CAPE01:
      summary: >-
        Placeholder for CAPE API 400 response.
      value:
        severity: Fatal
        code: CAPE01 
        text: TBC - stuff goes wrong 

    401-SwAP502-cert:
      summary: >-
        SwAP502: Invalid Signing Certificate. The certificate cannot be used for doing the API transaction.
      value:
        severity: Fatal
        code: SwAP502 
        text: Invalid Signing Certificate. The certificate cannot be used for doing the API transaction.
    401-SwAP502-token:
      summary: >-
        SwAP502: Invalid OAuth access token.
      value:
        severity: Fatal
        code: SwAP502 
        text: Invalid OAuth access token.
    401-SwAP508:
      summary: >-
        SwAP508: OAuth access token not provided.
      value:
        severity: Fatal
        code: SwAP508 
        text: OAuth access token not provided.
    401-SwAP509:
      summary: >-
        SwAP509: Customer number not defined.
      value:
        severity: Fatal
        code: SwAP509 
        text: Customer number not defined.
    403-SwAP503:
      summary: >-
        SwAP503: OAuth access token has insufficient scope for the requested service. 
      value:
        severity: Fatal
        code: SwAP503 
        text: OAuth access token has insufficient scope for the requested service. 
    404-SwAP506:
      summary: >-
        SwAP506: Resource does not exist.
      value:
        severity: Fatal
        code: SwAP506 
        text: Resource does not exist.
    429-SwAP507:
      summary: >-
        SwAP507: Request cannot be processed at this time. Please try again..
      value:
        severity: Transient
        code: SwAP507 
        text: Request cannot be processed at this time. Please try again..
    503-SwAP590:
      summary: >-
        SwAP590: Service is temporarily unavailable.
      value:
        severity: Transient
        code: SwAP590 
        text: Service is temporarily unavailable.
    503-SwAP599:
      summary: >-
        SwAP599: Service is temporarily unavailable.
      value:
        severity: Transient
        code: SwAP599 
        text: Service is temporarily unavailable.
    504-SwAP591:
      summary: >-
        SwAP591: Service Provider time out.
      value:
        severity: Transient
        code: SwAP591 
        text: Service Provider time out.

    # Default error response.
    500-InternalServerError:
      summary: Internal Server Error
      value:
        severity: Transient
        code: <error code here> 
        text: Server encountered an unexpected condition and cannot fulfill the request.
###########################
#       Examples          #
###########################
    # POST Request for Signature or Authentication
    SignatureRequest:
      summary: Signature Request 
      value:
        requester_bic: TESTBIC8
        requester_service: Test Application
        user_id: corp12345678
        digest: 
          - 'Pwo3e6CkpGDsthb2UHzg2M+j5wQCXU/aPtDFygVGhyg='
        digest_algorithm: SHA256
        user_preferred_method: SSSKEY_DIGITAL
        required_security_level: EASY
        message: 'currency: euro, value: 250, ...'
    AuthenticationRequest:
      summary: Authentication Request 
      value:
        requester_bic: TESTBIC8
        requester_service: Test Application
        user_id: corp12345678
        challenge: Pwo3e6CkpGDsthb2UHzg2M+j5wQCXU/aPtDFygVGhyg=
        user_preferred_method: SSSKEY_DIGITAL
        required_security_level: EASY
        message: 'Authenticate to the Payment system'    
    SignatureOrAuthenticationResponse:
      summary: Signature or Authentication Response 
      value:
        session_id: de305d54-75b4-431b-adb2-eb6b9e546014
        verification_code: '8691'
        state: PENDING
    # GET Signature or Authentication Request Status 
    SignatureOrAuthenticationResponse_PENDING:
      summary: Status_PENDING
      value:
        session_id: de305d54-75b4-431b-adb2-eb6b9e546014
        state: PENDING
    SignatureOrAuthenticationResponse_REFUSED:
      summary: Status_REFUSED
      value:
        session_id: de305d54-75b4-431b-adb2-eb6b9e546014
        state: COMPLETE
        result: USER_REFUSED
    SignatureOrAuthenticationResponse_COMPLETE:
      summary: Status_COMPLETE
      value:
        session_id: de305d54-75b4-431b-adb2-eb6b9e546014
        dn: CN=corp04367121,OU=section_7,OU=personalid,O=swift,C=ww
        signature: ['B+C9XVjIAZnCHH9vfBSv...']
        certificate: B+C9XVjIAZnCHH9vfBSv...
        pkcs7: ['B+C9XVjIAZnCHH9vfBSv...']
        state: COMPLETE
        result: OK