> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ndovu.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Onboard a customer

> Creates the customer as a KYC-completed Ndovu investor on your KYC confirmation. Idempotent on externalUserId: resending the same details returns the existing customer with 200; different details return 409.



## OpenAPI

````yaml /api-reference/openapi.json post /api/v3/partners/{shortName}/customers
openapi: 3.0.0
info:
  title: Ndovu Partner API
  description: API for partners distributing Ndovu investment products to their customers.
  version: '3'
  contact: {}
servers:
  - url: https://be-dev-1.dev.ndovu.co
    description: Development
security: []
tags: []
paths:
  /api/v3/partners/{shortName}/customers:
    post:
      tags:
        - partners
      summary: Onboard a customer
      description: >-
        Creates the customer as a KYC-completed Ndovu investor on your KYC
        confirmation. Idempotent on externalUserId: resending the same details
        returns the existing customer with 200; different details return 409.
      operationId: PartnerCustomersController_createCustomer_v3
      parameters:
        - name: shortName
          required: true
          in: path
          description: Your partner short name
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePartnerCustomerDto'
            examples:
              SHARED:
                summary: identityPolicy SHARED
                value:
                  externalUserId: cust_8842
                  firstName: Jane
                  lastName: Wanjiku
                  email: jane.wanjiku@example.com
                  phoneNumber: '+254712345678'
                  termsAndConditionsAccepted: true
                  kycVerification:
                    verifiedOn: '2026-10-14'
              REFERENCED:
                summary: identityPolicy REFERENCED
                value:
                  externalUserId: '938291'
                  termsAndConditionsAccepted: true
                  kycVerification:
                    verifiedOn: '2026-10-14'
      responses:
        '200':
          description: Customer already existed with the same details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerCustomerResponseDto'
        '201':
          description: Customer created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerCustomerResponseDto'
        '400':
          description: >-
            CUSTOMER_IDENTITY_REQUIRED (identityPolicy SHARED: names, email and
            phone are required) or CUSTOMER_PII_NOT_ACCEPTED (identityPolicy
            REFERENCED: send only externalUserId and kycVerification)
        '409':
          description: >-
            CUSTOMER_EXTERNAL_ID_CONFLICT, CUSTOMER_EMAIL_OR_PHONE_IN_USE or
            CUSTOMER_IDENTITY_IN_USE
      security:
        - bearer: []
