Skip to content

Boards configuration walkthrough

This walkthrough builds a working process board over the SupportTicket record type from the Configuration quickstart: a triage board where new tickets land in Triage, move to In progress, and finish in Resolved. Everything happens through the Configuration API, so the same flow works for an AI agent with a service-account key.

All examples were executed against a real Moltaro installation; response bodies are real, trimmed for length. For what boards are and how users work with them, see the Boards user documentation; for the complete contract, see the Configuration API reference.

An agent starts only with the prepared workspace guide, URL, key, and roles. If access or module administration is missing, ask the user to complete it in the Portal or administrative interface. Do not provision or elevate the agent through these APIs. Follow Reliable API automation for idempotent discovery, conflicts, and safe mutation rules.

One convention to know up front: every board administration mutation returns the full board administration model — the created status, transition, or target definition appears inside its Statuses, Transitions, or TargetDefinitions array rather than as the response root. Read the ids from there.

  • Admin or Configurator role for enabling the module and creating boards. Per-board changes are also open to subjects granted the board-scoped Manage configuration permission.
  • An existing entity definition to bind — this page uses SupportTicket (id pYZqCLZWb0K1) from the Configuration quickstart.

Boards ship disabled. POST /api/workspace/admin/boards/enable (operation) turns the module on for the workspace; the body is optional:

Terminal window
curl -s -X POST https://ops.example.com/api/workspace/admin/boards/enable \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" -d '{}'

GET /api/workspace/admin/boards/setup (operation) reports the module state at any time — useful as the idempotent first call of an automation.

POST /api/workspace/admin/boards/boards (operation). The Key must start with a letter and may contain only ASCII letters, numbers, and underscores (support-triage would be rejected with moltaroBoards.validation.boardKeyInvalid):

Terminal window
curl -s -X POST https://ops.example.com/api/workspace/admin/boards/boards \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d '{ "Key": "support_triage", "DisplayName": "Support triage",
"Description": "Incoming ticket triage and resolution.",
"BoardType": 0, "CreateDefaultStatuses": false }'
{
"Data": {
"Id": "zuq5JQx4kLF1",
"Key": "support_triage",
"DataEntityDefinitionId": "wJ8wB2plyd7F",
"DisplayName": "Support triage",
"IsActive": false,
"BoardType": 0,
"AllowedActions": { "CanUpdate": true, "CanActivate": false, "CanManageConfiguration": true },
"TargetDefinitions": [],
"Statuses": [],
"Transitions": []
},
"Success": true
}

BoardType: 0 is a Kanban board (1 adds planned operating cycles and then requires BoardCycleActivationMode). CreateDefaultStatuses: false starts with an empty status set so this walkthrough can build the process explicitly; with true the board is created with a ready Initial/Active/Terminal status trio instead.

All starter display metadata is created in the workspace locale: status labels, the Board Data entity and its Subject and Description fields, system link types, and initial-mapping destination labels. Their technical keys remain stable (init, active, terminal, child, related, Subject, and Description).

The response shows what a board brings along: it is inactive (invisible to end users until activated — which is what makes the configure-then-activate flow safe against a live workspace), it owns a board data model (DataEntityDefinitionId — process-specific fields that live on the board item rather than the record, see board data fields below). Board Security starts empty: configure Responsibilities, Access Policies, and Permissions explicitly.

Activation validates the configuration, so an agent can probe readiness honestly. Activating right after creation:

Terminal window
curl -s -X POST https://ops.example.com/api/workspace/admin/boards/boards/zuq5JQx4kLF1/activate \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" -d '{}'
{
"Data": null,
"Errors": [
{ "Code": "moltaroBoards.domain.initialStatusRequired",
"Message": "An active board must have exactly one active, non-deleted initial status.",
"Field": "Initial", "Type": 1, "Severity": 2 },
{ "Code": "moltaroBoards.domain.terminalStatusRequired",
"Message": "An active board must have at least one active, non-deleted terminal status.",
"Field": "Terminal", "Type": 1, "Severity": 2 }
],
"Success": false
}

Activation requires exactly one initial status and at least one terminal status. Transitions are not an activation requirement — but without them no status change is allowed at runtime, so a useful board defines both.

A target definition connects the board to the records it manages. POST /api/workspace/admin/boards/boards/{boardId}/target-definitions (operation):

