Skip to content

staff.clients ​

19 methods on staff.clients. Each returns the answer's data and throws NoviqaError on a failed answer.

list ​

GET/admin/v1/clients

List clients

One page of the clients the caller reaches, newest first (by id). A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found. page is 1-based (default 1); limit defaults to 100 and is capped at 1000. total counts every match. Linked accounts are not included; read one client for them.

More details

Rights: the staff member needs every one of: clients.view.

Parameters
statusstring · query
Only clients with this status; empty = any.
unregistered registered not_interested incompleted completed information rejected approved funded active inactive suspended closed terminated
qstring · query
#<id> for one client, otherwise part of the full name, company name, e-mail or phone (any case).
pageinteger · query
1-based page; default 1.
limitinteger · query
Rows per page; default 100, at most 1000.
Returns
Promise<clientPage>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.list({
  status: "unregistered",
  q: "string",
  page: 1
})
bash
curl -X GET "$NOVIQA_API_URL/admin/v1/clients?status=unregistered&q=string&page=1" \
  -H "Authorization: Bearer $NOVIQA_TOKEN"
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": {
    "items": [
      {
        "approved_at": "2026-09-25T10:15:00Z",
        "approved_by": 1,
        "assigned_manager": 1,
        "city": "London",
        "comment": "Deposit via bank",
        "company_name": "Smith Trading Ltd",
        "country": "United Kingdom",
        "created_at": "2026-09-25T10:15:00Z",
        "created_by": 1,
        "details": {},
        "email": "ann@example.com",
        "first_name": "Ann"
      }
    ],
    "page": 1,
    "total": 1
  },
  "request_id": "5b7f2c1e"
}
ts
staff.clients.list(query?: { status?, q?, page?, limit? }, options?: RequestOptions): Promise<http.clientPage>

create ​

POST/admin/v1/clients

Create a client

Adds a client record by hand (origin staff, created by the caller) and answers it with its (empty) linked accounts. Allowed fields: type, status, kyc_status, assigned_manager, preferred_group, first_name, last_name, email, phone, country, city, company_name, comment, details; anything else is refused. Defaults: type not_specified, status registered, kyc_status undefined. A first name, last name or company name is required. Limits: names, country, city 64 characters, company 128, e-mail 128 (a plain valid address, stored lower case, unique), phone 32 (digits, spaces and + ( ) -), comment 1024, each details text 256; no control characters; dates YYYY-MM-DD (1900-2200); amounts not negative. preferred_group must be a trading group in the caller's scope; assigned_manager a staff login. Setting status approved or any kyc_status other than undefined needs clients.verify. Writes a journal line.

More details

Rights: the staff member needs every one of: clients.create; and every one of: clients.view.

