Customers TCP API¶
Customer is a CRM/KYC/AML entity above trading accounts. It does not replace account login or trading runtime identity.
A lead is not a separate server entity. It is a customer with lifecycle_stage = 0. The same customer_id
is retained while the record moves through registration, KYC, first deposit, active trading, and dormancy.
customer_id is an int. A trading account is linked to a customer through AccountRecord.customer_id / Users.customer_id.
customer_id = 0 means the account is not linked to any customer. This is valid.
Access Control¶
All customer methods require one of:
SESSION_MANAGERSESSION_ADMINSESSION_DEALERSESSION_CRM_MANAGERSESSION_CRM_ADMIN
Manager access is resolved from the cached staff record. The token is used only as a source of manager id and session type; permissions, brand, desks, and groups are not trusted from the token.
Customer visibility is scoped by manager CRM permissions and customer brand / desk:
| Permission | Used for |
|---|---|
see_customers |
Read customer records, lists, customer accounts, and lookup by login |
set_customers |
Create or update customer records |
del_customers |
Delete customer records |
export_customers |
Export customers |
see_all_customers |
Bypass personal desk scope for customer visibility |
see_customer_contacts |
View unmasked customer/account contact fields and check customer password |
set_customer_contacts |
Set customer contacts or customer password |
Without see_customer_contacts, customer email and phone are returned masked where the method can return contact fields. Full-contact export also requires see_customer_contacts.
The bulk list and export methods mask contacts by default even for a caller who holds the permission, and open them only when the request asks: MngGetCustomersByFilter and MngExportCustomersByFilter take contacts: "full" for that. Single-customer methods unmask automatically for anyone holding the permission.
Customer status dictionary methods use the same CRM access model: see_customers for read, set_customers for create/update, and del_customers for delete. Read methods can return global statuses with empty brand; write/delete methods require the status brand to be inside manager brand scope unless the manager has admin scope.
Customer Fields¶
| Field | Type | Notes |
|---|---|---|
customer_id |
int | Primary customer identifier |
external_id |
string | Optional external CRM/PSP/reference ID |
type |
int | CUSTOMER_TYPE_INDIVIDUAL = 0, CUSTOMER_TYPE_BUSINESS = 1 |
status |
int | Operational state: ACTIVE = 0, BLOCKED = 1, ARCHIVED = 2 |
lifecycle_stage |
int | CRM lifecycle: LEAD = 0, REGISTERED = 1, KYC_PENDING = 2, KYC_APPROVED = 3, FIRST_DEPOSIT = 4, ACTIVE_TRADER = 5, DORMANT = 6 |
enable |
int | 1 enabled, 0 disabled |
enable_otp |
int | 1 requires OTP during customer auth |
deposit_allowed |
int | Global customer deposit gate. 1 allowed, 0 blocked |
withdrawal_allowed |
int | Global customer withdrawal gate. 1 allowed, 0 blocked |
first_name, last_name, middle_name, full_name |
string | Identity fields |
birth_date |
time_t | Unix timestamp |
citizenship, country_of_residence |
string | Profile/compliance fields |
email |
string | Unique for non-empty values; used for customer auth |
phone |
string | Customer phone |
preferred_language, timezone |
string | Communication preferences |
brand |
string | Optional brand scope |
desk |
string | CRM desk code, for example DESK_RETENTION |
manager_id |
int | Assigned manager id |
lead_source, campaign, affiliate_id, introducer_id |
string | Acquisition and partner references |
source_type |
int | MANUAL = 0, WEB = 1, IMPORT = 2, AFFILIATE = 3, SYSTEM = 4 |
landing_url, referrer_url |
string | Acquisition page and referrer |
utm_source, utm_medium, utm_campaign, utm_content, utm_term |
string | UTM attribution |
import_batch_id, old_id |
string | Import and legacy-system references |
assigned_manager_id |
int | CRM owner/manager id |
crm_stage, segment, tags_json |
string | CRM classification fields |
email_verified, phone_verified, marketing_allowed |
int | Boolean flags |
tax_id, national_id |
string | Compliance identifiers |
pep_status |
int | CUSTOMER_PEP_UNKNOWN = 0, CUSTOMER_PEP_CLEAR = 1, CUSTOMER_PEP_POSITIVE = 2 |
sanctions_status |
int | CUSTOMER_SANCTIONS_UNKNOWN = 0, CUSTOMER_SANCTIONS_CLEAR = 1, CUSTOMER_SANCTIONS_POSITIVE = 2, CUSTOMER_SANCTIONS_REVIEW = 3 |
risk_level |
int | CUSTOMER_RISK_LOW = 0, CUSTOMER_RISK_MEDIUM = 1, CUSTOMER_RISK_HIGH = 2 |
aml_status |
int | CUSTOMER_AML_PENDING = 0, CUSTOMER_AML_REVIEW = 1, CUSTOMER_AML_APPROVED = 2, CUSTOMER_AML_REJECTED = 3 |
kyc_status |
int | CRM status dictionary id, 0 means not assigned |
sales_status |
int | CRM status dictionary id, 0 means not assigned |
risk_status |
int | CRM status dictionary id, 0 means not assigned |
finance_status |
int | CRM status dictionary id, 0 means not assigned |
kyc_updated_time, aml_updated_time |
time_t | Status update timestamps |
first_contact_time, last_contact_time, next_contact_time, conversion_time, last_login_time, archive_time |
time_t | CRM/customer lifecycle timestamps |
created_time, updated_time |
time_t | Record lifecycle timestamps |
created_by, updated_by |
int | Manager ids |
meta_json |
string | Optional JSON extension payload |
Sensitive fields such as password hash and OTP secret are not returned in customer responses.
Marketing Attribution¶
Public registration can populate campaign, affiliate_id, source_type, landing/referrer values, and UTM fields from the marketing attribution subsystem. Attribution is resolved inside the common customer registration flow and stored as a historical snapshot.
- Brand-page traffic is matched by a server-side fingerprint.
- External affiliate landing pages pass public codes in the registration
attributionobject. - Mobile applications pass an
installation_idpreviously connected through the app activation endpoint. - Supplied campaign and affiliate codes are stored only when they are active and valid in the customer brand.
Management of campaigns, affiliates, links, and brand applications is documented in Marketing and Affiliates TCP API. Public registration flows are documented in Marketing Attribution API.
Lifecycle Transitions¶
Public registration creates a customer at LEAD = 0. Promotion to
REGISTERED = 1 is explicit and is performed by a CRM manager or workflow.
KYC processing does not promote the lifecycle automatically. A successfully
credited Cashier deposit advances a customer below that stage to
FIRST_DEPOSIT = 4 and records conversion_time.
- A CRM manager can change the stage manually with
MngUpdateCustomer. - An active workflow can change it with
customer.set_lifecycle_stage. - A workflow can use
customer.lifecycle_stageas a condition and explicitly promote a lead toREGISTERED = 1. - On the first transition from
LEADto any other stage, the server recordsconversion_timeautomatically. - Archiving is represented by
status = ARCHIVEDand setsarchive_time; it is independent of lifecycle stage.
Customer Status Dictionary¶
CRM workflow statuses are configurable records from customer_statuses. Customer fields kyc_status, sales_status, risk_status, and finance_status store status ids. Value 0 means that a status is not assigned.
Status types:
| Value | Name |
|---|---|
0 |
CUSTOMER_STATUS_TYPE_SALES |
1 |
CUSTOMER_STATUS_TYPE_FINANCE |
2 |
CUSTOMER_STATUS_TYPE_TRADE |
3 |
CUSTOMER_STATUS_TYPE_RISK |
4 |
CUSTOMER_STATUS_TYPE_KYC |
Status record fields:
| Field | Type | Notes |
|---|---|---|
id |
int | Status id |
brand |
string | Optional brand scope |
type |
int | Status type enum |
status_name |
string | Display name |
status_description |
string | Optional description |
status_color |
string | Optional UI color |
sort |
int | Sort order |
created_time, updated_time |
time_t | Record timestamps |
created_by, updated_by |
int | Manager ids |
Customer Commands¶
- MngAddCustomer
- MngUpdateCustomer
- MngUpdateCustomersByFilter
- MngUpdateCustomersDeskByFilter
- MngUpdateCustomersAssignedManagerByFilter
- MngUpdateCustomersStatusesByFilter
- MngDeleteCustomer
- MngDeleteCustomersByFilter
- MngGetCustomer
- MngGetCustomersByFilter
- MngGetCustomersListByDesk
- MngGetCustomerContacts
- MngExportCustomersByFilter
- MngGetCustomerAccounts
- MngGetCustomerByLogin
- MngSetCustomerPassword
- MngCheckCustomerPassword
Customer list methods require a deskFilter wildcard mask. See Desks TCP API.
Customer Status Commands¶
- MngAddCustomerStatus
- MngUpdateCustomerStatus
- MngDeleteCustomerStatus
- MngGetCustomerStatus
- MngGetCustomerStatusesByFilter
Errors¶
Common errors:
INVALID_DATARET_NOT_FOUNDRET_DUPLICATE_RECORDRET_INVALID_PASSWORD