Terminal window
curl -s -X POST https://ops.example.com/api/workspace/admin/boards/boards/zuq5JQx4kLF1/target-definitions \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d '{ "TargetKind": 0, "TargetModelId": "pYZqCLZWb0K1" }'
{
"Data": {
"Id": "zuq5JQx4kLF1",
"TargetDefinitions": [
{ "Id": "ojmxCpYFwfCY", "TargetKind": 0, "TargetModelId": "pYZqCLZWb0K1",
"IsActive": true, "RepeatPolicy": 0,
"RowVersion": "1c0b2008-f9da-46ff-96ea-8a85c683843c" }
]
},
"Success": true
}

TargetKind: 0 binds an entity definition; TargetModelId is the entity definition id. The created target definition id (ojmxCpYFwfCY here) comes back inside TargetDefinitions — the runtime item APIs will need it. One board can carry several target definitions, so records of different types share one process.

POST /api/workspace/admin/boards/boards/{boardId}/statuses (operation), one call per status. MetaType gives each status its role in the process: 0 Initial (new items land here), 1 Active, 2 Terminal:

Terminal window
curl -s -X POST https://ops.example.com/api/workspace/admin/boards/boards/zuq5JQx4kLF1/statuses \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d '{ "DisplayName": "Triage", "MetaType": 0, "SortOrder": 1 }'
StatusRequest bodyCreated id
Triage{ "DisplayName": "Triage", "MetaType": 0, "SortOrder": 1 }2FEzzRX4vMNg
In progress{ "DisplayName": "In progress", "MetaType": 1, "SortOrder": 2 }x2lpSYpWQ3q6
Resolved{ "DisplayName": "Resolved", "MetaType": 2, "SortOrder": 3 }gc3NgI61wO4D

As with every board mutation, each response is the full board model — the new status id appears in Data.Statuses.

Transitions define which status moves are allowed. POST /api/workspace/admin/boards/boards/{boardId}/transitions (operation) takes the two status ids from the previous step:

Terminal window
curl -s -X POST https://ops.example.com/api/workspace/admin/boards/boards/zuq5JQx4kLF1/transitions \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d '{ "FromBoardStatusId": "2FEzzRX4vMNg", "ToBoardStatusId": "x2lpSYpWQ3q6" }'

Create one per allowed move — here Triage → In progress and In progress → Resolved. Moves without a matching transition are rejected at runtime with moltaroBoards.runtime.transitionNotFound, and the runtime API exposes the allowed set per item through move-options, so an agent never has to guess.

LinkPrerequisites can require active item links before a transition is allowed. A prerequisite fixes the link system kind (0 Child, 1 Related), its direction relative to the item being moved (0 outgoing, 1 incoming), the target Board and exact target definition, and a minimum/optional maximum count. For example, this transition requires one incoming Child link from an item on the specified target definition:

{
"FromBoardStatusId": "2FEzzRX4vMNg",
"ToBoardStatusId": "x2lpSYpWQ3q6",
"LinkPrerequisites": [
{
"LinkType": 0,
"Direction": 1,
"TargetBoardId": "zuq5JQx4kLF1",
"TargetBoardTargetDefinitionId": "ojmxCpYFwfCY",
"MinimumCount": 1,
"MaximumCount": 1
}
]
}

The target Board and target definition must exist, be active, and match each other. Duplicate scopes and invalid count ranges are rejected. On update, omit LinkPrerequisites to preserve them or send an empty array to clear them.

Board Security is empty on a new board and therefore fails closed. Before the runtime walkthrough, create an enabled BoardItem Security Statement and assign the permissions used by that walkthrough to it. Start by reading the shared concurrency token and the server-owned permission catalog:

Terminal window
curl -s https://ops.example.com/api/workspace/admin/boards/boards/zuq5JQx4kLF1/security \
-H "Authorization: Bearer <token>"
curl -s https://ops.example.com/api/workspace/admin/boards/boards/zuq5JQx4kLF1/security/profiles/BoardItem/permissions \
-H "Authorization: Bearer <token>"

Create a Statement for the actors that will operate this example. The source below deliberately limits the walkthrough to the workspace ADMIN role; use the exact role design required by your workspace instead:

Terminal window
curl -s -X POST https://ops.example.com/api/workspace/admin/boards/boards/zuq5JQx4kLF1/security/profiles/BoardItem/statements \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d "{ \"OperationKey\": \"ae8fa130-25eb-4570-ab1c-ed372eef8380\",
\"RowVersion\": \"00000000-0000-0000-0000-000000000000\",
\"Key\": \"RuntimeAdmin\", \"Source\": \"HAS_ROLE('ADMIN')\", \"Enabled\": true }"

Then create one Permission Assignment per required catalog entry. Use each entry’s returned PermissionId, a unique assignment Key and OperationKey, and the latest RowVersion returned by the previous mutation:

Terminal window
curl -s -X POST https://ops.example.com/api/workspace/admin/boards/boards/zuq5JQx4kLF1/security/profiles/BoardItem/permission-assignments \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d '{ "OperationKey": "760eb25c-8f36-4b3c-9c0f-da1945750c8a",
"RowVersion": "<latest-security-row-version>",
"Key": "RuntimeAdminView", "PermissionId": "Resource|View|",
"StatementKey": "RuntimeAdmin" }'

Repeat that assignment for AddItem, MoveItem, EditBoardData, ViewAuditTrail, ManageItemLinks, Target:View, and the exact UseTransition entries returned for the two transitions. These entries match the action flags and link-candidate call shown in the runtime walkthrough. If you extend the example to change custom Board Data fields, also assign Field:Write for each changed field. The target Entity Definition must separately grant the same actor its own Create, View, and required field permissions, as described in Configure Entity Security. Responsibilities are optional: omit them when this board has no named responsibility assignments.

With statuses, process wiring, and explicit Security in place, activation succeeds and the same board model comes back with IsActive: true:

Terminal window
curl -s -X POST https://ops.example.com/api/workspace/admin/boards/boards/zuq5JQx4kLF1/activate \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" -d '{}'
{
"Data": {
"Id": "zuq5JQx4kLF1",
"Key": "support_triage",
"IsActive": true,
"AllowedActions": { "CanActivate": false, "CanDeactivate": true }
},
"Success": true
}

The board is now live for actors allowed by the configured Statements and Permissions. Continue with the Boards runtime walkthrough to create and move items through the public API.

Process-specific fields — an escalation flag, a triage note — belong to the board item, not the record. They live on the board-owned data model (DataEntityDefinitionId above) and are managed with POST /api/workspace/admin/boards/boards/{boardId}/data-model/fields (operation), which reuses the exact field request shape from the Configuration quickstart. The record keeps its own schema; the board carries the process context.

Board Statements are reusable Board-owned boolean expressions. Configure them through /api/workspace/admin/boards/boards/{boardId}/statements; the server-generated GET .../authoring response is the authoritative set of roots, typed paths, operators, functions, variables, examples, and diagnostic codes for the chosen optional target definition.

Use POST .../validate before create or update, and use POST .../preview with an explicit proposed values/collections payload when an integration needs a deterministic authoring check. Create and update persist source, normalized expression, dependency metadata, eligibility, fingerprints, and RowVersion. Installation package export persists portable source and recompiles it against the destination workspace during apply.

See the complete Board Statement DSL reference. Statements are not runtime gates by themselves.

Board Constraint configuration is available through the Board administration screen and the Configuration API. A Constraint owns its safe failure message; each ordered Binding selects Transition, EnterStatus, ExitStatus, or StatusInvariant, and combines a non-empty ordered Statement set with And or Or.

GET /api/workspace/admin/boards/boards/{boardId}/constraints
POST /api/workspace/admin/boards/boards/{boardId}/constraints
PUT /api/workspace/admin/boards/boards/{boardId}/constraints/{constraintId}
DELETE /api/workspace/admin/boards/boards/{boardId}/constraints/{constraintId}
POST /api/workspace/admin/boards/boards/{boardId}/constraints/reorder
POST /api/workspace/admin/boards/boards/{boardId}/constraints/bindings/validate
POST /api/workspace/admin/boards/boards/{boardId}/constraints/{constraintId}/bindings
PUT /api/workspace/admin/boards/boards/{boardId}/constraints/{constraintId}/bindings/{bindingId}
DELETE /api/workspace/admin/boards/boards/{boardId}/constraints/{constraintId}/bindings/{bindingId}
POST /api/workspace/admin/boards/boards/{boardId}/constraints/{constraintId}/bindings/reorder