Request body
approved_atstring
UTC time, RFC 3339.
approved_byinteger
Login is the numeric identity of every account, trader or staff.
assigned_managerinteger
0 = none Login is the numeric identity of every account, trader or staff.
citystring
commentstring
company_namestring
countrystring
created_atstring
UTC time, RFC 3339.
created_byinteger
Login is the numeric identity of every account, trader or staff.
detailsDetails
Details is the rest of the profile. Dates are YYYY-MM-DD, amounts are decimals.
emailstring
first_namestring
idinteger
kyc_statusstring
last_namestring
originstring
staff, demo or real; set once
phonestring
preferred_groupstring
"" = none
statusstring
typestring
updated_atstring
UTC time, RFC 3339.
versioninteger
Returns
Promise<Detail>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.csrf_invalid: request refused: reload the page and try again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
404not_found: not found
409conflict: already exists
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.create({
  assigned_manager: 1001,
  city: "London",
  country: "United Kingdom",
  details: {
    annual_income: "85000.00",
    birth_date: "1990-04-12"
  },
  email: "ann@example.com",
  first_name: "Ann",
  last_name: "Smith",
  phone: "+44 20 7946 0000",
  preferred_group: "real\\standard",
  type: "individual"
})
bash
curl -X POST "$NOVIQA_API_URL/admin/v1/clients" \
  -H "Authorization: Bearer $NOVIQA_TOKEN" \
  -H "Content-Type: application/json" \
  --data-raw '{
  "assigned_manager": 1001,
  "city": "London",
  "country": "United Kingdom",
  "details": {
    "annual_income": "85000.00",
    "birth_date": "1990-04-12"
  },
  "email": "ann@example.com",
  "first_name": "Ann",
  "last_name": "Smith",
  "phone": "+44 20 7946 0000",
  "preferred_group": "real\\standard",
  "type": "individual"
}'
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": {
    "accounts": [
      {
        "balance": "1000.00",
        "enabled": true,
        "group": "real\\standard",
        "leverage": 100,
        "login": 1001,
        "name": "Ann Smith"
      }
    ],
    "approved_at": "2026-09-25T10:15:00Z",
    "approved_by": 1,
    "assigned_manager": 1,
    "city": "London",
    "comment": "Deposit via bank",
    "company_name": "Smith Trading Ltd",
    "country": "United Kingdom",
    "created_at": "2026-09-25T10:15:00Z",
    "created_by": 1,
    "details": {
      "address": "1 High St",
      "allocation_id": 1,
      "annual_deposit": "1.08452",
      "annual_income": "1.08452",
      "birth_date": "string",
      "citizenship": "string",
      "close_date": "string",
      "contact_preferred": "string",
      "document_comment": "string",
      "document_expires": "string",
      "document_issued": "string",
      "document_number": "string"
    },
    "email": "ann@example.com"
  },
  "request_id": "5b7f2c1e"
}
ts
staff.clients.create(body: client.Client, options?: RequestOptions): Promise<client.Detail>

count ​

GET/admin/v1/clients/count

Count clients

How many clients the caller reaches with the same filters as the list. A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found.

More details

Rights: the staff member needs every one of: clients.view.

Parameters
statusstring · query
Only clients with this status; empty = any.
unregistered registered not_interested incompleted completed information rejected approved funded active inactive suspended closed terminated
qstring · query
#<id> for one client, otherwise part of the full name, company name, e-mail or phone (any case).
Returns
Promise<count>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.count({
  status: "unregistered",
  q: "string"
})
bash
curl -X GET "$NOVIQA_API_URL/admin/v1/clients/count?status=unregistered&q=string" \
  -H "Authorization: Bearer $NOVIQA_TOKEN"
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": {
    "total": 1
  },
  "request_id": "5b7f2c1e"
}
ts
staff.clients.count(query?: { status?, q? }, options?: RequestOptions): Promise<http.count>

retrieve ​

GET/admin/v1/clients/{id}

Get a client

One client with its linked trading accounts (by login). A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found.

More details

Rights: the staff member needs every one of: clients.view.

Parameters
idinteger · pathrequired
Client id.
Returns
Promise<Detail>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
404not_found: not found
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.retrieve(1)
bash
curl -X GET "$NOVIQA_API_URL/admin/v1/clients/1" \
  -H "Authorization: Bearer $NOVIQA_TOKEN"
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": {
    "accounts": [
      {
        "balance": "1000.00",
        "enabled": true,
        "group": "real\\standard",
        "leverage": 100,
        "login": 1001,
        "name": "Ann Smith"
      }
    ],
    "approved_at": "2026-09-25T10:15:00Z",
    "approved_by": 1,
    "assigned_manager": 1,
    "city": "London",
    "comment": "Deposit via bank",
    "company_name": "Smith Trading Ltd",
    "country": "United Kingdom",
    "created_at": "2026-09-25T10:15:00Z",
    "created_by": 1,
    "details": {
      "address": "1 High St",
      "allocation_id": 1,
      "annual_deposit": "1.08452",
      "annual_income": "1.08452",
      "birth_date": "string",
      "citizenship": "string",
      "close_date": "string",
      "contact_preferred": "string",
      "document_comment": "string",
      "document_expires": "string",
      "document_issued": "string",
      "document_number": "string"
    },
    "email": "ann@example.com"
  },
  "request_id": "5b7f2c1e"
}
ts
staff.clients.retrieve(id: number, options?: RequestOptions): Promise<client.Detail>

update ​

PATCH/admin/v1/clients/{id}

Change a client

