Skip to content

Contextual groups and views ​

Contextual groups separate row sources, typed input contexts, display bindings and write targets. They can read ObjectType records directly; a saved query is optional. See Context and bindings for configuration workflows.

All routes start with /v1/organizations/{organizationId}. Session, active membership, selected-role data permissions, origin checks and POST CSRF still apply. Configuration is Owner-only.

Contexts ​

Pass a JSON object of named record IDs in contexts, URL-encoded for GET:

text
/groups/{groupId}/rows?contexts={"student":"<Student record ID>"}

A group can declare Student context optional and use an explicit source scope. Omit it to get all permitted rows; supply it to narrow the same group. Invalid or unauthorized supplied contexts fail instead of falling back to all rows. View-declared contexts are required; an empty context list supports all-records views.

Bindings ​

MethodPathPurpose
GET/groups/{groupId}Authorized metadata for the supplied context
GET/groups/{groupId}/rowsMixed-record display rows and per-cell edit/revision metadata
GET/groups/{groupId}/bindings/{bindingKey}/optionsLive allowed relationship choices; requires rowId
POST/groups/{groupId}/bindings/{bindingKey}/valueSave one bound field or relationship

Contextual row pages accept limit (1–50, default 25) and after (record ID cursor). They return rows with id, values, cells, hasMore and nextCursor. Display and eligibility paths are explicit and bounded to two relationships. Hidden related records/fields do not expose IDs or values.

Field write:

json
{
  "contexts":{"student":"<Student ID>"},
  "rowId":"<Grade ID>",
  "groupVersion":1,
  "revision":2,
  "value":88
}

The destination comes from the saved binding, not a caller-supplied record/field name. Revision is the destination record's current revision. Schema validation and the underlying field's write permission remain enforced.

Relationship write:

json
{
  "contexts":{"student":"<Student ID>"},
  "rowId":"<Grade ID>",
  "groupVersion":1,
  "edgeRevision":1,
  "expectedTargetObjectId":"<current Teacher ID>",
  "targetObjectId":"<selected Teacher ID>",
  "queryVersion":1
}

The selector's query is run again on save; forged, stale, cross-tenant or no-longer-eligible choices are rejected. Use null targetObjectId to clear an assignment. Members need the parent data policy's explicit relationshipWriteIds grant as well as Update, group edit access and any eligibility condition. A selector changes the relationship, not the Teacher's name. Relationship replacement is fail-closed under the organization mutation lock; multi-document transactional guarantees are not claimed.

Views ​

MethodPathPurpose
GET/viewsRole-visible views and required context declarations
GET/views?manage=1Owner configuration catalog
POST/viewsCreate/update/retire a view
GET/views/{viewId}Render authorized placements using supplied contexts

A view definition contains name/key, contexts, userTypeIds and placements. Each placement has a unique key, groupId, contextMap, and optional restriction (readBindingKeys, editBindingKeys, readOnly, userTypeIds). Updates require id/version; retirement uses id/version/action=remove.

For group requests through a view, also supply viewId, placementKey and viewVersion. The server validates the view, requires its contexts, and derives the group context mapping itself. Placement restrictions intersect group/underlying permissions. Omitting a required view context cannot broaden the placement. Non-Owners must supply an authorized View placement for Group metadata, rows, lookups and mutations; omission fails with VIEW_REQUIRED. Independent record APIs retain their own data-policy checks.

Contextual groups support reading, per-binding updates and explicitly enabled anchor-record creation/deletion. Legacy query-backed groups remain supported as Owner previews. Bulk/multi-record creation, unrestricted relationship traversal and arbitrary expressions are not supported.

Records and summaries update ​

Owner Records, contextual anchor-record creation/deletion and permission-aware summary groups are implemented. See Records and summary groups. Authorized record search and prompted action record pickers are available. Multi-record creation remains planned.

Selected-record View navigation ​

Owner-only GET /navigations lists reusable navigation definitions. POST /navigations creates or updates them; updates require id and version. Retirement uses {id,version,action:"remove"} and is blocked while placement buttons reference the definition.

