Skip to main content
The org tree, branches and who sits where — the surfaces the OrgStructure and Branches pages manage. Reads take org:view, shaping the tree and branches takes org:configure, placing users on nodes takes org:assign.

The tree

Node types and the ladder they hang on: regioncountrybranchteamagent. A branch may hang directly under a region, an agent under anything, and any node may be a root. A branch node can be linked to a branch record (branch_id, one node per branch) and a team node to a team (team_id). Re-parenting is checked for cycles (409 CONFLICT, details.reason: cycle) and re-validated against the ladder. Deleting a node with children is refused (409 CONFLICT, details.reason: has_children) unless you pass cascade=true; the response then lists every deleted_ids entry, since the database takes the whole subtree and its memberships in one go.

Placement is reach

A membership (PUT …/members/{user_id}) is how a user gets team or branch reach in the visibility engine: with visibility_scope: full they see the whole subtree under that node, with own only their own records there. The same rules narrow an API key’s reads to what its owner may see, so moving a subtree or a member changes what both the UI and the API return for them. Role-level reach per module is read from GET /v1/visibility-scopes. A user’s branch_id (set on POST/PATCH /v1/users) is the branch they work in; an org-node membership is where they sit in the tree. Both matter: the branch on a record is matched against the user’s accessible branches, and the record’s org_node_id against their subtree.

Branches

Deleting a branch is refused while anything still references it: the response carries details.reason: in_use and details.references with counts of users, org nodes, teams, leads, deals and accounts. Reassign or remove those first. Every write records an auditlog row naming the API key that acted.