openapi: 3.0.3
info:
  title: SK-ID MFA
  description: 'The SK-ID integration provide functionality for clients to initiate and confirm documents signing'
  version: '2'
servers:
- url: 'https://api.plumery.com'
  description: Live Server
security:
- cookieAuth: [ ]
tags:
  - name: SK-ID Smart-ID signing
    description: API for signing documents with Smart-ID
  - name: SK-ID Mobile-ID signing
    description: API for signing documents with Mobile-ID
paths:
  '/internal/v2/mfa/sk-id/smart-id/signature/{challengeId}:initiate':
    post:
      tags:
      - SK-ID Smart-ID signing
      summary: Initiate Smart-ID signing challenge
      x-plumery-audit-action-type: SkIdSmartIdSigningChallengeInitiated
      x-plumery-audit-action-name: Smart-ID Signing Challenge Initiated
      x-plumery-audit-action-description: Smart-ID signing challenge was initiated to authorize some action
      description: |-
        Initiates SK-ID Smart-ID signing challenge.

        This endpoint initiates the document signing process and returns the current signing session status.
        - When the status is `PENDING_CODE`, the signing session is not fully initialized and the verification code is not present in the response.
        - When the status is `PENDING_SIGNATURE`, the signing session is fully initialized and the response includes a verification code that the end user must confirm in the SK-ID Smart-ID application.
      operationId: initiateSkIdSmartIdSigningChallengeV2
      parameters:
      - $ref: '#/components/parameters/challengeId'
      responses:
        '200':
          description: SK-ID Smart-ID signing challenge request accepted.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InitiateSigningResponse"
        '400':
          description: Signing session was already initiated for the challenge.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorised.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: ChallengeId not found or expired.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error occurred.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        default:
          description: Unexpected error
      x-internal: false
  '/internal/v2/mfa/sk-id/smart-id/signature:initiate':
    post:
      tags:
        - SK-ID Smart-ID signing
      summary: Initiate Smart-ID signing challenge
      x-plumery-audit-action-type: SkIdSmartIdGenericSigningChallengeInitiated
      x-plumery-audit-action-name: Smart-ID Signing Generic Data Challenge Initiated
      x-plumery-audit-action-description: Smart-ID signing challenge was initiated to authorize some action
      description: |-
        Initiates SK-ID Smart-ID signing challenge.

        This endpoint initiates the document signing process and returns the current signing session status together with the challengeId. Challenge id should be used in subsequent confirm endpoint.
        - When the status is `PENDING_CODE`, the signing session is not fully initialized and the verification code is not present in the response.
        - When the status is `PENDING_SIGNATURE`, the signing session is fully initialized and the response includes a verification code that the end user must confirm in the SK-ID Smart-ID application.
      operationId: initiateSkIdSmartIdGenericSigningChallenge
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InitiateSmartIdChallengeRequest'
      responses:
        '200':
          description: SK-ID Smart-ID signing challenge request accepted.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SkIdChallengeInitiationResponse"
        '400':
          description: Signing session was already initiated for the challenge.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorised.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: ChallengeId not found or expired.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error occurred.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        default:
          description: Unexpected error
      x-internal: false
  '/internal/v2/mfa/sk-id/smart-id/signature/{challengeId}:confirm':
    post:
      tags:
      - SK-ID Smart-ID signing
      summary: Confirm SK-ID Smart-ID signing challenge
      x-plumery-audit-action-type: SkIdSmartIdSigningChallengeConfirmed
      x-plumery-audit-action-name: Smart-ID Signing Challenge Confirmed
      x-plumery-audit-action-description: Smart-ID signing challenge was successfully confirmed
      description: |-
        Confirms SK-ID Smart-ID signing challenge.
        
        This endpoint initiates a signing session by sending a notification to the user’s phone, prompting them to confirm the signing request.
        The client must then poll this endpoint to track the signing session status until the process is completed or fails.
        
        The signing session progresses through the following statuses:
          - `PENDING_CODE`
            The signing session has been created, but is not fully initialized yet.
            The verification code is not returned at this stage.
        
          - `PENDING_SIGNATURE`
            The signing session is fully initialized.
            The verification code is returned and the user is expected to confirm the signing on their device.
        
          - `COMPLETED`
            The signing has been successfully completed.
            The signature is verified and saved.
        
        The client must poll this endpoint repeatedly until one of the following conditions is met:
          - A 200 OK response is returned with status `COMPLETED`, indicating successful signing
          - Any other error response is returned, indicating that the signing process has failed and polling must stop

      operationId: confirmSkIdSmartIdSigningChallengeV2
      parameters:
      - $ref: '#/components/parameters/challengeId'
      responses:
        '200':
          description: SK-ID Smart-ID signing challenge request confirmed. Endpoint intended to be polled. When signature is initiated, returns verification code and status PENDING_SIGNATURE. Otherwise, returns PENDING_CODE if the signing not yet initialized or COMPLETED if the signing completed successfully.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ConfirmSignatureResponse"
        '400':
          description: Signing already confirmed or Signing session not initiated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorised.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: ChallengeId not found or expired.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error occurred.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        default:
          description: Unexpected error
      x-internal: false
  '/internal/v2/mfa/sk-id/mobile-id/signature/{challengeId}:initiate':
    post:
      tags:
      - SK-ID Mobile-ID signing
      summary: Initiate Mobile-ID signing challenge
      x-plumery-audit-action-type: SkIdMobileIdSigningChallengeInitiated
      x-plumery-audit-action-name: Mobile-ID Signing Challenge Initiated
      x-plumery-audit-action-description: Mobile-ID signing challenge was initiated to authorize some action
      description: |-
        Initiates SK-ID Mobile-ID signing challenge.

        This endpoint initiates the document signing process and returns the current signing session status.
        - When the status is `PENDING_CODE`, the signing session is not fully initialized and the verification code is not present in the response.
        - When the status is `PENDING_SIGNATURE`, the signing session is fully initialized and the response includes a verification code that the end user must confirm in the SK-ID Mobile-ID application.
      operationId: initiateSkIdMobileIdSigningChallengeV2
      parameters:
      - $ref: '#/components/parameters/challengeId'
      responses:
        '200':
          description: SK-ID Mobile-ID signing challenge request accepted.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InitiateSigningResponse"
        '400':
          description: Signing session was already initiated for the challenge.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorised.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: ChallengeId not found or expired.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error occurred.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        default:
          description: Unexpected error
      x-internal: false
  '/internal/v2/mfa/sk-id/mobile-id/signature:initiate':
    post:
      tags:
        - SK-ID Mobile-ID signing
      summary: Initiate Mobile-ID signing challenge
      x-plumery-audit-action-type: SkIdMobileIdGenericSigningChallengeInitiated
      x-plumery-audit-action-name: Mobile-ID Generic Data Signing Challenge Initiated
      x-plumery-audit-action-description: Mobile-ID signing challenge was initiated to authorize some action
      description: |-
        Initiates SK-ID Mobile-ID signing challenge.

        This endpoint initiates the document signing process and returns the current signing session status together with the challengeId. Challenge id should be used in subsequent confirm endpoint.
        - When the status is `PENDING_CODE`, the signing session is not fully initialized and the verification code is not present in the response.
        - When the status is `PENDING_SIGNATURE`, the signing session is fully initialized and the response includes a verification code that the end user must confirm in the SK-ID Mobile-ID application.
      operationId: initiateSkIdMobileIdGenericSigningChallenge
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InitiateMobileIdChallengeRequest'
      responses:
        '200':
          description: SK-ID Mobile-ID signing challenge request accepted.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SkIdChallengeInitiationResponse"
        '400':
          description: Signing session was already initiated for the challenge.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorised.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: ChallengeId not found or expired.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error occurred.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        default:
          description: Unexpected error
      x-internal: false
  '/internal/v2/mfa/sk-id/mobile-id/signature/{challengeId}:confirm':
    post:
      tags:
      - SK-ID Mobile-ID signing
      summary: Confirm SK-ID Mobile-ID signing challenge
      x-plumery-audit-action-type: SkIdMobileIdSigningChallengeConfirmed
      x-plumery-audit-action-name: Mobile-ID Signing Challenge Confirmed
      x-plumery-audit-action-description: Mobile-ID signing challenge was successfully confirmed
      description: |-
        Confirms SK-ID Mobile-ID signing challenge.

        This endpoint initiates a signing session by sending a notification to the user’s phone, prompting them to confirm the signing request.
        The client must then poll this endpoint to track the signing session status until the process is completed or fails.
        
        The signing session progresses through the following statuses:
          - `PENDING_CODE`
            The signing session has been created, but is not fully initialized yet.
            The verification code is not returned at this stage.
        
          - `PENDING_SIGNATURE`
            The signing session is fully initialized.
            The verification code is returned and the user is expected to confirm the signing on their device.
        
          - `COMPLETED`
            The signing has been successfully completed.
            The signature is verified and saved.
        
        The client must poll this endpoint repeatedly until one of the following conditions is met:
          - A 200 OK response is returned with status `COMPLETED`, indicating successful signing
          - Any other error response is returned, indicating that the signing process has failed and polling must stop
      operationId: confirmSkIdMobileIdSigningChallengeV2
      parameters:
      - $ref: '#/components/parameters/challengeId'
      responses:
        '200':
          description: SK-ID Smart-ID signing challenge request confirmed. Endpoint intended to be polled. When signature is initiated, returns verification code and status PENDING_SIGNATURE. Otherwise, returns PENDING_CODE if the signing not yet initialized or COMPLETED if the signing completed successfully.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ConfirmSignatureResponse"
        '400':
            description: Signing already confirmed or signing session not initiated.
            content:
                application/json:
                  schema:
                    $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorised.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: ChallengeId not found or expired.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error occurred.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        default:
          description: Unexpected error
      x-internal: false
