---
title: "Register a business as an SME (step-based)"
method: POST
path: "/api/v1/sme-registration"
tags: ["SME Registration"]
---

# Register a business as an SME (step-based)

`POST /api/v1/sme-registration`

## Request

- Base URL: `https://sandbox.api.afriex.com`
- URL: `https://sandbox.api.afriex.com/api/v1/sme-registration`
- Auth: API key in header `x-api-key`
- TypeScript: <https://skmtc.dev/afriex/apis/afriex-business-api/docs/api/v1/sme-registration/post.ts> (a function with typed inputs; its response is checked against the schema)

Registers a business as its own SME so that dedicated virtual accounts are issued under the business's own legal entity rather than the shared default. The flow is stateful and driven by this single endpoint: the `step` field selects the payload carried in `data`. Call the steps in order: `INITIATE` (triggers a one-time passcode to the supplied mobile number), `CONFIRM_OTP`, then `SUBMIT` (company details, directors and documents). Upload each document first via `POST /api/v1/media/url` and pass the returned object keys in the `SUBMIT` payload. Calling `INITIATE` again while the registration is still waiting for its passcode returns that same registration with a `200`. Requires the `COMPLIANCE.KYB.SUBMIT` key permission.

## Request body

- union: The `step` field selects the payload carried in `data`, and it is case insensitive (`submit` is accepted as `SUBMIT`). Every mobile number (the applicant's on `INITIATE` and each director's on `SUBMIT`) must be a valid Kenyan number. Any of `254712345678`, `+254712345678`, `0712345678` or `712345678` is accepted and normalised to E.164; a number that is not Kenyan is rejected with `422`. Directors do not need a `countryCode`: it is derived from the number, and ignored if sent.
  - object
    - `step` 'INITIATE', required
    - `data` object, required
      - `mobile` string, required: A valid Kenyan mobile number.
      - `email` string, email, required
      - `businessType` 2, required: Must be `2`. Only Limited Liability Companies are supported at this time.
  - object
    - `step` 'CONFIRM_OTP', required
    - `data` object, required
      - `onboardingRequestId` string, required: The id returned by the `INITIATE` step.
      - `otp` string, required: The 6-digit one-time passcode, as a string.
  - object
    - `step` 'SUBMIT', required
    - `data` SmeRegistrationSubmitData, required: The `data` payload of the `SUBMIT` step.
      - `onboardingRequestId` string, required: The id returned by the `INITIATE` step.
      - `companyName` string, required
      - `certNumber` string, required: Company registration certificate number.
      - `kraPin` string, required: The company's KRA PIN.
      - `operatingMode` 1 | 2 | 3 | 4, required
      - `businessAddress` string, required
      - `businessIndustry` integer, required: Industry code. With `21`, `specifyIndustry` is required.
      - `specifyIndustry` string: Required when `businessIndustry` is `21`.
      - `directors` object[], required
        - `idType` '101' | '102' | '103', required
        - `idNumber` string, required
        - `gender` 0 | 1
        - `email` string, email
        - `mobile` string, required: A valid Kenyan mobile number.
        - `firstName` string, required
        - `middleName` string
        - `lastName` string, required
        - `kraPin` string, required
        - `idFrontSideFileKey` string, required
        - `idFrontSideFileType` 'image' | 'pdf', required
        - `idBackSideFileKey` string, required
        - `idBackSideFileType` 'image' | 'pdf', required
        - `selfieFileKey` string, required
        - `selfieFileType` 'image' | 'pdf', required
        - `kraPinFileKey` string, required
        - `kraPinFileType` 'image' | 'pdf', required
      - `organizationShareholders` object[]
        - `companyName` string, required
        - `registrationFileKey` string, required
        - `registrationFileType` 'image' | 'pdf', required
      - `media` object[]
        - `fileKey` string, required
        - `mediaType` string, required
        - `contentType` 'pdf' | 'image'

## Response `200`

Step processed successfully.

- object
  - `data` object
    - `onboardingRequestId` string
    - `step` 'INITIATE' | 'CONFIRM_OTP' | 'SUBMIT'
    - `status` 'OTP_PENDING' | 'DETAILS_PENDING' | 'SUBMITTED' | 'REJECTED' | 'EXPIRED'
    - `nextStep` 'CONFIRM_OTP' | 'SUBMIT' | 'null', nullable
    - `expiresAt` string, date-time: Deadline for the current step: OTP window after INITIATE, submit window after CONFIRM_OTP.

## Other responses

- `400`: A step called out of order, an expired OTP, or a duplicate active registration. Malformed field values return `422` instead.
- `401`: Unauthorized - Invalid business API key.
- `422`: Request failed schema validation. `details.friendlyMessage` carries the specific field error.
- `500`: Server error.
- `503`: Temporarily unavailable: an upstream service failed or timed out, or the API is momentarily offline. Retry with backoff and honour the Retry-After header when present.

---

[API](https://skmtc.dev/afriex/apis/afriex-business-api.md) - [All operations](https://skmtc.dev/afriex/apis/afriex-business-api/llms.txt) - [OpenAPI document](https://skmtc.dev/afriex/apis/afriex-business-api/revisions/d94198b6c256?raw)