Changes the fields sent (same fields and limits as create); version (the one last read) is required, a stale one answers conflict. details is replaced as a whole object. A new preferred group must be a trading group in the caller's scope; a new assigned manager a staff login. Moving status to or from approved, or changing kyc_status, needs clients.verify. Nothing changed = answered as it was, no journal line; otherwise one journal line lists the changed fields. A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found.

More details

Rights: the staff member needs every one of: clients.edit; and every one of: clients.view.

Parameters
idinteger · pathrequired
Client id.
Request body
approved_atstring
UTC time, RFC 3339.
approved_byinteger
Login is the numeric identity of every account, trader or staff.
assigned_managerinteger
0 = none Login is the numeric identity of every account, trader or staff.
citystring
commentstring
company_namestring
countrystring
created_atstring
UTC time, RFC 3339.
created_byinteger
Login is the numeric identity of every account, trader or staff.
detailsDetails
Details is the rest of the profile. Dates are YYYY-MM-DD, amounts are decimals.
emailstring
first_namestring
idinteger
kyc_statusstring
last_namestring
originstring
staff, demo or real; set once
phonestring
preferred_groupstring
"" = none
statusstring
typestring
updated_atstring
UTC time, RFC 3339.
versioninteger
Returns
Promise<Detail>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.csrf_invalid: request refused: reload the page and try again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
404not_found: not found
409conflict: already exists
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.update(1, {
  phone: "+44 20 7946 0001",
  status: "information",
  version: 4
})
bash
curl -X PATCH "$NOVIQA_API_URL/admin/v1/clients/1" \
  -H "Authorization: Bearer $NOVIQA_TOKEN" \
  -H "Content-Type: application/json" \
  --data-raw '{
  "phone": "+44 20 7946 0001",
  "status": "information",
  "version": 4
}'
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": {
    "accounts": [
      {
        "balance": "1000.00",
        "enabled": true,
        "group": "real\\standard",
        "leverage": 100,
        "login": 1001,
        "name": "Ann Smith"
      }
    ],
    "approved_at": "2026-09-25T10:15:00Z",
    "approved_by": 1,
    "assigned_manager": 1,
    "city": "London",
    "comment": "Deposit via bank",
    "company_name": "Smith Trading Ltd",
    "country": "United Kingdom",
    "created_at": "2026-09-25T10:15:00Z",
    "created_by": 1,
    "details": {
      "address": "1 High St",
      "allocation_id": 1,
      "annual_deposit": "1.08452",
      "annual_income": "1.08452",
      "birth_date": "string",
      "citizenship": "string",
      "close_date": "string",
      "contact_preferred": "string",
      "document_comment": "string",
      "document_expires": "string",
      "document_issued": "string",
      "document_number": "string"
    },
    "email": "ann@example.com"
  },
  "request_id": "5b7f2c1e"
}
ts
staff.clients.update(id: number, body: client.Client, options?: RequestOptions): Promise<client.Detail>

delete ​

DELETE/admin/v1/clients/{id}

Delete a client

Removes the client with its documents; its trading accounts stay and lose the link. Writes a journal line. A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found.

More details

Rights: the staff member needs every one of: clients.delete; and every one of: clients.view.

Parameters
idinteger · pathrequired
Client id.
Returns
Promise<null>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.csrf_invalid: request refused: reload the page and try again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
404not_found: not found
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.delete(1)
bash
curl -X DELETE "$NOVIQA_API_URL/admin/v1/clients/1" \
  -H "Authorization: Bearer $NOVIQA_TOKEN"
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": null,
  "request_id": "5b7f2c1e"
}
ts
staff.clients.delete(id: number, options?: RequestOptions): Promise<null>

linkAccount ​

POST/admin/v1/clients/{id}/accounts

Link a trading account

Links the trading account login (required, positive) to the client and answers the client with its accounts. The account must be in a trading group in the caller's scope. Already linked here = no change; linked to another client = conflict (unlink it there first). Writes a journal line. A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found.

More details

Rights: the staff member needs every one of: clients.edit, accounts.edit; and every one of: clients.view.

