Customer Management
Overview
This skill enables AI agents and applications to onboard new customers, look up existing customers, and manage tenant admin users using Eclipse APIs.
It supports:
- Onboarding new customers (create record → trigger KYC → check eligibility → provision wallet)
- Looking up customers by phone, identity number, or name
- Creating and managing tenant admin portal users
All base URLs follow the pattern: {baseUrl}/eclipse-conductor/rest/v1/tenants/{tenantId}/... for tenant-scoped operations. Phone numbers must be digits only with no + prefix (e.g. 27821234567).
1. Customer Onboarding
Trigger: "onboard a new customer", "create a customer", "register a user"
Required inputs: tenantId, firstName, lastName, phone1, email, nationalIdentityNumber, userTypeId, externalUniqueId
New customer onboarding follows five steps: create the customer record, trigger KYC, confirm the result, check wallet eligibility, then provision the wallet. KYC must run before wallet provisioning — eligibility is determined by the KYC outcome.
Step 1 — Create Customer
POST {baseUrl}/eclipse-conductor/rest/v1/tenants/{tenantId}/customers
Authorization: Bearer {jwt}
Content-Type: application/json{
"firstName": "Sipho",
"lastName": "Dlamini",
"phone1": "27821234567",
"email": "[email protected]",
"nationalIdentityNumber": "9001015009087",
"userTypeId": 1,
"externalUniqueId": "cust-a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"version": 0
}externalUniqueId is required — use a UUID unique to this customer. version: 0 is required for optimistic locking on creation.
Response:
{
"customerId": 3847291,
"firstName": "Sipho",
"lastName": "Dlamini",
"phone1": "27821234567",
"email": "[email protected]",
"nationalIdentityNumber": "9001015009087",
"status": "ACTIVE",
"userTypeId": 1,
"externalUniqueId": "cust-a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created": "2026-05-19T08:30:00.000Z"
}Step 2 — Trigger KYC
POST {baseUrl}/eclipse-conductor/rest/v1/tenants/{tenantId}/customers/{customerId}/ratify
Authorization: Bearer {jwt}
Content-Type: application/jsonRequest body may be empty ({}) to run the default check set, or include type (NORMAL or COMPARISON) and checksToRun to limit which checks are executed.
Response: An EclipseKycResult object containing one field per configured check (e.g. sanctionsListCheck, selfieMatchesNationalIdentity, nationalIdentityIsLegitimate), plus a top-level status string and lastModified timestamp.
{
"status": "PASSED",
"lastModified": "2026-05-19T08:30:20.000Z",
"sanctionsListCheck": { "result": "PASSED", "... per-check fields" },
"selfieMatchesNationalIdentity": { "result": "PASSED", "... per-check fields" }
}Step 3 — Check KYC Result
GET {baseUrl}/eclipse-conductor/rest/v1/tenants/{tenantId}/customers/{customerId}/ratify?offset=0&limit=1
Authorization: Bearer {jwt}Returns a list of EclipseKycResult objects, most recent first.
Expected output: surface the top-level status field and any per-check results that are not PASSED. Poll every 30–60 seconds until status is no longer PENDING.
Step 4 — Check Wallet Eligibility
Before provisioning a wallet, confirm which wallet types the customer is eligible for. This is determined by the KYC outcome.
GET {baseUrl}/eclipse-conductor/rest/v1/tenants/{tenantId}/customers/{customerId}/wallet-types
Authorization: Bearer {jwt}Response:
[
{ "walletTypeId": 5001, "allowed": true },
{ "walletTypeId": 5002, "allowed": false }
]Only provision a wallet for a walletTypeId where allowed is true. Do not proceed if no eligible types are returned.
Step 5 — Create Wallet
POST {baseUrl}/eclipse-conductor/rest/v1/tenants/{tenantId}/customers/{customerId}/wallets
Authorization: Bearer {jwt}
Content-Type: application/json{
"walletTypeId": 5001,
"currency": "ZAR",
"status": "ACTIVE",
"externalUniqueId": "wal-a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"version": 0
}status: "ACTIVE", externalUniqueId, and version: 0 are all required. Use a UUID distinct from the customer's externalUniqueId.
Response:
{
"walletId": 1092847,
"customerId": 3847291,
"walletTypeId": 5001,
"name": "Primary Wallet",
"currency": "ZAR",
"currentBalance": 0.00,
"availableBalance": 0.00,
"status": "ACTIVE",
"created": "2026-05-19T08:30:15.000Z"
}Notes
externalUniqueIdis required on both customer and wallet creation. Use a unique UUID for each. Duplicate values are rejected with409 Conflict.version: 0is required on both customer and wallet creation for optimistic locking.status: "ACTIVE"is required on wallet creation.- KYC must complete with
PASSEDbefore checking eligibility — do not skip steps 2–3. - KYC
statusvalues:PASSED,FAILED,PENDING. Individual check fields indicate which check failed.
API Reference: POST /customers · POST /customers/{id}/ratify · GET /customers/{id}/wallet-types · POST /customers/{id}/wallets
2. Customer Lookup
Trigger: "find customer", "look up user", "search for customer", "who is customer X"
Required inputs: At least one of: phone number, name, identity number, or externalId; plus tenantId
Step 1 — Search by Phone or Identity
GET {baseUrl}/eclipse-conductor/rest/v1/tenants/{tenantId}/customers?identity=27821234567&limit=10
Authorization: Bearer {jwt}Response:
[
{
"customerId": 3847291,
"firstName": "Sipho",
"lastName": "Dlamini",
"phone1": "27821234567",
"email": "[email protected]",
"nationalIdentityNumber": "9001015009087",
"status": "ACTIVE",
"created": "2026-05-19T08:30:00.000Z"
}
]Step 2 (Alternative) — Search by Name
GET {baseUrl}/eclipse-conductor/rest/v1/tenants/{tenantId}/customers?firstName=Sipho&lastName=Dlamini&limit=10
Authorization: Bearer {jwt}Step 3 — Get Full Customer Profile
GET {baseUrl}/eclipse-conductor/rest/v1/tenants/{tenantId}/customers/{customerId}
Authorization: Bearer {jwt}Response:
{
"customerId": 3847291,
"title": "MR",
"firstName": "Sipho",
"lastName": "Dlamini",
"phone1": "27821234567",
"email": "[email protected]",
"nationalIdentityNumber": "9001015009087",
"status": "ACTIVE",
"created": "2026-05-19T08:30:00.000Z",
"lastModified": "2026-05-19T08:30:00.000Z"
}Notes
- If multiple results are returned, list them and ask the user to confirm which customer they mean.
- Pagination is supported via
limitandoffset. - The
identityquery parameter matches against phone number or identity number.
API Reference: GET /customers · GET /customers/{customerId}
3. Admin User Management
Trigger: "create admin user", "add operator user", "new portal user"
Required inputs: tenantId, firstName, lastName, email, phone1, identity, role(s)
Step 1 — Create Admin User
POST {baseUrl}/eclipse-conductor/rest/v1/tenants/{tenantId}/admin-users
Authorization: Bearer {jwt}
Content-Type: application/json{
"firstName": "Thembi",
"lastName": "Nkosi",
"email": "[email protected]",
"phone1": "27794567890",
"identity": "thembi.nkosi",
"password": "initialPassword123!",
"positions": ["LEVEL_01"]
}Response:
{
"adminUserId": 58291,
"firstName": "Thembi",
"lastName": "Nkosi",
"email": "[email protected]",
"phone1": "27794567890",
"identity": "thembi.nkosi",
"positions": ["LEVEL_01"]
}Step 2 — List Admin Users
GET {baseUrl}/eclipse-conductor/rest/v1/tenants/{tenantId}/admin-users
Authorization: Bearer {jwt}Notes
identity(the login username) must be unique across the platform. Using email as identity is a common convention.passwordis required on creation; it may be passed as cleartext (Eclipse will hash it) or pre-hashed with BCrypt.positionscontrols access level. Valid values:TENANT_SYSTEM,LEVEL_01–LEVEL_20,ONBOARDING. The specific permissions attached to each level are configured per tenant.- Phone number must be digits only with no
+prefix (e.g.27794567890).
API Reference: POST /admin-users · GET /admin-users
Common Patterns for AI Agents
1. Full Onboarding Flow
- Create customer record (include
externalUniqueIdandversion: 0) - Trigger KYC ratification
- Poll KYC status every 30–60 seconds until
PASSEDorFAILED - If
FAILED, surface the specific failing check(s) for operator review — do not proceed to wallet creation - Check wallet eligibility (
GET .../wallet-types) — confirm at least oneallowed: truetype - Create wallet (include
status: "ACTIVE",externalUniqueId, andversion: 0)
2. Customer Lookup Before Action
Always look up the customer before performing operations:
- Search by phone or identity number
- Confirm identity with operator if multiple results are returned
- Retrieve full profile to confirm status is
ACTIVE
3. Onboarding Checklist
Before completing onboarding, verify:
- Customer record created (
customerIdreturned) - KYC status is
PASSED(notPENDINGorFAILED) - At least one wallet type returned with
allowed: truefrom the eligibility check - Wallet created (
walletIdreturned) - If KYC is
PENDING, advise the operator to check back in 30–60 seconds before proceeding
Error Handling
[
{
"type": "BUSINESS",
"severity": "LOW",
"description": "Customer already exists with this phone number",
"code": "USR004",
"traceId": "3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d",
"spanId": "1a2b3c4d5e6f7a8b",
"environment": "eclipse-sandbox"
}
]| HTTP Status | Meaning | Common Cause |
|---|---|---|
400 | Bad request | Missing required field, invalid phone format |
401 | Unauthorised | JWT missing, expired, or malformed |
403 | Forbidden | Caller role does not have permission for this operation |
404 | Not found | Customer ID does not exist or belongs to a different tenant |
409 | Conflict | Customer with this phone number or identity already exists |
When a traceId is present in an error response, always surface it to the user — it is the primary identifier for diagnosing the failure.
Best Practices
- Include
Authorization: Bearer {jwt}on every request. Renew proactively if within 5 minutes of expiry. - Always confirm with the operator before re-triggering KYC on a customer with
PASSEDstatus — this restarts the verification process. - Apply
limitandoffsetpagination on all list endpoints. Default tolimit=20. - Mask sensitive data in output — never log or display full identity numbers.
- When a
traceIdis returned in an error, record it and reference it in any support escalation. - Tenant-scoped endpoints enforce tenant isolation — never pass a
tenantIdthat does not match the authenticated operator's context.
