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 customer_kind = 0. The same customer_id
is retained while the record passes registration, KYC, first deposit, active trading, and dormancy, which are
recorded as independent bits in lifecycle_flags rather than as a single stage.
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_flags |
int64 | Milestone bit mask. See Lifecycle Flags |
customer_kind |
int | Lead or client: 0 lead, 1 client. See Lead and Client Kind |
conversion_flags |
int64 | Milestone mask captured when the customer became a client. Written by the server only |
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 |
address_of_residence |
string | Residence address, free text, up to 255 characters |
avatar |
string | Optional customer avatar reference. Legacy UUID filenames may use .svg, .png, .jpg, .jpeg, .webp, or .gif; a /storage/ prefix is normalized. Legacy UUID filenames need not be registered. Newly uploaded files must use public purpose customer_avatar. Arbitrary URLs and private file references are rejected. New customers receive a random identicon derived from email and UUID when no avatar is supplied. Existing customer rows are not bulk-changed and remain empty until an avatar is set |
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 | Acquisition channel: MANUAL = 0 (default), WEB = 1, AFFILIATE = 3, INTRODUCER = 5, REFERRAL = 6, LEAD_PROVIDER = 7. See Source Type |
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 |
created_by_import |
int | 0 created the usual way (default), 1 created by the CRM import. Accepted only on creation by MngAddClient, MngAddLead and MngAddCustomer; read-only afterwards |
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 |
time_t | Manager contact timestamps. Besides manual edits, the platform records them after a manual email, SMS or connected call from CRM: last_contact_time moves forward to the event time, first_contact_time is set once when empty. This update does not publish customer.updated and does not run workflow rules. See mailer.email.sent, sms.message.sent, click2call.call.started |
next_contact_time, conversion_time, last_login_time, archive_time |
time_t | CRM/customer lifecycle timestamps |
last_online_time |
time_t | Read-only. Time when any trading account of the customer last went offline in the trading terminal; 0 means never. An account goes offline about 60 seconds after its terminal connection drops (the reconnect window). While the customer is online, the field keeps the previous offline time. The value is set only by the platform: it is ignored in Add/Update requests, does not change updated_time, does not publish customer.updated, and does not run workflow rules |
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.
The server normalizes an optional /storage/ prefix and rejects arbitrary URLs and private file references. Legacy UUID references with supported extensions are accepted without upload registration; newly uploaded files must be registered public files with purpose customer_avatar. Public registration ignores a client-supplied avatar and assigns a server-generated identicon. Manager Add/Update customer, client, and lead commands accept avatar as an optional field. The customer table API appends this field after address_of_residence; existing column positions do not move.
The customer table API appends last_online_time after avatar; existing column positions do not move.
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.
Source Type¶
source_type is the acquisition channel: where the person came from. It does
not describe how the record was created; a CRM import is identified by
created_by_import.
| Value | Name | Meaning |
|---|---|---|
0 |
MANUAL |
Default. Added by a manager directly, or the channel is not specified |
1 |
WEB |
Self-registration on the brand website or landing |
3 |
AFFILIATE |
Brought by an affiliate |
5 |
INTRODUCER |
Brought by an introducing broker |
6 |
REFERRAL |
Invited by another client |
7 |
LEAD_PROVIDER |
Purchased from a lead provider |
Values 2 (former import) and 4 (former system) are retired: commands reject
them with INVALID_DATA, and stored records with these values were migrated to
0. The numbers are never reused.
The server sets the channel itself only on public registration:
CustomerRegistration
stores 3 when an affiliate is resolved and 1 otherwise, unless the request
passes source_type explicitly;
CustomerRegistrationByAffiliate
always stores 3. Every other path stores the value from the request or 0.
Lifecycle Flags¶
Milestones are stored in lifecycle_flags as an independent bit mask, not as an
ordered stage. Any combination is valid; there are no forbidden pairs.
| Bit | Value | Label |
|---|---|---|
1 << 0 |
1 |
Registered |
1 << 1 |
2 |
KYC pending |
1 << 2 |
4 |
KYC approved |
1 << 3 |
8 |
First deposit |
1 << 4 |
16 |
Active trader |
1 << 5 |
32 |
Dormant |
The maximum mask for the six defined flags is 63.
The engine never raises or clears a flag on its own. A flag changes only through an explicit command or a workflow rule:
- MngSetCustomerLifecycleFlags sets the mask
directly and validates it against
0..63; - MngAddCustomer and MngUpdateCustomer accept a whole mask and check only the lower bound, so bits outside the dictionary are stored as supplied;
- MngUpdateCustomersByFilter applies increments
with
lifecycle_flags_addandlifecycle_flags_remove, both bounded to0..63; - the workflow action
customer.set_lifecycle_flagsapplies the same increments.
Archiving stays separate: it is represented by status = ARCHIVED and sets
archive_time, independently of the mask.
Filtering by the mask uses its own operators, described in
MngGetCustomersByFilter. Sorting by
lifecycle_flags is not supported, because the order of a bit mask carries no
meaning.
Lifecycle Transitions¶
Public registration creates a customer with an empty mask and
customer_kind = 0. Every later milestone is recorded explicitly, by a CRM
manager or by a workflow; neither KYC processing nor a credited Cashier deposit
raises a flag by itself.
Conversion from lead to client is a separate operation with its own pair of commands; see Lead and Client Kind.
Lead and Client Kind¶
customer_kind records whether a customer is a lead or a client, and two
commands move it in either direction:
- MngConvertLeadToClient sets it to
1; - MngConvertClientToLead sets it back to
0.
Three fields belong to this pair:
| Field | Type | How it is written |
|---|---|---|
customer_kind |
int | 0 lead, 1 client |
conversion_flags |
int64 | Server only. Not accepted as input by any command |
conversion_time |
int64, Unix seconds | By the server on conversion, and manually through MngAddCustomer and MngUpdateCustomer |
The model invariant: a lead has both conversion fields at zero, and a client has both filled.
Both commands refuse a customer that is already in the target kind, returning
400 RET_INVALID_DATA. They replace the removed MngSetCustomerKind, which
took customer_kind as an argument and forced the customer to it regardless of
the starting point, answering 200 even when nothing changed.
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
- MngConvertLeadToClient
- MngConvertClientToLead
- MngSetCustomerLifecycleFlags
- MngDeleteCustomer
- MngDeleteCustomersByFilter
- MngGetCustomer
- MngGetCustomersByFilter
- MngGetCustomersListByDesk
- MngGetCustomerContacts
- MngExportCustomersByFilter
- MngGetCustomerAccounts
- MngGetCustomerByLogin
- MngSetCustomerPassword
- MngCheckCustomerPassword
Customer list methods require a deskFilter wildcard mask. See Desks TCP API.
How Updates Are Written¶
The update commands — MngUpdateCustomer,
MngUpdateClient, MngUpdateLead and every
...ByFilter update — write only their own fields. The server applies them to the
current customer record in one step under the customer lock. A change made at the
same time to other fields — by a workflow rule, by KYC, or by another manager — is
kept.
- A single update writes the fields whose values the request changes compared with the record read when the command started.
-
A bulk update sets every field it names on each record it writes, including a field that already had the target value when the selection was read. A record whose read copy already had all the target values is counted in
skippedwithout a write. -
A whole
lifecycle_flagsmask is applied as the bits it adds and removes compared with the record read when the command started. Without concurrent changes the stored mask equals the supplied one; bits changed by someone else in the meantime stay as they are. - Targets are checked for the customer's brand. If the brand changes between the
read and the write, the update is refused with
RET_INVALID_DATA: a single update answers400, a bulk command lists the record infailures. emailuniqueness is checked when the request changesemail.- When the request changes nothing, the record is not written and no
customer.updateevent is emitted. A bulk command counts such a record inskipped.
Unlinking From an Affiliate¶
MngUnlinkClientAffiliate,
MngUnlinkLeadAffiliate,
MngUnlinkClientsAffiliateByFilter and
MngUnlinkLeadsAffiliateByFilter detach a
record from its affiliate. Besides the kind permission (set_clients or
set_leads) they require set_marketing.
A record counts as linked when any of these holds:
affiliate_idis not empty;source_typeis3(AFFILIATE);- the marketing attribution or a conversion event of the record still names an affiliate.
Unlinking a linked record:
- clears
affiliate_id,campaign,lead_source,utm_source,utm_medium,utm_campaign,utm_content,utm_term,landing_urlandreferrer_url; - changes
source_typefrom3(AFFILIATE) to0(MANUAL); any othersource_typeis kept; - sets the campaign, affiliate and marketing link to none in the record's marketing attribution and in all its conversion events (registration, KYC approval, first deposit, active trader, deposits). Later deposits and lifecycle stages are recorded without an affiliate as well.
It does not change:
introducer_id, contacts, desk, manager, statuses and lifecycle flags;- deposits, withdrawals and other cashier history, or trading accounts;
- tracking-link visits;
- brand totals in MngGetMarketingFunnel: the record moves from the affiliate's row to the row without an affiliate.
After unlinking, the previous affiliate no longer receives the record, its
transactions or its first deposit from the Affiliate API (customers,
transactions, first-deposits). The record is also gone from the affiliate
cabinet dashboard and conversions, from
MngGetAffiliatesByFilter stats, and
from the funnel and link stats filtered by that affiliate, its campaign or its
links. The record is not assigned to another affiliate. Registration, deposits
and restarts do not link it back automatically. The update commands do not
accept affiliate_id, so the affiliate cannot be changed through them either.
The record is written through the same per-field path as the update commands
and emits customer.update. Each unlinked record is logged with the manager,
the time, the customer_id and the previous affiliate id and code. The command
call itself goes to the journal.
Customer Status Commands¶
- MngAddCustomerStatus
- MngUpdateCustomerStatus
- MngDeleteCustomerStatus
- MngGetCustomerStatus
- MngGetCustomerStatusesByFilter
Clients and Leads Commands¶
Customer commands are split by customer kind. Clients and leads have their own command for every operation, and the kind is expressed by the command name instead of a request field. The pair that moves a record between the two halves is MngConvertLeadToClient and MngConvertClientToLead.
All of these commands share the session list from Access Control
and the access_crm scope. What differs is the permission.
| Operation | Clients | Leads |
|---|---|---|
| Read | see_clients |
see_leads |
| Create and update | set_clients |
set_leads |
| Delete | del_clients |
del_leads |
| Export | export_clients |
export_leads |
| Read contacts | see_clients_contacts |
see_leads_contacts |
| Write contacts | set_clients_contacts |
set_leads_contacts |
| Bypass desk scope | see_all_clients |
see_all_leads |
| Terminal login link | login_as_clients |
login_as_leads |
Each of the kind-split commands requires exactly one permission of its own, with no leftovers from the customer-wide set.
The four conversion commands stand apart:
MngConvertLeadToClient,
MngConvertClientToLead,
MngConvertLeadsToClientsByFilter, and
MngConvertClientsToLeadsByFilter require
both set_leads and set_clients, because the record leaves one half and
appears in the other. That is not an exception to the rule but the rule itself
applied to a cross-kind operation.
Rules Common to the Kind-Split Commands¶
customer_kindis not accepted on input by any of them: not on create, not on update, and not inside thefieldsobject of a bulk update. The command name carries the kind.- Addressing the wrong kind is refused with
400 RET_INVALID_DATA, for example MngGetLead called with a client identifier. List commands have no such refusal: they return the records of their own kind and nothing else. - Lookup by login separates two cases.
404 RET_NOT_FOUNDmeans no customer with that login exists at all;400 RET_INVALID_DATAmeans one exists but is of the other kind, and the paired command has to be called. - For list commands
countmatches what is returned. The kind is selected before counting and before the page is cut, so a page never arrives short.
Extended Desk Visibility¶
see_all_clients opens every client of the brand, see_all_leads every lead.
Neither substitutes for the other, and neither substitutes for the read
permission itself: see_all_leads without see_leads grants nothing.
The brand always bounds the result. see_all_* widens the desk scope only and
never reaches outside the brand.
Bulk Commands Process the Whole Selection¶
Every ...ByFilter write command processes every record matching the filter.
limit and offset are present in the filter for uniformity with the read
commands and are validated, but they do not limit the amount of work.
The guard against an accidental run is confirm. With confirm: false the
command performs every check and reports what would happen, changing nothing.
Client and Lead Commands¶
Every operation exists once per kind. The rules these commands share are in Clients and Leads Commands.
Clients¶
- MngGetClient
- MngGetClientByLogin
- MngGetClientAccounts
- MngGetClientsByFilter
- MngGetClientsListByDesk
- MngAddClient
- MngUpdateClient
- MngSetClientLifecycleFlags
- MngUpdateClientsByFilter
- MngUpdateClientsDeskByFilter
- MngUpdateClientsAssignedManagerByFilter
- MngUpdateClientsStatusesByFilter
- MngUnlinkClientAffiliate
- MngUnlinkClientsAffiliateByFilter
- MngDeleteClient
- MngDeleteClientsByFilter
- MngExportClientsByFilter
- MngGetClientContacts
- MngCheckClientPassword
- MngSetClientPassword
- MngCreateClientLoginLink
Leads¶
- MngGetLead
- MngGetLeadByLogin
- MngGetLeadAccounts
- MngGetLeadsByFilter
- MngGetLeadsListByDesk
- MngAddLead
- MngUpdateLead
- MngSetLeadLifecycleFlags
- MngUpdateLeadsByFilter
- MngUpdateLeadsDeskByFilter
- MngUpdateLeadsAssignedManagerByFilter
- MngUpdateLeadsStatusesByFilter
- MngUnlinkLeadAffiliate
- MngUnlinkLeadsAffiliateByFilter
- MngDeleteLead
- MngDeleteLeadsByFilter
- MngExportLeadsByFilter
- MngGetLeadContacts
- MngCheckLeadPassword
- MngSetLeadPassword
- MngCreateLeadLoginLink
Conversion¶
- MngConvertLeadToClient
- MngConvertClientToLead
- MngConvertLeadsToClientsByFilter
- MngConvertClientsToLeadsByFilter
All four require both set_leads and set_clients.
Deprecated Commands¶
Eighteen customer commands are deprecated. Every one of them still works, with no change to its behavior, request, response, or required permissions. They are deprecated, not removed.
The reason is that customer commands have been split by customer kind: clients and leads now have their own commands, and the kind is expressed by the command name instead of a request field. Each old command is therefore replaced by a pair, and the permission splits along with it.
Removal is a separate task, to be carried out once frontends have moved to the new commands. No date is fixed in advance; the signal is that the old commands stop being called.
Reading¶
| Deprecated | Permission | Replaced by | Replacement permission |
|---|---|---|---|
| MngGetCustomer | see_customers |
MngGetClient | see_clients |
| MngGetLead | see_leads |
||
| MngGetCustomerByLogin | see_customers |
MngGetClientByLogin | see_clients |
| MngGetLeadByLogin | see_leads |
||
| MngGetCustomerAccounts | see_customers |
MngGetClientAccounts | see_clients |
| MngGetLeadAccounts | see_leads |
||
| MngGetCustomersByFilter | see_customers |
MngGetClientsByFilter | see_clients |
| MngGetLeadsByFilter | see_leads |
||
| MngGetCustomersListByDesk | see_customers |
MngGetClientsListByDesk | see_clients |
| MngGetLeadsListByDesk | see_leads |
Creating and Updating¶
| Deprecated | Permission | Replaced by | Replacement permission |
|---|---|---|---|
| MngAddCustomer | set_customers |
MngAddClient | set_clients |
| MngAddLead | set_leads |
||
| MngUpdateCustomer | set_customers |
MngUpdateClient | set_clients |
| MngUpdateLead | set_leads |
||
| MngSetCustomerLifecycleFlags | set_customers |
MngSetClientLifecycleFlags | set_clients |
| MngSetLeadLifecycleFlags | set_leads |
||
| MngUpdateCustomersByFilter | set_customers |
MngUpdateClientsByFilter | set_clients |
| MngUpdateLeadsByFilter | set_leads |
||
| MngUpdateCustomersDeskByFilter | set_customers |
MngUpdateClientsDeskByFilter | set_clients |
| MngUpdateLeadsDeskByFilter | set_leads |
||
| MngUpdateCustomersAssignedManagerByFilter | set_customers |
MngUpdateClientsAssignedManagerByFilter | set_clients |
| MngUpdateLeadsAssignedManagerByFilter | set_leads |
||
| MngUpdateCustomersStatusesByFilter | set_customers |
MngUpdateClientsStatusesByFilter | set_clients |
| MngUpdateLeadsStatusesByFilter | set_leads |
Deleting and Exporting¶
| Deprecated | Permission | Replaced by | Replacement permission |
|---|---|---|---|
| MngDeleteCustomer | del_customers |
MngDeleteClient | del_clients |
| MngDeleteLead | del_leads |
||
| MngDeleteCustomersByFilter | del_customers plus set_customers |
MngDeleteClientsByFilter | del_clients |
| MngDeleteLeadsByFilter | del_leads |
||
| MngExportCustomersByFilter | export_customers |
MngExportClientsByFilter | export_clients |
| MngExportLeadsByFilter | export_leads |
Contacts and Passwords¶
| Deprecated | Permission | Replaced by | Replacement permission |
|---|---|---|---|
| MngGetCustomerContacts | see_customer_contacts |
MngGetClientContacts | see_clients_contacts |
| MngGetLeadContacts | see_leads_contacts |
||
| MngCheckCustomerPassword | see_customer_contacts |
MngCheckClientPassword | see_clients_contacts |
| MngCheckLeadPassword | see_leads_contacts |
||
| MngSetCustomerPassword | set_customer_contacts |
MngSetClientPassword | set_clients_contacts |
| MngSetLeadPassword | set_leads_contacts |
How the Replacements Differ¶
These points apply to the new commands, not to the deprecated ones:
customer_kindis not accepted, neither on create, nor on update, nor in thefieldsobject of a bulk update. The command name carries the kind.- Addressing the wrong kind is refused with
RET_INVALID_DATAand status400, for example MngGetLead called with a client identifier. List commands have no such refusal: they simply return the records of their own kind. - Lookup by login distinguishes two cases.
404means no customer with that login exists at all;400means one exists but is of the other kind, and the paired command has to be called. - For list commands
countmatches what is returned. The kind is selected before counting and before the page is cut, so a page never arrives short.
What Is Not Deprecated¶
MngConvertLeadToClient and MngConvertClientToLead stay as they are, and two bulk commands join them: MngConvertLeadsToClientsByFilter and MngConvertClientsToLeadsByFilter.
All four require both set_leads and set_clients, because the record leaves
one half and appears in the other.
Errors¶
Common errors:
INVALID_DATARET_NOT_FOUNDRET_DUPLICATE_RECORDRET_INVALID_PASSWORD