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
Users
/v1/identity/usersList all users associated with the authenticated company.
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..."[
{
"id": "usr_01hx...",
"mobileNumber": "+263771234567",
"firstName": "Tendai",
"lastName": "Mutasa",
"kycLevel": 1,
"identityStatus": "CLEAR",
"createdAt": "2026-06-01T08:00:00.000Z"
}
]/v1/identity/users/:idRetrieve full profile for a single user including KYC status and linked accounts.
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid (path) | Yes | UUID 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..."{
"id": "usr_01hx...",
"mobileNumber": "+263771234567",
"idNumber": "63-123456A78",
"firstName": "Tendai",
"lastName": "Mutasa",
"email": "tendai@example.com",
"kycLevel": 2,
"identityStatus": "CLEAR",
"documentUrl": "https://...",
"metadata": {}
}/v1/identity/usersRegister a new user within the company. Accepts multipart/form-data to include an identity document upload.
Set Content-Type: multipart/form-data when uploading a document. For JSON-only creation, omit the document field and use application/json.
| Field | Type | Required | Description |
|---|---|---|---|
| mobileNumber | string | Yes | Unique mobile number within the company (E.164 recommended). |
| idNumber | string | Yes | Zimbabwean National ID number. |
| firstName | string | No | User's legal first name. |
| lastName | string | No | User's legal last name. |
| string | No | User's email address. | |
| metadata | object | No | Arbitrary key-value metadata (JSON string in multipart). |
| bankAccount | object | No | Default bank account: institutionId, accountNumber, accountName?, branchName?, branchCode?. |
| customReference | string | No | Auto-assign deposits matching this bank reference to the user. |
| document | file | No | Identity 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"
}'{
"id": "usr_01hx...",
"mobileNumber": "+263771234567",
"kycLevel": 1,
"identityStatus": "CLEAR",
"createdAt": "2026-06-23T10:00:00.000Z"
}Documents
/v1/identity/users/:id/documentUpload or replace the identity document for an existing user. Accepts multipart/form-data with a 'document' file field.
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid (path) | Yes | UUID of the user. |
| document | file | Yes | Identity 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"
}'{ "documentUrl": "https://...", "updatedAt": "2026-06-23T10:05:00.000Z" }/v1/identity/users/:id/ledgerRetrieve the primary ledger associated with a user.
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid (path) | Yes | UUID 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..."{
"ledgerId": "ldg_01hx...",
"userId": "usr_01hx...",
"accounts": [
{ "id": "acc_...", "currency": "USD", "balance": "25000" },
{ "id": "acc_...", "currency": "ZIG", "balance": "150000" }
]
}/v1/identity/users/:id/link-idManually link a National ID number to an existing user account.
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid (path) | Yes | UUID of the user. |
| idNumber | string | Yes | The National ID number to link. |
| customReference | string | No | Bank 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"
}'{ "userId": "usr_01hx...", "kycLevel": 1, "idLinked": true }Financial Institutions
The list of supported banks used when setting a user's bank account details.
/v1/identity/financial-institutionsList all supported banks and financial institutions. No authentication required.
curl -X GET "https://api.switchlock.co.zw/v1/identity/financial-institutions"[
{ "id": "inst_...", "name": "CBZ Bank", "code": "CBZ", "branchCodes": [...] },
{ "id": "inst_...", "name": "Stanbic Bank Zimbabwe", "code": "SBZ", "branchCodes": [...] }
]/v1/identity/financial-institutions/seedInternal utility to populate the database with the default set of Zimbabwean banks. Run once during setup.
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..."{ "seeded": 12, "skipped": 0 }Admin
SUPER_ADMIN role requiredThese endpoints require the SUPER_ADMIN role on the company admin account in addition to the standard API key headers.
/v1/identity/admin/usersPaginated user list with KYC status filtering. Use for the merchant portal user management dashboard.
| Field | Type | Required | Description |
|---|---|---|---|
| page | integer (query) | No | Page number (1-indexed). |
| limit | integer (query) | No | Results per page. |
| search | string (query) | No | Free-text search against name and mobile number. |
| status | enum (query) | No | PENDING | APPROVED | BLACKLISTED | ALL |
curl -X GET "https://api.switchlock.co.zw/v1/identity/admin/users"{
"data": [ { "id": "...", "firstName": "Tendai", "kycStatus": "PENDING", ... } ],
"total": 128,
"page": 1,
"limit": 20
}/v1/identity/admin/users/:id/approveApprove or revoke a user's KYC (Level 2). Sets the user's identity to manually verified.
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid (path) | Yes | UUID of the user to approve or reject. |
| approved | boolean | Yes | true 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
}'{ "userId": "usr_01hx...", "kycLevel": 2, "approved": true }/v1/identity/admin/users/:id/statusSet the identity status of a user to CLEAR or BLACKLISTED.
| Field | Type | Required | Description |
|---|---|---|---|
| id | uuid (path) | Yes | UUID of the user. |
| status | enum | Yes | CLEAR 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"
}'{ "userId": "usr_01hx...", "identityStatus": "BLACKLISTED" }