Exchange is excluded from this API/CLI release. Any historical Exchange API or CLI example in this guide is unavailable; native portal behavior is outside this exclusion. See [current release scope](/developers/guides/release-scope?lang=en).

# Delegates, calendars, mailing lists and rooms

Manage mailbox access and colleague calendars, mailing lists and meeting rooms from the same portal, customer API or CLI. **These four features are free**: no personal seat, product order, invoice line or storage pool. A shared mailbox with its own mail store is a separate paid feature; see the [shared mailbox manual](/developers/guides/workspace-shared-mailboxes?lang=en).

All people, addresses and resources must belong to the same company and the same mail server. Existing permissions, current company binding, and workspace resource limitations remain in effect. The API requests `workspace.mailboxes:read` for reading and `workspace.mailboxes:write` for modifying, without `orders:commit` or other financial scope. Only **Enable Send As** and **permanently delete a room** also require recent strong personal authentication and clearance for sensitive API actions. A service token cannot replace that human approval.

## 1. Delegates on a personal mailbox

Open the regular mailbox in the Workspace and go to **Delegates**. Select the colleague and assess mail access and calendar access separately. Under **This person has access to** you will see the same link from the other side.

| Mail level | What the colleague can do |
| --- | --- |
| `none` | No email access; only calendar access can still be set |
| `read` | Read mail and set read/unread; no permission to send |
| `full` | Read mail, add, delete, mark and create subfolders; do not rename or delete the shared root itself |

**Full access** also gives **send on behalf**. For example, the recipient sees “Anna on behalf of Ronald”; the mail server will keep track of this within about a minute. **Send as** is a separate, choice requiring strong verification that may only be enabled with `full`: the recipient will then only see Ronald. Decreasing to `read` or removing also revokes this Send As permission. The portal does not write directly to the server list for “on behalf of”.

If only **Send as** is turned off and **Full access** remains, **send on behalf** remains available. The server then adds `Sender: Anna`; the recipient can see who actually sent the message. Completely revoking or reducing mail access also removes this on behalf authority once the server agent has processed it. So don't expect SMTP rejection just because the separate Send As switch goes off.

With SMTP, the envelope address (`MAIL FROM`) remains the own address of the logged-in delegate; the visible `From:` is the owner's address. The controlled authorization allows this difference. Mailbox permissions do not grant permission to use the owner's envelope address as your own.

Mail access applies to the owner's folders. Folders created later are included in the recovery step; Stalwart does not automatically inherit those rights. Rights that someone sets themselves in webmail are shown as **set by the user**. An administrator can explicitly remove them, but the regular restore step will not clear them solely because there is no portal row for them. An observation is not a new approval or assignment. Different rights per folder or calendar are shown as `custom`; that's just a read label, not a configurable permission level. The reverse view uses the last known observations.

## 2. Share calendars

Calendar access uses the same owner/delegate association and can exist without mail access:

| `calendar_level` | Permission |
| --- | --- |
| `none` | No calendar access |
| `freebusy` | View availability |
| `read` | Read calendar and appointments |
| `write` | Manage calendar, including changing and deleting appointments |

The choice applies to the owner's calendars. Calendars added later are also included in the recovery step. Other delegates are retained; a change only patches the selected person.

## 3. Mailing lists

The Workspace page says **Shared mailboxes and mailing lists**. A shared mailbox is one mailbox in which several people work. A mailing list, such as `team@voorbeeld.nl`, sends a copy to each member and does not have its own mailbox or login.

Choose an active domain, name and any aliases, and select existing addresses as members. Members can be regular mailboxes, shared mailboxes or their aliases, but only from the same company on the same server. Do not enter an external address. Another mailing list is not an allowed member in this version; this way no list loop is created.

**Anyone can email the list, even from outside.** There is no “members only” or “this company only” setting. The server does not rewrite senders via SRS; forwarding to external members is therefore outside the contract. A list cannot use an address that already belongs to a mailbox, alias, shared mailbox, or room.

