Skip to content

Organizations

Endpoints for managing organizations, their members, and invitations.

Base path: /api/organizations

Authentication: All endpoints require a valid session.


Endpoints

Organization CRUD

Method Path Min Role Description
GET /api/organizations OrganizationAdmin List organizations
POST /api/organizations PlatformAdmin Create an organization
GET /api/organizations/:id OrganizationAdmin Get organization details
PATCH /api/organizations/:id OrganizationAdmin Update organization
DELETE /api/organizations/:id PlatformAdmin Archive organization

Organization Members

Method Path Min Role Description
GET /api/organizations/:id/users Coach List organization members
POST /api/organizations/:id/users OrganizationAdmin Add a user to the organization
PATCH /api/organizations/:id/users/:userId OrganizationAdmin Update a member's role or status
DELETE /api/organizations/:id/users/:userId OrganizationAdmin Disable a member's access

Invitations

Method Path Min Role Description
GET /api/organizations/:id/invites Manager List pending invites
POST /api/organizations/:id/invites Manager Create or resend an invite

GET /api/organizations

List organizations.

  • PlatformAdmin: Returns all organizations in the system with optional filters.
  • OrganizationAdmin: Returns only their own organization.

Query parameters:

Parameter Type Description
limit integer Max records (default: 100, max: 1000)
offset integer Records to skip (default: 0)
search string Filter by org name (case-insensitive, partial match)
status string Filter by status: active, inactive, suspended, or archived

Response 200:

{
  "data": [
    {
      "id": "org-uuid",
      "name": "Praxia Academy",
      "description": "Educational consultants",
      "logoUrl": null,
      "status": "active",
      "settings": {},
      "defaultTimezone": "UTC",
      "createdAt": "2025-01-01T00:00:00.000Z",
      "updatedAt": "2025-01-01T00:00:00.000Z"
    }
  ],
  "meta": {
    "total_count": 5
  }
}

POST /api/organizations

Create a new organization. Only PlatformAdmin can create organizations.

Request body:

{
  "name": "Praxia Academy",
  "description": "Educational consultants",
  "logoUrl": "https://...",
  "status": "active",
  "settings": {}
}
Field Type Required Constraints
name string Yes 1–255 characters
description string No Free text
logoUrl string No Must be a valid URL
status string No active, inactive, suspended, or archived (default: active)
settings object No Arbitrary JSON settings

Response 201:

{
  "data": {
    "id": "org-uuid",
    "name": "Praxia Academy",
    "description": "Educational consultants",
    "logoUrl": null,
    "status": "active",
    "settings": {},
    "createdAt": "2025-01-01T00:00:00.000Z",
    "updatedAt": "2025-01-01T00:00:00.000Z"
  }
}

GET /api/organizations/:id

Get a single organization by ID.

  • PlatformAdmin: Can view any organization.
  • OrganizationAdmin: Can only view their own organization.

Path parameters:

Parameter Type Description
id string Organization UUID

Response 200:

{
  "data": {
    "id": "org-uuid",
    "name": "Praxia Academy",
    "description": "Educational consultants",
    "logoUrl": null,
    "status": "active",
    "settings": {},
    "createdAt": "2025-01-01T00:00:00.000Z",
    "updatedAt": "2025-01-01T00:00:00.000Z"
  }
}

Error responses:

Code Condition
403 OrganizationAdmin attempting to view another org
404 Organization not found

PATCH /api/organizations/:id

Update organization details.

  • PlatformAdmin: Can update any organization.
  • OrganizationAdmin: Can only update their own organization.

Path parameters:

Parameter Type Description
id string Organization UUID

Request body (all fields optional):

{
  "name": "Praxia Academy (Updated)",
  "description": "Updated description",
  "logoUrl": "https://...",
  "status": "inactive",
  "settings": { "theme": "dark" },
  "defaultTimezone": "America/New_York"
}
Field Type Constraints
name string 1–255 characters
description string Free text
logoUrl string Must be a valid URL
status string active, inactive, suspended, or archived
settings object Arbitrary JSON settings
defaultTimezone string IANA timezone identifier (e.g. America/New_York); max 100 chars

Response 200:

{
  "data": {
    "id": "org-uuid",
    "name": "Praxia Academy (Updated)",
    ...
  }
}

Error responses:

Code Condition
403 OrganizationAdmin attempting to update another org
404 Organization not found

DELETE /api/organizations/:id

Archive an organization (soft delete). Sets status = 'archived'.

Min role: PlatformAdmin

Path parameters:

Parameter Type Description
id string Organization UUID

Response 200:

{
  "success": true
}

GET /api/organizations/:id/users

List members of an organization.

Access rules:

  • PlatformAdmin can list members of any org.
  • OrganizationAdmin, Manager, Coach can only list members of their own org.
  • Manager cannot see OrganizationAdmin members.
  • Coach only sees active Teacher members (used by the mentorship creation UI).

Path parameters:

Parameter Type Description
id string Organization UUID

Query parameters:

