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 → create wallet → trigger KYC)
  • 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, email1, identity number, userTypeId, walletTypeId

New customer onboarding follows three steps: create the customer record, create at least one wallet, then trigger KYC (ratification).

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
}

Response:

{
  "customerId": 3847291,
  "firstName": "Sipho",
  "lastName": "Dlamini",
  "phone1": "27821234567",
  "email": "[email protected]",
  "nationalIdentityNumber": "9001015009087",
  "status": "ACTIVE",
  "userTypeId": 1,
  "created": "2026-05-19T08:30:00.000Z"
}

Step 2 — Create Wallet

POST {baseUrl}/eclipse-conductor/rest/v1/tenants/{tenantId}/customers/{customerId}/wallets
Authorization: Bearer {jwt}
Content-Type: application/json
{
  "walletTypeId": 5001,
  "currency": "ZAR",
  "friendlyId": "SIPHO-PRIMARY",
  "externalId": "ext-sipho-dlamini-001"
}

Response:

{
  "walletId": 1092847,
  "customerId": 3847291,
  "walletTypeId": 5001,
  "name": "Primary Wallet",
  "currency": "ZAR",
  "currentBalance": 0.00,
  "availableBalance": 0.00,
  "status": "ACTIVE",
  "friendlyId": "SIPHO-PRIMARY",
  "created": "2026-05-19T08:30:15.000Z"
}

Step 3 — Trigger KYC

POST {baseUrl}/eclipse-conductor/rest/v1/tenants/{tenantId}/customers/{customerId}/ratify
Authorization: Bearer {jwt}
Content-Type: application/json

Request 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 4 — Check KYC Result

GET {baseUrl}/eclipse-conductor/rest/v1/tenants/{tenantId}/customers/{customerId}/ratify
Authorization: Bearer {jwt}

Returns a list of EclipseKycResult objects, most recent first. Pass offset=0&limit=1 for the latest result only.

Expected output: surface the top-level status field and any per-check results that are not PASSED.

Notes

  • walletTypeId must be a valid type configured for the tenant. Query /eclipse-conductor/rest/v1/tenants/{tenantId}/wallet-types to retrieve available types.
  • KYC status values include PASSED and FAILED. Individual check fields indicate exactly which check failed.

API Reference: POST /customers · POST /customers/{id}/wallets · POST /customers/{id}/ratify


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 limit and offset.
  • The identity query 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, email1, 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.
  • password is required on creation; it may be passed as cleartext (Eclipse will hash it) or pre-hashed with BCrypt.
  • positions controls access level. Valid values: TENANT_SYSTEM, LEVEL_01LEVEL_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

  1. Create customer record
  2. Create wallet linked to customer
  3. Trigger KYC ratification
  4. Poll KYC status every 30–60 seconds until PASSED or FAILED
  5. If FAILED, surface the specific failing check(s) for operator review

2. Customer Lookup Before Action

Always look up the customer before performing operations:

  1. Search by phone or identity number
  2. Confirm identity with operator if multiple results are returned
  3. Retrieve full profile to confirm status is ACTIVE

3. Onboarding Checklist

Before completing onboarding, verify:

  • Customer record created (customerId returned)
  • At least one wallet created (walletId returned)
  • KYC status is PASSED
  • If PENDING, advise the operator to check back in 30–60 seconds

Error Handling

[
  {
    "type": "BUSINESS",
    "severity": "LOW",
    "description": "Customer already exists with this phone number",
    "code": "USR004",
    "traceId": "3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d",
    "spanId": "1a2b3c4d5e6f7a8b",
    "environment": "eclipse-sandbox"
  }
]
HTTP StatusMeaningCommon Cause
400Bad requestMissing required field, invalid phone format
401UnauthorisedJWT missing, expired, or malformed
403ForbiddenCaller role does not have permission for this operation
404Not foundCustomer ID does not exist or belongs to a different tenant
409ConflictCustomer 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 PASSED status — this restarts the verification process.
  • Apply limit and offset pagination on all list endpoints. Default to limit=20.
  • Mask sensitive data in output — never log or display full identity numbers.
  • When a traceId is returned in an error, record it and reference it in any support escalation.
  • Tenant-scoped endpoints enforce tenant isolation — never pass a tenantId that does not match the authenticated operator's context.