Skip to main content

Add Org Member

API Endpoint: POST /admin/logto/orgs/{lawFirmId}/members

Priority: P1

User Story: As an admin, I want to add a user to a law firm's Logto organization with specific roles.

Overview

Add an existing Logto user to a law firm's organization with designated organization roles. This grants the user access to organization-scoped resources and enables role-based permissions within the firm.

Scenarios

Scenario 1: Add member with single role

Given:

  • Admin is authenticated with scope logto-orgs:write
  • Law firm firm_abc123 exists with logtoOrgId: "org_xyz789"
  • Logto user user_12345 exists
  • User is not currently a member of organization

When:

  • Admin POSTs to /admin/logto/orgs/firm_abc123/members with payload:
    {
    "logtoUserId": "user_12345",
    "orgRoles": ["member"]
    }

Then:

  • Response status is 201 Created
  • Response body contains:
    {
    "logtoUserId": "user_12345",
    "email": "john.doe@example.com",
    "name": "John Doe",
    "orgRoles": ["member"],
    "joinedAt": "2025-10-19T10:00:00Z"
    }
  • User is added to Logto organization
  • User can now access organization resources

Scenario 2: Add member with multiple roles

Given:

  • Admin is authenticated with scope logto-orgs:write
  • Law firm and Logto user exist
  • User is not an org member

When:

  • Admin POSTs with multiple roles:
    {
    "logtoUserId": "user_67890",
    "orgRoles": ["admin", "lawyer", "billing"]
    }

Then:

  • Response status is 201 Created
  • User is added with all specified roles
  • User receives combined permissions from all roles

Scenario 3: User already a member

Given:

  • Admin is authenticated with scope logto-orgs:write
  • User user_12345 is already a member of organization

When:

  • Admin attempts to add user again:
    {
    "logtoUserId": "user_12345",
    "orgRoles": ["admin"]
    }

Then:

  • Response status is 409 Conflict
  • Response body contains:
    {
    "error": "ALREADY_MEMBER",
    "message": "User 'user_12345' is already a member of organization. Use PUT /members/{userId}/roles to update roles."
    }

Scenario 4: Invalid organization role

Given:

  • Admin is authenticated with scope logto-orgs:write

When:

  • Admin POSTs with invalid role:
    {
    "logtoUserId": "user_12345",
    "orgRoles": ["invalid_role"]
    }

Then:

  • Response status is 400 Bad Request
  • Response body contains:
    {
    "error": "VALIDATION_ERROR",
    "message": "Invalid organization role",
    "details": [
    {
    "field": "orgRoles",
    "message": "Role 'invalid_role' is not defined for this organization. Available roles: admin, member, lawyer, paralegal, billing"
    }
    ]
    }

Scenario 5: Logto user not found

Given:

  • Admin is authenticated with scope logto-orgs:write
  • No Logto user with ID user_nonexistent

When:

  • Admin POSTs:
    {
    "logtoUserId": "user_nonexistent",
    "orgRoles": ["member"]
    }

Then:

  • Response status is 404 Not Found
  • Response body contains:
    {
    "error": "NOT_FOUND",
    "message": "Logto user with ID 'user_nonexistent' not found"
    }

Scenario 6: Empty roles array

Given:

  • Admin is authenticated with scope logto-orgs:write

When:

  • Admin POSTs with empty roles:
    {
    "logtoUserId": "user_12345",
    "orgRoles": []
    }

Then:

  • Response status is 400 Bad Request
  • Response body contains:
    {
    "error": "VALIDATION_ERROR",
    "message": "At least one organization role is required",
    "details": [
    {
    "field": "orgRoles",
    "message": "Array must contain at least one role"
    }
    ]
    }

Request Specification

Path Parameters

ParameterTypeRequiredDescription
lawFirmIdstringYesLaw firm identifier

Request Body

FieldTypeRequiredConstraintsDescription
logtoUserIdstringYesValid Logto user IDUser to add to organization
orgRolesarrayYesNon-empty array of valid role namesOrganization roles to assign

Validation Rules

RuleDescription
User uniquenessUser cannot already be org member
Roles non-emptyMust provide at least one role
Role validityAll roles must exist in Logto organization
User existsLogto user must exist

Response Specification

Success Response (201 Created)

{
"logtoUserId": "user_12345",
"email": "john.doe@example.com",
"name": "John Doe",
"avatar": "https://avatar.example.com/john.jpg",
"orgRoles": ["admin", "lawyer"],
"joinedAt": "2025-10-19T10:00:00Z"
}

Response Fields

FieldTypeDescription
logtoUserIdstringLogto user identifier
emailstring | nullUser's email address
namestring | nullUser's display name
avatarstring | nullAvatar URL
orgRolesarrayAssigned organization roles
joinedAtstringTimestamp when user joined org

Error Responses

StatusError CodeDescription
400VALIDATION_ERRORInvalid roles or empty roles array
401UNAUTHORIZEDMissing or invalid auth token
403FORBIDDENMissing logto-orgs:write scope
404NOT_FOUNDLaw firm or Logto user not found
409ALREADY_MEMBERUser already in organization
503SERVICE_UNAVAILABLELogto service unreachable

Requirements Mapping

  • FR-090: Accept POST with logtoUserId and orgRoles
  • FR-091: Validate user is not already org member
  • FR-092: Validate all roles are defined in organization
  • FR-093: Require at least one role
  • FR-094: Call Logto Management API to add member
  • FR-095: Return member details with assigned roles
  • FR-096: Return 409 if user already member
  • FR-097: Return 404 if Logto user not found
  • FR-098: Require logto-orgs:write scope

Notes

Member vs Profile

Adding a user to a Logto organization (this endpoint) is separate from creating a user profile in the law firm:

  • This endpoint: Adds Logto user to org for RBAC
  • Provision User endpoint: Creates law firm profile with functional roles

Both may be needed for complete user setup.

Organization Roles

Organization roles are managed in Logto and define permissions:

  • Predefined: admin, member
  • Custom: Defined per organization (e.g., lawyer, paralegal, billing)

Use GET /admin/logto/org-roles to list available roles.

Invitation Flow

For new users who don't have Logto accounts yet:

  1. Create Logto user (via separate Logto API or invitation)
  2. Use this endpoint to add them to organization
  3. User receives invitation email from Logto
  4. User accepts and joins organization

Automatic Cleanup

When a law firm is deleted:

  • Logto organization is automatically deleted
  • All memberships are removed
  • No manual cleanup required