# How workspaces group grants

Source: https://developer.nylas.com/docs/dev-guide/platform/workspaces/

A workspace groups the grants in a Nylas application by the domain of the users' email addresses. If one application serves many customer organizations, workspaces keep each organization's grants together. This page explains how a grant is assigned to a workspace, what the default workspace does, and how to move and filter grants.

If your application serves one organization, you can ignore workspaces. Every grant lands in the default workspace, and the Email, Calendar, and Contacts APIs behave the same way.

## What is a workspace?

A workspace is a container inside an application that holds grants. It has a `name`, an email `domain`, and an `auto_group` flag. When `auto_group` is `true`, new grants whose email domain matches the workspace's `domain` join it automatically. Each grant records the workspace it belongs to in its `workspace_id` field.

In the resource hierarchy, an application owns connectors, credentials, and workspaces, and a grant belongs to one connector and one workspace. Deleting a workspace doesn't invalidate its grants. [Deleting resources and data](/docs/dev-guide/platform/deleting-resources/) describes what each deletion does.

Create a workspace with a `POST /v3/workspaces` request. The request takes 5 fields: `name`, `domain`, `auto_group`, `policy_id`, and `rule_ids`. Only [Agent Accounts](/docs/v3/agent-accounts/workspaces/) use `policy_id` and `rule_ids`. Within one application, each domain can belong to only one workspace, and you can't change a workspace's `domain` after you create it. There's no limit on the number of workspaces in an application.

```bash
curl --request POST \
  --url "https://api.us.nylas.com/v3/workspaces" \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "The Nylas Workspace",
    "domain": "nylas.com",
    "auto_group": true,
    "policy_id": "<POLICY_ID>",
    "rule_ids": ["<RULE_ID>"]
  }'


```

