Cadana KYB API

APIs for business verification

OpenAPI Specification

cadana-kyb-api-openapi.yml Raw ↑
openapi: 3.0.0
info:
  description: APIs for interacting with Cadana Embedded Consumer Wallets
  version: 1.0.0
  title: Embedded Consumer Wallets Balances KYB API
  termsOfService: https://cadanapay.com/terms-and-conditions
  contact:
    email: api@cadanapay.com
  license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0.html
servers:
- url: https://api.cadanapay.com
  description: Prod Server
- url: https://dev-api.cadanapay.com
  description: Dev Server
security:
- Authorization: []
tags:
- name: KYB
  description: APIs for business verification
paths:
  /v1/businesses/{businessId}/kyb:
    post:
      summary: Submit KYB
      description: Submit Know Your Business (KYB) information for verification. Use POST to provide new information — the initial submission and any change to the set of principals; to correct information already on file, use PATCH instead.
      operationId: submitKYB
      tags:
      - KYB
      parameters:
      - $ref: '#/components/parameters/businessId'
      - $ref: '#/components/parameters/XMultiTenantKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/KYBRequest'
      responses:
        '204':
          description: KYB information submitted successfully
        '400':
          description: Bad input, or the KYB is not editable. Submission is only allowed while the KYB status is `initialized`, `incomplete`, `awaiting-principal-kyc`, or `needs-additional-info` — a KYB that is `pending-review`, `complete`, or `rejected` cannot be modified.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        5XX:
          $ref: '#/components/responses/InternalError'
      security:
      - Authorization: []
    get:
      summary: Get KYB
      description: Returns the business's KYB details. Returns 404 if KYB has not been started for the business.
      operationId: getKyb
      tags:
      - KYB
      parameters:
      - $ref: '#/components/parameters/businessId'
      - $ref: '#/components/parameters/XMultiTenantKey'
      responses:
        '200':
          $ref: '#/components/responses/GetKYBResponse'
        '400':
          $ref: '#/components/responses/BadRequestError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        5XX:
          $ref: '#/components/responses/InternalError'
      security:
      - Authorization: []
    patch:
      summary: Update KYB
      description: Update KYB information already provided. Only the fields you include are changed; new principals cannot be added with PATCH — re-POST the full submission instead. Document arrays are appended to, not replaced.
      operationId: updateKyb
      tags:
      - KYB
      parameters:
      - $ref: '#/components/parameters/businessId'
      - $ref: '#/components/parameters/XMultiTenantKey'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              allOf:
              - $ref: '#/components/schemas/KYBRequest'
              - type: object
                properties:
                  principals:
                    type: array
                    description: Principals to update. Each entry — including individuals nested under an entity principal's 'entity.individuals' — must include the 'id' of an existing principal (returned by GET KYB); a missing or unknown 'id' fails the request with 400. PATCH cannot add new principals — re-POST the full submission to add one.
                    items:
                      allOf:
                      - $ref: '#/components/schemas/PrincipalRequest'
                      - type: object
                        required:
                        - id
                        properties:
                          id:
                            type: string
                            format: uuid
                            description: ID of the existing principal being updated (required at every nesting level in PATCH requests)
                            example: 123e4567-e89b-12d3-a456-426614174000
      responses:
        '204':
          description: KYB information updated successfully
        '400':
          description: Bad input, an unknown principal `id` (`"principal not found"`), or the KYB is not editable. Updates are only allowed while the KYB status is `initialized`, `incomplete`, `awaiting-principal-kyc`, or `needs-additional-info` — a KYB that is `pending-review`, `complete`, or `rejected` cannot be modified.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        5XX:
          $ref: '#/components/responses/InternalError'
      security:
      - Authorization: []
  /v1/businesses/{businessId}/kyb-link:
    post:
      summary: Generate KYB Link
      description: Get KYB Link
      operationId: getKybLink
      tags:
      - KYB
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GenerateKybLinkRequest'
      parameters:
      - $ref: '#/components/parameters/businessId'
      - $ref: '#/components/parameters/XMultiTenantKey'
      responses:
        '200':
          $ref: '#/components/responses/CreateKybLinkResponse'
        '400':
          $ref: '#/components/responses/BadRequestError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        5XX:
          $ref: '#/components/responses/InternalError'
      security:
      - Authorization: []
