SWC API reference
HTTP endpoints
| Method | Path | Description |
|---|---|---|
| GET | /web/swc/workspace | Workspace payload (arch + records) |
| WS | /web/swc/bus | Live outbox events (authenticated WebSocket; plain GET → 404) |
Query params for /web/swc/workspace:
| Param | Purpose |
|---|---|
action | Window action id (optional if model is set) |
menu_id | Menu context |
view_type | list, form, kanban, graph, pivot, calendar |
id | Record id (form) |
edit | 1 for edit mode |
q | List/kanban search (ilike across view columns) |
model | Load workspace by model when action is omitted |
filter | Named search-view filters (comma-separated) |
sort | List sort (field or -field) |
offset | List page offset |
WebSocket bus
Upgrade GET /web/swc/bus with standard WebSocket headers after session login. The server forwards in-process outbox queue messages as JSON:
{ "channel": "record.updated", "payload": { "model": "crm.lead", "id": 1 } }
Non-upgrade GET requests return 404 (no error log). Enable in bootstrap with busEnabled: true; the client connects from ShellLayout when set.
Workspace JSON schema
{
"actionId": 12,
"menuId": "5",
"viewType": "list",
"model": "sale.order",
"recordId": 0,
"formEdit": false,
"csrfToken": "…",
"arch": {
"type": "list",
"model": "sale.order",
"fields": [{ "name": "name", "type": "char" }],
"kanban": { "groupField": "stage_id", "draggable": true, "quickCreate": true, "columns": [] }
},
"records": [],
"viewTabs": [{ "mode": "list", "label": "List", "href": "/web?…", "active": true }],
"breadcrumbs": [],
"listSearch": "",
"listTotal": 42,
"listSort": "",
"listOffset": 0,
"listFilter": "",
"formBaseQuery": "action=12&menu_id=5&view_type=form&id=7",
"defaults": { "state": "draft" }
}
defaults comes from the window action context keys default_* (for example {"default_type":"opportunity"} → "type": "opportunity"). New forms merge them into record; kanban quick-create merges them into rpc.create.
Records are redacted with the same rules as ORM RedactRecordForRead.
See Arch JSON pipeline for the XML → JSON pipeline.
JSON-RPC (primary data plane)
SWC uses POST /api/rpc for:
search_read,read,write,create,unlinkread_group(pivot/graph)call(object buttons; optional vals asargs[2])onchange
Send header X-CSRF-Token with the bootstrap csrfToken.
Client helper:
await rpc.callMethod("crm.lead", "action_merge_wizard", recordId, {
active_ids: "3,7",
});
Client registry
registry.category("fields").add("many2one", Many2OneField);
registry.category("views").add("list", ListView);
registry.category("services").add("rpc", rpcService);
registry.category("main_components").add("shell", ShellLayout);
Categories: fields, views, services, main_components, actions, systray.
RecordStore
fromPayload(model, id, data)→SwcRecordsave(rec)→ RPCwrite/createunlink(rec)→ RPCunlinkvalidate(rec, requiredFields)— client-side required check before save (SwcErrorcodevalidation)applyOnchange(rec, fieldName)— RPC onchange
Write-path toasts: SWC notifications.
Bootstrap (window.__SWC_BOOTSTRAP__)
| Field | Purpose |
|---|---|
rpcUrl | /api/rpc |
swcApiBase | /web/swc |
user, company, companies | Shell chrome |
topMenus, sidebarMenus | Navigation |
apps, pinnedApps | App launcher index |
workspace | Initial route hints |
busEnabled | When true, client opens /web/swc/bus WebSocket |
toasts | Optional NotificationService.bootstrap messages |