Parameters
idinteger · pathrequired
Client id.
Request body
logininteger
Returns
Promise<Detail>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.csrf_invalid: request refused: reload the page and try again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
404not_found: not found
409conflict: already exists
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.linkAccount(1, {
  login: 100023
})
bash
curl -X POST "$NOVIQA_API_URL/admin/v1/clients/1/accounts" \
  -H "Authorization: Bearer $NOVIQA_TOKEN" \
  -H "Content-Type: application/json" \
  --data-raw '{
  "login": 100023
}'
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": {
    "accounts": [
      {
        "balance": "1000.00",
        "enabled": true,
        "group": "real\\standard",
        "leverage": 100,
        "login": 1001,
        "name": "Ann Smith"
      }
    ],
    "approved_at": "2026-09-25T10:15:00Z",
    "approved_by": 1,
    "assigned_manager": 1,
    "city": "London",
    "comment": "Deposit via bank",
    "company_name": "Smith Trading Ltd",
    "country": "United Kingdom",
    "created_at": "2026-09-25T10:15:00Z",
    "created_by": 1,
    "details": {
      "address": "1 High St",
      "allocation_id": 1,
      "annual_deposit": "1.08452",
      "annual_income": "1.08452",
      "birth_date": "string",
      "citizenship": "string",
      "close_date": "string",
      "contact_preferred": "string",
      "document_comment": "string",
      "document_expires": "string",
      "document_issued": "string",
      "document_number": "string"
    },
    "email": "ann@example.com"
  },
  "request_id": "5b7f2c1e"
}
ts
staff.clients.linkAccount(id: number, body: http.linkRequest, options?: RequestOptions): Promise<client.Detail>

unlinkAccount ​

DELETE/admin/v1/clients/{id}/accounts/{login}

Unlink a trading account

Detaches one of the client's accounts (the account itself stays) and answers the client with its remaining accounts. The account's group must be in the caller's scope; an account not linked to this client is not found. Writes a journal line. A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found.

More details

Rights: the staff member needs every one of: clients.edit, accounts.edit; and every one of: clients.view.

Parameters
idinteger · pathrequired
Client id.
logininteger · pathrequired
Trading account login.
Returns
Promise<Detail>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.csrf_invalid: request refused: reload the page and try again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
404not_found: not found
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.unlinkAccount(1, 1001)
bash
curl -X DELETE "$NOVIQA_API_URL/admin/v1/clients/1/accounts/1001" \
  -H "Authorization: Bearer $NOVIQA_TOKEN"
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": {
    "accounts": [
      {
        "balance": "1000.00",
        "enabled": true,
        "group": "real\\standard",
        "leverage": 100,
        "login": 1001,
        "name": "Ann Smith"
      }
    ],
    "approved_at": "2026-09-25T10:15:00Z",
    "approved_by": 1,
    "assigned_manager": 1,
    "city": "London",
    "comment": "Deposit via bank",
    "company_name": "Smith Trading Ltd",
    "country": "United Kingdom",
    "created_at": "2026-09-25T10:15:00Z",
    "created_by": 1,
    "details": {
      "address": "1 High St",
      "allocation_id": 1,
      "annual_deposit": "1.08452",
      "annual_income": "1.08452",
      "birth_date": "string",
      "citizenship": "string",
      "close_date": "string",
      "contact_preferred": "string",
      "document_comment": "string",
      "document_expires": "string",
      "document_issued": "string",
      "document_number": "string"
    },
    "email": "ann@example.com"
  },
  "request_id": "5b7f2c1e"
}
ts
staff.clients.unlinkAccount(id: number, login: number, options?: RequestOptions): Promise<client.Detail>

approve ​

POST/admin/v1/clients/{id}/approve

Approve a client

Sets status approved and kyc_status approved, and records the caller and time as approver. The body is optional; a comment (at most 1024 characters) is appended to the client comment on a new line (the result must also fit 1024). Writes a journal line. A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found.

More details

Rights: the staff member needs every one of: clients.verify; and every one of: clients.view.

