Messages CDD Core sends
Address: POST {trading_base_url}/rest/v1/rpc/{function}, body {"p": { …envelope… }}, headers x-link-key and apikey. The trading system answers with a receipt.
How sending works
Section titled “How sending works”- Messages wait on a dispatch list in the database and are sent every minute, in this order: customer state, then restriction commands, then limits, oldest first within each.
- A message is marked sent only after HTTP 200 with a receipt naming its
message_id. - A message missing a required field is held and logged with the field names. It is never sent half-built.
- A 4xx stops the run so that order is never broken. A 5xx or network failure also stops it, and the message stays on the list for the next run.
CUSTOMER_STATE · function core_customer_state
Section titled “CUSTOMER_STATE · function core_customer_state”Sent when a customer is approved for service and again whenever a field changes. It always carries the whole current state.
"body": { "link_ref": "…", "core_customer_id": "5d0c…", "state_version": 17, "effective_at": "2026-09-20T08:15:30.000Z", "account_no": "IA-0048-1193", "customer_type": "INDIVIDUAL", "display_name_th": "…", "display_name_en": "…", "service_status": "ACTIVE", "risk_level": "MEDIUM", "investor_class": "RETAIL", "withdrawal_class": "W1", "knowledge_test_valid_until": "2027-09-20", "suitability_level": 3, "bank_accounts": [ { "bank_code": "004", "account_no_masked": "xxx-x-x9082-6", "account_ref": "ba_01", "status": "VERIFIED", "usable_from": "2026-09-20T08:15:30.000Z" } ], "language": "th"}| Field | Values |
|---|---|
state_version | Rises by one with every change, per customer. A version not higher than the one held is acknowledged and ignored |
customer_type | INDIVIDUAL · JURISTIC |
service_status | ACTIVE · SUSPENDED · CLOSED |
risk_level | LOW · MEDIUM · HIGH. Used only to pick limits and review routes |
bank_accounts[].usable_from | The hold after a bank-account change. The trading system enforces it and never computes it |
RESTRICTION_COMMAND · function core_restriction_command
Section titled “RESTRICTION_COMMAND · function core_restriction_command”One customer, one leg, one action. Restricting three legs is three messages under one case_ref. No message means “lock everything”.
"body": { "link_ref": "…", "command_ref": "RC-000123-3", "core_customer_id": "5d0c…", "leg": "DA_TRANSFER_OUT", "action": "RESTRICT", "trading_scope": "ALL", "ground_code": "G-07", "source": "OFFICER_DECISION", "priority": 2, "case_ref": "CASE-2026-000045", "issued_at": "2026-09-20T08:15:30.123Z", "effective_at": "2026-09-20T08:15:30.123Z"}| Field | Values |
|---|---|
leg | THB_DEPOSIT · THB_WITHDRAWAL · TRADING · DA_TRANSFER_OUT · DA_TRANSFER_IN_ACCESS |
action | RESTRICT · RELEASE |
trading_scope | Only when leg is TRADING: ALL · BUY_ONLY. Exit-Only is TRADING + RESTRICT + BUY_ONLY, which keeps selling open |
source | CORE_RULE · OFFICER_DECISION · AUTHORITY_ORDER |
ground_code · priority | Stored by the receiver, never shown to the customer, never used to decide |
Per customer and leg, the command with the latest issued_at stands. An older command arriving late is acknowledged, then reported SUPERSEDED. The trading system never decides whether a release is allowed: priority is applied in CDD Core, and only the resulting command is sent.
LIMIT_PUSH · function core_limit_push
Section titled “LIMIT_PUSH · function core_limit_push”"body": { "link_ref": "…", "core_customer_id": "5d0c…", "limit_version": 4, "effective_at": "2026-09-20T08:15:30.000Z", "limits": [ { "limit_code": "THB_OUT_DAY", "amount": "500000.00", "currency": "THB" }, { "limit_code": "DA_OUT_DAY", "amount": "500000.00", "currency": "THB" }, { "limit_code": "DA_OUT_SINGLE", "amount": "200000.00", "currency": "THB" } ]}The whole set replaces the previous set at effective_at. Limit codes in this release: THB_OUT_DAY · DA_OUT_DAY · DA_OUT_SINGLE.
PING · function core_ping
Section titled “PING · function core_ping”Checks the link from CDD Core’s side. Used at acceptance and on demand.