Validation returns configuration health separately from runtime availability. Healthy Transition, EnterStatus, and ExitStatus Bindings report runtime availability and can be enabled. A Constraint can be enabled only after it has at least one enabled, healthy Binding; disabling or deleting its last enforcing Binding is rejected. IsEnforcing requires an enabled Constraint, an enabled Binding, valid configuration, an available trigger runtime, and an active Board.

StatusInvariant Bindings can be enabled when every referenced Statement is invariant-safe. Moltaro enforces them against the complete proposed Target or Board Data aggregate before supported Entity API, NetOperationProject, and Package SDK writes commit. Package YAML applies the same health and activation checks and never silently downgrades an enabled definition.

The Board resource keeps portable Statement source and Binding references. A minimal fragment is shown below; use stable ids within the resource and let the installer recompile the expression for the destination workspace.

Statements:
- Id: owner-present
Name: OwnerPresent
DisplayName: Owner is present
BoardTargetDefinitionId: null
Expression: BoardData.Owner IS NOT NULL
SortOrder: 0
IsEnabled: true
Constraints:
- Id: ready-requires-owner
Name: ReadyRequiresOwner
DisplayName: Ready requires an owner
FailureMessage: Select an owner before moving this item to Ready.
SortOrder: 0
IsEnabled: true
Bindings:
- Id: enter-ready
TriggerType: EnterStatus
BoardStatusId: ready
EvaluatorType: Statements
LogicalOperator: And
SortOrder: 0
IsEnabled: true
BoardStatementIds:
- owner-present

Package validation, planning, and apply reject unknown Statement ids, invalid trigger shapes, missing target coverage, unhealthy expressions, and active configuration that cannot enforce. Export writes current portable source; it does not serialize a compiled plan or retain a destination-specific schema fingerprint as executable state.

See Board constraints for the product model and the event/status-invariant enforcement boundaries.

Board Security uses the same three administration concepts as Entity Security:

  • Responsibilities define optional named assignments for Board Items or Board Statuses and the rules that may change them;
  • Access Policies project one reusable Security Statement condition plus all exact Permissions assigned to it and use atomic Plan/Apply;
  • Permissions expose inherited field access, explicit field refinements and exact transition coverage. Multiple Statements assigned to a Permission use OR semantics.

Raw Security Statement and Permission Assignment operations remain available through the Configuration API as an immediate Advanced surface.

An empty configuration fails closed for Board Item and direct Board Status access.

Board Item collections, search, saved filters, link candidates and cycle item counts evaluate BoardItem.View before count, ordering and pagination. Direct reads use the same policy. Owner, Admin and Configurator can manage Board configuration, but those roles do not bypass Board Item data authorization.

Runtime operations compose View with one exact Permission: for example, MoveItem and UseTransition:<transition-key> for a configured transition, or EditBoardData plus each changed Field:Write Permission for Board Data. Responsibility changes are different: they require the resource profile’s View and an active Assignment Rule for the exact responsibility key and action. Board cycle administration is Owner/Admin or ManageCycles; Configurator has no implicit cycle authority.

Target display and Security conditions are separate. Cards project the target selected by BoardTargetDefinition and require BoardItem.View, the separate Target:View Permission, and that target resource’s own access. Inside a Security Statement, target(<TargetKind>, '<TargetModelKey?>').<path> selects one exact target type; target.<path> selects the first configured Target Definition by SortOrder, then Id. Predicate traversal does not require or grant Target:View.

Board status columns remain part of the process shell. A Board Item requires BoardItem.View; it does not additionally require BoardStatus.View. BoardStatus.View governs direct status responsibility and history access.

Workspace C# automation and background Board work enter the same captured authorization scope as HTTP operations. A confirmed trusted system invocation may use the reserved system actor identity, but it receives no automatic Permission and must satisfy the configured Statements. A package host without the Moltaro Boards evaluator fails closed.

  • Boards runtime walkthrough — items, moves, and process collaboration through the public API.
  • Board Security — configure Responsibilities, Access Policies, and Permissions through the Configuration API reference.
  • Due-date and attention-signal policies — per-board operational policies in the same administration group.