Parameters
idinteger · pathrequired
Client id.
Request body
commentstring
Returns
Promise<Detail>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.csrf_invalid: request refused: reload the page and try again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
404not_found: not found
409conflict: already exists
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.approve(1, {
  comment: "Documents checked"
})
bash
curl -X POST "$NOVIQA_API_URL/admin/v1/clients/1/approve" \
  -H "Authorization: Bearer $NOVIQA_TOKEN" \
  -H "Content-Type: application/json" \
  --data-raw '{
  "comment": "Documents checked"
}'
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": {
    "accounts": [
      {
        "balance": "1000.00",
        "enabled": true,
        "group": "real\\standard",
        "leverage": 100,
        "login": 1001,
        "name": "Ann Smith"
      }
    ],
    "approved_at": "2026-09-25T10:15:00Z",
    "approved_by": 1,
    "assigned_manager": 1,
    "city": "London",
    "comment": "Deposit via bank",
    "company_name": "Smith Trading Ltd",
    "country": "United Kingdom",
    "created_at": "2026-09-25T10:15:00Z",
    "created_by": 1,
    "details": {
      "address": "1 High St",
      "allocation_id": 1,
      "annual_deposit": "1.08452",
      "annual_income": "1.08452",
      "birth_date": "string",
      "citizenship": "string",
      "close_date": "string",
      "contact_preferred": "string",
      "document_comment": "string",
      "document_expires": "string",
      "document_issued": "string",
      "document_number": "string"
    },
    "email": "ann@example.com"
  },
  "request_id": "5b7f2c1e"
}
ts
staff.clients.approve(id: number, body: client.Decision, options?: RequestOptions): Promise<client.Detail>

listComments ​

GET/admin/v1/clients/{id}/comments

List a client's comments

Staff comments about the client and its documents, newest first; deleted comments are left out. A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found.

More details

Rights: the staff member needs every one of: comments.view; and every one of: clients.view.

Parameters
idinteger · pathrequired
Client id.
Returns
Promise<Comment[]>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
404not_found: not found
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.listComments(1)
bash
curl -X GET "$NOVIQA_API_URL/admin/v1/clients/1/comments" \
  -H "Authorization: Bearer $NOVIQA_TOKEN"
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": [
    {
      "author": 1,
      "call_result": "string",
      "client_id": 1,
      "created_at": "2026-09-25T10:15:00Z",
      "document_id": 1,
      "id": 1,
      "important": true,
      "kind": "string",
      "text": "string"
    }
  ],
  "request_id": "5b7f2c1e"
}
ts
staff.clients.listComments(id: number, options?: RequestOptions): Promise<client.Comment[]>

createComments ​

POST/admin/v1/clients/{id}/comments

Add a client comment

Records a comment by the caller. text is required (at most 4000 characters, trimmed; line breaks and tabs allowed, other control characters not). kind is note (default), record, call or auto; call_result (no_answer, wrong_number, not_interested, successful) only with kind call. document_id > 0 ties it to one of the client's documents (0 = the client itself). Writes a journal line. A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found.

More details

Rights: the staff member needs every one of: comments.create; and every one of: clients.view.

Parameters
idinteger · pathrequired
Client id.
Request body
call_resultstring
document_idinteger
importantboolean
kindstring
textstring
Returns
Promise<Comment>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.csrf_invalid: request refused: reload the page and try again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
404not_found: not found
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.createComments(1, {
  call_result: "successful",
  important: true,
  kind: "call",
  text: "Confirmed the address by phone."
})
bash
curl -X POST "$NOVIQA_API_URL/admin/v1/clients/1/comments" \
  -H "Authorization: Bearer $NOVIQA_TOKEN" \
  -H "Content-Type: application/json" \
  --data-raw '{
  "call_result": "successful",
  "important": true,
  "kind": "call",
  "text": "Confirmed the address by phone."
}'
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": {
    "author": 1,
    "call_result": "string",
    "client_id": 1,
    "created_at": "2026-09-25T10:15:00Z",
    "document_id": 1,
    "id": 1,
    "important": true,
    "kind": "string",
    "text": "string"
  },
  "request_id": "5b7f2c1e"
}
ts
staff.clients.createComments(id: number, body: client.NewComment, options?: RequestOptions): Promise<client.Comment>

deleteComments ​