Parameter Type Description
limit integer Max records (default: 100, max: 1000)
offset integer Records to skip (default: 0)
search string Filter by email or display name
role string Filter by org role (e.g. Coach, Teacher)

Response 200:

{
  "data": [
    {
      "id": "user-cuid",
      "email": "jane@example.com",
      "status": "active",
      "firstName": "Jane",
      "lastName": "Smith",
      "avatarUrl": null,
      "roleInOrganization": "Coach",
      "isPrimary": true,
      "membershipStatus": "active",
      "joinedAt": "2025-01-15T09:00:00.000Z"
    }
  ],
  "meta": {
    "total_count": 12
  }
}

Error responses:

Code Condition
403 Caller is not a member of this org (or viewing a restricted org)

POST /api/organizations/:id/users

Add an existing user to the organization and assign them a role.

Min role: OrganizationAdmin

Path parameters:

Parameter Type Description
id string Organization UUID

Request body:

{
  "userId": "user-cuid",
  "roleInOrganization": "Coach",
  "isPrimary": false
}
Field Type Required Constraints
userId string Yes Must be an existing user CUID
roleInOrganization string Yes One of OrganizationAdmin, Manager, Coach, Teacher
isPrimary boolean No Mark as primary org (default: false)

Response 201:

{
  "data": {
    "organizationId": "org-uuid",
    "userId": "user-cuid",
    "roleInOrganization": "Coach",
    "isPrimary": false,
    "membershipStatus": "active",
    "joinedAt": "2025-04-01T12:00:00.000Z"
  }
}

Error responses:

Code Condition
403 Caller is modifying a different org
409 User is already a member of this organization

PATCH /api/organizations/:id/users/:userId

Update a member's role in the organization or re-enable a disabled membership.

Min role: OrganizationAdmin

Path parameters:

Parameter Type Description
id string Organization UUID
userId string User CUID

Request body (all fields optional):

{
  "roleInOrganization": "Manager",
  "isPrimary": true,
  "membershipStatus": "active"
}
Field Type Constraints
roleInOrganization string OrganizationAdmin, Manager, Coach, or Teacher
isPrimary boolean Mark as primary org
membershipStatus string active or disabled

Response 200:

{
  "data": {
    "organizationId": "org-uuid",
    "userId": "user-cuid",
    "roleInOrganization": "Manager",
    "isPrimary": true,
    "membershipStatus": "active",
    "updatedAt": "2025-04-01T12:00:00.000Z"
  }
}

Error responses:

Code Condition
403 Caller is modifying a different org
404 Membership not found

DELETE /api/organizations/:id/users/:userId

Soft-disable a user's membership. Sets membershipStatus = 'disabled'. The user loses org-scoped access immediately but their data (mentorships, sessions, files) is preserved.

To restore access, call PATCH /api/organizations/:id/users/:userId with { "membershipStatus": "active" }.

Min role: OrganizationAdmin

Path parameters:

Parameter Type Description
id string Organization UUID
userId string User CUID

Response 200:

{
  "success": true
}

Error responses:

Code Condition
403 Caller is modifying a different org
404 Membership not found

GET /api/organizations/:id/invites

List pending, non-expired invitations for the organization.

Access rules:

  • PlatformAdmin and Owner can list invites for any org.
  • OrganizationAdmin can see all pending invites for their org.
  • Manager can only see invites for Coach and Teacher roles.

Path parameters:

Parameter Type Description
id string Organization UUID

Response 200:

{
  "data": [
    {
      "id": "invite-uuid",
      "email": "newcoach@example.com",
      "roleInOrganization": "Coach",
      "status": "pending",
      "expiresAt": "2025-04-15T12:00:00.000Z",
      "createdAt": "2025-04-08T12:00:00.000Z"
    }
  ],
  "meta": {
    "total_count": 3
  }
}

POST /api/organizations/:id/invites

Create a new invitation or resend an existing pending invite to the same email address.

Access rules:

  • OrganizationAdmin, PlatformAdmin, and Owner can invite any org role.
  • Manager can only invite Coach and Teacher roles.

If a pending invite already exists for the same email in this org, it is updated (expiry reset, token regenerated) and the invite email is resent. The response is 200 in that case; 201 for a new invite.

Path parameters:

Parameter Type Description
id string Organization UUID

Request body:

{
  "email": "newcoach@example.com",
  "roleInOrganization": "Coach",
  "expiresInDays": 7
}
Field Type Required Constraints
email string Yes Valid email address
roleInOrganization string Yes OrganizationAdmin, Manager, Coach, or Teacher
expiresInDays integer No 1–30 (default: 7)

Response 201 (new invite):

{
  "data": {
    "id": "invite-uuid",
    "email": "newcoach@example.com",
    "roleInOrganization": "Coach",
    "status": "pending",
    "expiresAt": "2025-04-15T12:00:00.000Z",
    "inviteToken": "abc123..."
  }
}

inviteToken in non-production

The inviteToken field is only included in non-production environments to aid development and testing.

Error responses:

Code Condition
403 Caller is from a different org, or Manager attempting to invite a Manager or above
500 Failed to create or update the invite record