components:
  schemas:
    ErrorCode:
      enum:
      - 'urn:plmr:mfa:sk-id:api:USER_NOT_FOUND'
      - 'urn:plmr:mfa:sk-id:api:USER_MISSING_REQUIRED_DETAILS'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_COMMUNICATION_FAILURE'
      - 'urn:plmr:mfa:sk-id:api:STEP_UP_REQUEST_CONTEXT_NOT_FOUND'
      - 'urn:plmr:mfa:sk-id:api:SIGNING_CONFIRMATION_MESSAGE_TEMPLATE_NOT_FOUND'
      - 'urn:plmr:mfa:sk-id:api:SIGNING_CONFIRMATION_MESSAGE_TEMPLATE_EVALUATION_FAILED'
      - 'urn:plmr:mfa:sk-id:api:SIGNING_SESSION_NOT_FOUND'
      - 'urn:plmr:mfa:sk-id:api:SIGNING_SESSION_ALREADY_INITIATED'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_WRONG_VERIFICATION_CODE'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_USER_REFUSED'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_TIMEOUT'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_USER_NOT_MID_CLIENT'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_USER_CANCELED'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_DOCUMENT_UNUSABLE'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_PHONE_ABSENT'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_DELIVERY_ERROR'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_SIM_ERROR'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_SIGNATURE_HASH_MISMATCH'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_INTERACTION_NOT_SUPPORTED'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_USER_CANCELED_VERIFICATION_CODE_AND_MESSAGE'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_USER_DOES_NOT_EXISTS'
      - 'urn:plmr:mfa:sk-id:api:USER_ID_DOES_NOT_MATCH_WITH_CHALLENGE_SUBJECT_USER_ID'
      - 'urn:plmr:mfa:sk-id:api:INCORRECT_SK_ID_TYPE'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_UNKNOWN_RESPONSE'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_SIGNATURE_VERIFICATION_FAILURE'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_SIGNING_INITIATION_FAILURE'
      - 'urn:plmr:mfa:sk-id:api:SK_ID_SIGNING_NOT_YET_COMPLETED_EXCEPTION'
      - 'urn:plmr:mfa:sk-id:api:NOT_SUPPORTED_SK_ID_TYPE'
      - 'urn:plmr:mfa:sk-id:api:INVALID_PERSONAL_ID'
      - 'urn:plmr:mfa:sk-id:api:INVALID_PHONE_NUMBER'
      - 'urn:plmr:mfa:sk-id:api:BAD_REQUEST'
      type: string
      example: 'urn:plmr:mfa:sk-id:api:USER_NOT_FOUND'
    FieldErrorCode:
      enum:
      - 'urn:plmr:mfa:sk-id:NOT_BLANK'
      - 'urn:plmr:mfa:sk-id:NOT_NULL'
      type: string
    FieldError:
      type: object
      properties:
        code:
          $ref: '#/components/schemas/FieldErrorCode'
        message:
          type: string
        field:
          type: string
    ErrorResponse:
      type: object
      properties:
        code:
          $ref: '#/components/schemas/ErrorCode'
        message:
          type: string
        requestId:
          type: string
        fieldErrors:
          type: array
          items:
            $ref: '#/components/schemas/FieldError'
    InitiateSigningResponse:
      type: object
      properties:
        verificationCode:
          type: string
        status:
          type: string
          enum:
          - PENDING_CODE
          - PENDING_SIGNING
    SkIdChallengeInitiationResponse:
      type: object
      required:
        - challengeId
        - status
      properties:
        challengeId:
          type: string
        verificationCode:
          type: string
        status:
          type: string
          enum:
            - PENDING_CODE
            - PENDING_SIGNING
    ConfirmSignatureResponse:
      type: object
      properties:
        verificationCode:
          type: string
        status:
          type: string
          enum:
          - PENDING_CODE
          - PENDING_SIGNING
          - COMPLETED
    InitiateSmartIdChallengeRequest:
      type: object
      required:
        - signableContent
        - displayText
        - username
        - source
      properties:
        signableContent:
          type: string
          description: Base64 content that will be signed by Smart-ID
        confirmationMessage:
          type: string
          description: Text shown to the user during Smart-ID confirmation
        username:
          type: string
          description: Name of the user inside Plumery system
        source:
          type: string
          description: The path of the resource which needs to be signed(e.g. /api/v1/documents/1234567890)
    InitiateMobileIdChallengeRequest:
      type: object
      required:
        - signableContent
        - displayText
        - username
        - source
      properties:
        signableContent:
          type: string
          description: Base64 content that will be signed by Smart-ID
        confirmationMessage:
          type: string
          description: Text shown to the user during Smart-ID confirmation
        username:
          type: string
          description: Name of the user inside Plumery system
        source:
          type: string
          description: The path of the resource which needs to be signed(e.g. /api/v1/documents/1234567890)

  securitySchemes:
    cookieAuth:
      type: apiKey
      in: cookie
      name: auth-session
  parameters:
    challengeId:
      in: path
      name: challengeId
      required: true
      allowEmptyValue: false
      example: 2751d7d9-df79-4412-b4c4-28aaa7075548
      schema:
        type: string
        minLength: 36
        maxLength: 36
        nullable: false
      description: |
        The ID of the challenge.