openapi: 3.0.1
info:
  title: Cybersign Sponsored Onboarding & Signing API
  version: 1.1.0
  description: >-
    API endpoints for Cybersign's sponsored user onboarding flow, including
    authentication, data enrichment, phone verification, KYC status check,
    document signing preparation (upload/download URLs), certificate management,
    and document signing.
servers:
  - url: https://api.cybersign.com/v1
    description: Production Server
tags:
  - name: Authentication
    description: Operations related to user signup initiation and login.
  - name: Onboarding
    description: >-
      Operations related to the user onboarding process after initial login,
      including data submission, phone verification, and status checks.
  - name: Documents
    description: >-
      Operations related to preparing documents for signing (upload/download)
      and performing the signature.
  - name: Certificates
    description: Operations related to managing digital certificates.
paths:
  /auth/signup:
    post:
      tags:
        - Authentication
      summary: Register or Check User Existence
      description: >-
        Attempts to register a new user with the provided email. If the user
        already exists, it returns a 200 OK. If the user is successfully
        created, it returns a 201 Created. Both responses return the user's
        email.
      operationId: authSignup
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignupRequest'
      responses:
        '200':
          description: User already exists. No action taken.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignupResponse'
        '201':
          description: User successfully created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignupResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - m2m_oauth: []
  /auth/login:
    post:
      tags:
        - Authentication
      summary: Initiate Login (Send Email OTP)
      description: >-
        Initiates the login process for a given email by sending an OTP via
        email. Returns a session identifier required for the confirmation step.
        Responds with 200 OK even if the email is not registered to prevent user
        enumeration.
      operationId: authLoginInitiate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginInitiateRequest'
      responses:
        '200':
          description: >-
            Login process initiated successfully (OTP sent or queued). Includes
            session details needed for confirmation. This response is returned
            even if the email is not registered.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LoginInitiateResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - m2m_oauth: []
  /auth/login-confirmation:
    post:
      tags:
        - Authentication
      summary: Confirm Login (Verify Email OTP)
      description: >-
        Confirms the login attempt by verifying the provided email OTP against
        the session identifier returned by `/auth/login`. On success, returns
        standard OAuth2 tokens (for subsequent API calls) and onboarding
        status/details if applicable.
      operationId: authLoginConfirm
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginConfirmRequest'
      responses:
        '200':
          description: >-
            Login successful. Returns authentication tokens and potentially
            onboarding information.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LoginConfirmResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/InvalidOtpOrSession'
        '412':
          $ref: '#/components/responses/AccountInactive'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - m2m_oauth: []
  /onboarding/{onboarding_process_ulid}/data-enrichment:
    post:
      tags:
        - Onboarding
      summary: Submit and Enrich Personal Data
      description: >-
        Submits user-provided personal data (DPI, phone, address) for a specific
        onboarding process. Cybersign enriches this data using
        government/external sources and returns the combined data for user
        review. Triggered when the company shows the initial info form to the
        end user.
      operationId: onboardingEnrichData
      parameters:
        - name: onboarding_process_ulid
          in: path
          required: true
          description: >-
            The unique identifier (ULID) for the user's onboarding process,
            obtained after login confirmation.
          schema:
            type: string
            format: ulid
            example: 01ARZ3NDEKTSV4RRFFQ69G5FAV
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DataEnrichmentRequest'
      responses:
        '200':
          description: >-
            Personal data successfully submitted and enriched. Returns the
            combined data for user review.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PersonData'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - user_bearer_auth: []
  /onboarding/{onboarding_process_ulid}/phone/send-otp:
    post:
      tags:
        - Onboarding
      summary: Request Phone Verification OTP
      description: >-
        Requests an OTP to be sent via SMS to the phone number associated with
        the specified onboarding process (previously submitted via
        data-enrichment). Trigger this *after* the user confirms the enriched
        data presented by the Company.
      operationId: onboardingSendPhoneOtp
      parameters:
        - name: onboarding_process_ulid
          in: path
          required: true
          description: The unique identifier (ULID) for the user's onboarding process.
          schema:
            type: string
            format: ulid
            example: 01ARZ3NDEKTSV4RRFFQ69G5FAV
      responses:
        '202':
          description: >-
            Accepted. The request to send an SMS OTP has been accepted and is
            being processed.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - user_bearer_auth: []
  /onboarding/{onboarding_process_ulid}/phone/confirm-otp:
    post:
      tags:
        - Onboarding
      summary: Confirm Phone Number via OTP
      description: >-
        Submits the OTP received via SMS to verify the phone number associated
        with the onboarding process. On success, returns the URL for the next
        onboarding step (KYC/identity verification).
      operationId: onboardingConfirmPhoneOtp
      parameters:
        - name: onboarding_process_ulid
          in: path
          required: true
          description: The unique identifier (ULID) for the user's onboarding process.
          schema:
            type: string
            format: ulid
            example: 01ARZ3NDEKTSV4RRFFQ69G5FAV
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PhoneOtpConfirmRequest'
      responses:
        '200':
          description: >-
            Phone number successfully verified. Returns the URL for the next
            step (KYC).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PhoneOtpConfirmResponse'
        '400':
          $ref: '#/components/responses/InvalidOtp'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - user_bearer_auth: []
  /onboarding/{onboarding_process_ulid}/kyc-status:
    get:
      tags:
        - Onboarding
      summary: Get KYC Verification Status
      description: >-
        Retrieves the current status of the Know Your Customer (KYC)
        verification step for the specified onboarding process. Provides details
        on liveness, face match, and document checks based on the results from
        the identity verification provider.
      operationId: onboardingGetKycStatus
      parameters:
        - name: onboarding_process_ulid
          in: path
          required: true
          description: The unique identifier (ULID) for the user's onboarding process.
          schema:
            type: string
            format: ulid
            example: 01ARZ3NDEKTSV4RRFFQ69G5FAV
      responses:
        '200':
          description: KYC status retrieved successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/KycStatusResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - user_bearer_auth: []
  /documents/upload-url:
    post:
      tags:
        - Documents
      summary: Generate Pre-signed Upload URL
      description: >-
        Generates a pre-signed URL suitable for uploading a document directly to
        Cybersign's secure storage (e.g., S3). The URL expiry depends on the
        selected file tier.
      operationId: generateDocumentUploadUrl
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UploadUrlRequest'
      responses:
        '200':
          description: Pre-signed URL and associated data generated successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UploadUrlResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - user_bearer_auth: []
  /documents/download-url:
    get:
      tags:
        - Documents
      summary: Generate Pre-signed Download URL
      description: >-
        Generates a pre-signed URL for securely downloading a previously signed
        document. The URL has a short expiry time (e.g., 5 minutes) and is
        single-use.
      operationId: generateDocumentDownloadUrl
      parameters:
        - name: document-path
          in: query
          required: true
          description: >-
            The storage path/key of the signed document to download (obtained
            previously, e.g., from upload response or signing confirmation).
          schema:
            type: string
            example: user-uuid/onboarding-ulid/document-name.pdf
      responses:
        '200':
          description: Pre-signed download URL generated successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DownloadUrlResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - user_bearer_auth: []
  /documents/{doc-ulid}/sign:
    post:
      tags:
        - Documents
      summary: Sign Uploaded Document
      description: >-
        Applies a digital signature to a previously uploaded document using the
        specified user certificate and OTP verification. Supports visible and
        invisible signatures.
      operationId: signDocument
      parameters:
        - name: doc-ulid
          in: path
          required: true
          description: >-
            The unique ULID of the document (obtained from the upload URL
            response) to be signed.
          schema:
            type: string
            format: ulid
            example: 01JE9KCR0H22PDY9C1GYZABCDE
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DocumentSignRequest'
      responses:
        '200':
          description: Document signed successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentSignResponse'
        '400':
          description: >-
            Bad Request (e.g., Invalid OTP, Certificate not active, Document not
            ready for signing, Invalid visible signature options).
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/responses/InvalidOtp'
                  - $ref: '#/components/responses/CertificateNotActive'
                  - $ref: '#/components/responses/DocumentNotReady'
                  - $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - user_bearer_auth: []
  /certificates:
    get:
      tags:
        - Certificates
      summary: Get User Certificates
      description: >-
        Retrieves a list of active and usable digital certificates associated
        with the authenticated user.
      operationId: getUserCertificates
      responses:
        '200':
          description: Successfully retrieved the list of user certificates.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CertificateSummary'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - user_bearer_auth: []