You can change the name, aliases and members, and delete the list. An alias array replaces its own entire alias set. A separate member change only changes that member and saves all other recipients. Deleting a list stops forwarding; it does not delete mail from the recipients.

## 4. Rooms and resources

Under **Rooms and resources** you choose an address, name, type (`room` or `equipment`), possible capacity and location. If desired, choose existing colleagues as room managers. Regular business colleagues on the same server are given read access to the room calendar by default; administrators may also change it. The permissions on all affected workspaces are checked, including the standard readers. So a restricted token cannot share to hidden workspaces this way.

Invite the room address for an appointment. The room agent accepts a free time slot and rejects an overlap with a previously accepted appointment, usually within a minute. In the case of a **repeating appointment, he only checks the first occurrence**. Replies from the room are also subject to the outgoing limit of 25 messages per hour per account.

A room is not a personal workplace. The portal does not store or display a usable password and does not offer a settings PDF, Drive or Conserio. Permanent cancellation requires recent strong personal verification and the fully entered address; please read the warning about the associated calendar and content before confirming.

## API paths and ETags

All paths below start with `/api/v1/accounts/{account}/workspaces/{workspace}`.

| Part | Paths |
| --- | --- |
| Delegates | `GET /mailboxes/{mailbox}/delegates`, `PUT`/`DELETE /mailboxes/{mailbox}/delegates/{delegate}` |
| Reverse Access | `GET /mailboxes/{mailbox}/delegations` |
| Mailing Lists | `GET`/`POST /mailing-lists`, `GET`/`PATCH`/`DELETE /mailing-lists/{list}` |
| List members | `GET /mailing-lists/{list}/members`, `PUT`/`DELETE /mailing-lists/{list}/members/{member}` |
| Rooms | `GET`/`POST /rooms`, `GET`/`PATCH`/`DELETE /rooms/{room}` |
| Room managers | `GET /rooms/{room}/managers`, `PUT`/`DELETE /rooms/{room}/managers/{mailbox}` |

A list key is typed: `mailbox-23`, `shared_mailbox-31`, `alias-12` or `shared_alias-9`. An equal number in another table is a different object. Raw email addresses, external recipients, and list-as-members are not accepted as keys.

Each write uses `Idempotency-Key` and the current `If-Match`. For `POST` use the workspace ETag, for a list or room its own resource ETag, and for a delegate the **ETag of the owner mailbox**. `GET delegates` also returns that as `meta.mailbox_version`. After a change, read the new version; the collaboration revision also changes if two changes occur in the same second. A `412` requires re-reading and review, not an automatic overwrite.

The API checks each target independently. Another corporate colleague, member, alias domain, or room manager outside the allowed workspace boundaries gets `404`. Old members and aliases also count when replacing or removing: a limited connection cannot remove hidden existing links by sending an empty list. Reading only shows objects within the current reading range. Private server IDs, provider responses, passwords, and approval proofs are not published.

## Examples

Mail and calendar in one approved body (`delegate.json`):

```json
{"level":"full","send_as":false,"calendar_level":"write"}
```

```sh
binadit workspace delegates list 7 23 --account 42
binadit workspace delegates set 7 23 24 --account 42 --version '<eigenaar-ETag>' --input delegate.json --dry-run
binadit workspace delegates set 7 23 24 --account 42 --version '<eigenaar-ETag>' --input delegate.json --yes
binadit workspace delegates access 7 24 --account 42
binadit workspace delegates remove 7 23 24 --account 42 --version '<nieuwe eigenaar-ETag>' --yes
```

For calendar availability only: `{"level":"none","send_as":false,"calendar_level":"freebusy"}`. For Send As, `level` must be equal to `full`; Only set the switch to `true` after the separate strong human review.

To create a list (`list.json`):

```json
{"domain_id":12,"local_part":"team","display_name":"Team verkoop","aliases":[],"members":[{"kind":"mailbox","id":23},{"kind":"shared_mailbox","id":31}]}
```