components:
  schemas:
    PrincipalRequest:
      type: object
      description: A principal is either an individual or a business entity. For individuals, provide the personal fields (firstName, lastName, dateOfBirth, identifier, etc.). For entities, set isEntity to true and provide the entity object instead — the personal fields do not apply.
      properties:
        firstName:
          type: string
          description: First name of the principal. Individuals only.
          example: John
        lastName:
          type: string
          description: Last name of the principal. Individuals only.
          example: Doe
        ownershipPercentage:
          type: number
          format: float
          minimum: 0.25
          maximum: 1
          description: Percentage of ownership held by the principal in the business
          example: 0.5
        email:
          type: string
          format: email
          description: Email address of the principal
          example: john.doe@example.com
        phoneNumber:
          $ref: '#/components/schemas/phoneNumber'
        address:
          $ref: '#/components/schemas/address'
        isExecutive:
          type: boolean
          description: Whether the principal is an executive of the company
          example: true
        title:
          type: string
          description: Job title or role of the principal
          example: CEO
        dateOfBirth:
          type: string
          format: date
          description: Date of birth in YYYY-MM-DD format. Individuals only.
          example: '1990-01-15'
        isEntity:
          type: boolean
          description: Set to true when this principal is a business entity rather than an individual. Entity principals must include the entity object; the personal fields (firstName, lastName, dateOfBirth, identifier) do not apply.
          example: false
        entity:
          type: object
          description: Details of the entity principal. Required when isEntity is true.
          properties:
            companyName:
              type: string
              description: Registered legal name of the entity
              example: Acme Holdings LLC
            entityType:
              type: string
              enum:
              - corporation
              - c-corporation
              - s-corporation
              - partnership
              - sole proprietorship
              - limited liability company
              - non profit
              - other
              description: Type of entity
              example: limited liability company
            taxIdentificationNumber:
              type: string
              description: Tax identification number of the entity
              example: 98-7654321
            email:
              type: string
              format: email
              description: Contact email address for the entity
              example: ops@acmeholdings.com
            websiteURL:
              type: string
              format: uri
              description: Entity website URL
              example: https://www.acmeholdings.com
            incorporation:
              type: object
              description: Incorporation details of the entity
              properties:
                date:
                  type: string
                  format: date
                  description: Date of incorporation (YYYY-MM-DD)
                  example: '2015-03-01'
                address:
                  $ref: '#/components/schemas/address'
            address:
              $ref: '#/components/schemas/address'
            certificateOfIncorporationFileId:
              type: string
              format: uuid
              description: Optional file ID for the entity's certificate of incorporation
              example: file-id-201
            proofOfAddressFileId:
              type: string
              format: uuid
              description: Optional file ID for the entity's proof of address
              example: file-id-202
            ownershipDocumentFileId:
              type: string
              format: uuid
              description: File ID for the document evidencing the entity's ownership stake in the business. The only required document for an entity principal.
              example: file-id-203
            individuals:
              type: array
              description: The entity's own principals — individuals or further entities holding 25% or more of the entity, plus at least one controlling person (an executive such as the CEO, with isExecutive true and a title). If no individual holds 25% or more, the controlling person alone is sufficient. Same shape as top-level principals; nesting can continue as deep as the ownership chain requires.
              items:
                $ref: '#/components/schemas/EntityIndividual'
        identifier:
          type: object
          description: Government-issued identification document details. Individuals only.
          properties:
            type:
              enum:
              - passport
              - ssn
              description: Type of identification document
              example: passport
            value:
              type: string
              description: Identification number or value
              example: '1234567890'
            identityFileId:
              type: string
              format: uuid
              description: File ID for the identity document (front page)
              example: file-id-123
            identityBackPageFileId:
              type: string
              format: uuid
              description: File ID for the identity document (back page)
              example: file-id-124
            addressFileId:
              type: string
              format: uuid
              description: File ID for address proof document
              example: file-id-125
    GenerateKybLinkRequest:
      allOf:
      - $ref: '#/components/schemas/HostedLinkRequest'
      - type: object
        required:
        - refreshURL
        - returnURL
    phoneNumber:
      type: object
      description: Person's phone number
      properties:
        countryCode:
          type: string
          example: '1'
        number:
          type: string
          example: '2345678901'
    GetKYB:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: KYB record ID
          example: d4475c70-d759-495e-a052-3e3a1cba1857
        tenantKey:
          type: string
          description: Tenant key
          example: cad62002887
        entityName:
          type: string
          description: Business name
          example: Airtel
        entityType:
          type: string
          enum:
          - corporation
          - c-corporation
          - s-corporation
          - partnership
          - sole proprietorship
          - limited liability company
          - non profit
          - other
          description: Type of entity
          example: corporation
        taxIdentificationNumber:
          type: string
          description: Tax identification number
          example: NN-528343998
        incorporation:
          type: object
          description: Incorporation details
          properties:
            date:
              type: string
              format: date-time
              description: Date of incorporation
              example: '2025-01-01T00:00:00.000Z'
            address:
              $ref: '#/components/schemas/address'
        phoneNumber:
          $ref: '#/components/schemas/phoneNumber'
        email:
          type: string
          format: email
          description: Business email address
        websiteURL:
          type: string
          format: uri
          description: Business website URL
          example: ''
        natureOfBusiness:
          type: string
          description: Description of the primary business activities and industry
          example: Software Development
        sizeOfCompany:
          type: string
          description: Size of the company
          example: 300-400
        sourceOfFunds:
          type: string
          description: Source of funds
          example: Personal Savings
        status:
          type: string
          enum:
          - initialized
          - needs-additional-info
          - pending-review
          - awaiting-principal-kyc
          - incomplete
          - complete
          - rejected
          description: KYB status
          example: pending-review
        annualRevenue:
          type: object
          description: Annual revenue range
          properties:
            currency:
              type: string
              description: Currency code (ISO 4217)
              example: USD
            min:
              type: number
              description: Minimum annual revenue
              example: 100000
            max:
              type: number
              description: Maximum annual revenue
              example: 1000000
        expectedMonthlyTransactionVolume:
          type: object
          description: Expected monthly transaction volume range
          properties:
            currency:
              type: string
              description: Currency code (ISO 4217)
              example: USD
            min:
              type: number
              description: Minimum expected monthly transaction volume
              example: 50000
            max:
              type: number
              description: Maximum expected monthly transaction volume
              example: 80000
        address:
          $ref: '#/components/schemas/address'
        documents:
          type: object
          description: Document file URLs
          properties:
            articlesOfIncorporation:
              type: array
              nullable: true
              description: Presigned URLs for articles of incorporation documents
              items:
                type: string
            bankStatements:
              type: array
              nullable: true
              description: Presigned URLs for bank statements
              items:
                type: string
            proofOfAddress:
              type: array
              nullable: true
              description: Presigned URLs for proof of address documents
              items:
                type: string
            taxDocuments:
              type: array
              nullable: true
              description: Presigned URLs for tax documents
              items:
                type: string
        principals:
          type: array
          description: Principals associated with the business
          items:
            $ref: '#/components/schemas/KYBPrincipal'
        requirements:
          type: object
          description: KYB requirements and validation status
          properties:
            currentlyDue:
              type: array
              description: List of field paths that are currently required
              items:
                type: string
                description: Field path that is required
              example:
              - principals.0.phoneNumber.countryCode
              - phoneNumber.countryCode
              - principals.0.address.state
              - email
              - entityName
            errors:
              type: array
              description: List of validation errors
              items:
                type: object
                properties:
                  field:
                    type: string
                    description: Field path with the error
                    example: entityName
                  reason:
                    type: string
                    description: Reason for the error
                    example: Only english letters are allowed
    uuid:
      type: string
      format: uuid
      example: 8ef9a712-cdae-4110-b1ea-9ba95abbee6e
    KYBPrincipal:
      type: object
      description: A principal on the KYB record — either an individual or, when isEntity is true, a business entity with its own owners nested under entity.individuals.
      properties:
        firstName:
          type: string
          description: First name of the principal. Individuals only.
          example: John
        lastName:
          type: string
          description: Last name of the principal. Individuals only.
          example: Doe
        ownershipPercentage:
          type: number
          format: float
          description: Percentage of ownership held by the principal
          example: 0.5
        email:
          type: string
          format: email
          description: Email address of the principal
        phoneNumber:
          $ref: '#/components/schemas/phoneNumber'
        address:
          $ref: '#/components/schemas/address'
        isExecutive:
          type: boolean
          description: Whether the principal is an executive
          example: false
        title:
          type: string
          description: Job title or role of the principal
          example: ''
        id:
          type: string
          format: uuid
          description: Principal ID — include this when re-POSTing or PATCHing the principal
          example: f116c829-3c93-4d24-880d-3a00faf784a2
        identifier:
          type: object
          description: Government-issued identification document details. Individuals only.
          properties:
            type:
              enum:
              - passport
              - ssn
              description: Type of identification document
              example: passport
            value:
              type: string
              description: Identification number or value
              example: '1234567890'
        isEntity:
          type: boolean
          description: Whether this principal is a business entity rather than an individual
          example: false
        entity:
          type: object
          description: Entity details. Only present when isEntity is true.
          properties:
            companyName:
              type: string
              description: Registered legal name of the entity
              example: Acme Holdings LLC
            entityType:
              type: string
              description: Type of entity
              example: limited liability company
            taxIdentificationNumber:
              type: string
              description: Tax identification number of the entity
              example: 98-7654321
            email:
              type: string
              format: email
              description: Contact email address for the entity
            websiteURL:
              type: string
              format: uri
              description: Entity website URL
            incorporation:
              type: object
              description: Incorporation details of the entity
              properties:
                date:
                  type: string
                  format: date
                  description: Date of incorporation (YYYY-MM-DD)
                address:
                  $ref: '#/components/schemas/address'
            address:
              $ref: '#/components/schemas/address'
            certificateOfIncorporationFileURLs:
              type: array
              nullable: true
              description: Presigned URLs for the entity's certificate of incorporation documents
              items:
                type: string
            proofOfAddressFileURLs:
              type: array
              nullable: true
              description: Presigned URLs for the entity's proof of address documents
              items:
                type: string
            ownershipDocumentFileURLs:
              type: array
              nullable: true
              description: Presigned URLs for the entity's ownership documents
              items:
                type: string
            individuals:
              type: array
              description: The entity's own principals — individuals or further entities holding 25% or more of the entity, plus at least one controlling person (executive). Same shape as top-level principals, nested recursively.
              items:
                allOf:
                - $ref: '#/components/schemas/EntityIndividual'
                - type: object
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: Principal ID — include this when re-POSTing or PATCHing the individual
                      example: 2a7fb1e0-9c44-4e1b-8f6d-1d2e3f4a5b6c
    InternalError:
      description: Internal server error
      allOf:
      - $ref: '#/components/schemas/Error'
      example:
        code: internal_error
        message: An unexpected error occurred. Please try again later.
    NotFoundError:
      description: Not Found
      allOf:
      - $ref: '#/components/schemas/Error'
      example:
        code: resource_not_found
        message: Requested resource could not be found.
    KYBRequest:
      type: object
      properties:
        entityName:
          type: string
          description: Business name
          example: Tesla
        entityType:
          type: string
          enum:
          - corporation
          - c-corporation
          - s-corporation
          - partnership
          - sole proprietorship
          - limited liability company
          - non profit
          - other
          description: Type of entity
          example: corporation
        taxIdentificationNumber:
          type: string
          description: Tax identification number
          example: NN-528343998
        incorporation:
          type: object
          description: Incorporation details
          properties:
            date:
              type: string
              format: date
              description: Date of incorporation (YYYY-MM-DD)
              example: '2025-01-01'
            address:
              $ref: '#/components/schemas/address'
        phoneNumber:
          $ref: '#/components/schemas/phoneNumber'
        websiteURL:
          type: string
          format: uri
          description: Business website URL
          example: https://www.tesla.com
        natureOfBusiness:
          type: string
          description: Description of the primary business activities and industry
          example: Software Development
        sizeOfCompany:
          type: string
          description: Size of the company
          example: 300-400
        sourceOfFunds:
          type: string
          description: Source of funds
          example: Personal Savings
        annualRevenue:
          type: object
          description: Annual revenue range
          properties:
            currency:
              type: string
              description: Currency code (ISO 4217)
              example: USD
            min:
              type: number
              description: Minimum annual revenue
              example: 100000
            max:
              type: number
              description: Maximum annual revenue
              example: 1000000
        expectedMonthlyTransactionVolume:
          type: object
          description: Expected monthly transaction volume range
          properties:
            currency:
              type: string
              description: Currency code (ISO 4217)
              example: USD
            min:
              type: number
              description: Minimum expected monthly transaction volume
              example: 50000
            max:
              type: number
              description: Maximum expected monthly transaction volume
              example: 80000
        address:
          $ref: '#/components/schemas/address'
        principals:
          type: array
          description: Principals are the individuals or business entities that own 25% or more of the business, or exercise significant control over it. POST always carries the full list and replaces any previously submitted principals — to add a principal, re-POST all existing principals (including their `id` so completed identity verification is preserved) along with the new one.
          items:
            $ref: '#/components/schemas/PrincipalRequest'
        articlesOfIncorporation:
          type: array
          description: File IDs for articles of incorporation documents
          items:
            type: string
            format: uuid
          example:
          - file-id-001
          - file-id-002
        bankStatements:
          type: array
          description: File IDs for bank statements
          items:
            type: string
            format: uuid
          example:
          - file-id-003
          - file-id-004
        proofOfAddress:
          type: array
          description: File IDs for proof of address documents
          items:
            type: string
            format: uuid
          example:
          - file-id-005
        taxDocuments:
          type: array
          description: File IDs for tax documents
          items:
            type: string
            format: uuid
          example:
          - file-id-006
          - file-id-007
    BadRequestError:
      description: Bad input provided by client
      allOf:
      - $ref: '#/components/schemas/Error'
      - type: object
        properties:
          params:
            description: A map for meta data around the error that occurred
            type: object
      example:
        code: invalid_request_body
        message: The request body provided is not valid
        params:
          field: Value is invalid.
    EntityIndividual:
      type: object
      description: An owner or controlling person of an entity principal. Same shape as a top-level principal — when the owner is itself a company, set isEntity to true and provide the entity object; nesting continues as deep as the ownership chain requires.
      properties:
        firstName:
          type: string
          description: First name of the individual
          example: John
        lastName:
          type: string
          description: Last name of the individual
          example: Owner
        ownershipPercentage:
          type: number
          format: float
          minimum: 0.25
          maximum: 1
          description: Percentage of ownership held in the entity
          example: 1
        email:
          type: string
          format: email
          description: Email address of the individual
          example: john@acmeholdings.com
        phoneNumber:
          $ref: '#/components/schemas/phoneNumber'
        address:
          $ref: '#/components/schemas/address'
        isExecutive:
          type: boolean
          description: Whether the individual is an executive of the entity. At least one controlling person with isExecutive true is required per entity.
          example: true
        title:
          type: string
          description: Job title or role of the individual
          example: CEO
        dateOfBirth:
          type: string
          format: date
          description: Date of birth in YYYY-MM-DD format
          example: '1970-02-20'
        identifier:
          type: object
          description: Government-issued identification document details
          properties:
            type:
              enum:
              - passport
              - ssn
              description: Type of identification document
              example: ssn
            value:
              type: string
              description: Identification number or value
              example: 987-65-4321
            identityFileId:
              type: string
              format: uuid
              description: File ID for the identity document (front page)
              example: file-id-123
            identityBackPageFileId:
              type: string
              format: uuid
              description: File ID for the identity document (back page)
              example: file-id-124
            addressFileId:
              type: string
              format: uuid
              description: File ID for address proof document
              example: file-id-125
        isEntity:
          type: boolean
          description: Set to true when this owner is itself a business entity rather than an individual
          example: false
        entity:
          type: object
          description: Details of the nested entity owner — same shape as `principals[].entity`, including its own `individuals` list. Required when isEntity is true.
    HostedLinkRequest:
      type: object
      description: Common request body for endpoints that generate hosted (link-out) URLs.
      properties:
        refreshURL:
          type: string
          description: The URL the user will be redirected to if the link is expired
        returnURL:
          type: string
          description: The URL that the user will be redirected to upon leaving or completing the linked flow.
    address:
      type: object
      description: Address
      required:
      - countryCode
      properties:
        line1:
          type: string
          example: Street 1
        line2:
          type: string
          example: Apt 1
        city:
          type: string
          example: Gotham
        postalCode:
          type: string
          example: '10001'
        state:
          type: string
          example: NY
        countryCode:
          type: string
          example: US
    Error:
      type: object
      properties:
        code:
          description: A machine parsable error code
          type: string
          enum:
          - invalid_request_body
          - resource_not_found
          - forbidden
          - internal_error
        message:
          description: A human readable message describing the error
          type: string
  responses:
    InternalError:
      description: Internal error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/InternalError'
    NotFoundError:
      description: Requested resource was not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/NotFoundError'
    GetKYBResponse:
      description: get KYB response
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/GetKYB'
    CreateKybLinkResponse:
      description: create kyb link response
      content:
        application/json:
          schema:
            type: object
            properties:
              id:
                $ref: '#/components/schemas/uuid'
              url:
                type: string
              expiresAt:
                type: number
            

# --- truncated at 32 KB (32 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/cadana/refs/heads/main/openapi/cadana-kyb-api-openapi.yml