# Workspaces API

Workspaces are the top-level organizational unit in LVNG. They scope channels, agents, workflows, and team members. Each workspace has its own visibility settings, member roles (owner, admin, member), and configurable settings. Users can belong to multiple workspaces. All endpoints require JWT authentication and are rate-limited to 100 requests per minute.

---

## Health Check

### GET /api/v2/workspaces/health

Returns service health status.

**Example Request**

```bash
curl -X GET https://api.lvng.ai/api/v2/workspaces/health \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response -- 200**

```json
{
  "status": "healthy",
  "service": "workspaces-api-v2"
}
```

---

## Workspace CRUD

Create, retrieve, update, and delete workspaces. List returns only workspaces where the user is a member. The creator is automatically added as owner.

### GET /api/v2/workspaces

List all workspaces the authenticated user belongs to.

**Example Request**

```bash
curl -X GET https://api.lvng.ai/api/v2/workspaces \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response -- 200**

```json
{
  "success": true,
  "workspaces": [
    {
      "id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
      "name": "LVNG Engineering",
      "slug": "lvng-engineering",
      "description": "Engineering team workspace for product development",
      "owner_id": "8f3a2b1c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
      "created_at": "2026-01-10T08:00:00.000Z",
      "updated_at": "2026-03-19T10:00:00.000Z",
      "settings": {},
      "my_role": "owner",
      "is_owner": true
    }
  ],
  "count": 2
}
```

---

### POST /api/v2/workspaces

Create a new workspace. The authenticated user is automatically added as the owner.

**Body Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `name` | string | Yes | Display name for the workspace. |
| `slug` | string | Yes | URL-safe identifier. Must be lowercase alphanumeric with hyphens. |
| `description` | string | No | A brief description of the workspace purpose. |
| `visibility` | string | No | Workspace visibility: public, private, or invite-only. Default: `private` |
| `discoverable` | boolean | No | Whether the workspace appears in search/discovery. Default: `false` |
| `settings` | object | No | Initial workspace settings object. |

**Example Request**

```bash
curl -X POST https://api.lvng.ai/api/v2/workspaces \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Marketing Hub",
    "slug": "marketing-hub",
    "description": "Central workspace for marketing campaigns and analytics",
    "visibility": "private",
    "discoverable": false
  }'
```

**Response -- 201**

```json
{
  "success": true,
  "workspace": {
    "id": "d4e5f6a7-b8c9-0123-def4-567890123456",
    "name": "Marketing Hub",
    "slug": "marketing-hub",
    "description": "Central workspace for marketing campaigns and analytics",
    "owner_id": "8f3a2b1c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
    "visibility": "private",
    "discoverable": false,
    "settings": {},
    "created_at": "2026-03-19T18:30:00.000Z",
    "updated_at": "2026-03-19T18:30:00.000Z",
    "my_role": "owner",
    "is_owner": true
  }
}
```

---

### GET /api/v2/workspaces/:id

Get detailed workspace information. Verifies the user is a member.

**Path Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `id` | uuid | Yes | The workspace ID. |

**Example Request**

```bash
curl -X GET https://api.lvng.ai/api/v2/workspaces/b2c3d4e5-f6a7-8901-bcde-f23456789012 \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response -- 200**

```json
{
  "success": true,
  "workspace": {
    "id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
    "name": "LVNG Engineering",
    "slug": "lvng-engineering",
    "description": "Engineering team workspace for product development",
    "owner_id": "8f3a2b1c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
    "settings": {},
    "member_count": 12,
    "my_role": "owner",
    "is_owner": true,
    "created_at": "2026-01-10T08:00:00.000Z",
    "updated_at": "2026-03-19T10:00:00.000Z"
  }
}
```

---

### PUT /api/v2/workspaces/:id

Update workspace properties. Requires admin or owner role.

**Path Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `id` | uuid | Yes | The workspace ID. |

**Body Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `name` | string | No | Updated workspace name. |
| `description` | string | No | Updated description. |
| `visibility` | string | No | Updated visibility: public, private, or invite-only. |
| `discoverable` | boolean | No | Updated discoverability setting. |
| `settings` | object | No | Updated settings object (replaces existing). |

**Example Request**

```bash
curl -X PUT https://api.lvng.ai/api/v2/workspaces/b2c3d4e5-f6a7-8901-bcde-f23456789012 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "LVNG Engineering & Platform",
    "description": "Engineering and platform team workspace"
  }'
```

**Response -- 200**

```json
{
  "success": true,
  "workspace": {
    "id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
    "name": "LVNG Engineering & Platform",
    "slug": "lvng-engineering",
    "description": "Engineering and platform team workspace",
    "updated_at": "2026-03-19T18:40:00.000Z"
  }
}
```

---

### DELETE /api/v2/workspaces/:id

Delete a workspace and all related data (CASCADE). Only the workspace owner can delete.

**Path Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `id` | uuid | Yes | The workspace ID. |

**Example Request**

```bash
curl -X DELETE https://api.lvng.ai/api/v2/workspaces/d4e5f6a7-b8c9-0123-def4-567890123456 \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response -- 200**