| Field            | Set by | Description                                                                                    |
| ---------------- | ------ | ---------------------------------------------------------------------------------------------- |
| `workspace_id`   | Nylas  | The workspace's ID.                                                                            |
| `application_id` | Nylas  | The application the workspace belongs to.                                                      |
| `name`           | You    | A short, descriptive name.                                                                     |
| `domain`         | You    | The email domain the workspace groups, such as `nylas.com`. Can't be changed after creation.   |
| `auto_group`     | You    | When `true`, new grants whose email domain matches `domain` join the workspace automatically.  |
| `default`        | Nylas  | `true` on the application's default workspace.                                                 |
| `policy_id`      | You    | An [Agent Accounts policy](/docs/v3/agent-accounts/policies-rules-lists/).                     |
| `rule_ids`       | You    | [Agent Accounts rules](/docs/v3/agent-accounts/policies-rules-lists/#rules).                   |
| `created_at`     | Nylas  | Creation time as a Unix timestamp in seconds.                                                  |
| `updated_at`     | Nylas  | Last update time as a Unix timestamp in seconds. Equal to `created_at` until the first update. |

## How does a grant get its workspace?

Nylas assigns a workspace to each new grant in 3 steps, and the first step that applies wins. It checks for an explicit workspace, then for a workspace whose domain matches the grant's email address, and finally falls back to the application's default workspace.

1. **Explicit assignment.** Only Agent Accounts can be placed in a workspace at creation. The Agent Account variant of the [custom authentication request](/docs/reference/api/manage-grants/byo_auth/) accepts a top-level `workspace_id`. Hosted authentication, IMAP, and the other custom authentication variants don't.
2. **Domain match.** Nylas looks for a workspace whose `domain` equals the part of the grant's email address after the `@` and whose `auto_group` is `true`. The comparison is exact and case-sensitive. A `sales.acme.com` address doesn't match an `acme.com` workspace.
3. **Default workspace.** If neither step applies, the grant joins the application's default workspace, if the application has one.

Automatic grouping applies only to grants created after the workspace exists. To sort older grants, run the [automatic grouping job](#sort-existing-grants-by-domain).

The grant object's `workspace_id` field shows the result. Agent Accounts always return it. For other providers, Nylas omits the field when the grant is in the default workspace and returns it when the grant is in any other workspace.

## The default workspace

The default workspace is a workspace that Nylas creates with the application and manages for you. Each application has at most 1 default workspace, and applications created before default workspaces were introduced might not have one. A grant that isn't explicitly assigned or grouped by domain joins the default workspace.

The [application object](/docs/reference/api/applications/) exposes the default workspace's ID as `default_workspace_id`. Nylas manages this value and ignores it in create and update requests. In a [list workspaces](/docs/reference/api/workspaces/get-all-workspaces/) response, the default workspace has `"default": true`.

You can update only `policy_id` and `rule_ids` on the default workspace. A request that changes `name`, `domain`, or `auto_group` returns an error, and you can't delete it. When you delete another workspace, Nylas moves its grants to the default workspace.

## Move grants between workspaces

Three requests move grants after creation. A grant update moves one grant, the manual-assign endpoint moves up to 500 grants per list, and the automatic grouping job sorts every grant that has no workspace. A grant can be moved into any workspace in the application, including one with `auto_group` enabled. Grants keep working through every move.

### Move one grant

The [Update grant](/docs/reference/api/manage-grants/patch_grant_by_id/) request, `PATCH /v3/grants/{grant_id}`, accepts a `workspace_id` alongside `settings` and `scope`. A `workspace_id` that differs from the grant's current one moves the grant. The target workspace must exist and belong to the same application, or the request returns a 400 or 401 error. If you omit `workspace_id`, the grant stays where it is.

```bash
curl --request PATCH \
  --url "https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>" \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "workspace_id": "<WORKSPACE_ID>"
  }'
```

### Assign specific grants manually

The `POST /v3/workspaces/{workspace_id}/manual-assign` request adds grants to a workspace, removes grants from it, or both. Send grant IDs in `assign_grants` and `remove_grants`, with up to 500 IDs per list and at least one ID across the two lists. The response returns the IDs in `grants_assigned` and `grants_removed`.

```bash
curl --request POST \
  --url "https://api.us.nylas.com/v3/workspaces/<WORKSPACE_ID>/manual-assign" \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "assign_grants": [
      "10726e7c-89c3-4a1d-9f4a-5f3f37f6f2d9",
      "3b9f5c1a-21d4-46c1-b84f-0e8d1f9eaa42"
    ],
    "remove_grants": [
      "5f1a2c9e-739b-4c66-9a3d-2c88a0c6d123",
      "9c6e4b7d-2e4a-4ef0-a1b8-badf5a76a555"
    ]
  }'

```

A grant in `remove_grants` doesn't return to the default workspace. Nylas clears its `workspace_id`, and the grant has no workspace until you assign one or the automatic grouping job picks it up.

### Sort existing grants by domain

The `POST /v3/workspaces/auto-group` request starts a background job that sorts grants into workspaces by email domain. The job considers only grants that have no workspace, so grants you placed manually stay where they are. Where no workspace exists for a domain, the job creates one with `auto_group` set to `true` and a generated name. The response returns a `job_id` because the job runs asynchronously.

```bash
curl --request POST \
  --url "https://api.us.nylas.com/v3/workspaces/auto-group" \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "after_created_at": 1725273600,
    "invalid_also": true,
    "specific_domain": "nylas.com"
  }'

```

The job accepts 3 optional filters. `specific_domain` limits it to one email domain, `after_created_at` limits it to grants created at or after a Unix timestamp, and `invalid_also` includes invalid grants. Without filters, the job considers every unassigned grant in the application.

## Filter grants by workspace

The [Get all grants](/docs/reference/api/manage-grants/get-all-grants/) endpoint accepts a `workspace_id` query parameter that returns only the grants in that workspace. This lists one customer's connected accounts in a single request.

```bash
curl --request GET \
  --url "https://api.us.nylas.com/v3/grants?workspace_id=<WORKSPACE_ID>&limit=50" \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>'
```

The filter combines with the other parameters on the endpoint, such as `provider`, `grant_status`, and `since`. The default page size is 10 grants. Use `limit` and `offset` to page through the results.

## What workspaces affect

For grants from Google, Microsoft, IMAP, and the other mail and calendar providers, a workspace only groups grants and filters the grant list. It doesn't change how the Email, Calendar, or Contacts APIs behave for those grants.

Agent Accounts are the exception. An Agent Account inherits its workspace's `policy_id`, which sets send limits (for example, 200 messages per account per day on the free plan), storage, and spam detection, and runs the workspace's `rule_ids` on its mail. [How Agent Account workspaces work](/docs/v3/agent-accounts/workspaces/) covers this layer.

The Nylas Dashboard shows the workspaces that hold Agent Accounts. Workspaces for other grant types are managed through the [Workspaces endpoints](/docs/reference/api/workspaces/).

## What's next

- [Workspaces API reference](/docs/reference/api/workspaces/) for the create, update, delete, `auto-group`, and `manual-assign` endpoints
- [Managing grants](/docs/dev-guide/best-practices/manage-grants/) for creating, re-authenticating, and deleting grants
- [How Agent Account workspaces work](/docs/v3/agent-accounts/workspaces/) for the policy and rules that workspaces carry for Agent Accounts
- [Deleting resources and data](/docs/dev-guide/platform/deleting-resources/) for what happens to grants when you delete a workspace, connector, or application