> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gominerva.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Workspace management & tenant configuration via API

> Create and configure workspaces, profile groups, presets, customer risk rating, custom fields, custom-list activation, and monitoring cadences with an admin application key.

Use the Admin API to manage your organization's workspaces and their configuration from your own tooling: create a workspace for a new book of business, define its profile groups and monitoring cadences, and switch custom lists on, without anyone working through the Minerva dashboard.

These endpoints need an **admin application key**. Workspace-scoped and tenant-scoped keys keep working for screening and profile management. These endpoints refuse them for reads as well as changes. To create and update profile groups with a workspace-scoped key, use the [Profile Groups API](https://docs.gominerva.com/api-reference/profile-groups.md).

This guide covers the admin key, authentication, each endpoint family, how monitoring cadences resolve across workspaces and profile groups, the error codes, and a complete walkthrough.

## The admin application key

An admin application key is a tenant-wide key that can create, update, archive, and delete workspaces, and edit every workspace's configuration through the API. In the Minerva dashboard it appears as the **Admin (tenant-wide)** key type.

* Only an **Owner** or **Admin** can create, edit, rotate, deactivate, or delete an admin key. **Developers** see the **Admin (tenant-wide)** option disabled, with a hint to ask an owner or admin.
* The key acts only while the person who created it is still an owner or admin of the organization. If that person is demoted, disabled, or removed, every Workspace Management API request made with the key is refused with `403` from the next request onward. Create a replacement key from an account that still holds the role.
* The admin role can be set only when the key is created. You cannot change an existing workspace-scoped or tenant-scoped key into an admin key: that request returns `400` with the message "Admin role can only be set when an application is created. Create a new admin application instead."
* The key belongs to one organization. It is never accepted for another organization's `orgId`.
* Changes made with an admin key are recorded in the audit trail under the application's name, not under a person.
* The key does not reach team management, SSO and SCIM settings, custom-list content, or searches. Those stay dashboard-only or on their existing APIs.

> [!WARNING]
>
> An admin key can rewrite every workspace in your organization. For most use
> cases, we recommend workspace-scoped keys, which follow least-privilege
> access. Create an admin key only for the integration that provisions or
> configures workspaces, keep it in a secrets manager, and deactivate it when
> that integration is retired.

### Create an admin key

1. Sign in as an **Owner** or **Admin** and open **Administration** > **Developers**.
2. On **API keys**, select **Create application**.
3. Enter a name and an optional description, and choose **Live** mode. Admin keys can't be created in **Dev** mode.
4. Under **Scope**, choose **Admin (tenant-wide)**. Minerva sets **Mode** to **Live** and shows "Admin keys are always Live."
5. Create the application and copy the key. Minerva shows the plaintext key only once.

See [API Keys](https://docs.gominerva.com/api-reference/api-keys.md) for the full key lifecycle, including deactivation and deletion.

## Authentication and base URL

Send every request to the Admin API host:

```http theme={null}
https://admin-api.gominerva.com
```

Authenticate with the admin key in the `Authorization` header. The legacy `x-api-key` header is also accepted.

```http theme={null}
Authorization: Api-Key YOUR_ADMIN_API_KEY
```

Every path starts with `/v2/organizations/{orgId}`. `orgId` is your organization ID, and it must be the organization the key was created in.

Successful responses wrap the record in a `data` envelope that echoes the organization ID:

```json theme={null}
{
  "data": {
    "id": "ORG_ID",
    "workspace": { "id": "WORKSPACE_ID", "name": "EU book" }
  }
}
```

## Endpoints

The **Admin Actions - Endpoints** reference in this tab, starting at [List workspaces](https://docs.gominerva.com/api-reference/workspaces/list-workspaces.md), lists every request and response field. The tables below summarize what each family does.

### Workspaces

| Method | Path | Purpose |
| - | - | - |
| `GET` | `/v2/organizations/{orgId}/workspaces` | List the organization's workspaces with their configuration. |
| `POST` | `/v2/organizations/{orgId}/workspaces` | Create a workspace. Pass `sourceWorkspaceId` to copy another workspace's setup. |
| `GET` | `/v2/organizations/{orgId}/workspaces/{workspaceId}` | Read one workspace. |
| `PATCH` | `/v2/organizations/{orgId}/workspaces/{workspaceId}` | Update a workspace's name or configuration sections. |
| `DELETE` | `/v2/organizations/{orgId}/workspaces/{workspaceId}` | Delete an archived workspace. |

* `POST` requires `name` and accepts the same configuration sections as `PATCH`, such as `monitoringFeedFrequencies`, `monitoringRiskFrequencies`, `matchScoring`, `automaticDisposition`, and `riskInference`. `clientRiskRating` is accepted on `PATCH` only.
* `PATCH` is sparse at the top level. A section you omit keeps its stored value. A section you send replaces that section, so send the complete `monitoringFeedFrequencies` map you want to keep.
* Unknown fields are rejected with `400`.
* Archive a workspace with `PATCH` and `{"archived": true}` before you delete it. The default workspace cannot be archived or deleted.

### Profile groups

| Method | Path | Purpose |
| - | - | - |
| `GET` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/profile-groups` | List groups. Add `includeArchived=true` to include archived ones. |
| `POST` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/profile-groups` | Create a group. |
| `PATCH` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/profile-groups/{profileGroupId}` | Update a group's name, description, priority, or cadences. |
| `DELETE` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/profile-groups/{profileGroupId}` | Archive a group. |

* `POST` requires `name` (up to 160 characters) and `priority`. `description` (up to 4,000 characters) and `monitoringFeedFrequencies` are optional.
* `priority` is an integer from `0` to `1000000`. Higher values win when a profile belongs to several groups, and each priority can be used by only one active group in a workspace. Reusing one returns `409`.
* A group `PATCH` that carries `monitoringFeedFrequencies` replaces the group's whole cadence map. Include every feed you want the group to keep.
* `DELETE` archives the group rather than erasing it, so profiles that still reference it keep an auditable assignment.

For what profile groups are and how to assign profiles to them, see the [Profile Groups API](https://docs.gominerva.com/api-reference/profile-groups.md) and the [Profile Groups Guide](https://docs.gominerva.com/profile-groups-guide.md).

### Presets

| Method | Path | Purpose |
| - | - | - |
| `GET` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/presets?configType=...` | List built-in and custom presets for one config type. |
| `POST` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/presets` | Create a custom preset. |
| `PATCH` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/presets/{presetId}` | Update a custom preset. |
| `DELETE` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/presets/{presetId}?configType=...` | Delete a custom preset. |
| `POST` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/presets/{presetId}/promotions` | Promote a configuration from this workspace to another. |

* `configType` is `match_scoring` or `alert_suppression`. A preset body carries `configType`, `label`, an optional `description`, and the `config` object.
* A promotion body names `configType`, `targetWorkspaceId`, and an optional `changeSummary`. Promotion also accepts `customer_risk_rating`, in which case `presetId` is a CRR scorecard ID.

See the [Workspaces Guide](https://docs.gominerva.com/workspaces-guide.md) for how presets and promotion fit a Calibration-to-Live workflow.

### Customer Risk Rating

| Method | Path | Purpose |
| - | - | - |
| `GET` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/crr-scorecards` | List scorecards. |
| `POST` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/crr-scorecards` | Create a scorecard. |
| `GET` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/crr-scorecards/{scorecardId}` | Read a scorecard. |
| `PATCH` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/crr-scorecards/{scorecardId}` | Update a scorecard. |
| `DELETE` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/crr-scorecards/{scorecardId}` | Archive a scorecard. |
| `POST` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/crr-scorecards/{scorecardId}/default` | Make a scorecard the workspace default. |
| `GET` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/crr-scorecards/{scorecardId}/revisions` | List a scorecard's revisions. |
| `GET` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/crr-templates` | List CRR profile templates. |
| `POST` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/crr-templates` | Create a template. |
| `GET` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/crr-templates/selectable` | List the templates a profile can use now. |
| `GET` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/crr-templates/{templateId}` | Read a template. |
| `PATCH` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/crr-templates/{templateId}` | Update a template. |
| `POST` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/crr-templates/{templateId}/activate` | Activate a template. |
| `POST` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/crr-templates/{templateId}/archive` | Archive a template. |
| `GET` | `/v2/organizations/{orgId}/workspaces/{workspaceId}/crr-templates/{templateId}/revisions` | List a template's revisions. |

### Profile custom fields

Profile custom fields are defined once for the whole organization, so these paths carry no workspace.

| Method | Path | Purpose |
| - | - | - |
| `GET` | `/v2/organizations/{orgId}/profile-custom-fields` | List field definitions. |
| `POST` | `/v2/organizations/{orgId}/profile-custom-fields` | Create a field definition. |
| `GET` | `/v2/organizations/{orgId}/profile-custom-fields/{profileCustomFieldId}` | Read a field definition. |
| `PATCH` | `/v2/organizations/{orgId}/profile-custom-fields/{profileCustomFieldId}` | Update a field definition. |
| `DELETE` | `/v2/organizations/{orgId}/profile-custom-fields/{profileCustomFieldId}` | Archive a field definition. |

The [Profile Custom Fields](https://docs.gominerva.com/api-reference/profile-custom-fields.md) page describes field types and how values are written on profiles.

### Custom-list activation and entitlements

An admin key can read your custom-list entitlements and switch lists on or off in a workspace. Uploading and editing list content stays in the dashboard.

| Method | Path | Purpose |
| - | - | - |
| `GET` | `/v2/organizations/{orgId}/custom-lists` | List the organization's custom lists. |
| `GET` | `/v2/organizations/{orgId}/custom-lists/entitlements` | Read the organization's custom-list entitlements. |
| `GET` | `/v2/organizations/{orgId}/custom-lists/workspaces/{workspaceId}/manifest` | Read which lists are active in a workspace. |
| `PUT` | `/v2/organizations/{orgId}/custom-lists/workspaces/{workspaceId}/lists/{listId}/activation` | Switch a list on or off in a workspace. |

The activation body takes `enabled` (default `true`). When you switch a list on, `feedCategory` and `versionId` are required so the list is bound to the feed and published version you intend.

## Monitoring cadences

Monitoring cadences decide how often each data feed rescreens a profile. You set them per feed (`Sanctions`, `PEP`, `News`, `Legal`, `Criminal`, `Internal`) in a `monitoringFeedFrequencies` map, on a workspace and on each profile group. In the dashboard, `News` appears as **Adverse Media** and `Internal` as **Internal Risk**. A workspace can also set cadences per risk tier in `monitoringRiskFrequencies` (`low`, `medium`, `high`), which apply to profiles with that customer risk rating.

| Value | Where | Meaning |
| - | - | - |
| `daily`, `weekly`, `monthly`, `quarterly`, `semiannually`, `annually` | Workspaces and groups | Rescreen on that cadence. |
| `deltas` | Workspaces and groups | Rescreen when a supported source changes. Sanctions only. |
| `never` | Workspaces and groups | Do not monitor this feed. |
| `unset` | Profile groups only | Let a lower-priority group or the risk tier decide. If none does, the feed is not monitored (`never`). Shown as **Unset** in the dashboard. |
| Omitted or empty | Profile groups | On the profile's highest-priority group, use the risk tier or workspace cadence. Shown as **Inherit** in the dashboard. |

### How a profile's cadence is resolved

Minerva resolves each feed on its own.

1. Minerva orders the profile's active groups by `priority`, highest first.
2. It checks the groups in that order. The first group that sets a cadence for the feed, including `never`, decides the feed for the groups.
3. A group set to `unset` passes the decision to the next group down.
4. If every group is set to `unset`, the risk tier decides. If the risk tier sets no cadence for the feed, the feed is `never`. It does not fall back to the workspace cadence.
5. If the highest-priority group leaves the feed empty, the profile uses its risk-tier cadence, or the workspace cadence when the risk tier sets none. Once a group has passed the decision down with `unset`, a lower group that leaves the feed empty is skipped too.

Risk tiers have fixed priorities: low 800, medium 900, and high 1000. When the profile's risk tier sets a cadence for the feed, that cadence applies unless the group that decided the feed has a higher priority than the tier. A tie goes to the risk tier. To let a group override every risk tier, give it a priority above 1000.

Two consequences follow:

* `never` beats `unset`. A group set to `never` decides the feed, so a lower group cannot turn it back on. Only a risk tier that outranks the group can.
* Empty and `unset` are different. Empty on the top group means "use the risk tier or workspace cadence". `unset` means "let a lower group or the risk tier decide, and otherwise do not monitor".

> [!NOTE]
>
> `unset` is valid only on profile groups. Sending it in a workspace's
> `monitoringFeedFrequencies` or in `monitoringRiskFrequencies` returns `400`.
> Use `never` there to stop monitoring a feed.

### Example: combining two groups

Group A monitors Sanctions daily and leaves every other feed `unset`:

```json theme={null}
{
  "Sanctions": "daily",
  "PEP": "unset",
  "News": "unset",
  "Legal": "unset",
  "Criminal": "unset",
  "Internal": "unset"
}
```

Group B monitors PEP monthly and leaves every other feed `unset`:

```json theme={null}
{
  "Sanctions": "unset",
  "PEP": "monthly",
  "News": "unset",
  "Legal": "unset",
  "Criminal": "unset",
  "Internal": "unset"
}
```

A profile in both groups, with no risk-tier cadence for these feeds, is monitored like this, whichever group has the higher priority:

| Feed | Result | Why |
| - | - | - |
| Sanctions | `daily` | Group A sets it. Group B is set to `unset`. |
| PEP | `monthly` | Group B sets it. Group A is set to `unset`. |
| News, Legal, Criminal, and Internal | `never` | Both groups are set to `unset`, and no risk tier sets a cadence. |

A profile only in group A, with no risk-tier cadence, is monitored for Sanctions daily and nothing else.

## Errors

Most error responses carry the message as a plain string in the body. Custom-list activation can also return a JSON object with `error` and `message` fields, as the `409` and `422` rows below describe. When the response's `Content-Type` is `application/json`, parse the body as JSON.

| Status | When |
| - | - |
| `400` | The body is invalid: an unknown field, a value out of range, `unset` on a workspace or risk tier, or `deltas` on a feed other than Sanctions. |
| `403` | The request has no API key. The response message is "Missing Authorization: Api-Key or x-api-key header." |
| `403` | The key has been revoked or has expired, or its application has been deactivated. The response message is "API-key authentication was denied." |
| `403` | The key is a workspace-scoped or tenant-scoped key, not an admin key. The response message is "An admin application key is required." |
| `403` | `orgId` is not the organization the key belongs to. The response message is "The API key does not belong to this organization." |
| `403` | The key's creator is no longer an owner or admin. The response message is "The admin key's creator no longer has owner or admin access." |
| `403` | The key's creator has been disabled, or the organization has been archived. The response message starts with "Your account has been disabled" or "Your organization has been archived". |
| `404` | The workspace, group, or other record is not in this organization, or Minerva does not recognize the application API key (`mrva-…`). For an unrecognized key the response message is "API-key authentication was denied." |
| `409` | Another active profile group in the workspace already uses that `priority`. |
| `409` | A custom-list activation conflicted with a concurrent change to the organization's custom lists. The response body's `error` is `conflict`. Retry the request. |
| `422` | The custom-list activation would exceed a custom-list limit, such as the maximum number of active custom-list records in a workspace (`maxActiveCustomListRecordsPerWorkspace`). The response body's `error` is `limit_exceeded`, `limit` names the limit, and `max` is its maximum. To free capacity, switch off a list you no longer need in that workspace, or contact Minerva about your limits. |
| `503` | Minerva could not verify the key at that moment. The response message is "Authentication service is unavailable." This does not mean the key has lost access. Retry the request with backoff. |

## Walkthrough: set up a new workspace

This walkthrough creates a workspace, adds the two groups from the example above, adjusts their priorities, and assigns a profile to both. Set these variables first:

```bash theme={null}
export MINERVA_ADMIN_KEY="YOUR_ADMIN_API_KEY"
export ORG_ID="YOUR_ORG_ID"
```

### 1. Create the workspace

The workspace monitors Sanctions and PEP weekly for profiles that are not in any group.

```bash cURL theme={null}
curl -X POST "https://admin-api.gominerva.com/v2/organizations/$ORG_ID/workspaces" \
  -H "Authorization: Api-Key $MINERVA_ADMIN_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "name": "EU book",
    "monitoringFeedFrequencies": {
      "Sanctions": "weekly",
      "PEP": "weekly"
    }
  }'
```

The response returns `201` with the new workspace in `data.workspace`. Keep `data.workspace.id` as `WORKSPACE_ID`.

### 2. Create two profile groups

```bash cURL theme={null}
curl -X POST "https://admin-api.gominerva.com/v2/organizations/$ORG_ID/workspaces/$WORKSPACE_ID/profile-groups" \
  -H "Authorization: Api-Key $MINERVA_ADMIN_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "name": "Sanctions daily",
    "priority": 200,
    "monitoringFeedFrequencies": {
      "Sanctions": "daily",
      "PEP": "unset",
      "News": "unset",
      "Legal": "unset",
      "Criminal": "unset",
      "Internal": "unset"
    }
  }'
```

```bash cURL theme={null}
curl -X POST "https://admin-api.gominerva.com/v2/organizations/$ORG_ID/workspaces/$WORKSPACE_ID/profile-groups" \
  -H "Authorization: Api-Key $MINERVA_ADMIN_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "name": "PEP monthly",
    "priority": 100,
    "monitoringFeedFrequencies": {
      "Sanctions": "unset",
      "PEP": "monthly",
      "News": "unset",
      "Legal": "unset",
      "Criminal": "unset",
      "Internal": "unset"
    }
  }'
```

Each response returns `201` with the group in `data.profileGroup`. Keep the two IDs as `GROUP_A_ID` and `GROUP_B_ID`.

### 3. Set priorities

Priority decides which group is checked first. Raise group B above group A with a `PATCH` that carries only `priority`, so the group's cadences are left as they are:

```bash cURL theme={null}
curl -X PATCH "https://admin-api.gominerva.com/v2/organizations/$ORG_ID/workspaces/$WORKSPACE_ID/profile-groups/$GROUP_B_ID" \
  -H "Authorization: Api-Key $MINERVA_ADMIN_KEY" \
  -H "Content-Type: application/json" \
  --data '{"priority": 300}'
```

In this example the order does not change the result, because each group is set to `unset` for the other group's feed. Priority matters when two groups both set a cadence for the same feed. These priorities are below every risk-tier priority, so a risk-tier cadence for the profile's rating would still win. Use a priority above 1000 if a group must override risk tiers.

### 4. Assign a profile to both groups

Profile assignment is part of profile management, on `https://api.gominerva.com/clm/v1`, not the Admin API. Use a workspace-scoped application key created for the new workspace:

```bash cURL theme={null}
curl -X PATCH "https://api.gominerva.com/clm/v1/profiles/PROFILE_ID" \
  -H "x-api-key: YOUR_WORKSPACE_API_KEY" \
  -H "Content-Type: application/json" \
  --data "{\"profileGroupIds\": [\"$GROUP_A_ID\", \"$GROUP_B_ID\"]}"
```

If the profile's risk tier sets no cadence for these feeds, it is now monitored for Sanctions daily and PEP monthly, and is not monitored on News, Legal, Criminal, or Internal.

## Related documentation

* [API Keys](https://docs.gominerva.com/api-reference/api-keys.md) for creating and managing application keys
* [Profile Groups API](https://docs.gominerva.com/api-reference/profile-groups.md) for assigning and filtering profiles by group
* [Workspaces Guide](https://docs.gominerva.com/workspaces-guide.md) for workspace-scoped and tenant-wide settings
* [Screening Frequencies Guide](https://docs.gominerva.com/screening-frequencies-guide.md) for the dashboard view of monitoring cadences


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.