```json
{
  "success": true,
  "message": "Workspace deleted successfully"
}
```

---

## Workspace Members

Manage team members within a workspace. Members have roles: owner, admin, or member.

### GET /api/v2/workspaces/:id/members

List all members of a workspace with profile data and online status.

**Path Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `id` | uuid | Yes | The workspace ID. |

**Query Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `search` | string | No | Filter members by name or email (case-insensitive). |
| `role` | string | No | Filter by role: owner, admin, or member. |
| `limit` | integer | No | Maximum number of members to return. Default: `50` |
| `offset` | integer | No | Pagination offset. Default: `0` |

**Example Request**

```bash
curl -X GET "https://api.lvng.ai/api/v2/workspaces/b2c3d4e5-f6a7-8901-bcde-f23456789012/members?role=admin" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response -- 200**

```json
{
  "success": true,
  "members": [
    {
      "id": "mem_1a2b3c4d-5e6f-7890-abcd-ef1234567890",
      "user_id": "8f3a2b1c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
      "role": "owner",
      "joined_at": "2026-01-10T08:00:00.000Z",
      "email": "matty@lvng.ai",
      "display_name": "Matty Squarzoni",
      "avatar_url": "https://cdn.lvng.ai/avatars/matty.jpg",
      "job_title": "CEO",
      "online_status": "online"
    }
  ],
  "count": 2,
  "total": 12
}
```

---

### GET /api/v2/workspaces/:id/members/:userId

Get detailed member profile including shared channels and DM link.

**Path Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `id` | uuid | Yes | The workspace ID. |
| `userId` | uuid | Yes | The user ID of the member. |

**Example Request**

```bash
curl -X GET https://api.lvng.ai/api/v2/workspaces/b2c3d4e5-f6a7-8901-bcde-f23456789012/members/2a3b4c5d-6e7f-8901-abcd-ef2345678901 \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response -- 200**

```json
{
  "success": true,
  "member": {
    "user_id": "2a3b4c5d-6e7f-8901-abcd-ef2345678901",
    "role": "admin",
    "email": "sarah@lvng.ai",
    "display_name": "Sarah Chen",
    "job_title": "Engineering Lead",
    "online_status": "offline",
    "shared_channels": [
      { "id": "ch_1a2b3c4d", "name": "general", "is_private": false },
      { "id": "ch_2b3c4d5e", "name": "engineering", "is_private": true }
    ],
    "dm_id": "dm_3c4d5e6f-7890-1234-abcd-ef5678901234",
    "is_self": false
  }
}
```

---

### POST /api/v2/workspaces/:id/members

Add a user to the workspace. Returns 409 if user is already a member.

**Path Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `id` | uuid | Yes | The workspace ID. |

**Body Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `user_id` | uuid | Yes | The user ID to add. |
| `role` | string | No | Role to assign: owner, admin, or member. Default: `member` |
| `message` | string | No | Message to include with join request. |

**Example Request**

```bash
curl -X POST https://api.lvng.ai/api/v2/workspaces/b2c3d4e5-f6a7-8901-bcde-f23456789012/members \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "4c5d6e7f-8091-0234-cdef-456789012345",
    "role": "member"
  }'
```

**Response -- 201**

```json
{
  "success": true,
  "member": {
    "id": "mem_4c5d6e7f-8091-0234-cdef-456789012345",
    "workspace_id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
    "user_id": "4c5d6e7f-8091-0234-cdef-456789012345",
    "role": "member",
    "invited_by": "8f3a2b1c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
    "joined_at": "2026-03-19T18:50:00.000Z"
  }
}
```

---

### DELETE /api/v2/workspaces/:id/members/:userId

Remove a member from the workspace. The workspace owner cannot be removed.

**Path Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `id` | uuid | Yes | The workspace ID. |
| `userId` | uuid | Yes | The user ID to remove. |

**Example Request**

```bash
curl -X DELETE https://api.lvng.ai/api/v2/workspaces/b2c3d4e5-f6a7-8901-bcde-f23456789012/members/4c5d6e7f-8091-0234-cdef-456789012345 \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response -- 200**

```json
{
  "success": true,
  "message": "Member removed successfully"
}
```

---

### PATCH /api/v2/workspaces/:id/members/:userId

Update a member's role. Requires admin or owner role.

**Path Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `id` | uuid | Yes | The workspace ID. |
| `userId` | uuid | Yes | The user ID to update. |

**Body Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `role` | string | Yes | New role: owner, admin, or member. |

**Example Request**

```bash
curl -X PATCH https://api.lvng.ai/api/v2/workspaces/b2c3d4e5-f6a7-8901-bcde-f23456789012/members/3b4c5d6e-7f80-9012-bcde-f34567890123 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "role": "admin"
  }'
