Quick Summary: Org structure is two unrelated things. Eleven flat dimensions — businessUnits, divisions, businessRegions, countries, states, cities, sites, buildings, departments, teams, shifts — say where someone sits; the manager hierarchy says who they report to. They share nothing, and the dimensions have no parent-child structure between them.
Dimension values
Every dimension behaves identically. A value is{ id, name, isActive }:
GET /api/v1/org/dimensions— the eleven keys.GET /api/v1/org/{dimension}— every value, deactivated ones included.POST /api/v1/org/{dimension}— create (name only; no ordering exists).PATCH /api/v1/org/{dimension}/{id}— rename, orisActive: falseto deactivate;isActive: truereactivates.DELETE /api/v1/org/{dimension}/{id}— deactivates the value. Org values are retired, never removed, exactly as in the app:DELETEandPATCH { "isActive": false }are the same operation. It is idempotent (an already-inactive value returns204) and needs no confirmation; theconfirmquery parameter is deprecated and ignored.GET /api/v1/org/{dimension}/{id}/usage— how many people hold the value, before deactivating it.GET /api/v1/org/{dimension}/{id}/people— everyone holding the value.
What deactivation does
Deactivating a value through the API does what deactivating it in Settings > Org Schema does:- The value leaves every person’s profile — its membership rows are removed, so
GET .../usagereportspeopleCount: 0andGET .../peopleis empty. - Draft surveys and draft assessments that targeted the value drop it. Launched ones are untouched.
- The value stays readable with
isActive: falseand reappears inGET /api/v1/org/{dimension}as inactive.PATCH { "isActive": true }brings it back. - The dimension’s history records who deactivated it (the key’s acting person).
true, so such a value keeps its memberships. GET .../usage shows whether that happened.
Deactivation never clears the legacy single-value columns on the person record (departments and businessRegions); usage.personRecordCount keeps that drift visible.
A person’s placement
Placement is many-to-many — someone can belong to two sites or three teams. It lives on the Person resource:GET|POST|DELETE /api/v1/people/{id}/org-schema (additive attach / explicit detach) and PUT /api/v1/people/{id}/org-schema/{dimension} to replace one dimension exactly.
Countries come from a fixed list.
POST /api/v1/org/countries takes a name that must match a country exactly as GET /api/v1/countries lists it (the same global list the app offers); any other name is a 400 on name. The other ten dimensions accept any name.One representation is published. Internally five org facts also exist in a second, legacy form on the person record (single-value department and business-region columns, free-text city/state/country strings). The API reads and writes the membership form only; the usage read reports legacy-column references for departments and businessRegions so any drift is visible.Manager hierarchy
GET /api/v1/org/manager-tree— the company’s reporting hierarchy as flat parent-pointer rows ordered by depth (roots at level 0), company-scoped, paginated.GET /api/v1/people/{id}/span-of-control— one person’s subtree, subject included at level 0.
PATCH /api/v1/people/{id}/manager on the Person resource.