Skip to content

MngDeleteLeadsByFilter

Deletes every lead matching the supplied filter. A single flag decides what happens to the trading accounts linked to those records: delete_accounts: false detaches them, delete_accounts: true deletes them.

The confirm flag decides whether anything is written. With confirm: false the command runs every check and returns the counters describing what would happen, without touching a record.

The command is available through the manager command API only; there is no REST path for it. The kind is fixed by the command name, so customer_kind is not accepted on input. See Clients and Leads Commands.

It replaces the deprecated MngDeleteCustomersByFilter.

Nothing here can be undone

Deleted records, accounts, and trades are removed from storage, not archived. Recovery is possible only from a backup. Treat the dry run as a mandatory step, not a convenience.

Access Control

Allowed sessions:

  • SESSION_MANAGER
  • SESSION_ADMIN
  • SESSION_DEALER
  • SESSION_CRM_MANAGER
  • SESSION_CRM_ADMIN

The caller must have CRM access and del_leads.

delete_accounts: true additionally requires access_backoffice and del_accounts, and every account's group must fall inside the caller's groups mask, the same rule as MngDeleteAccount. A caller who asks for it without those rights is refused with 403 before any record is selected.

Every call is written to the journal, successful ones included.

Request

Dry run, delete records together with their accounts:

{
  "command": "MngDeleteLeadsByFilter",
  "extID": "1",
  "data": {
    "delete_accounts": true,
    "confirm": false,
    "filter": {
      "deskFilter": "*",
      "limit": 100,
      "offset": 0,
      "where": [
        ["lifecycle_flags", "has_all", 32]
      ]
    }
  }
}

Request Data

Top level:

Field Type Required Description
delete_accounts bool Yes true deletes the linked accounts and their trade history. false keeps them and clears customer_id
confirm bool Yes false reports what would happen without writing. true performs the deletion
filter object Yes Record selection

filter object:

Field Type Required Description
deskFilter string Yes Desk wildcard mask, for example *, DESK_*, DESK_EU*,!DESK_EU_TEST. Must not be empty
limit int Yes From 1 to 50000. Validated, but it does not limit how much is processed
offset int Yes Minimum 0. Validated, but it does not limit how much is processed
where array No [[field, operator, value], ...], all conditions must match
orWhere array No OR comparison group; at least one condition must match
whereNot array No [[field, value], ...]
whereIn array No [[field, [values...]], ...]
whereNotIn array No [[field, [values...]], ...]
whereBetween array No [[field, [from, to]], ...]
whereNotBetween array No [[field, [from, to]], ...]
orderBy array No Example: [["created_time", "desc"]]

Filter fields and operators are the same as for the customer table, including the lifecycle_flags operators has_all, has_any, and has_none. Common filter semantics are described in Table filter syntax; desk masks in Desks TCP API.

Behavior

Each record is all-or-nothing: if any check fails, it is reported in failures and none of its accounts are touched. Accounts are processed first and the record last, so an interrupted run leaves a consistent, retryable state.

An open market position blocks deletion and fails the record with ACCOUNT_HAS_TRADES, listing the offending logins. Pending orders do not block and are deleted together with the account. A non-zero balance does not block either: it is reported through accounts_with_balance, not enforced.

Response Data

{
  "confirm": true,
  "delete_accounts": true,
  "matched": 10,
  "deleted": 9,
  "failed": 1,
  "accounts_matched": 44,
  "accounts_deleted": 41,
  "accounts_unlinked": 0,
  "accounts_with_balance": 12,
  "failures": [
    {
      "customer_id": 1207,
      "error": "ACCOUNT_HAS_TRADES",
      "message": "Accounts have open market positions",
      "logins": [500780]
    }
  ]
}
Field Type Description
confirm bool Echo of the request flag
delete_accounts bool Echo of the request flag
matched int Records selected by the filter, kind, brand scope, and desk mask
deleted int Records actually deleted. Always 0 when confirm is false
failed int Records that did not pass. One entry in failures each
accounts_matched int Accounts belonging to records that passed every check
accounts_deleted int Accounts actually deleted. Always 0 in a dry run and in the detach branch
accounts_unlinked int Accounts actually detached. Always 0 in a dry run and in the delete branch
accounts_with_balance int How many of accounts_matched hold a non-zero balance. A count, never a sum
failures array One entry per failure, with an optional logins array naming the accounts at fault

After an applied run matched = deleted + failed.

Response Statuses

Status Condition
200 Dry run, or an applied run with no failures
207 Applied, at least one record deleted, some failed
403 delete_accounts: true without the account rights, or the caller context could not be resolved
409 Applied, nothing was deleted

A 409 has two readings: matched: 0 means the filter selected nobody, while a non-zero failed equal to matched means every selected record was blocked.

Errors

HTTP Error Description
400 INVALID_DATA Request validation failed
403 RET_NOT_ENOUGH_RIGHTS Missing permission, missing scope, or the record is outside the caller's visibility
404 RET_NOT_FOUND No customer with that identifier exists

Every error carries a message field with free-form text. Its contents are not part of the contract; branch on error.