```

**Response -- 200**

```json
{
  "success": true,
  "member": {
    "user_id": "3b4c5d6e-7f80-9012-bcde-f34567890123",
    "role": "admin",
    "joined_at": "2026-01-15T14:00:00.000Z"
  }
}
```

---

## Settings & Permissions

### GET /api/v2/workspaces/:id/settings

Get workspace settings. Creates default settings if none exist.

**Path Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `id` | uuid | Yes | The workspace ID. |

**Example Request**

```bash
curl -X GET https://api.lvng.ai/api/v2/workspaces/b2c3d4e5-f6a7-8901-bcde-f23456789012/settings \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response -- 200**

```json
{
  "success": true,
  "settings": {
    "workspace_id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
    "allow_member_invite": true,
    "allow_conversation_creation": true,
    "allow_result_sharing": true,
    "require_admin_approval": false,
    "default_twin_mode": "active",
    "join_mode": null
  }
}
```

---

### PATCH /api/v2/workspaces/:id/settings

Update workspace settings. Requires workspace admin/owner role.

**Path Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `id` | uuid | Yes | The workspace ID. |

**Body Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `allow_member_invite` | boolean | No | Whether members can invite others. |
| `allow_conversation_creation` | boolean | No | Whether members can create conversations. |
| `allow_result_sharing` | boolean | No | Whether members can share results externally. |
| `require_admin_approval` | boolean | No | Whether new member additions require admin approval. |
| `default_twin_mode` | string | No | Default twin mode: active, observer, or on-demand. |
| `join_mode` | string | No | How users can join: open, request, or invite-only. |

**Example Request**

```bash
curl -X PATCH https://api.lvng.ai/api/v2/workspaces/b2c3d4e5-f6a7-8901-bcde-f23456789012/settings \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "require_admin_approval": true,
    "default_twin_mode": "observer",
    "join_mode": "request"
  }'
```

**Response -- 200**

```json
{
  "success": true,
  "settings": {
    "workspace_id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
    "require_admin_approval": true,
    "default_twin_mode": "observer",
    "join_mode": "request",
    "updated_at": "2026-03-19T19:10:00.000Z"
  }
}
```

---

### GET /api/v2/workspaces/:id/permissions

Get effective permissions for the authenticated user.

**Path Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `id` | uuid | Yes | The workspace ID. |

**Example Request**

```bash
curl -X GET https://api.lvng.ai/api/v2/workspaces/b2c3d4e5-f6a7-8901-bcde-f23456789012/permissions \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response -- 200**

```json
{
  "success": true,
  "permissions": {
    "role": "owner",
    "canViewSettings": true,
    "canEditSettings": true,
    "canManageMembers": true,
    "canInviteMembers": true,
    "canCreateConversations": true,
    "canDeleteWorkspace": true,
    "isOwner": true,
    "isOrgAdmin": false
  }
}
```

---

## Join Requests

Manage pending join requests for workspaces with admin approval enabled.

### GET /api/v2/workspaces/:id/requests

List join requests for the workspace. Requires admin or owner role.

**Path Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `id` | uuid | Yes | The workspace ID. |

**Query Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `status` | string | No | Filter by status: pending, approved, or rejected. Default: `pending` |

**Example Request**

```bash
curl -X GET "https://api.lvng.ai/api/v2/workspaces/b2c3d4e5-f6a7-8901-bcde-f23456789012/requests?status=pending" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response -- 200**

```json
{
  "success": true,
  "requests": [
    {
      "id": "a7b8c9d0-e1f2-3456-7890-abcdef123456",
      "user_id": "5d6e7f80-9102-3456-def0-567890123456",
      "status": "pending",
      "message": "I'd like to join the engineering workspace.",
      "created_at": "2026-03-19T15:00:00.000Z",
      "user": {
        "email": "jordan@example.com",
        "full_name": "Jordan Taylor"
      }
    }
  ],
  "count": 1
}
```

---

### PATCH /api/v2/workspaces/:id/requests/:requestId

Approve or reject a pending join request.

**Path Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `id` | uuid | Yes | The workspace ID. |
| `requestId` | uuid | Yes | The join request ID. |

**Body Parameters**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `action` | string | Yes | Action to take: approve or reject. |
| `rejection_reason` | string | No | Reason for rejection (optional). |

**Example Request**

```bash
curl -X PATCH https://api.lvng.ai/api/v2/workspaces/b2c3d4e5-f6a7-8901-bcde-f23456789012/requests/a7b8c9d0-e1f2-3456-7890-abcdef123456 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "approve"
  }'
```

**Response -- 200**

```json
{
  "success": true,
  "action": "approved",
  "request": {
    "id": "a7b8c9d0-e1f2-3456-7890-abcdef123456",
    "status": "approved",
    "reviewed_by": "8f3a2b1c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
    "reviewed_at": "2026-03-19T19:20:00.000Z"
  },
  "member": {
    "user_id": "5d6e7f80-9102-3456-def0-567890123456",
    "role": "member",
    "joined_at": "2026-03-19T19:20:00.000Z"
  }
}
```