DELETE/admin/v1/clients/{id}/comments/{comment}

Delete a client comment

Hides the comment: it stays stored but no longer shows. Deleting it again is not found. Writes a journal line. A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found.

More details

Rights: the staff member needs every one of: comments.delete; and every one of: clients.view.

Parameters
idinteger · pathrequired
Client id.
commentinteger · pathrequired
Comment id.
Returns
Promise<null>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.csrf_invalid: request refused: reload the page and try again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
404not_found: not found
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.deleteComments(1, 1)
bash
curl -X DELETE "$NOVIQA_API_URL/admin/v1/clients/1/comments/1" \
  -H "Authorization: Bearer $NOVIQA_TOKEN"
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": null,
  "request_id": "5b7f2c1e"
}
ts
staff.clients.deleteComments(id: number, comment: number, options?: RequestOptions): Promise<null>

listDocuments ​

GET/admin/v1/clients/{id}/documents

List a client's documents

The client's KYC documents (their data only; files are not stored), oldest first. A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found.

More details

Rights: the staff member needs every one of: documents.view; and every one of: clients.view.

Parameters
idinteger · pathrequired
Client id.
Returns
Promise<Document[]>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
404not_found: not found
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.listDocuments(1)
bash
curl -X GET "$NOVIQA_API_URL/admin/v1/clients/1/documents" \
  -H "Authorization: Bearer $NOVIQA_TOKEN"
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": [
    {
      "approved_at": "2026-09-25T10:15:00Z",
      "approved_by": 1,
      "client_id": 1,
      "comment": "Deposit via bank",
      "created_at": "2026-09-25T10:15:00Z",
      "expires": "string",
      "id": 1,
      "issued": "string",
      "name": "Ann Smith",
      "number": "string",
      "status": "active",
      "type": "string"
    }
  ],
  "request_id": "5b7f2c1e"
}
ts
staff.clients.listDocuments(id: number, options?: RequestOptions): Promise<client.Document[]>

createDocuments ​

POST/admin/v1/clients/{id}/documents

Add a client document

Records a document's data; it starts with status new. type is required, one of passport, driver_license, national_id, proof_of_address, other. name, number and comment are at most 256 characters without control characters; issued and expires are YYYY-MM-DD (1900-2200) or empty. Unknown fields are refused. Writes a journal line. A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found.

More details

Rights: the staff member needs every one of: documents.create; and every one of: clients.view.

Parameters
idinteger · pathrequired
Client id.
Request body
commentstring
expiresstring
issuedstring
namestring
numberstring
typestring
Returns
Promise<Document>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.csrf_invalid: request refused: reload the page and try again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
404not_found: not found
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.createDocuments(1, {
  comment: "Scan received by e-mail",
  expires: "2030-02-28",
  issued: "2020-03-01",
  name: "Ann Smith",
  number: "123456789",
  type: "passport"
})
bash
curl -X POST "$NOVIQA_API_URL/admin/v1/clients/1/documents" \
  -H "Authorization: Bearer $NOVIQA_TOKEN" \
  -H "Content-Type: application/json" \
  --data-raw '{
  "comment": "Scan received by e-mail",
  "expires": "2030-02-28",
  "issued": "2020-03-01",
  "name": "Ann Smith",
  "number": "123456789",
  "type": "passport"
}'
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": {
    "approved_at": "2026-09-25T10:15:00Z",
    "approved_by": 1,
    "client_id": 1,
    "comment": "Deposit via bank",
    "created_at": "2026-09-25T10:15:00Z",
    "expires": "string",
    "id": 1,
    "issued": "string",
    "name": "Ann Smith",
    "number": "string",
    "status": "active",
    "type": "string"
  },
  "request_id": "5b7f2c1e"
}
ts
staff.clients.createDocuments(id: number, body: client.NewDocument, options?: RequestOptions): Promise<client.Document>

updateDocuments ​

PUT/admin/v1/clients/{id}/documents/{doc}

Edit document metadata

Replaces document metadata using the same validation as creation. Approval and client ownership cannot be supplied. Files are not stored. A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found.

More details

Rights: the staff member needs every one of: documents.edit; and every one of: clients.view.