```sh
binadit workspace lists create 7 --account 42 --version '<workspace-ETag>' --input list.json --yes
binadit workspace lists get 7 9 --account 42
binadit workspace lists members add 7 9 alias 12 --account 42 --version '<lijst-ETag>' --yes
binadit workspace lists members remove 7 9 mailbox 23 --account 42 --version '<nieuwe lijst-ETag>' --yes
```

With curl you use the same typed key and no raw recipient data:

```sh
curl --fail-with-body -X PUT "$BINADIT_ENDPOINT/api/v1/accounts/42/workspaces/7/mailing-lists/9/members/mailbox-23" \
  -H "Authorization: Bearer $BINADIT_ACCESS_TOKEN" -H 'Content-Type: application/json' \
  -H 'If-Match: "<lijst-ETag>"' -H 'Idempotency-Key: team-member-reviewed-20261031' --data-binary '{}'
```

Create a room (`room.json`):

```json
{"domain_id":12,"local_part":"vergaderzaal","display_name":"Vergaderzaal 1","kind":"room","capacity":8,"location":"Eerste verdieping","manager_ids":[23]}
```

```sh
binadit workspace rooms create 7 --account 42 --version '<workspace-ETag>' --input room.json --yes
binadit workspace rooms list 7 --account 42
binadit workspace rooms managers add 7 11 24 --account 42 --version '<ruimte-ETag>' --yes
binadit workspace rooms delete 7 11 --account 42 --version '<nieuwe ruimte-ETag>' --confirm-address 'vergaderzaal@voorbeeld.nl' --yes
```

`update WORKSPACE RESOURCE --input FILE` uses `PATCH`. Updating a list accepts `display_name`, `aliases`, and `members`; updating a room accepts `display_name`, `kind`, `capacity`, `location` and `manager_ids`. The specified collections replace their own full set. `list` supports `--limit`, `--cursor` and `--all`; `members list` and `managers list` show the corresponding visible targets. Products, prices, passwords and financial fields are not allowed entries.

## Queue, recovery and cleanup

An accepted request returns `task_ids`, `delivery_status: queued`, and `free: true`. A held free task with uncertain server outcome gets `requires_reconciliation`; no invoice needs to be paid for this. That is not yet confirmation from the supplier. Follow the original operation with `binadit operations watch OPERATION_UUID --account 42` and read the current resource. Additional `operations:read` is required for this. Preview with `--dry-run` or `X-Binadit-Dry-Run: true` does not create a resource, approval, or vendor effect.

If a timeout occurs, keep the original operation, exact input, and key. An uncertain creation or destruction is not blindly repeated. The own source/consent proves the actual intended mailboxes and connection; a current role alone does not replace that original evidence. Restore checks current identity, permissions, corporate boundaries, and server configuration, preserves other user sharing, and repairs only explicitly managed permissions. The portal never writes to `binadit-send-on-behalf`.

Blocking or deleting a regular mailbox first clears both-way permissions and list memberships on the server. Removing or moving should not leave any residual cross-company access. Don't change rows, resource IDs, or tokens to push a task with uncertain outcome. In the event of a verification error, support will review the original request.

Changing a main address, removing a used alias or moving a Workspace to another company can therefore give `409`. First revoke the affected permissions, list references, and room dependencies and wait for the original sync job. Also a failed or canceled task with uncertain server outcome will continue to block such a change until support has confirmed that outcome. Existing aliases retain their ID when edited. For administrators and developers, the technical recovery conditions are in the repo document `docs/WORKSPACE-MAIL-DEPENDENCY-GUARDS.md`.

New folders, calendars, and default room readers are checked every hour. The control command `workspace:mail-collaboration-reconcile` uses only the original signed permission and current permissions; it does not create a new login or wider connection. `--dry-run` shows the quantities without tasks. `--limit` determines the database chunk size, so that records after the first page are also included. This command is server management; customers use the portal, API, or CLI actions described above.

These are Stalwart Workspace features. They do not enable the deferred Exchange provider integration. See [current availability](/developers/guides/release-scope?lang=en) and the [agent manual](/developers/agents?lang=en).
