Appearance
trader.mail
9 methods on trader.mail. Each returns the answer's data and throws NoviqaError on a failed answer.
list
GET
/trader/v1/mailList the own mailbox (trader)
One page of the caller's own folder: inbox (default), sent or draft. Inbox and sent come one row per thread, newest thread first: the row is the thread's newest message, thread_count is how many messages of the thread the folder holds and read is false while any of them is unread; drafts come one row each, newest first. total counts threads (drafts: drafts), unread counts unread messages. page is 1-based; limit defaults to 50, values outside 1-200 fall back to 50.
More details
With thread (a thread_id) the answer is instead a plain array of every inbox and sent message of that thread, oldest first, and all of them are marked read; folder, page and limit are ignored.
A trader account whose group has mail switched off gets an empty page with enabled false (an empty array for thread); staff always have a mailbox.
Parameters
X-HST-Accountstring · headerIntended signed-in login captured by the browser tab before dispatch and retained across retries. A mismatch returns auth.account_changed (409) before mutation or refresh rotation. This never selects or authorizes an account; omission preserves existing API client compatibility.
folderstring · querythreadstring · queryone thread across inbox and sent, oldest first
pageinteger · querylimitinteger · queryReturns
Promise<Page>The answer's
data.Errors
400
invalid_input: invalid input401
auth.session_expired: session expired, sign in again403
auth.invalid_terminal: this terminal cannot be used here403
auth.otp_enrol_required: your group requires one-time codes: set them up to continue403
auth.password_change_required: you must change your password first409
auth.account_changed: the signed-in account changed; sign in again before continuing500
internal: something went wrongts
import { trader } from "@/lib/noviqa"
const data = await trader.mail.list({
folder: "string",
thread: "string",
page: 1
})bash
curl -X GET "$NOVIQA_API_URL/trader/v1/mail?folder=string&thread=string&page=1" \
-H "Authorization: Bearer $NOVIQA_TOKEN"json
{
"success": true,
"code": "ok",
"message": "done",
"data": {
"enabled": true,
"items": [
{
"attachments": [
{}
],
"body": "string",
"created_at": "2026-09-25T10:15:00Z",
"draft": {},
"folder": "string",
"from": 1,
"from_name": "string",
"id": 1,
"message_id": "3f2a9c1e-8b7d-4e6f-a5c4-1b2d3e4f5a6b",
"read": true,
"recipients": "string",
"subject": "string"
}
],
"page": 1,
"total": 1,
"unread": 1
},
"request_id": "5b7f2c1e"
}ts
trader.mail.list(query?: { folder?, thread?, page?, limit? }, options?: RequestOptions): Promise<mail.Page>create
POST
/trader/v1/mailWrite to a staff mailbox
Sends the account's message to one of its mailboxes: to must be a login from GET /trader/v1/mailboxes (staff with the mailbox right whose scope covers the account's group). subject is required (1-256 characters, one line), body is plain text up to 64 KiB. Attachments: up to 5 files per message, each 1 byte to 1 MB, 2 MB together (files already uploaded onto the draft count too); the name must be a plain file name of up to 128 characters (no path, quotes or line breaks) ending in .png, .jpg, .jpeg, .bmp, .gif, .zip, .7z, .doc, .docx, .xls, .xlsx, .odt, .rtf, .csv, .txt, .log or .pdf. In JSON bodies content is the file base64-encoded; the whole request may be 4 MB at most. reply_to (a mail the account holds) joins its thread; draft_id sends from that draft (its files go along, the draft is removed). Refused when the account's group has mail switched off.
More details
Answers the account's sent copy; the staff member gets an inbox copy and a mail socket message; a journal line is written. Not idempotent.
Parameters
X-HST-Accountstring · headerIntended signed-in login captured by the browser tab before dispatch and retained across retries. A mismatch returns auth.account_changed (409) before mutation or refresh rotation. This never selects or authorizes an account; omission preserves existing API client compatibility.
Request body
attachmentsNewAttachment_input[]bodystringdraft_idintegerreply_tointegersubjectstringtointegerLogin is the numeric identity of every account, trader or staff.
Returns
Promise<Mail>The answer's
data.Errors
400
invalid_input: invalid input401
auth.session_expired: session expired, sign in again403
auth.csrf_invalid: request refused: reload the page and try again403
auth.invalid_terminal: this terminal cannot be used here403
auth.otp_enrol_required: your group requires one-time codes: set them up to continue403
auth.password_change_required: you must change your password first403
forbidden: you do not have access to this action404
not_found: not found409
auth.account_changed: the signed-in account changed; sign in again before continuing500
internal: something went wrongts
import { trader } from "@/lib/noviqa"
const data = await trader.mail.create({
body: "Hello, when will my withdrawal arrive?",
subject: "Withdrawal question",
to: 1000
})bash
curl -X POST "$NOVIQA_API_URL/trader/v1/mail" \
-H "Authorization: Bearer $NOVIQA_TOKEN" \
-H "Content-Type: application/json" \
--data-raw '{
"body": "Hello, when will my withdrawal arrive?",
"subject": "Withdrawal question",
"to": 1000
}'json
{
"success": true,
"code": "ok",
"message": "done",
"data": {
"attachments": [
{
"id": 1,
"name": "Ann Smith",
"size": 1
}
],
"body": "string",
"created_at": "2026-09-25T10:15:00Z",
"draft": {
"email": "ann@example.com",
"reply_to": 1,
"to": 1,
"to_group": "string",
"to_logins": [
1
]
},
"folder": "string",
"from": 1,
"from_name": "string",
"id": 1,
"message_id": "3f2a9c1e-8b7d-4e6f-a5c4-1b2d3e4f5a6b",
"read": true,
"recipients": "string",
"subject": "string"
},
"request_id": "5b7f2c1e"
}ts
trader.mail.create(body: mail.TraderMessage, options?: RequestOptions): Promise<models.Mail>drafts
POST
/trader/v1/mail/draftsSave a draft (trader)
Stores what the caller is writing in the draft folder and answers it as saved. id 0 (or left out) makes a new draft; an id of one of the caller's drafts rewrites it (same as PUT). Staff address a draft with to_logins (up to 1000) or to_group (a group mask, up to 128 characters) and may set email; a trader account uses to (a staff mailbox login from GET /trader/v1/mailboxes) and the staff fields are ignored. reply_to (a non-draft mail the caller holds) keeps the draft in that thread. Nothing is checked against scope or mailboxes here — sending does that — and the subject may still be empty; it must fit 256 characters on one line and the body 64 KiB. Upload files with POST …/mail/drafts/{id}/attachments. A trader whose group has mail switched off is refused.
Parameters
X-HST-Accountstring · headerIntended signed-in login captured by the browser tab before dispatch and retained across retries. A mismatch returns auth.account_changed (409) before mutation or refresh rotation. This never selects or authorizes an account; omission preserves existing API client compatibility.
Request body
bodystringemailbooleanidintegerreply_tointegersubjectstringtointegerLogin is the numeric identity of every account, trader or staff.
to_groupstringto_loginsinteger[]Returns
Promise<Mail>The answer's
data.Errors
400
invalid_input: invalid input401
auth.session_expired: session expired, sign in again403
auth.csrf_invalid: request refused: reload the page and try again403
auth.invalid_terminal: this terminal cannot be used here403
auth.otp_enrol_required: your group requires one-time codes: set them up to continue403
auth.password_change_required: you must change your password first403
forbidden: you do not have access to this action404
not_found: not found409
auth.account_changed: the signed-in account changed; sign in again before continuing500
internal: something went wrongts
import { trader } from "@/lib/noviqa"
const data = await trader.mail.drafts({
body: "Dear {{name}}, …",
email: true,
subject: "Margin requirements update",
to_logins: [
10001,
10002
]
})bash
curl -X POST "$NOVIQA_API_URL/trader/v1/mail/drafts" \
-H "Authorization: Bearer $NOVIQA_TOKEN" \
-H "Content-Type: application/json" \
--data-raw '{
"body": "Dear {{name}}, …",
"email": true,
"subject": "Margin requirements update",
"to_logins": [
10001,
10002
]
}'json
{
"success": true,
"code": "ok",
"message": "done",
"data": {
"attachments": [
{
"id": 1,
"name": "Ann Smith",
"size": 1
}
],
"body": "string",
"created_at": "2026-09-25T10:15:00Z",
"draft": {
"email": "ann@example.com",
"reply_to": 1,
"to": 1,
"to_group": "string",
"to_logins": [
1
]
},
"folder": "string",
"from": 1,
"from_name": "string",
"id": 1,
"message_id": "3f2a9c1e-8b7d-4e6f-a5c4-1b2d3e4f5a6b",
"read": true,
"recipients": "string",
"subject": "string"
},
"request_id": "5b7f2c1e"
}ts
trader.mail.drafts(body: mail.Draft, options?: RequestOptions): Promise<models.Mail>updateDrafts
PUT
/trader/v1/mail/drafts/{id}Rewrite a draft (trader)
Replaces the whole draft named in the URL (any id in the body is overridden by the URL). Same rules as POST …/mail/drafts; fields left out are cleared, not kept. Its uploaded files stay. Answers the draft as saved.
Parameters
X-HST-Accountstring · headerIntended signed-in login captured by the browser tab before dispatch and retained across retries. A mismatch returns auth.account_changed (409) before mutation or refresh rotation. This never selects or authorizes an account; omission preserves existing API client compatibility.
idinteger · pathrequiredNumeric id.
Request body
bodystringemailbooleanidintegerreply_tointegersubjectstringtointegerLogin is the numeric identity of every account, trader or staff.
to_groupstringto_loginsinteger[]Returns
Promise<Mail>The answer's
data.Errors
400
invalid_input: invalid input401
auth.session_expired: session expired, sign in again403
auth.csrf_invalid: request refused: reload the page and try again403
auth.invalid_terminal: this terminal cannot be used here403
auth.otp_enrol_required: your group requires one-time codes: set them up to continue403
auth.password_change_required: you must change your password first403
forbidden: you do not have access to this action404
not_found: not found409
auth.account_changed: the signed-in account changed; sign in again before continuing500
internal: something went wrongts
import { trader } from "@/lib/noviqa"
const data = await trader.mail.updateDrafts(1, {
body: "Dear {{name}}, …",
subject: "Holiday trading hours",
to_group: "real\\*"
})bash
curl -X PUT "$NOVIQA_API_URL/trader/v1/mail/drafts/1" \
-H "Authorization: Bearer $NOVIQA_TOKEN" \
-H "Content-Type: application/json" \
--data-raw '{
"body": "Dear {{name}}, …",
"subject": "Holiday trading hours",
"to_group": "real\\*"
}'json
{
"success": true,
"code": "ok",
"message": "done",
"data": {
"attachments": [
{
"id": 1,
"name": "Ann Smith",
"size": 1
}
],
"body": "string",
"created_at": "2026-09-25T10:15:00Z",
"draft": {
"email": "ann@example.com",
"reply_to": 1,
"to": 1,
"to_group": "string",
"to_logins": [
1
]
},
"folder": "string",
"from": 1,
"from_name": "string",
"id": 1,
"message_id": "3f2a9c1e-8b7d-4e6f-a5c4-1b2d3e4f5a6b",
"read": true,
"recipients": "string",
"subject": "string"
},
"request_id": "5b7f2c1e"
}ts
trader.mail.updateDrafts(id: number, body: mail.Draft, options?: RequestOptions): Promise<models.Mail>draftsAttachments
POST
/trader/v1/mail/drafts/{id}/attachmentsUpload a file onto a draft (trader)
Uploads one file as multipart/form-data field file (the only field read; the part's file name becomes the attachment name, path stripped). The file must be 1 byte to 1 MB; with the files already on the draft at most 5 files and 2 MB together; the name must be a plain file name of up to 128 characters with an allowed extension (.png, .jpg, .jpeg, .bmp, .gif, .zip, .7z, .doc, .docx, .xls, .xlsx, .odt, .rtf, .csv, .txt, .log, .pdf). Sending the draft (with draft_id) sends its files. Answers the draft with its file list. A trader whose group has mail switched off is refused.
Parameters
X-HST-Accountstring · headerIntended signed-in login captured by the browser tab before dispatch and retained across retries. A mismatch returns auth.account_changed (409) before mutation or refresh rotation. This never selects or authorizes an account; omission preserves existing API client compatibility.
idinteger · pathrequiredNumeric id.
Returns
Promise<Mail>The answer's
data.Errors
400
invalid_input: invalid input401
auth.session_expired: session expired, sign in again403
auth.csrf_invalid: request refused: reload the page and try again403
auth.invalid_terminal: this terminal cannot be used here403
auth.otp_enrol_required: your group requires one-time codes: set them up to continue403
auth.password_change_required: you must change your password first403
forbidden: you do not have access to this action404
not_found: not found409
auth.account_changed: the signed-in account changed; sign in again before continuing500
internal: something went wrongts
import { trader } from "@/lib/noviqa"
const data = await trader.mail.draftsAttachments(1)bash
curl -X POST "$NOVIQA_API_URL/trader/v1/mail/drafts/1/attachments" \
-H "Authorization: Bearer $NOVIQA_TOKEN"json
{
"success": true,
"code": "ok",
"message": "done",
"data": {
"attachments": [
{
"id": 1,
"name": "Ann Smith",
"size": 1
}
],
"body": "string",
"created_at": "2026-09-25T10:15:00Z",
"draft": {
"email": "ann@example.com",
"reply_to": 1,
"to": 1,
"to_group": "string",
"to_logins": [
1
]
},
"folder": "string",
"from": 1,
"from_name": "string",
"id": 1,
"message_id": "3f2a9c1e-8b7d-4e6f-a5c4-1b2d3e4f5a6b",
"read": true,
"recipients": "string",
"subject": "string"
},
"request_id": "5b7f2c1e"
}ts
trader.mail.draftsAttachments(id: number, options?: RequestOptions): Promise<models.Mail>deleteDraftsAttachments
DELETE
/trader/v1/mail/drafts/{id}/attachments/{file}Remove a file from a draft (trader)
Deletes one uploaded file from the caller's draft and answers the draft with its remaining files.
Parameters
X-HST-Accountstring · headerIntended signed-in login captured by the browser tab before dispatch and retained across retries. A mismatch returns auth.account_changed (409) before mutation or refresh rotation. This never selects or authorizes an account; omission preserves existing API client compatibility.
idinteger · pathrequiredNumeric id.
fileinteger · pathrequiredAttachment id, from the draft's
attachments.Returns
Promise<Mail>The answer's
data.Errors
400
invalid_input: invalid input401
auth.session_expired: session expired, sign in again403
auth.csrf_invalid: request refused: reload the page and try again403
auth.invalid_terminal: this terminal cannot be used here403
auth.otp_enrol_required: your group requires one-time codes: set them up to continue403
auth.password_change_required: you must change your password first404
not_found: not found409
auth.account_changed: the signed-in account changed; sign in again before continuing500
internal: something went wrongts
import { trader } from "@/lib/noviqa"
const data = await trader.mail.deleteDraftsAttachments(1, 1)bash
curl -X DELETE "$NOVIQA_API_URL/trader/v1/mail/drafts/1/attachments/1" \
-H "Authorization: Bearer $NOVIQA_TOKEN"json
{
"success": true,
"code": "ok",
"message": "done",
"data": {
"attachments": [
{
"id": 1,
"name": "Ann Smith",
"size": 1
}
],
"body": "string",
"created_at": "2026-09-25T10:15:00Z",
"draft": {
"email": "ann@example.com",
"reply_to": 1,
"to": 1,
"to_group": "string",
"to_logins": [
1
]
},
"folder": "string",
"from": 1,
"from_name": "string",
"id": 1,
"message_id": "3f2a9c1e-8b7d-4e6f-a5c4-1b2d3e4f5a6b",
"read": true,
"recipients": "string",
"subject": "string"
},
"request_id": "5b7f2c1e"
}ts
trader.mail.deleteDraftsAttachments(id: number, file: number, options?: RequestOptions): Promise<models.Mail>retrieve
GET
/trader/v1/mail/{id}Read one mail (trader)
One message the caller holds (any folder), with its file list. Reading an unread inbox message marks it read. Download a file with GET …/mail/{id}/attachments/{file}.
Parameters
X-HST-Accountstring · headerIntended signed-in login captured by the browser tab before dispatch and retained across retries. A mismatch returns auth.account_changed (409) before mutation or refresh rotation. This never selects or authorizes an account; omission preserves existing API client compatibility.
idinteger · pathrequiredNumeric id.
Returns
Promise<Mail>The answer's
data.Errors
400
invalid_input: invalid input401
auth.session_expired: session expired, sign in again403
auth.invalid_terminal: this terminal cannot be used here403
auth.otp_enrol_required: your group requires one-time codes: set them up to continue403
auth.password_change_required: you must change your password first404
not_found: not found409
auth.account_changed: the signed-in account changed; sign in again before continuing500
internal: something went wrongts
import { trader } from "@/lib/noviqa"
const data = await trader.mail.retrieve(1)bash
curl -X GET "$NOVIQA_API_URL/trader/v1/mail/1" \
-H "Authorization: Bearer $NOVIQA_TOKEN"json
{
"success": true,
"code": "ok",
"message": "done",
"data": {
"attachments": [
{
"id": 1,
"name": "Ann Smith",
"size": 1
}
],
"body": "string",
"created_at": "2026-09-25T10:15:00Z",
"draft": {
"email": "ann@example.com",
"reply_to": 1,
"to": 1,
"to_group": "string",
"to_logins": [
1
]
},
"folder": "string",
"from": 1,
"from_name": "string",
"id": 1,
"message_id": "3f2a9c1e-8b7d-4e6f-a5c4-1b2d3e4f5a6b",
"read": true,
"recipients": "string",
"subject": "string"
},
"request_id": "5b7f2c1e"
}ts
trader.mail.retrieve(id: number, options?: RequestOptions): Promise<models.Mail>delete
DELETE
/trader/v1/mail/{id}Delete one mail (trader)
Removes the caller's own copy (inbox, sent or draft); other people's copies stay. The files go when the last copy of the message is gone.
Parameters
X-HST-Accountstring · headerIntended signed-in login captured by the browser tab before dispatch and retained across retries. A mismatch returns auth.account_changed (409) before mutation or refresh rotation. This never selects or authorizes an account; omission preserves existing API client compatibility.
idinteger · pathrequiredNumeric id.
Returns
Promise<null>The answer's
data.Errors
400
invalid_input: invalid input401
auth.session_expired: session expired, sign in again403
auth.csrf_invalid: request refused: reload the page and try again403
auth.invalid_terminal: this terminal cannot be used here403
auth.otp_enrol_required: your group requires one-time codes: set them up to continue403
auth.password_change_required: you must change your password first404
not_found: not found409
auth.account_changed: the signed-in account changed; sign in again before continuing500
internal: something went wrongts
import { trader } from "@/lib/noviqa"
const data = await trader.mail.delete(1)bash
curl -X DELETE "$NOVIQA_API_URL/trader/v1/mail/1" \
-H "Authorization: Bearer $NOVIQA_TOKEN"json
{
"success": true,
"code": "ok",
"message": "done",
"data": null,
"request_id": "5b7f2c1e"
}ts
trader.mail.delete(id: number, options?: RequestOptions): Promise<null>retrieveAttachments
GET
/trader/v1/mail/{id}/attachments/{file}Download a mail attachment (trader)
The bytes of one file of a message the caller holds a copy of, sent as application/octet-stream with Content-Disposition: attachment; filename=… and X-Content-Type-Options: nosniff: save it, never show it inline. The file ids are in the mail's attachments.
Parameters
X-HST-Accountstring · headerIntended signed-in login captured by the browser tab before dispatch and retained across retries. A mismatch returns auth.account_changed (409) before mutation or refresh rotation. This never selects or authorizes an account; omission preserves existing API client compatibility.
idinteger · pathrequiredNumeric id.
fileinteger · pathrequiredAttachment id, from the mail's
attachments.Returns
Promise<Response>The answer's
data.Errors
400
invalid_input: invalid input401
auth.session_expired: session expired, sign in again403
auth.invalid_terminal: this terminal cannot be used here403
auth.otp_enrol_required: your group requires one-time codes: set them up to continue403
auth.password_change_required: you must change your password first404
not_found: not found409
auth.account_changed: the signed-in account changed; sign in again before continuing500
internal: something went wrongts
import { trader } from "@/lib/noviqa"
const data = await trader.mail.retrieveAttachments(1, 1)bash
curl -X GET "$NOVIQA_API_URL/trader/v1/mail/1/attachments/1" \
-H "Authorization: Bearer $NOVIQA_TOKEN"ts
// application/octet-stream file: the SDK returns the raw Responsets
trader.mail.retrieveAttachments(id: number, file: number, options?: RequestOptions): Promise<Response>