Parameters
idinteger · pathrequired
Client id.
docinteger · pathrequired
Document id.
Request body
commentstring
expiresstring
issuedstring
namestring
numberstring
typestring
Returns
Promise<Document>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.csrf_invalid: request refused: reload the page and try again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
404not_found: not found
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.updateDocuments(1, 1, {
  comment: "Deposit via bank",
  expires: "string",
  issued: "string",
  name: "Ann Smith",
  number: "string",
  type: "string"
})
bash
curl -X PUT "$NOVIQA_API_URL/admin/v1/clients/1/documents/1" \
  -H "Authorization: Bearer $NOVIQA_TOKEN" \
  -H "Content-Type: application/json" \
  --data-raw '{
  "comment": "Deposit via bank",
  "expires": "string",
  "issued": "string",
  "name": "Ann Smith",
  "number": "string",
  "type": "string"
}'
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": {
    "approved_at": "2026-09-25T10:15:00Z",
    "approved_by": 1,
    "client_id": 1,
    "comment": "Deposit via bank",
    "created_at": "2026-09-25T10:15:00Z",
    "expires": "string",
    "id": 1,
    "issued": "string",
    "name": "Ann Smith",
    "number": "string",
    "status": "active",
    "type": "string"
  },
  "request_id": "5b7f2c1e"
}
ts
staff.clients.updateDocuments(id: number, doc: number, body: client.NewDocument, options?: RequestOptions): Promise<client.Document>

patchDocuments ​

PATCH/admin/v1/clients/{id}/documents/{doc}

Approve or reject a document

Sets the document's status (required: new, approved or rejected). approved or rejected record the caller and time; new clears them. A non-empty comment (at most 256 characters) replaces the document comment. No version. Writes a journal line. A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found.

More details

Rights: the staff member needs every one of: clients.verify; and every one of: documents.edit; and every one of: clients.view.

Parameters
idinteger · pathrequired
Client id.
docinteger · pathrequired
Document id.
Request body
commentstring
statusstring
Returns
Promise<Document>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.csrf_invalid: request refused: reload the page and try again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
404not_found: not found
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.patchDocuments(1, 1, {
  comment: "Valid until 2030",
  status: "approved"
})
bash
curl -X PATCH "$NOVIQA_API_URL/admin/v1/clients/1/documents/1" \
  -H "Authorization: Bearer $NOVIQA_TOKEN" \
  -H "Content-Type: application/json" \
  --data-raw '{
  "comment": "Valid until 2030",
  "status": "approved"
}'
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": {
    "approved_at": "2026-09-25T10:15:00Z",
    "approved_by": 1,
    "client_id": 1,
    "comment": "Deposit via bank",
    "created_at": "2026-09-25T10:15:00Z",
    "expires": "string",
    "id": 1,
    "issued": "string",
    "name": "Ann Smith",
    "number": "string",
    "status": "active",
    "type": "string"
  },
  "request_id": "5b7f2c1e"
}
ts
staff.clients.patchDocuments(id: number, doc: number, body: client.DocumentDecision, options?: RequestOptions): Promise<client.Document>

deleteDocuments ​

DELETE/admin/v1/clients/{id}/documents/{doc}

Delete document metadata

Removes the scoped client's document metadata. Comments remain, with the document link cleared. A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found.

More details

Rights: the staff member needs every one of: documents.delete; and every one of: clients.view.

Parameters
idinteger · pathrequired
Client id.
docinteger · pathrequired
Document id.
Returns
Promise<null>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.csrf_invalid: request refused: reload the page and try again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
404not_found: not found
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.deleteDocuments(1, 1)
bash
curl -X DELETE "$NOVIQA_API_URL/admin/v1/clients/1/documents/1" \
  -H "Authorization: Bearer $NOVIQA_TOKEN"
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": null,
  "request_id": "5b7f2c1e"
}
ts
staff.clients.deleteDocuments(id: number, doc: number, options?: RequestOptions): Promise<null>

history ​

GET/admin/v1/clients/{id}/history

Client history

Journal lines about the client and its linked accounts, newest first. Lines stay limited to groups in the caller's scope and to the caller's journal depth (logs_months). Page back by sending the smallest line id you have as before. A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found.

