SwitchLock Docs
API Reference/Identity

Identity & KYC

Register users, upload identity documents, link National IDs, and manage KYC status. Admin-flagged endpoints require the SUPER_ADMIN role in addition to the standard API key.

User creation accepts multipart/form-data so you can upload an identity document in the same request. The document field is optional — you can upload separately later using POST /users/:id/document.

KYC Levels

Level 0
Unverified
Mobile number registered, no ID linked.
Level 1
ID Linked
National ID number attached to the user record.
Level 2
KYC Approved
Document verified and manually approved by admin.

Users

GET
/v1/identity/users

List all users associated with the authenticated company.

Auth
curl -X GET "https://api.switchlock.co.zw/v1/identity/users" \
  -H "x-api-key: zl_sk_your_key_here" \
  -H "x-company-id: cmp_01HXYZ..."
Response Example
[
  {
    "id": "usr_01hx...",
    "mobileNumber": "+263771234567",
    "firstName": "Tendai",
    "lastName": "Mutasa",
    "kycLevel": 1,
    "identityStatus": "CLEAR",
    "createdAt": "2026-06-01T08:00:00.000Z"
  }
]
GET
/v1/identity/users/:id

Retrieve full profile for a single user including KYC status and linked accounts.

Auth
FieldTypeRequiredDescription
iduuid (path)YesUUID of the user.
curl -X GET "https://api.switchlock.co.zw/v1/identity/users/value" \
  -H "x-api-key: zl_sk_your_key_here" \
  -H "x-company-id: cmp_01HXYZ..."
Response Example
{
  "id": "usr_01hx...",
  "mobileNumber": "+263771234567",
  "idNumber": "63-123456A78",
  "firstName": "Tendai",
  "lastName": "Mutasa",
  "email": "tendai@example.com",
  "kycLevel": 2,
  "identityStatus": "CLEAR",
  "documentUrl": "https://...",
  "metadata": {}
}
POST
/v1/identity/users

Register a new user within the company. Accepts multipart/form-data to include an identity document upload.

Auth

Set Content-Type: multipart/form-data when uploading a document. For JSON-only creation, omit the document field and use application/json.

FieldTypeRequiredDescription
mobileNumberstringYesUnique mobile number within the company (E.164 recommended).
idNumberstringYesZimbabwean National ID number.
firstNamestringNoUser's legal first name.
lastNamestringNoUser's legal last name.
emailstringNoUser's email address.
metadataobjectNoArbitrary key-value metadata (JSON string in multipart).
bankAccountobjectNoDefault bank account: institutionId, accountNumber, accountName?, branchName?, branchCode?.
customReferencestringNoAuto-assign deposits matching this bank reference to the user.
documentfileNoIdentity document image (multipart only).
curl -X POST "https://api.switchlock.co.zw/v1/identity/users" \
  -H "x-api-key: zl_sk_your_key_here" \
  -H "x-company-id: cmp_01HXYZ..." \
  -H "Content-Type: application/json" \
  -d '{
  "mobileNumber": "string",
  "idNumber": "string",
  "firstName": "string",
  "lastName": "string",
  "email": "string",
  "metadata": {},
  "bankAccount": {},
  "customReference": "string",
  "document": "string"
}'
Response Example
{
  "id": "usr_01hx...",
  "mobileNumber": "+263771234567",
  "kycLevel": 1,
  "identityStatus": "CLEAR",
  "createdAt": "2026-06-23T10:00:00.000Z"
}

Documents

POST
/v1/identity/users/:id/document

Upload or replace the identity document for an existing user. Accepts multipart/form-data with a 'document' file field.

Auth
FieldTypeRequiredDescription
iduuid (path)YesUUID of the user.
documentfileYesIdentity document file (image or PDF). Field name must be 'document'.
curl -X POST "https://api.switchlock.co.zw/v1/identity/users/value/document" \
  -H "x-api-key: zl_sk_your_key_here" \
  -H "x-company-id: cmp_01HXYZ..." \
  -H "Content-Type: application/json" \
  -d '{
  "id": "string",
  "document": "string"
}'
Response Example
{ "documentUrl": "https://...", "updatedAt": "2026-06-23T10:05:00.000Z" }
GET
/v1/identity/users/:id/ledger

Retrieve the primary ledger associated with a user.

