System
Base URL
Every path below is relative to https://api.laksonoteknologi.com/v2.
Applies to every endpoint on this page
Accept-Languageheader (or?lang=query param, which wins if both are sent) picks the response/error locale - optional, falls back to the server's configured default if neither is sent.- Successful responses are
{"response_code":"001", "response_text":"Success", "data": {...}}.
Create Menu Item
/v2/system/menu-itemscommandCreates a new sidebar menu item node - either a root node (omit parent_id) or a child of an existing node (parent_id must point to an existing menu item, checked server-side). code must be kebab-case and globally unique across the whole tree, not just among siblings. required_obj/required_act gate visibility: if set, the item only shows up in get-menu for callers who hold that permission; the two fields must be supplied together (setting one without the other is rejected). system_owner only.
Headers
Authorization: Bearer <token>
Content-Type: application/json
Accept-Language: en (optional - defaults to server config, or use ?lang= instead)Requires
"command": "create-menu-item"in the request body.
Request fields
| Field | Source | Type | Required | Validation |
|---|---|---|---|---|
data.parent_id | body | string | false | omitempty |
data.code | body | string | true | required,kebabcase |
data.label | body | string | true | required |
data.icon | body | string | false | omitempty |
data.route | body | string | false | omitempty |
data.required_obj | body | string | true | omitempty,required_with=RequiredAct |
data.required_act | body | string | true | omitempty,required_with=RequiredObj |
data.sort_order | body | integer | false | omitempty |
data.is_active | body | boolean | false | - |
Example
Create Merchant
/v2/system/merchantscommandCreates a new merchant profile (name/email/phone/address/company_registration_number) together with its mandatory super_admin account (email/password/name/phone) in a single transaction - a merchant can never exist without a super_admin. system_owner only; a merchant token is rejected at the auth layer before this handler is even reached, and the usecase separately re-checks the caller's parent_role, since is_root alone can't tell 'root everywhere' apart from 'root only within my own merchant domain'.
Headers
Authorization: Bearer <token>
Content-Type: application/json
Accept-Language: en (optional - defaults to server config, or use ?lang= instead)Requires
"command": "create-merchant"in the request body.
Request fields
| Field | Source | Type | Required | Validation |
|---|---|---|---|---|
data.name | body | string | true | required |
data.email | body | string | false | omitempty,email |
data.phone | body | string | false | omitempty |
data.address | body | string | false | omitempty |
data.company_registration_number | body | string | false | omitempty |
data.admin | body | object | false | - |
data.admin.email | body | string | true | required,email |
data.admin.password | body | string | true | required,min=8 |
data.admin.name | body | string | true | required |
data.admin.phone | body | string | false | omitempty |
Example
Menu Items
Deactivate Menu Item
/v2/system/menu-items/:idcommandSoft-deactivates a menu item by id (is_active becomes false) - the row and any children stay in the DB, it just stops being returned by get-menu for FE sidebars. Not a hard delete, so it can be reactivated later via update-menu-item. system_owner only.
Headers
Authorization: Bearer <token>
Content-Type: application/json
Accept-Language: en (optional - defaults to server config, or use ?lang= instead)Requires
"command": "deactivate-menu-item"in the request body.
Request fields
| Field | Source | Type | Required | Validation |
|---|---|---|---|---|
:id | path | string | true | required |
Example
Update Menu Item
/v2/system/menu-items/:idcommandUpdates an existing menu item's label/icon/route/parent_id/permission gate (required_obj+required_act)/sort_order/is_active. code is set once at creation and is immutable here - it's not part of this request body at all. Re-parenting via parent_id is allowed and re-validated (the new parent must exist). system_owner only.
Headers
Authorization: Bearer <token>
Content-Type: application/json
Accept-Language: en (optional - defaults to server config, or use ?lang= instead)Requires
"command": "update-menu-item"in the request body.
Request fields
| Field | Source | Type | Required | Validation |
|---|---|---|---|---|
:id | path | string | true | required |
data.parent_id | body | string | false | omitempty |
data.label | body | string | true | required |
data.icon | body | string | false | omitempty |
data.route | body | string | false | omitempty |
data.required_obj | body | string | true | omitempty,required_with=RequiredAct |
data.required_act | body | string | true | omitempty,required_with=RequiredObj |
data.sort_order | body | integer | false | omitempty |
data.is_active | body | boolean | false | - |
Example
Roles
Create Sub Role
/v2/system/roles/sub-rolescommandCreates a custom sub-role (code + display name) under one of the fixed parent roles (system_owner/merchant/customer/device_player). code must be kebab-case and unique within that parent_role. The new sub-role starts with no permissions attached - grant them separately via grant-role-permission.
Headers
Authorization: Bearer <token>
Content-Type: application/json
Accept-Language: en (optional - defaults to server config, or use ?lang= instead)Requires
"command": "create-sub-role"in the request body.
Request fields
| Field | Source | Type | Required | Validation |
|---|---|---|---|---|
data.parent_role | body | string | true | required,oneof=system_owner merchant customer device_player |
data.code | body | string | true | required,kebabcase |
data.name | body | string | true | required |
Example
Deactivate Sub Role
/v2/system/roles/sub-roles/:idcommandSoft-deactivates a sub-role by id (is_active becomes false) - the row and its permission grants are kept, it just stops being assignable/usable going forward. Rejects the seeded, protected codes (super_admin/device_admin) outright; only custom sub-roles can be deactivated.
Headers
Authorization: Bearer <token>
Content-Type: application/json
Accept-Language: en (optional - defaults to server config, or use ?lang= instead)Requires
"command": "deactivate-sub-role"in the request body.
Request fields
| Field | Source | Type | Required | Validation |
|---|---|---|---|---|
:id | path | string | true | required |
Example
Get Parent Roles
/v2/system/roles/parent-rolesqueryLists the fixed set of parent roles seeded at setup time (system_owner/merchant/customer/device_player) - these are not user-creatable or editable, this endpoint exists purely so FE can populate a parent_role dropdown (e.g. when creating a sub-role) without hardcoding the list client-side.
Headers
Authorization: Bearer <token>
Accept-Language: en (optional - defaults to server config, or use ?lang= instead)Plain query parameters - no request body /
commandfield needed.
Example
Get Sub Roles
/v2/system/roles/sub-rolesqueryLists sub-roles (super_admin/device_admin and any custom ones created via create-sub-role), each flagged with is_root/is_active/protected. Optionally filter to just one parent_role's sub-roles via the query param; omit it to get all sub-roles across every parent_role.
Headers
Authorization: Bearer <token>
Accept-Language: en (optional - defaults to server config, or use ?lang= instead)Plain query parameters - no request body /
commandfield needed.
Request fields
| Field | Source | Type | Required | Validation |
|---|---|---|---|---|
parent_role | query | string | false | omitempty,oneof=system_owner merchant customer device_player |
Example
Update Sub Role
/v2/system/roles/sub-roles/:idcommandRenames a sub-role's display name (name only - code is immutable and not part of this request). Rejects the seeded, protected codes (super_admin/device_admin) outright; only custom sub-roles created via create-sub-role can be renamed.
Headers
Authorization: Bearer <token>
Content-Type: application/json
Accept-Language: en (optional - defaults to server config, or use ?lang= instead)Requires
"command": "update-sub-role"in the request body.
Request fields
| Field | Source | Type | Required | Validation |
|---|---|---|---|---|
:id | path | string | true | required |
data.name | body | string | true | required |
Example