Overview
Two independent levers control what your end-users see in the embedded builder. End-users are the people using the builder, identified by their user key or the sub claim on their Discover JWT.
- Group rules on items. Put a
groupsformula on an action, trigger, or data field so only users whose groups satisfy the formula can see it. - Account default visibility. One account-level setting,
default_visibility, decides what an ungated item (one with nogroupsformula) is visible to.
Together they let you gate individual items by group and set a baseline for everything you haven't gated.
Browsing the catalog as the account owner (your API key or main user) shows you every item, so you can administer the full set. Gating only takes effect for end-users, so to see what a user sees, scope the request to them with their user_key (or use their JWT). One exception to owner-sees-all: a specific user's embedded data fields are always filtered to that user's own groups, even when you read them as the owner. See Common mistakes.
Most trouble with groups comes down to a few recurring errors: confusing a flat list (OR) with a nested one (AND), treating empty groups as "nobody" when it means "ungated," or a Discover JWT that silently wipes a user's groups. If visibility doesn't behave the way you expect, check Common mistakes first.
Group formula syntax
The groups field on an item holds a rule in OR-of-ANDs form. The shape of the array is the syntax: the outer array is an OR, and each inner array is an AND.
| You write | Means | Plain English |
|---|---|---|
["admin"] | admin | User must have admin. |
["admin", "viewer"] | admin OR viewer | A flat list is an OR: any one of these groups. |
[["inventory", "team"]] | inventory AND team | A nested clause is an AND: all groups in it. |
[["admin"], ["inventory", "team"]] | admin OR (inventory AND team) | OR across clauses, AND within a clause. |
[] or omitted | ungated | No rule. Governed by account default visibility. |
Rule of thumb: outer array is OR, inner array is AND. A plain flat list is the common case (any of these groups).
Here it is on an action type. The same groups field works the same way on triggers and on data fields:
1 2 3 4 5action_types: - name: Change Invoice Status groups: [["inventory", "team"]] # user needs BOTH inventory and team - name: Send Receipt groups: ["admin", "billing"] # user needs admin OR billing
Where you can set groups
The formula is identical on every item. What differs is whether you can set it through config import/export or only through the API.
| Item | Where groups lives | How to set it |
|---|---|---|
| Action types | On the action type | Config import/export and the REST API |
| Triggers | On the trigger | REST API only. Trigger groups are not applied on config import |
| Data fields | On a field in user_data_schema, a trigger's data_input_schema, or an action's response_data_schema | REST API |
Two caveats worth knowing: account data (account_data_schema) is global and is never group-filtered, so a groups rule there has no effect; and config export does not carry groups set on response_data_schema fields, so set those on the source if you re-import.
Config examples here are YAML; import also accepts JSON with the same structure, so use whichever you prefer.
Assigning groups to a user
A user's groups are their membership: a plain, flat list, not a formula. There are two ways to set it.
REST API, with PUT /api/v1/users/{key}:
1{ "groups": ["admin", "inventory"] }
Discover JWT, by including a groups claim in the identity token:
1 2 3 4 5 6 7{ "sub": "user_key_123", "name": "Alice", "email": "alice@example.com", "groups": ["admin", "inventory"], "discover": true }
The array you send becomes the user's complete group set. For the Discover JWT this matters a lot: the token is treated as the source of truth, so a token with no groups claim wipes the user's groups. Always include the complete groups array in every Discover token. See Common mistakes.
Account default visibility
default_visibility is an account-level setting that controls who sees ungated items (items with no groups formula). Set it with PUT /api/v1/account:
1{ "default_visibility": "all" }
It accepts exactly two values. Any other value is rejected.
| Value | Meaning |
|---|---|
all (default) | Ungated items are public. Every user sees them. |
none | Ungated items are private. A user sees an item only if their groups explicitly match its rule. |
default_visibility governs only ungated items. An item that has a groups rule is always gated on that rule regardless of this setting, so only a matching user sees it.
Embed Workflow's built-in building blocks (such as Delay, Loop, Paths, and WaitUntil) and the built-in recurring trigger are always available, even under none, so the builder stays usable. none hides your own ungated items, not the native building blocks.
The visibility rule
For a given user and item:
- Item has no
groupsrule (ungated): visible ifdefault_visibilityisall, hidden ifnone. - Item has a
groupsrule: visible if the user's groups satisfy at least one clause, meaning the user has every group named in that clause. Otherwise hidden. Default visibility doesn't apply to gated items.
Worked example, for an item with rule [["admin"], ["inventory", "team"]]:
| User's groups | Result | Why |
|---|---|---|
["admin"] | Sees it | Matches clause 1. |
["inventory", "team"] | Sees it | Matches clause 2. |
["inventory"] | Hidden | Missing team. |
[] | Hidden | Matches no clause. |
Common mistakes
These are the real support issues. Run through them before you rely on group gating.
| Symptom | Cause | Fix |
|---|---|---|
| An item needs two groups but shows for users who only have one | Flat list used where you meant AND. ["a", "b"] is a OR b | Nest the clause: [["a", "b"]] means a AND b |
Setting groups: [] to hide an item still shows it to everyone | Empty groups is ungated, not "nobody." It follows default_visibility | To hide from everyone-except-a-group, give a real rule. To hide ungated items globally, set default_visibility: none |
| A user's groups vanish after they sign in | A Discover JWT with no groups claim. Assignment is full-replace and the token is source of truth | Always include the complete groups array in every Discover token |
| Gating doesn't seem to work while testing | You're browsing as the account owner (API key or main user), who sees the full catalog | Test as an end-user by passing their user_key or using their JWT |
| Your whole catalog disappears for users after a settings change | Switched default_visibility to none, which hides every ungated item | Audit your items and add groups rules where needed before flipping it |
| A user with the right group still can't see an item | Group names don't match exactly. Admin is not admin, and trailing spaces count | Keep names identical between user membership and item rules |
| A user's membership list stops working as expected | Nested a user's membership like an item formula. On a user, groups is a flat list; on an item it's an OR/AND formula | Keep user membership flat; only item rules nest |
Next steps
- Authoring a Configuration: the full config structure, where
groupslives on each resource - Actions, Triggers, and Workflows: the items you gate
- Import Configuration: install a config through the admin portal