components:
  schemas:
    SignupRequest:
      type: object
      required:
        - email
        - client_id
      properties:
        email:
          type: string
          format: email
          description: The email address for the user signup attempt.
          example: user@company.com
        client_id:
          type: string
          description: The OAuth client_id of the company initiating the request.
          example: aBcDeFgHiJkLmNoPqRsT
    LoginInitiateRequest:
      type: object
      required:
        - email
        - client_id
      properties:
        email:
          type: string
          format: email
          description: The email address of the user attempting to log in.
          example: user@company.com
        client_id:
          type: string
          description: The OAuth client_id of the company initiating the request.
          example: aBcDeFgHiJkLmNoPqRsT
    LoginConfirmRequest:
      type: object
      required:
        - email
        - session
        - method
        - client_id
        - otp
        - user_id
      properties:
        email:
          type: string
          format: email
          description: The email address of the user confirming login.
          example: user@company.com
        session:
          type: string
          description: >-
            The session challenge identifier returned by the /auth/login
            endpoint.
          example: sess_abc123xyz789
        method:
          type: string
          enum:
            - email
          description: The confirmation method being used.
        client_id:
          type: string
          description: The OAuth client_id of the company initiating the request.
          example: aBcDeFgHiJkLmNoPqRsT
        otp:
          type: string
          description: The One-Time Password received by the user via email.
          example: '123456'
        user_id:
          type: string
          description: User Id
          example: aaaa-bbbb-xxxx-yyyy
    SignupResponse:
      type: object
      required:
        - email
      properties:
        email:
          type: string
          format: email
          description: The email address associated with the signup status.
          example: user@company.com
    LoginInitiateResponse:
      type: object
      required:
        - email
        - session
        - method
        - user_id
      properties:
        email:
          type: string
          format: email
          description: The email address for which the login was initiated.
          example: user@company.com
        session:
          type: string
          description: >-
            A unique session identifier for this specific login attempt.
            Required for the /auth/login-confirmation step.
          example: sess_abc123xyz789
        method:
          type: string
          enum:
            - email
          description: The method used for this login attempt.
        user_id:
          type: string
          description: User id.
          example: 27c7e9af-b519-4bec-a9c1-c7fd51aad8b6
    LoginConfirmResponse:
      type: object
      required:
        - access_token
        - expires_in
        - token_type
        - id_token
      properties:
        access_token:
          type: string
          description: >-
            The OAuth2.0 access token for making authenticated requests to
            non-auth endpoints.
          example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
        expires_in:
          type: integer
          format: int32
          description: The lifetime in seconds of the access token.
          example: 3600
        token_type:
          type: string
          description: Type of the token issued (e.g., "Bearer").
          example: Bearer
        id_token:
          type: string
          description: A JWT containing identity information about the user.
          example: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
        onboarding_step:
          type: string
          nullable: true
          description: >-
            Identifier for the next onboarding step required, if any. Null or
            absent if onboarding is complete.
          example: data_enrichment
        onboarding_process_ulid:
          type: string
          format: ulid
          nullable: true
          description: >-
            The unique ULID for the user's current onboarding process, if
            onboarding is not complete. Null or absent otherwise.
          example: 01ARZ3NDEKTSV4RRFFQ69G5FAV
    DataEnrichmentRequest:
      type: object
      required:
        - dpi
        - telephone
        - address
      properties:
        dpi:
          type: string
          description: >-
            Documento Personal de Identificación (e.g., Guatemalan National ID
            number). Define specific format constraints if known.
          example: '1234567890101'
        telephone:
          type: string
          description: >-
            The user's primary phone number, including country code (E.164
            format recommended).
          example: '+50212345678'
        address:
          type: string
          description: The user's primary residential address.
          example: 1 Calle 1-23 Zona 4, Guatemala City
    PhoneOtpConfirmRequest:
      type: object
      required:
        - otp
        - client_id
      properties:
        otp:
          type: string
          description: The One-Time Password received by the user via SMS.
          example: '654321'
        client_id:
          type: string
          description: The OAuth client_id of the company initiating the request.
          example: aBcDeFgHiJkLmNoPqRsT
    PersonData:
      type: object
      description: Enriched personal data retrieved from various sources for user review.
      required:
        - full_name
        - date_of_birth
        - national_id_number
        - telephone
        - address
      properties:
        full_name:
          type: string
          description: The user's full name as retrieved from verified sources.
          example: Juan José Pérez López
        date_of_birth:
          type: string
          format: date
          description: The user's date of birth as retrieved from verified sources.
          example: '1990-05-15'
        national_id_number:
          type: string
          description: The user's national ID number (e.g., DPI) as retrieved/verified.
          example: '1234567890101'
        tax_id:
          type: string
          nullable: true
          description: >-
            The user's tax identification number (e.g., NIT), if
            available/retrieved. Null if not found or applicable.
          example: 1234567-8
        telephone:
          type: string
          description: >-
            The user's primary phone number, including country code (E.164
            format recommended).
          example: '+50212345678'
        address:
          type: string
          description: The user's primary residential address.
          example: 1 Calle 1-23 Zona 4, Guatemala City
    PhoneOtpConfirmResponse:
      type: object
      required:
        - kyc_url
      properties:
        kyc_url:
          type: string
          format: url
          description: >-
            The URL the user should be redirected to for the KYC/identity
            verification step.
          example: https://id.cybersign.gt/start/01ARZ3NDEKTSV4RRFFQ69G5FAV
    KycStatusResponse:
      type: object
      description: Detailed status of the KYC verification process.
      required:
        - user_id
        - status
      properties:
        user_id:
          type: string
          description: User id.
          example: 27c7e9af-b519-4bec-a9c1-c7fd51aad8b6
        status:
          type: string
          description: The overall status of a verification check or the entire process.
          enum:
            - Approved
            - Rejected
            - Processing
            - RequiresReview
            - NotPerformed
            - Error
          example: Approved
        message:
          type: string
          description: Message explaining the rejection type.
          example: Do not retry
          enum:
            - Retry available
            - Do not retry
    VerificationStatus:
      type: string
      description: The overall status of a verification check or the entire process.
      enum:
        - Approved
        - Rejected
        - Processing
        - RequiresReview
        - NotPerformed
        - Error
      example: Approved
    LivenessCheckStatus:
      type: object
      description: Status details of the liveness check.
      properties:
        status:
          $ref: '#/components/schemas/VerificationStatus'
        confidence:
          type: number
          format: float
          nullable: true
          description: >-
            Confidence score (e.g., percentage) of the liveness check, if
            available and applicable.
          example: 98.58
    FaceMatchCheckStatus:
      type: object
      description: Status details of the face match check (selfie vs document photo).
      properties:
        status:
          $ref: '#/components/schemas/VerificationStatus'
        similarity:
          type: number
          format: float
          nullable: true
          description: >-
            Similarity score (e.g., percentage) between the selfie and the
            document photo, if available and applicable.
          example: 95.27
    DocumentCheckStatus:
      type: object
      description: >-
        Status details of the document verification (OCR, template matching,
        security features).
      properties:
        status:
          $ref: '#/components/schemas/VerificationStatus'
        documentType:
          type: string
          nullable: true
          description: Type of document identified (e.g., 'Identity Card', 'Passport').
          example: Identity Card
        issuingCountry:
          type: string
          nullable: true
          description: Issuing country code of the document.
          example: GTM
    WarningReason:
      type: object
      description: >-
        Represents a warning or a reason for rejection identified by the KYC
        provider.
      properties:
        code:
          type: string
          description: A provider-specific code identifying the warning or reason.
          example: POSSIBLE_DUPLICATED_USER
        shortDescription:
          type: string
          description: A brief summary of the issue.
          example: Possible duplicated approved user from other session
        longDescription:
          type: string
          description: A more detailed explanation of the issue.
          example: >-
            The system identified a potential duplicate user with previously
            approved documents from another session, requiring further
            investigation.
    UploadUrlRequest:
      type: object
      required:
        - file_tier
        - file_name
      properties:
        file_tier:
          type: string
          description: >-
            Determines the expiry time of the generated pre-signed URL based on
            expected file size:

            * `tier-1`: Up to 20MB (7 min expiry)

            * `tier-2`: Up to 40MB (14 min expiry)

            * `tier-3`: Up to 80MB (28 min expiry)

            * `tier-4`: Up to 100MB (35 min expiry)

            * `tier-5`: Up to 120MB (42 min expiry)
          enum:
            - tier-1
            - tier-2
            - tier-3
            - tier-4
            - tier-5
          example: tier-1
        file_name:
          type: string
          description: >-
            The intended filename for the document being uploaded (e.g.,
            'contrato-laboral.pdf'). Used to construct the storage path.
          example: documento.pdf
    UploadUrlResponse:
      type: object
      description: >-
        Contains the pre-signed URL details required to perform a direct upload
        (e.g., S3 POST).
      required:
        - url
        - fields
        - doc_ulid
        - doc_path
      properties:
        url:
          type: string
          format: url
          description: The base URL endpoint to which the upload request should be sent.
          example: https://your-bucket-name.s3.your-region.amazonaws.com/
        fields:
          type: object
          description: >-
            Key-value pairs that must be included as form fields in the upload
            request (e.g., multipart/form-data).
          properties:
            key:
              type: string
              description: The full path/key where the object will be stored in the bucket.
              example: user-uuid/onboarding-ulid/documento.pdf
            x-amz-algorithm:
              type: string
              example: AWS4-HMAC-SHA256
            x-amz-credential:
              type: string
              example: AKIAEXAMPLE/20240101/us-east-1/s3/aws4_request
            x-amz-date:
              type: string
              example: 20240101T120000Z
            policy:
              type: string
              description: Base64-encoded policy document governing the upload permissions.
              example: >-
                eyJleHBpcmF0aW9uIjoiMjAyNC0wMS0wMVQxMjowNzowMFoiLCJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJ5b3VyLWJ1Y2tldC1uYW1lIn0seyJrZXkiOiJ1c2VyLXV1aWQvb25ib2FyZGluZy11bGlkL2RvY3VtZW50by5wZGYifV19
            x-amz-signature:
              type: string
              description: The calculated signature for the request.
              example: a1b2c3d4e5f6...
          required:
            - key
            - x-amz-algorithm
            - x-amz-credential
            - x-amz-date
            - policy
            - x-amz-signature
        doc_ulid:
          type: string
          format: ulid
          description: >-
            A unique ULID generated by Cybersign to identify this specific
            document upload instance.
          example: 01JE9KCR0H22PDY9C1GYZABCDE
        doc_path:
          type: string
          description: >-
            The storage path/key assigned to this document. Matches the 'key'
            field within 'fields'.
          example: user-uuid/onboarding-ulid/documento.pdf
    DownloadUrlResponse:
      type: object
      required:
        - download_url
      properties:
        download_url:
          type: string
          format: url
          description: >-
            The pre-signed URL that can be used to download the specified
            document.
          example: >-
            https://your-bucket-name.s3.your-region.amazonaws.com/user-uuid/onboarding-ulid/documento.pdf?AWSAccessKeyId=...&Expires=...&Signature=...
    CertificateSummary:
      type: object
      description: Summary information about a user's digital certificate.
      required:
        - certificate_id
        - name
        - type
        - status
        - expiry_date
      properties:
        certificate_id:
          type: string
          description: >-
            Unique identifier for the certificate (e.g., thumbprint or internal
            ID).
          example: cert_thmb_abc123def456
        name:
          type: string
          description: A user-friendly name or label for the certificate.
          example: Personal Qualified Certificate
        type:
          type: string
          description: The type or level of the certificate.
          enum:
            - QualifiedESignature
            - AdvancedESignature
            - Seal
          example: QualifiedESignature
        status:
          type: string
          description: Current status of the certificate.
          enum:
            - Active
            - Expired
            - Revoked
          example: Active
        expiry_date:
          type: string
          format: date-time
          description: The date and time when the certificate expires.
          example: '2026-10-20T15:00:00Z'
    DocumentSignRequest:
      type: object
      description: Specifies the parameters required to sign a document.
      required:
        - file_name
        - certificate_id
        - signature_format
        - otp
      properties:
        file_name:
          type: string
          description: >-
            The identifier of the user's certificate (obtained from GET
            /certificates) to use for signing.
          example: my-file.pdf
        certificate_id:
          type: string
          description: >-
            The identifier of the user's certificate (obtained from GET
            /certificates) to use for signing.
          example: cert_thmb_abc123def456
        signature_format:
          type: string
          description: The cryptographic standard to use for the signature.
          enum:
            - PKCS7
          default: PKCS7
          example: PKCS7
        otp:
          $ref: '#/components/schemas/OtpInput'
        visible_signature_options:
          $ref: '#/components/schemas/VisibleSignatureOptions'
    OtpInput:
      type: object
      description: One-Time Password details for MFA verification.
      required:
        - value
        - type
      properties:
        value:
          type: string
          description: The actual OTP code provided by the user.
          example: '123456'
        type:
          type: string
          description: The method used to deliver/generate the OTP.
          enum:
            - sms
            - totp
            - email
            - biometric
          example: sms
    VisibleSignatureOptions:
      type: object
      description: >-
        Optional parameters to configure a visible signature appearance block in
        the PDF. Omit this object for an invisible signature.
      required:
        - page_number
        - position_x
        - position_y
      properties:
        page_number:
          type: integer
          description: >-
            The 0-indexed page number where the visible signature should be
            placed.
          minimum: 0
          example: 0
        position_x:
          type: number
          format: float
          description: >-
            Relative X coordinates for the lower-left corner of the signature
            block (range 0.0 to 1.0 for each axis). [0,0] is bottom-left, [1,1]
            is top-right.
          minimum: 0
          maximum: 1
          example: 0.4378
        position_y:
          type: number
          format: float
          description: >-
            Relative  Y coordinates for the lower-left corner of the signature
            block (range 0.0 to 1.0 for each axis). [0,0] is bottom-left, [1,1]
            is top-right.
          minimum: 0
          maximum: 1
          example: 0.3577
        include_date:
          type: boolean
          description: Whether to include the signing date in the visible block.
          default: true
          example: true
        include_initials:
          type: boolean
          description: >-
            Whether to include the signer's initials (if available) in the
            visible block.
          default: false
          example: false
        include_motive:
          type: boolean
          description: >-
            Whether to include the signing motive in the visible block. Requires
            'motive' to be provided if true.
          default: true
          example: true
        include_signature_graphic:
          type: boolean
          description: >-
            Whether to include a standard digital signature graphic element in
            the visible block.
          default: true
          example: true
        motive:
          type: string
          description: >-
            The reason or motive for signing (e.g., "Approval", "Agreement").
            Required if 'include-motive' is true.
          example: Aprobación de documento
    DocumentSignResponse:
      type: object
      description: Confirmation that the document signing process was successful.
      required:
        - message
        - doc_ulid
      properties:
        message:
          type: string
          description: Confirmation message.
          example: Document signed successfully.
        doc_ulid:
          type: string
          format: ulid
          description: The ULID of the document that was signed.
          example: 01JE9KCR0H22PDY9C1GYZABCDE
    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: An application-specific error code string.
          example: INVALID_OTP
        message:
          type: string
          description: >-
            A human-readable explanation specific to this occurrence of the
            problem.
          example: The OTP provided is invalid or has expired.
  responses:
    BadRequest:
      description: >-
        Bad Request. The request is malformed, missing required fields, or
        contains invalid data according to schema/validation rules.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
            properties:
              code:
                example: INVALID_INPUT
    Unauthorized:
      description: >-
        Unauthorized. The provided authentication token is missing, invalid, or
        expired.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
            properties:
              code:
                example: UNAUTHORIZED
    Forbidden:
      description: >-
        Forbidden. The authenticated user does not have permission to access the
        requested resource or perform the requested action.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
            properties:
              code:
                example: FORBIDDEN
    NotFound:
      description: >-
        Not Found. The requested resource (e.g., onboarding process, document
        path, certificate) could not be found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
            properties:
              code:
                example: RESOURCE_NOT_FOUND
    InternalServerError:
      description: Internal Server Error. An unexpected condition occurred on the server.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
            properties:
              code:
                example: INTERNAL_ERROR
    InvalidOtpOrSession:
      description: >-
        Unauthorized. The provided Email OTP is invalid, expired, or the session
        identifier does not match an active login attempt.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
            properties:
              code:
                example: INVALID_SESSION_OR_OTP
    AccountInactive:
      description: >-
        Precondition Failed. The user account associated with this email is
        inactive or locked.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
            properties:
              code:
                example: ACCOUNT_INACTIVE
    InvalidOtp:
      description: Bad Request. The provided OTP is invalid or expired.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
            properties:
              code:
                example: INVALID_OTP
    CertificateNotActive:
      description: >-
        Bad Request. The specified certificate is expired, revoked, or not yet
        active.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
            properties:
              code:
                example: CERTIFICATE_NOT_ACTIVE
    DocumentNotReady:
      description: >-
        Bad Request. The specified document is not in a state ready for signing
        (e.g., still uploading, processing error).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
            properties:
              code:
                example: DOCUMENT_NOT_READY
  securitySchemes:
    m2m_oauth:
      type: oauth2
      description: >-
        OAuth2 Client Credentials Grant (M2M) for company server-to-server
        authentication with Cybersign auth endpoints.
      flows:
        clientCredentials:
          tokenUrl: https://auth.cybersign.com/oauth2/token
          scopes: {}
    user_bearer_auth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Bearer token authentication using the JWT access_token obtained by the
        user during login confirmation. Used for accessing user-specific
        endpoints.