json
{
  "name": "Manage Student",
  "key": "manage-student",
  "kind": "openView",
  "targetViewId": "<Student Details View ID>",
  "inputs": [{"key":"student","objectTypeId":"<Student ObjectType ID>"}]
}

Inputs must exactly match the destination View's required context names and types. Keys are immutable; definitions have optimistic versions and bounded audit history. Only active definitions in the same organization can be referenced. At most 200 active navigation definitions and 10 buttons per placement are supported.

A View placement may include:

json
{
  "buttons": [{
    "key": "manage-student",
    "navigationId": "<navigation ID>",
    "label": "Manage Student",
    "selection": "single",
    "inputMap": {"student":{"kind":"selectedRow"}}
  }]
}

Alternatively an input source can be { "kind":"viewContext", "key":"student" }. Every mapping must match the required ObjectType. Optional userTypeIds restricts button visibility; it cannot grant access. Summary rows cannot supply record navigation. Tables enable toolbar buttons for one selected saved record; form groups use their chosen saved record. Navigation opens a same-tab View URL with named context query parameters, which the existing loader supplies automatically.

Runtime View responses include authorized buttons beside each placement's group. Buttons targeting Views hidden from the selected role are omitted. Destination View/context/record authorization remains authoritative even for manually changed URLs. Navigation never grants CRUD permissions or executes a state-changing DynamicAction. Referenced destination context contracts, navigation targets/inputs, and source row types cannot change incompatibly. Remove references before retiring a destination View.

Definition presentation ​

Groups and Views accept a plain-text description (maximum 4000 UTF-8 bytes). View definitions additionally accept:

json
{
  "appearance": {
    "backgroundColor": "#f1f5f9",
    "borderColor": "#cbd5e1",
    "density": "compact",
    "showBackButton": true,
    "showTitle": true,
    "showFavorite": false
  }
}

Colors accept six-digit hexadecimal values or null for the default. Density is compact or comfortable; display options are booleans. Unknown appearance keys and arbitrary CSS are rejected. Defaults preserve the back link and title, hide the header favorite star, and use compact spacing. Omitting description/appearance on an existing definition preserves its saved values. Appearance changes use the same Owner authorization, version checks and bounded audit history as other definition changes.

View placements may include a plain-text title (maximum 200 UTF-8 bytes), falling back to the Group name. Runtime View responses include the resolved title for each placement, description, appearance and canModify. Runtime Group metadata includes description and canModify; current capability is true only in Owner mode. Presentation metadata never authorizes configuration or data writes.

Explicit action buttons ​

Views and non-summary placements support actionButtons, separate from navigation buttons. Each action button has key, actionId, selection (none or placement-only single), and an inputMap mapping each action record input to {kind:"prompt"}, {kind:"viewContext",key:…}, or {kind:"selectedRow"}. Optional label, icon, tooltip, description customize presentation; absent labels use the action name. Optional userTypeIds can only narrow action visibility. Icons use the existing allowlist.

Owner-only GET/POST /actions manages versioned action definitions. POST /actions/{id}/prepare, /options, /execute requires a valid authorized View/button invocation, current versions and input revisions. Actions never authorize standalone member Group access. Runtime button metadata is not an execution grant; APIs enforce action role grants, record/field scope, connection creation grants, group/placement constraints and conditions again. Definition dependencies protect referenced types, fields, roles and relationships; referenced actions cannot be retired or have their input/type contracts changed without first updating buttons.

Sheets, filters and inherited buttons ​

Contextual Group definitions accept renderer: "sheet" and sheetFormats, alongside defaultSort and the existing bindingModel. Sheets use the same rows, objects and binding-write routes as Groups; there is no separate Sheet CRUD API. Formatting affects presentation only.

Group definitions also accept navigationButtons, actionButtons and linkButtons. View placements inherit Group buttons and may disable, hide, narrow or reposition them. Runtime rendering and action invocation enforce the same effective policy; a read-only placement cannot execute a mutation action. See custom Group buttons.

Enabled search and column filters operate on authorized rows before pagination. Filters support up to twenty readable columns, each with one to three All/Any conditions. Groups across columns combine with AND and intersect search. Summary results reject search/filter requests. Filtering never grants access to unreadable bindings. See Group filtering.

Dynamic Tables — product guides and API reference.