---
title: "Tenancy API"
description: "Organizations, workspaces, environments and the enforcement mode of each."
label: "Tenancy"
generated: "the API catalogue in apps/control-plane/src/routes/developer.ts"
---


Every other resource in Veefore is reachable only through this hierarchy. The enforcement mode lives on the environment, which is why promoting to `ENFORCE` is a tenancy operation and not a policy one.

:::warning Step-up required
1 endpoint in this group require a fresh step-up authentication within the last few minutes, even for a session that already holds the permission. They are marked below.
:::

## Endpoints

| | Endpoint | Permission | Notes |
| --- | --- | --- | --- |
| `GET` | `/v1/organization` | `organization:read` | — |
| `PATCH` | `/v1/organization` | `organization:update` | — |
| `GET` | `/v1/fx-rates` | `organization:read` | — |
| `GET` | `/v1/fx-rates/history` | `organization:read` | — |
| `POST` | `/v1/fx-rates` | `organization:update` | — |
| `DELETE` | `/v1/fx-rates/{rateId}` | `organization:update` | — |
| `POST` | `/v1/fx-rates/refresh` | `organization:update` | — |
| `GET` | `/v1/workspaces` | `workspace:read` | — |
| `POST` | `/v1/workspaces` | `workspace:create` | accepts `Idempotency-Key` |
| `GET` | `/v1/environments` | `environment:read` | — |
| `POST` | `/v1/environments` | `environment:create` | accepts `Idempotency-Key` |
| `POST` | `/v1/environments/{environmentId}/gateway-mode` | `environment:set_mode` | — |
| `POST` | `/v1/environments/{environmentId}/pause` | `environment:pause` | step-up, high impact |

## What each endpoint does

### `GET /v1/organization`

Read the active organization.

Requires `organization:read`.

### `PATCH /v1/organization`

Update organization settings, including base_currency (ISO 4217). Changing the base currency is audited; existing limits keep their own currency and are converted.

Requires `organization:update`.

Request body:

```json
{
  "name": "string?",
  "require_mfa": "boolean?",
  "base_currency": "string? (ISO 4217)"
}
```

### `GET /v1/fx-rates`

Exchange rates in force (manual overrides automatic for the same pair) and automatic-provider status.

Requires `organization:read`.

### `GET /v1/fx-rates/history`

Every stored exchange rate, newest first.

Requires `organization:read`.

### `POST /v1/fx-rates`

Add a manual exchange rate: `rate` units of quote per 1 base. Overrides automatic rates.

Requires `organization:update`.

Request body:

```json
{
  "base_currency": "string (ISO 4217)",
  "quote_currency": "string (ISO 4217)",
  "rate": "string (decimal, e.g. \"83.25\")",
  "effective_at": "string? (ISO-8601)"
}
```

### `DELETE /v1/fx-rates/{rateId}`

Delete a manual exchange rate.

Requires `organization:update`.

### `POST /v1/fx-rates/refresh`

Fetch automatic exchange rates now. Requires VEEFORE_FX_PROVIDER_URL; only the rate request is sent.

Requires `organization:update`.

### `GET /v1/workspaces`

List workspaces.

Requires `workspace:read`.

### `POST /v1/workspaces`

Create a workspace.

Requires `workspace:create`.

Request body:

```json
{
  "name": "string",
  "slug": "string?"
}
```

### `GET /v1/environments`

List environments.

Requires `environment:read`.

### `POST /v1/environments`

Create an environment.

Requires `environment:create`.

Request body:

```json
{
  "workspace_id": "string",
  "name": "string",
  "type": "DEVELOPMENT|STAGING|PRODUCTION"
}
```

### `POST /v1/environments/{environmentId}/gateway-mode`

Change enforcement mode. Reducing enforcement needs step-up and a reason.

Requires `environment:set_mode`.

Request body:

```json
{
  "mode": "OBSERVE|SIMULATE|ENFORCE",
  "reason": "string?"
}
```

### `POST /v1/environments/{environmentId}/pause`

Emergency: pause all protected execution in an environment.

Requires `environment:pause`. Step-up authentication is also required.

Request body:

```json
{
  "reason": "string"
}
```
