Skip to main content
This walkthrough sets up organizational structure: a new local center (chapter, branch, regional office), the admins who run it, and the per-domain permissions that scope what they can do. It uses the LocalCenter, Unit, UserRole, and Role resources. Who is this for: enterprise-onboarding integrations that spin up multi-tenant structure programmatically, federation tools that synchronize org-chart changes from an upstream system, or admin dashboards that need to audit permissions in bulk.

Concepts

The three permission domains

Orgo splits permissions into three domains. Each domain has its own roles. Granting one doesn’t grant the others. Each domain has three scope levels: TENANT (whole org), PARENT_LOCAL (a local center and everything under it), and LOCAL (one specific local center). So HR_LOCAL means “manages people for this one local center”, ADMIN_TENANT means “configures the whole organization”. The combinations make 9 distinct permission scopes; see Permissions for the full matrix.

Where local centers fit

A LocalCenter is a kind of Unit. Units are the generic grouping primitive — local centers, role groups (automatic membership by role), private project teams. Most permission scopes attach to a specific Unit (which, for local-scope roles, is the LocalCenter itself).

Step 1 — Create a local center

isPublic: true makes the local center appear on the public “find your center” map and listing. isActive: false hides it from new-member registration forms while keeping it visible to admins. Response carries the integer id you’ll use for /api/v1/local_centers/{id} references throughout the rest of the system.

Step 2 — Create a role definition

Roles are the named permission containers (“Chapter Lead”, “Treasurer”, “Outreach Coordinator”). Create one per distinct responsibility:
Roles live at the tenant level — they’re reusable across local centers. The permission strings are constants; the full list lives at GET /api/v1/permission_definitions (or see Permissions).

Step 3 — Assign the role to a user, scoped to a unit

The scoping happens at assignment time. The same role can be assigned to different users with different unit scopes.
This grants James Patterson the “Chapter Lead” role for the Boston local center only. He cannot HR-manage Manchester members. Multiple UserRole assignments stack. A user can be Chapter Lead in Boston, Outreach Coordinator in Manchester, and Treasurer at the tenant level — three separate UserRole records.

Step 4 — Audit who has what

Who admins this local center?

The response includes each assignment with the user, role, and assignment date. hydra:totalItems gives the count.

Every assignment for one user

Useful for “show me everything James can do” before revoking.

The org chart

Returns a structured view of every person + role across the tenant, suitable for rendering an org chart.

Step 5 — Revoke

Delete the UserRole record:
The user’s underlying User account is untouched — they remain a member; they just lose the elevated permissions immediately. Active sessions are not invalidated; revocation takes effect on the next request that re-evaluates permissions (which, for most endpoints, is the next request).

Step 6 — Restructure the hierarchy (parent locals)

For federations with regional hierarchy (“Northeast Region” containing Boston, New York, Philadelphia), set a parent on each local center:
Now anyone with HR_PARENT_LOCAL on the parent (Northeast Region) can manage all children — Boston, New York, Philadelphia — without needing individual HR_LOCAL grants on each.

Step 7 — Self-service join

For local centers configured as isOpen: true, members can join themselves:
Creates a UserRole with the default member role for that local center. Useful for self-organizing chapters where any member can join.

Common gotchas

ADMIN_TENANT is the configuration domain — it grants access to settings, branding, modules. It does NOT grant HR (manage people) or FINANCIAL (manage payments). To grant truly everything, assign all three: ADMIN_TENANT, HR_TENANT, FINANCIAL_TENANT. This is intentional — it separates the “configure the org” role from the “see member PII” role from the “issue refunds” role.
Local centers with active members, ongoing fees, or unresolved payments cannot be deleted. Reassign members to another center first (PATCH /api/v1/users/{id} setting localCenter to the new one), then close out fees, then delete.
PARENT_LOCAL scope only cascades when the parent relationship is set via local_centers.parent. Setting it via the Unit hierarchy alone doesn’t grant cascading permissions on local-center-scoped queries. If cascading isn’t working, double-check the LocalCenter has parent set correctly, not just the Unit.
Two options: (1) automatic role groups — create a Unit of type “role group” filtered by membership criteria; new members auto-join. (2) Loop on the client side — paginate through GET /api/v1/users?localCenter=... and POST one UserRole per. The bulk endpoint doesn’t exist for role assignment because the side effects (audit log, permission cache invalidation) are per-user.

What to do next

  • Permissions — the full domain × scope matrix
  • Onboard a new member — the adhesion side of getting members into a local center
  • Tenancy — how tenant isolation interacts with local-center scoping