More details

Rights: the staff member needs every one of: server.logs; and every one of: clients.view.

Parameters
idinteger · pathrequired
Client id.
beforeinteger · query
Only lines with a smaller id; 0 or absent = from the newest.
limitinteger · query
Lines per page; default 100. A value above 500 (or 0 or less) falls back to 100.
Returns
Promise<Entry[]>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
404not_found: not found
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.history(1, {
  limit: 1
})
bash
curl -X GET "$NOVIQA_API_URL/admin/v1/clients/1/history?limit=1" \
  -H "Authorization: Bearer $NOVIQA_TOKEN"
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": [
    {
      "action": "string",
      "actor_ip": "string",
      "actor_login": 1,
      "at": "2026-09-25T10:15:00Z",
      "category": "auth",
      "channel": "string",
      "correlation_id": "string",
      "detail_ref": {
        "at": "2026-09-25T10:15:00Z",
        "line_id": "3f2a9c1e-8b7d-4e6f-a5c4-1b2d3e4f5a6b"
      },
      "details": null,
      "id": 1,
      "level": "debug",
      "line_id": "3f2a9c1e-8b7d-4e6f-a5c4-1b2d3e4f5a6b"
    }
  ],
  "request_id": "5b7f2c1e"
}
ts
staff.clients.history(id: number, query?: { before?, limit? }, options?: RequestOptions): Promise<journal.Entry[]>

reject ​

POST/admin/v1/clients/{id}/reject

Reject a client

Sets status rejected and kyc_status declined; an earlier approver stays recorded. The body is optional; a comment (at most 1024 characters) is appended to the client comment on a new line. Writes a journal line. A client is reachable when it is assigned to or was created by the caller, or its preferred group or the group of one of its linked accounts is a trading group in the caller's group scope; any other client reads as not found.

More details

Rights: the staff member needs every one of: clients.verify; and every one of: clients.view.

Parameters
idinteger · pathrequired
Client id.
Request body
commentstring
Returns
Promise<Detail>
The answer's data.
Errors
400invalid_input: invalid input
401auth.session_expired: session expired, sign in again
403auth.csrf_invalid: request refused: reload the page and try again
403auth.invalid_terminal: this terminal cannot be used here
403auth.otp_enrol_required: your group requires one-time codes: set them up to continue
403auth.password_change_required: you must change your password first
403forbidden: you do not have access to this action
404not_found: not found
409conflict: already exists
500internal: something went wrong
ts
import { staff } from "@/lib/noviqa"

const data = await staff.clients.reject(1, {
  comment: "Proof of address missing"
})
bash
curl -X POST "$NOVIQA_API_URL/admin/v1/clients/1/reject" \
  -H "Authorization: Bearer $NOVIQA_TOKEN" \
  -H "Content-Type: application/json" \
  --data-raw '{
  "comment": "Proof of address missing"
}'
json
{
  "success": true,
  "code": "ok",
  "message": "done",
  "data": {
    "accounts": [
      {
        "balance": "1000.00",
        "enabled": true,
        "group": "real\\standard",
        "leverage": 100,
        "login": 1001,
        "name": "Ann Smith"
      }
    ],
    "approved_at": "2026-09-25T10:15:00Z",
    "approved_by": 1,
    "assigned_manager": 1,
    "city": "London",
    "comment": "Deposit via bank",
    "company_name": "Smith Trading Ltd",
    "country": "United Kingdom",
    "created_at": "2026-09-25T10:15:00Z",
    "created_by": 1,
    "details": {
      "address": "1 High St",
      "allocation_id": 1,
      "annual_deposit": "1.08452",
      "annual_income": "1.08452",
      "birth_date": "string",
      "citizenship": "string",
      "close_date": "string",
      "contact_preferred": "string",
      "document_comment": "string",
      "document_expires": "string",
      "document_issued": "string",
      "document_number": "string"
    },
    "email": "ann@example.com"
  },
  "request_id": "5b7f2c1e"
}
ts
staff.clients.reject(id: number, body: client.Decision, options?: RequestOptions): Promise<client.Detail>