Auth
FieldTypeRequiredDescription
iduuid (path)YesUUID of the user.
curl -X GET "https://api.switchlock.co.zw/v1/identity/users/value/ledger" \
  -H "x-api-key: zl_sk_your_key_here" \
  -H "x-company-id: cmp_01HXYZ..."
Response Example
{
  "ledgerId": "ldg_01hx...",
  "userId": "usr_01hx...",
  "accounts": [
    { "id": "acc_...", "currency": "USD", "balance": "25000" },
    { "id": "acc_...", "currency": "ZIG", "balance": "150000" }
  ]
}
POST
/v1/identity/users/:id/link-id

Manually link a National ID number to an existing user account.

Auth
FieldTypeRequiredDescription
iduuid (path)YesUUID of the user.
idNumberstringYesThe National ID number to link.
customReferencestringNoBank reference for auto-deposit matching.
curl -X POST "https://api.switchlock.co.zw/v1/identity/users/value/link-id" \
  -H "x-api-key: zl_sk_your_key_here" \
  -H "x-company-id: cmp_01HXYZ..." \
  -H "Content-Type: application/json" \
  -d '{
  "id": "string",
  "idNumber": "string",
  "customReference": "string"
}'
Response Example
{ "userId": "usr_01hx...", "kycLevel": 1, "idLinked": true }

Financial Institutions

The list of supported banks used when setting a user's bank account details.

GET
/v1/identity/financial-institutions

List all supported banks and financial institutions. No authentication required.

Public
curl -X GET "https://api.switchlock.co.zw/v1/identity/financial-institutions"
Response Example
[
  { "id": "inst_...", "name": "CBZ Bank", "code": "CBZ", "branchCodes": [...] },
  { "id": "inst_...", "name": "Stanbic Bank Zimbabwe", "code": "SBZ", "branchCodes": [...] }
]
POST
/v1/identity/financial-institutions/seed

Internal utility to populate the database with the default set of Zimbabwean banks. Run once during setup.

Auth
curl -X POST "https://api.switchlock.co.zw/v1/identity/financial-institutions/seed" \
  -H "x-api-key: zl_sk_your_key_here" \
  -H "x-company-id: cmp_01HXYZ..."
Response Example
{ "seeded": 12, "skipped": 0 }

Admin

SUPER_ADMIN role required

These endpoints require the SUPER_ADMIN role on the company admin account in addition to the standard API key headers.

GET
/v1/identity/admin/users

Paginated user list with KYC status filtering. Use for the merchant portal user management dashboard.

Admin Only
FieldTypeRequiredDescription
pageinteger (query)NoPage number (1-indexed).
limitinteger (query)NoResults per page.
searchstring (query)NoFree-text search against name and mobile number.
statusenum (query)NoPENDING | APPROVED | BLACKLISTED | ALL
curl -X GET "https://api.switchlock.co.zw/v1/identity/admin/users"
Response Example
{
  "data": [ { "id": "...", "firstName": "Tendai", "kycStatus": "PENDING", ... } ],
  "total": 128,
  "page": 1,
  "limit": 20
}
POST
/v1/identity/admin/users/:id/approve

Approve or revoke a user's KYC (Level 2). Sets the user's identity to manually verified.

Admin Only
FieldTypeRequiredDescription
iduuid (path)YesUUID of the user to approve or reject.
approvedbooleanYestrue to approve; false to revoke approval. Defaults to true.
curl -X POST "https://api.switchlock.co.zw/v1/identity/admin/users/value/approve" \
  -H "Content-Type: application/json" \
  -d '{
  "id": "string",
  "approved": true
}'
Response Example
{ "userId": "usr_01hx...", "kycLevel": 2, "approved": true }
POST
/v1/identity/admin/users/:id/status

Set the identity status of a user to CLEAR or BLACKLISTED.

Admin Only
FieldTypeRequiredDescription
iduuid (path)YesUUID of the user.
statusenumYesCLEAR or BLACKLISTED.
curl -X POST "https://api.switchlock.co.zw/v1/identity/admin/users/value/status" \
  -H "Content-Type: application/json" \
  -d '{
  "id": "string",
  "status": "string"
}'
Response Example
{ "userId": "usr_01hx...", "identityStatus": "BLACKLISTED" }

Next steps