components:
  schemas:
    CreatePartnerCustomerDto:
      type: object
      properties:
        externalUserId:
          type: string
          maxLength: 255
          description: The partner's own ID for this customer. Unique per partner.
          example: cust_8842
        firstName:
          type: string
          example: Jane
          description: >-
            Required when your identityPolicy is SHARED; not accepted when
            REFERENCED
        lastName:
          type: string
          example: Wanjiku
          description: >-
            Required when your identityPolicy is SHARED; not accepted when
            REFERENCED
        email:
          type: string
          format: email
          example: jane.wanjiku@example.com
          description: >-
            Required when your identityPolicy is SHARED; not accepted when
            REFERENCED
        phoneNumber:
          type: string
          example: '+254712345678'
          description: >-
            Required when your identityPolicy is SHARED; not accepted when
            REFERENCED
        termsAndConditionsAccepted:
          type: boolean
          description: 'Must be true: the customer accepted Ndovu''s terms and conditions'
        kycVerification:
          $ref: '#/components/schemas/PartnerKycVerificationDto'
        kyc:
          description: Not accepted when your identityPolicy is REFERENCED
          allOf:
            - $ref: '#/components/schemas/PartnerCustomerKycDto'
      required:
        - externalUserId
        - termsAndConditionsAccepted
        - kycVerification
    PartnerCustomerResponseDto:
      type: object
      properties:
        externalUserId:
          type: string
          example: cust_8842
        investorId:
          type: string
          example: 3f9c2a1e-7b4d-4c8e-9a61-2d5f0b8e4c17
          description: >-
            Ndovu's investor identifier. Returned for reference; never accepted
            as input.
        kycStatus:
          type: string
          example: COMPLETED
        country:
          type: string
          example: KE
        currency:
          type: string
          example: KES
        firstName:
          type: string
          nullable: true
          example: Jane
          description: null when your identityPolicy is REFERENCED
        lastName:
          type: string
          nullable: true
          example: Wanjiku
          description: null when your identityPolicy is REFERENCED
        email:
          type: string
          nullable: true
          example: jane.wanjiku@example.com
          description: null when your identityPolicy is REFERENCED
        phoneNumber:
          type: string
          nullable: true
          example: '+254712345678'
          description: null when your identityPolicy is REFERENCED
        kyc:
          description: Fields not yet sent are null
          allOf:
            - $ref: '#/components/schemas/PartnerCustomerKycDto'
        documents:
          type: array
          items:
            $ref: '#/components/schemas/PartnerCustomerDocumentDto'
        createdAt:
          format: date-time
          type: string
          example: '2026-10-22T09:14:03.511Z'
        updatedAt:
          format: date-time
          type: string
          example: '2026-10-22T09:14:03.511Z'
      required:
        - externalUserId
        - investorId
        - kycStatus
        - country
        - currency
        - firstName
        - lastName
        - email
        - phoneNumber
        - kyc
        - documents
        - createdAt
        - updatedAt
    PartnerKycVerificationDto:
      type: object
      properties:
        verifiedOn:
          type: string
          pattern: /^\d{4}-\d{2}-\d{2}$/
          description: The date the partner completed KYC on this customer (YYYY-MM-DD)
          example: '2026-10-14'
        reference:
          type: string
          maxLength: 255
          example: KYC-2026-00931
          description: The partner's own KYC case or reference ID
      required:
        - verifiedOn
    PartnerCustomerKycDto:
      type: object
      properties:
        identificationType:
          enum:
            - NATIONAL_ID
            - PASSPORT
            - ALIEN_ID
            - ELECTRONIC_ID_CARD
            - ID_BOOK
            - RESIDENT_ID
            - SEAMAN_ID
            - SOCIAL_ID
            - KE_ARMY_ID
            - DRIVING_LICENSE
            - TRAVEL_DOCS
            - VOTING_CARD
          type: string
        identificationNumber:
          type: string
          example: '29384756'
        identificationCountry:
          type: string
          description: ISO 3166-1 alpha-2 code of the country that issued the ID
          example: KE
        residencyCountry:
          type: string
          description: ISO 3166-1 alpha-2 code of the country the customer lives in
          example: KE
        dateOfBirth:
          type: string
          example: '1991-04-02'
        gender:
          enum:
            - MALE
            - FEMALE
            - NON_BINARY
          type: string
        taxPayerNumber:
          type: string
          example: A012345678Z
          description: Tax identification number. For Kenyan customers, the KRA PIN.
        residentialAddress:
          type: string
          example: Riverside Drive, Westlands
        city:
          type: string
          example: Nairobi
        postalCode:
          type: string
          example: '00100'
        postalAddress:
          type: string
          example: P.O. Box 12345
        sourceOfFunds:
          enum:
            - SALARY_OR_BUSINESS_PROFIT
            - BANK_CREDIT
            - PERSONAL_SAVINGS
            - PROPERTY_SALES
            - INHERITANCE
            - SHARE_SALES_OR_DIVIDEND
          type: string
        employmentStatus:
          enum:
            - Full Time
            - Part Time
            - Contractor
            - Not employed
          type: string
        nextOfKinNames:
          type: string
          example: John Wanjiku
        nextOfKinContact:
          type: string
          example: '+254722000000'
        nextOfKinEmail:
          type: string
          format: email
          example: john.wanjiku@example.com
    PartnerCustomerDocumentDto:
      type: object
      properties:
        type:
          type: string
          example: id-card
        side:
          type: string
          nullable: true
          example: front
        uploadedAt:
          format: date-time
          type: string
          example: '2026-10-22T09:20:41.102Z'
        url:
          type: string
          example: https://ndovu-documents.s3.amazonaws.com/...
          description: >-
            Temporary link to download the file. Valid for 5 minutes; fetch the
            customer again for a fresh one.
        expiresAt:
          format: date-time
          type: string
          example: '2026-10-22T09:25:41.102Z'
          description: When `url` stops working
      required:
        - type
        - uploadedAt
        - url
        - expiresAt
  securitySchemes:
    bearer:
      scheme: bearer
      bearerFormat: JWT
      type: http

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.