---
title: Users, Roles & Invitations
excerpt: Manage workspace users, roles, organisations and user invitations via the API.
order: 5
---

All endpoints in this section are **workspace-scoped** unless stated otherwise.

**Headers:** `Authorization: Bearer {workspace-token}`

---

## Users

### GET /api/users

Returns a paginated list of users in the workspace. Supports filtering and sorting.

**Query parameters**

| Parameter | Description |
|---|---|
| `filter[name]` | Filter by name |
| `filter[email]` | Filter by email |
| `filter[phone]` | Filter by phone |
| `filter[term]` | Full-text search |
| `sort` | Sort field: `id`, `name`, `email`, `created_at`, `updated_at`. Prefix with `-` for descending (e.g. `-created_at`) |
| `per_page` | Results per page (default: 20) |
| `page` | Page number |

**Response `200`** — paginated response

```json
{
  "data": [
    {
      "id": 3,
      "name": "Bob Smith",
      "email": "bob@acme.com",
      "phone": "+33 1 00 00 00 00",
      "mobile_phone": null,
      "created_at": "2024-01-20T12:00:00Z",
      "updated_at": "2024-06-01T08:00:00Z"
    }
  ],
  "current_page": 1,
  "last_page": 1,
  "per_page": 20,
  "total": 1
}
```

---

### GET /api/users/{id}

Returns a single user. Requires admin group permission.

**Response `200`** — user object

**Response `403`** — not authorized

---

## Roles

### GET /api/roles

Returns all roles defined in the workspace.

**Response `200`**

```json
[
  { "id": 1, "name": "manager", "permissions_count": 12 },
  { "id": 2, "name": "agent", "permissions_count": 5 }
]
```

---

### GET /api/roles/{id}

Returns a single role with its full permission list.

**Response `200`**

```json
{
  "id": 1,
  "name": "manager",
  "permissions_count": 12,
  "permissions": ["customer.view", "customer.create", "customer.update", ...]
}
```

---

## Organisations

### GET /api/organisations

Returns all organisations in the workspace.

**Response `200`** — array of organisation objects

---

### GET /api/organisations/{id}

Returns a single organisation by ID.

**Response `200`** — organisation object

---

### PUT /api/organisations/{id}

Updates an organisation's details.

**Response `201`** — updated organisation object

---

## User Invitations

Invitations are managed from the **central API** (sent to the central domain) for cross-workspace actions, or from the workspace API for workspace-level management.

### GET /api/user-invites *(workspace)*

Lists all pending invitations in the workspace.

**Response `200`** — array of invite objects

---

### POST /api/user-invites *(workspace)*

Sends an invitation to a user to join the workspace.

**Request body**

| Field | Type | Required | Description |
|---|---|---|---|
| `email` | string | yes | Email address of the invitee |
| `group` | string | yes | User group: `admin` or `user` |
| `role` | string | yes | Role name (must exist in the workspace) |
| `customer_id` | integer | yes (if group=user) | Customer the user will be linked to |

**Response `201`**

```json
{
  "id": 8,
  "group": "user",
  "email": "newuser@example.com",
  "role": "agent",
  "customer_id": 12
}
```

**Response `403`** — cannot create admin invites without the required permission

---

### DELETE /api/user-invites/{id} *(workspace)*

Cancels a pending invitation.

**Response `200`**

```json
{ "response": "element deleted" }
```

---

### GET /api/user-invites/pending *(central)*

Returns all pending invitations sent to the currently authenticated user's email address, across all workspaces. Use this endpoint against the **central domain**.

**Headers:** `Authorization: Bearer {central-token}`

**Response `200`** — array of invite objects (token visible)

---

### GET /api/user-invites/{token}/inspect *(central, unauthenticated)*

Retrieves public information about a specific invitation without requiring authentication. Useful for pre-filling registration or login forms.

**Response `200`**

```json
{
  "invite": { "id": 8, "email": "newuser@example.com", "group": "user" },
  "workspace": { "name": "Acme Corp" },
  "exists": false
}
```

**Response `400`** — invite expired or no longer pending

---

### POST /api/user-invites/{token}/accept *(central)*

Accepts an invitation. The authenticated user is added to the workspace with the invited role.

**Headers:** `Authorization: Bearer {central-token}`

**Response `200`**

```json
{
  "message": "You have been successfully added to the workspace.",
  "workspace": { ... }
}
```

---

### POST /api/user-invites/{token}/decline *(central)*

Declines an invitation.

**Headers:** `Authorization: Bearer {central-token}`

**Response `200`**

```json
{ "response": "invite declined" }
```
