# Organization

Part of AppEngine API Documentation. Full index: https://appengine.appmint.io/documentation.md
## GET /org-management/check-org-name/{orgName}

**Check organization name availability**

`operationId: OrgManagementController_checkOrgNameAvailability`

Whether a name is free to register. **Public**, because it runs during signup before an account exists — which also means it lets anyone enumerate which org names are taken.

#### Signature

```http
GET /org-management/check-org-name/{orgName} (orgName: string) -> Availability
```

#### Access

Public — no credentials required.

#### Notes

- Unauthenticated; discloses whether a name is taken.

#### Errors

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /org-management/org-register`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgName` | path | string | yes | The name to check. |

### Request body

Organization name to check

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Availability |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

Example response:

```json
{
  "available": true
}
```

## GET /org-management/profile/{orgId}

**Get an organization profile**

`operationId: OrgManagementController_getProfile`

The full profile — company, customer and address information. `orgId` is optional: omit it for the calling org, supply it to read another org (which the caller must be entitled to do).

#### Signature

```http
GET /org-management/profile/{orgId} (orgId: string) -> The profile
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/profile/update`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgId` | path | string | yes | Org to read. Defaults to the caller's own. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The profile |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/profile/update

**Update the company profile**

`operationId: OrgManagementController_updateCompanyProfile`

Updates company profile information on the root org record.

#### Signature

```http
POST /org-management/profile/update (body) -> The updated profile
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `PUT /org-management/profile/customer`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

Fields to change.

```json
{
  "companyName": "Acme Ltd",
  "phone": "+15551234567"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated profile |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/company/meta

**Update company metadata**

`operationId: OrgManagementController_updateCompanyMeta`

Merges a namespaced blob into the **caller's own** org at `company.data.meta` — for example `{ namespace: "onboarding", value: { setupCompletedAt } }`.

Deliberately narrow: it writes only `data.meta.<namespace>.*`. Plan, balance and status cannot be reached through it, which is what makes it safe to expose to an app that needs to remember its own state.

#### Signature

```http
POST /org-management/company/meta (body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Cannot reach plan, balance or status.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | NAMESPACE_REQUIRED | A valid meta namespace is required | `namespace` is missing or invalid. | Supply a namespace. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /org-management/profile/{orgId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The namespace and its value.

```json
{
  "namespace": "onboarding",
  "value": {
    "setupCompletedAt": "2026-08-30T10:00:00.000Z"
  }
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | A valid meta namespace is required — `namespace` is missing or invalid. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## PUT /org-management/profile/customer

**Update the customer profile**

`operationId: OrgManagementController_updateCustomerProfile`

Updates the customer-side profile on the root org record.

#### Signature

```http
PUT /org-management/profile/customer (body) -> The updated profile
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/profile/update`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

Fields to change.

```json
{
  "firstName": "Ada",
  "lastName": "Lovelace"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The updated profile |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/profile/addresses

**Get addresses**

`operationId: OrgManagementController_getAddresses`

The current user's addresses.

#### Signature

```http
GET /org-management/profile/addresses () -> Addresses
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/profile/addresses`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Addresses |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/profile/addresses

**Add an address**

`operationId: OrgManagementController_addAddress`

Adds an address for the current user.

#### Signature

```http
POST /org-management/profile/addresses (body) -> The address
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /org-management/profile/addresses`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The address.

```json
{
  "line1": "1 Market St",
  "city": "San Francisco",
  "state": "CA",
  "postalCode": "94105",
  "country": "US"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The address |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/billing/balance

**Get the credit balance**

`operationId: OrgManagementController_getBalance`

Current credit balance and spending. `customerOrgId` reads another org's balance, for an operator managing a customer.

#### Signature

```http
GET /org-management/billing/balance (customerOrgId?: string) -> Balance and spending
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /org-management/billing/transactions`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `customerOrgId` | query | string | — | Read another org's balance. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Balance and spending |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/billing/buy-credits

**Buy credits**

`operationId: OrgManagementController_buyCredits`

Starts a credit purchase through the payment gateway. **Charges a real card.** Marked public because it is also reachable from a payment-return context; supply the org explicitly when there is no session.

#### Signature

```http
POST /org-management/billing/buy-credits (body) -> The payment setup
```

#### Access

Public — no credentials required.

#### Notes

- Charges a card.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_AMOUNT | Invalid amount | The amount is missing or not positive. | Send a positive amount. |
| `402` | PAYMENT_FAILED | Payment failed | The card was declined or the charge could not be taken. | Try another payment method. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /org-management/billing/complete-payment`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The purchase.

```json
{
  "amount": 5000
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The payment setup |
| `400` | Invalid amount — The amount is missing or not positive. |
| `402` | Payment failed — The card was declined or the charge could not be taken. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/billing/complete-payment

**Complete a credit payment**

`operationId: OrgManagementController_completePayment`

Finalises a pending credit purchase after Stripe validation, crediting the balance. The session id is single-use — replaying one is refused rather than crediting twice.

#### Signature

```http
POST /org-management/billing/complete-payment (body) -> The result
```

#### Access

Public — no credentials required.

#### Notes

- Single-use per session.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | PAYMENT_INTENT_REQUIRED | Payment intent ID is required | No intent id was supplied. | Pass the intent id from the client-side confirmation. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /org-management/billing/buy-credits`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The payment reference.

```json
{
  "paymentIntentId": "pi_3Abc123"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Payment intent ID is required — No intent id was supplied. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/billing/transactions

**Get transaction history**

`operationId: OrgManagementController_getTransactionHistory`

The org's billing transactions.

#### Signature

```http
GET /org-management/billing/transactions () -> Transactions
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /org-management/billing/balance`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `customerOrgId` | query | any | — | Read another org (root only). Defaults to the caller. |
| `endDate` | query | string | — | End date filter |
| `startDate` | query | string | — | Start date filter |
| `pageSize` | query | number | — | Items per page |
| `page` | query | number | — | Page number |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Transactions |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/billing/transactions/backfill-org-links

**Backfill transaction org links**

`operationId: OrgManagementController_backfillTransactionOrgLinks`

One-time repair: links root-owned credit purchases that predate the `data.customerOrgId` field back to the org they were paid for, using their Stripe PaymentIntent.

Idempotent, so a re-run is safe, but it rewrites historical ledger rows — run it deliberately and bound it with `limit` on a first pass.

#### Signature

```http
POST /org-management/billing/transactions/backfill-org-links (limit?: integer) -> What was linked
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `RootSystem`, `RootPowerUser`.

#### Notes

- Rewrites historical transactions. Idempotent.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /org-management/billing/transactions`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `limit` | query | integer | — | Cap how many rows are processed. |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | What was linked |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/billing/gift-credits

**Gift credits (admin)**

`operationId: OrgManagementController_giftCredits`

Grants credits to an org without payment. Admin-only, and it creates spendable balance out of nothing — the transaction record is the only trail, so record why.

#### Signature

```http
POST /org-management/billing/gift-credits (body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `ConfigAdmin`.

#### Notes

- Creates balance with no payment behind it.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_AMOUNT | Invalid amount | The amount is not positive. | Send a positive amount. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/billing/add-credit`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The gift.

```json
{
  "customerOrgId": "org_4821",
  "amount": 5000,
  "reason": "Service credit for the March outage"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Invalid amount — The amount is not positive. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/billing/add-credit

**Add credit to an organization**

`operationId: OrgManagementController_addCredit`

Adds credit directly to an org and writes the transaction record. An email is required so the record says **who** the credit was added for — a credit with no attributable person cannot be audited later.

#### Signature

```http
POST /org-management/billing/add-credit (body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `RootSystem`, `RootPowerUser`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | EMAIL_REQUIRED | An email is required to record who the credit was added for | `email` is missing. | Supply the recipient email. |
| `422` | INVALID_CUSTOMER_ORG | Invalid customerOrgId <id> | The target org does not exist. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/billing/gift-credits`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The credit.

```json
{
  "customerOrgId": "org_4821",
  "amount": 5000,
  "email": "ada@example.com"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | An email is required to record who the credit was added for — `email` is missing. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `422` | Invalid customerOrgId <id> — The target org does not exist. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/subscription/plans

**Get subscription plans**

`operationId: OrgManagementController_getSubscriptionPlans`

The plans available. Public, since pricing pages show it before signup. `customer-org-id` (a **hyphenated** query parameter) scopes the list to what a specific org can take.

#### Signature

```http
GET /org-management/subscription/plans (customer-org-id?: string) -> Plans
```

#### Access

Public — no credentials required.

#### Errors

Plus the standard platform errors: `429`, `500`.

#### See also

- `GET /org-management/subscription/current`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `customer-org-id` | query | string | — | Note the hyphens — this is not `customerOrgId`. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Plans |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/subscription/current

**Get the current subscription**

`operationId: OrgManagementController_getCurrentSubscription`

The org's current plan, status and expiry. `customer-org-id` reads another org's.

#### Signature

```http
GET /org-management/subscription/current (customer-org-id?: string) -> The subscription
```

#### Access

Public — no credentials required.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `500` | PLAN_RETRIEVAL_FAILED | Failed to retrieve customer plan | The plan record could not be read. | Retry. |

Plus the standard platform errors: `429`.

#### See also

- `POST /org-management/subscription/create`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `customer-org-id` | query | string | — |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The subscription |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | Failed to retrieve customer plan — The plan record could not be read. |

## POST /org-management/subscription/create

**Create a subscription**

`operationId: OrgManagementController_createSubscription`

Starts a new subscription. **Charges the card** and sets the org's plan, which changes what the account is allowed to do.

#### Signature

```http
POST /org-management/subscription/create (body) -> The subscription
```

#### Access

Public — no credentials required.

#### Notes

- Charges a card and changes plan entitlements.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | PLAN_REQUIRED | Plan is required | `plan` is missing. | Name a plan. |
| `402` | PAYMENT_FAILED | Payment failed | The card was declined or the charge could not be taken. | Try another payment method. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /org-management/subscription/upgrade`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The plan.

```json
{
  "plan": "pro-monthly",
  "paymentMethodId": "pm_1Abc123"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The subscription |
| `400` | Plan is required — `plan` is missing. |
| `402` | Payment failed — The card was declined or the charge could not be taken. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/subscription/upgrade

**Upgrade a subscription**

`operationId: OrgManagementController_upgradeSubscription`

Moves the org to a higher plan. Charges the difference and raises the entitlements immediately.

#### Signature

```http
POST /org-management/subscription/upgrade (body) -> The subscription
```

#### Access

Public — no credentials required.

#### Notes

- Charges the difference.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | NEW_PLAN_REQUIRED | New plan is required | `newPlan` is missing. | Name the target plan. |
| `402` | PAYMENT_FAILED | Payment failed | The card was declined or the charge could not be taken. | Try another payment method. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /org-management/subscription/downgrade`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The target plan.

```json
{
  "newPlan": "enterprise-monthly"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The subscription |
| `400` | New plan is required — `newPlan` is missing. |
| `402` | Payment failed — The card was declined or the charge could not be taken. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/subscription/downgrade

**Downgrade a subscription**

`operationId: OrgManagementController_downgradeSubscription`

Moves the org to a lower plan. **Lowers entitlements**, so anything the org has that exceeds the new plan's limits — sites, seats, storage — may stop working or be refused on next use. Check usage against the target plan first.

#### Signature

```http
POST /org-management/subscription/downgrade (body) -> The subscription
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Reduces what the org is allowed to do.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | NEW_PLAN_REQUIRED | New plan is required | `newPlan` is missing. | Name the target plan. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/subscription/upgrade`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The target plan.

```json
{
  "newPlan": "starter-monthly"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The subscription |
| `400` | New plan is required — `newPlan` is missing. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/subscription/cancel

**Cancel a subscription**

`operationId: OrgManagementController_cancelSubscription`

Cancels the current subscription. The org keeps its data but loses plan entitlements at the end of the term — separate from cancelling the account itself.

#### Signature

```http
POST /org-management/subscription/cancel (body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/account/cancel`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

Optional reason.

```json
{
  "reason": "No longer needed"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/subscription/admin/update

**Update a customer plan (admin)**

`operationId: OrgManagementController_updateCustomerPlan`

Admin override for a customer's plan — type, status and expiry — with audit logging. Sets the plan directly without payment, so it is the tool for a negotiated arrangement, not the normal upgrade path.

#### Signature

```http
POST /org-management/subscription/admin/update (body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `RootPowerUser`.

#### Notes

- Bypasses payment. Audited.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /org-management/subscription/current`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The plan fields to set.

```json
{
  "customerOrgId": "org_4821",
  "planType": "enterprise",
  "status": "active",
  "expiry": "2027-08-30"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/subscription/complete-payment

**Complete a subscription payment**

`operationId: OrgManagementController_completeSubscriptionPayment`

Finalises a pending subscription payment after Stripe validation and activates the plan.

#### Signature

```http
POST /org-management/subscription/complete-payment (body) -> The result
```

#### Access

Public — no credentials required.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | PAYMENT_INTENT_REQUIRED | Payment intent ID is required | No intent id was supplied. | Pass the intent id from the client-side confirmation. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /org-management/subscription/complete-checkout`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The payment reference.

```json
{
  "paymentIntentId": "pi_3Abc123"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Payment intent ID is required — No intent id was supplied. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/subscription/complete-checkout

**Complete a subscription checkout**

`operationId: OrgManagementController_completeSubscriptionCheckout`

Activates a subscription after a successful Stripe Checkout session. The session id is single-use — a replay is refused rather than starting a second subscription.

#### Signature

```http
POST /org-management/subscription/complete-checkout (body) -> The subscription
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | SESSION_REQUIRED | Session ID is required | `sessionId` is missing. | Pass the Stripe session id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/subscription/complete-payment`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The checkout session.

```json
{
  "sessionId": "cs_test_a1b2c3"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The subscription |
| `400` | Session ID is required — `sessionId` is missing. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/account/cancel

**Cancel the account**

`operationId: OrgManagementController_cancelAccount`

Cancels the entire organization account — not just the subscription. Everything the org runs stops. Reactivation is an admin action, so this is not something a customer can undo themselves.

#### Signature

```http
POST /org-management/account/cancel (body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Takes the whole org offline; only an admin can reverse it.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | EMAIL_MISMATCH | Email confirmation does not match | The confirmation email does not match the org's. | Type the account email exactly. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `PUT /org-management/account/reactivate`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

Confirmation and reason.

```json
{
  "confirmEmail": "owner@acme.example",
  "reason": "Closing the business"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Email confirmation does not match — The confirmation email does not match the org's. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## PUT /org-management/account/reactivate

**Reactivate an account (admin)**

`operationId: OrgManagementController_reactivateAccount`

Brings a cancelled account back. Admin only; refused if the account is already active.

#### Signature

```http
PUT /org-management/account/reactivate () -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `ConfigAdmin`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | ALREADY_ACTIVE | Account is already active | The account was not cancelled. | Nothing to do. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/account/cancel`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The result |
| `400` | Account is already active — The account was not cancelled. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/pre-approved-signups

**List pre-approved signups (admin)**

`operationId: OrgManagementController_getPreApprovedSignups`

The emails and signup codes cleared to register.

#### Signature

```http
GET /org-management/pre-approved-signups (type?: string, active?: boolean) -> Pre-approved entries
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `ConfigAdmin`.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/pre-approved-signups`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `type` | query | string | — | `email` or `code`. |
| `active` | query | boolean | — |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Pre-approved entries |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/pre-approved-signups

**Add a pre-approved signup (admin)**

`operationId: OrgManagementController_addPreApprovedSignup`

Adds an email or a signup code to the pre-approved list. A code can be redeemed by anyone who has it, so treat codes as shareable and emails as individual.

#### Signature

```http
POST /org-management/pre-approved-signups (body) -> The entry
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `ConfigAdmin`.

#### Notes

- A code is usable by anyone holding it.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_EMAIL_FORMAT | Invalid email format | The email is malformed. | Supply a valid address. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/pre-approved-signups/remove`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The entry.

```json
{
  "email": "ada@example.com"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The entry |
| `400` | Invalid email format — The email is malformed. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/pre-approved-signups/remove

**Remove a pre-approved signup (admin)**

`operationId: OrgManagementController_removePreApprovedSignup`

Removes an email or code from the pre-approved list, so it can no longer be used to register.

#### Signature

```http
POST /org-management/pre-approved-signups/remove (body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `ConfigAdmin`.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /org-management/pre-approved-signups`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The entry to remove.

```json
{
  "email": "ada@example.com"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/pre-approved-signups/validate

**Validate a pre-approved signup**

`operationId: OrgManagementController_validatePreApprovedSignup`

Checks whether an email or code is cleared to sign up. **Public**, because it runs before an account exists — which also makes it an oracle for whether a given email is on the list, so rate-limit it.

#### Signature

```http
POST /org-management/pre-approved-signups/validate (body) -> Whether it is approved
```

#### Access

Public — no credentials required.

#### Notes

- Unauthenticated; confirms list membership.

#### Errors

Plus the standard platform errors: `429`, `500`.

#### See also

- `GET /org-management/pre-approved-signups`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

What to check.

```json
{
  "email": "ada@example.com"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | Whether it is approved |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

Example response:

```json
{
  "approved": true
}
```

## POST /org-management/org-register

**Register an organization**

`operationId: OrgManagementController_registerOrganization`

Creates an organization and, optionally, a development environment for cloud development. Provisioning a site or dev environment can fail after the org is created, so check the response rather than assuming all parts exist.

#### Signature

```http
POST /org-management/org-register (body) -> The organization
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `System`, `RootAdmin`, `RootPowerUser`.

#### Notes

- Partial success is possible.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `422` | INVALID_EMAIL | Invalid Email <email> | The owner email is malformed. | Supply a valid address. |
| `500` | PROVISIONING_FAILED | Failed to create site or dev environment | The org was created but provisioning failed. | The org exists — retry the provisioning step rather than re-registering. |

Plus the standard platform errors: `401`, `403`, `429`.

#### See also

- `GET /org-management/check-org-name/{orgName}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The organization to create.

```json
{
  "orgName": "acme",
  "ownerEmail": "owner@acme.example",
  "createDevEnv": true
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The organization |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `422` | Invalid Email <email> — The owner email is malformed. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | Failed to create site or dev environment — The org was created but provisioning failed. |

## POST /org-management/business-made-register

**Register a Business Made organization**

`operationId: OrgManagementController_registerBusinessMadeOrganization`

Public org creation dedicated to the Business Made app. **Origin/Referer must match** localhost, appmint.io or businessmade.io — that check is the only thing standing between this route and open org creation, since it is otherwise unauthenticated.

It forces the plan into the `bm-*` family and does **not** provision a site or dev environment, unlike `org-register`.

#### Signature

```http
POST /org-management/business-made-register (body) -> The organization
```

#### Access

Public — no credentials required.

#### Notes

- Unauthenticated; gated only by Origin/Referer.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `403` | ORIGIN_NOT_ALLOWED | Origin not allowed | The Origin or Referer is not one of the permitted hosts. | Call it from an allowed front end. |
| `422` | INVALID_EMAIL | Invalid Email <email> | The owner email is malformed. | Supply a valid address. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /org-management/org-register`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The organization.

```json
{
  "orgName": "acme-hr",
  "ownerEmail": "owner@acme.example"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The organization |
| `403` | Origin not allowed — The Origin or Referer is not one of the permitted hosts. |
| `422` | Invalid Email <email> — The owner email is malformed. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/delete

**Delete an organization**

`operationId: OrgManagementController_deleteOrganization`

Deletes an organization and, optionally, its sites and resources. Destructive and not recoverable through this API — everything the org owns goes with it. Cancel the account instead if the data may be needed.

#### Signature

```http
POST /org-management/delete (body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `System`, `RootAdmin`, `RootPowerUser`.

#### Notes

- Irreversible. Prefer account cancellation.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/account/cancel`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

What to delete.

```json
{
  "orgId": "org_4821",
  "deleteSites": true
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/services/available

**Get available services**

`operationId: OrgManagementController_getAvailableServices`

Additional services the org can buy — export time, support and the like.

#### Signature

```http
GET /org-management/services/available (category?: string) -> Available services
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/services/purchase`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `category` | query | string | — |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Available services |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/services/purchase

**Purchase a service**

`operationId: OrgManagementController_purchaseService`

Buys an additional service. Charges the card or draws down credit, depending on the service.

#### Signature

```http
POST /org-management/services/purchase (body) -> The purchase
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Costs money.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | SERVICE_ID_REQUIRED | Service ID is required | `serviceId` is missing. | Name the service. |
| `402` | PAYMENT_FAILED | Payment failed | The card was declined or the charge could not be taken. | Try another payment method. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/services/complete-payment`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

What to buy.

```json
{
  "serviceId": "export-time",
  "quantity": 1
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The purchase |
| `400` | Service ID is required — `serviceId` is missing. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `402` | Payment failed — The card was declined or the charge could not be taken. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/services/purchased

**Get purchased services**

`operationId: OrgManagementController_getPurchasedServices`

Services the org has bought and their status.

#### Signature

```http
GET /org-management/services/purchased (status?: string) -> Purchased services
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /org-management/services/available`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `status` | query | string | — |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Purchased services |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/services/complete-payment

**Complete a service payment**

`operationId: OrgManagementController_completeServicePayment`

Finalises a pending service payment after gateway validation and activates the service.

#### Signature

```http
POST /org-management/services/complete-payment (body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | PAYMENT_INTENT_REQUIRED | Payment intent ID is required | No intent id was supplied. | Pass the intent id from the client-side confirmation. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/services/purchase`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The payment reference.

```json
{
  "paymentIntentId": "pi_3Abc123"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Payment intent ID is required — No intent id was supplied. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/transfer/ownership

**Transfer organization ownership**

`operationId: OrgManagementController_transferOrgOwnership`

Hands an organization to a new email, creating a user account for the new owner with the admin role.

This gives someone else administrative control of the org. There is no confirmation step from the recipient — the transfer takes effect on the call, so verify the address character by character.

#### Signature

```http
POST /org-management/transfer/ownership (body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `RootPowerUser`, `ConfigAdmin`.

#### Notes

- Grants admin control immediately, with no recipient confirmation.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_NEW_OWNER_EMAIL | Invalid email format for new owner | The address is malformed. | Check the address. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/transfer/change-email`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The new owner.

```json
{
  "newOwnerEmail": "newowner@acme.example"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Invalid email format for new owner — The address is malformed. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/transfer/change-email

**Change the primary email**

`operationId: OrgManagementController_changeOrgPrimaryEmail`

Changes an org's primary email **without** transferring ownership — for a rename or a mailbox change, where `transfer/ownership` would be wrong.

#### Signature

```http
POST /org-management/transfer/change-email (body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `RootPowerUser`, `ConfigAdmin`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_EMAIL_FORMAT | Invalid email format | The address is malformed. | Check the address. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/transfer/ownership`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The new email.

```json
{
  "newEmail": "billing@acme.example"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Invalid email format — The address is malformed. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/transfer/assets

**Transfer assets between organizations**

`operationId: OrgManagementController_transferAssets`

Moves or copies assets from one org to another. **`move` deletes the original** — copy first if there is any doubt, since a move across orgs is not undone by transferring back.

#### Signature

```http
POST /org-management/transfer/assets (body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `RootPowerUser`.

#### Notes

- `move` is destructive on the source.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | SAME_ORG | Source and target organizations cannot be the same | Source and target match. | Pick two different orgs. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/transfer/assets-bulk`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

What to transfer, and how.

```json
{
  "sourceOrgId": "org_4821",
  "targetOrgId": "org_7712",
  "assetType": "product",
  "mode": "copy"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Source and target organizations cannot be the same — Source and target match. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/transfer/assets-bulk

**Bulk-transfer assets between organizations**

`operationId: OrgManagementController_transferAssetsBulk`

Transfers several asset types at once. Same `copy`/`move` semantics as the single form, applied across everything named — which makes a `move` here considerably wider in blast radius.

#### Signature

```http
POST /org-management/transfer/assets-bulk (body) -> Per-type results
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `RootPowerUser`.

#### Notes

- A bulk `move` deletes across every named type.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | SAME_ORG | Source and target organizations cannot be the same | Source and target match. | Pick two different orgs. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/transfer/assets`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

What to transfer.

```json
{
  "sourceOrgId": "org_4821",
  "targetOrgId": "org_7712",
  "assetTypes": [
    "product",
    "customer"
  ],
  "mode": "copy"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | Per-type results |
| `400` | Source and target organizations cannot be the same — Source and target match. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/services/pricing/{serviceName}

**Get service pricing**

`operationId: OrgManagementController_getServicePricing`

Pricing and terms for one service.

#### Signature

```http
GET /org-management/services/pricing/{serviceName} (serviceName: string) -> Pricing and terms
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /org-management/services/available`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `serviceName` | path | string | yes | Service name. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Pricing and terms |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/services/agreements

**Get service agreements**

`operationId: OrgManagementController_getServiceAgreements`

Every service agreement the org has, and its state.

#### Signature

```http
GET /org-management/services/agreements () -> Agreements
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /org-management/services/agreement/{serviceName}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Agreements |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/init/{orgid}

**Check an org's initialization**

`operationId: OrgManagementController_initStatus`

Per step, whether the org has what every org starts with: the access-request workflow, the `meeting` reservation definition, and the publishing-approval workflow (seeded switched off). `complete` is true when every step is present.

#### Signature

```http
GET /org-management/init/{orgid} (orgid: string) -> { orgId, steps: [{ key, title, present }], complete }
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `RootSystem`, `RootPowerUser`, `ConfigAdmin`.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/init/{orgid}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | { orgId, steps: [{ key, title, present }], complete } |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

Example response:

```json
{
  "orgId": "acme",
  "complete": false,
  "steps": [
    {
      "key": "workflow.access-approval",
      "title": "Access request workflow",
      "present": true
    },
    {
      "key": "reservation-definition.meeting",
      "title": "Meeting bookings (reservation definition \"meeting\")",
      "present": false
    }
  ]
}
```

## POST /org-management/init/{orgid}

**Initialize an org**

`operationId: OrgManagementController_initRun`

Runs every initialization step the org is missing and leaves the rest alone — safe to repeat. A step that fails is reported and the others still run.

#### Signature

```http
POST /org-management/init/{orgid} (orgid: string) -> { orgId, done, present, failed }
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `RootSystem`, `RootPowerUser`, `ConfigAdmin`.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /org-management/init/{orgid}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | { orgId, done, present, failed } |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

Example response:

```json
{
  "orgId": "acme",
  "done": [
    "reservation-definition.meeting"
  ],
  "present": [
    "workflow.access-approval",
    "workflow.publish-approval"
  ],
  "failed": []
}
```

## GET /org-management/setup/catalog

**Get the setup wizard catalog**

`operationId: OrgManagementController_getSetupCatalog`

Every configuration item in the setup wizard, with live per-item status and completeness for this org — one call behind a whole onboarding checklist.

#### Signature

```http
GET /org-management/setup/catalog () -> The catalog with status
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/company/meta`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The catalog with status |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/services/agreement/{serviceName}

**Get a service agreement**

`operationId: OrgManagementController_getServiceAgreement`

Whether the org has accepted the terms for one shareable service.

#### Signature

```http
GET /org-management/services/agreement/{serviceName} (serviceName: string) -> The agreement status
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/services/agreement/accept/{serviceName}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `serviceName` | path | string | yes | Service name. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The agreement status |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/services/agreement/accept/{serviceName}

**Accept a service agreement**

`operationId: OrgManagementController_acceptServiceAgreement`

Records acceptance of the terms for a shareable service — a legal act on the org's behalf, recorded against the accepting user.

#### Signature

```http
POST /org-management/services/agreement/accept/{serviceName} (serviceName: string, body) -> The agreement
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Records a binding acceptance.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/services/agreement/revoke/{serviceName}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `serviceName` | path | string | yes | Service name. |

### Request body

Acceptance detail.

```json
{
  "version": "2026-01"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The agreement |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/services/agreement/revoke/{serviceName}

**Revoke a service agreement**

`operationId: OrgManagementController_revokeServiceAgreement`

Withdraws acceptance for a shareable service. Anything relying on that agreement stops working.

#### Signature

```http
POST /org-management/services/agreement/revoke/{serviceName} (serviceName: string) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /org-management/services/agreements`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `serviceName` | path | string | yes | Service name. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/users/{orgid}

**List an organization's users**

`operationId: OrgManagementController_getOrgUsers`

Users in the named org. The path `orgid` is the org being read; the header identifies the caller, which is what lets an operator read another org's users.

#### Signature

```http
GET /org-management/users/{orgid} (orgid: string) -> Users
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootSystem`, `RootAdmin`, `RootPowerUser`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /org-management/users/{orgid}/{userId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Users |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/users/{orgid}/{userId}

**Get an organization user**

`operationId: OrgManagementController_getOrgUser`

One user in the named org.

#### Signature

```http
GET /org-management/users/{orgid}/{userId} (orgid: string, userId: string) -> The user
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootSystem`, `RootAdmin`, `RootPowerUser`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/users/{orgid}/update`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |
| `userId` | path | string | yes | User id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The user |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/users/{orgid}/create

**Create an organization user**

`operationId: OrgManagementController_createOrgUser`

Creates a user inside the named org. The role given here decides what they can do — a user created with an admin role has administrative control from the moment they sign in.

#### Signature

```http
POST /org-management/users/{orgid}/create (orgid: string, body) -> The user
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootSystem`, `RootAdmin`, `RootPowerUser`.

#### Notes

- The role grants real access.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/users/{orgid}/update`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |

### Request body

The user.

```json
{
  "email": "ada@acme.example",
  "firstName": "Ada",
  "lastName": "Lovelace",
  "role": "editor"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The user |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/users/{orgid}/update

**Update an organization user**

`operationId: OrgManagementController_updateOrgUser`

Updates a user in the named org, including their role. A role change takes effect on their next request.

#### Signature

```http
POST /org-management/users/{orgid}/update (orgid: string, body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootSystem`, `RootAdmin`, `RootPowerUser`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/users/{orgid}/status`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |

### Request body

The user id and fields to change.

```json
{
  "id": "USR-4821",
  "role": "admin"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/users/{orgid}/status

**Set organization users' status**

`operationId: OrgManagementController_setOrgUsersStatus`

Activates or deactivates users in bulk. Deactivating removes their access at once — the reversible alternative to deleting them.

#### Signature

```http
POST /org-management/users/{orgid}/status (orgid: string, body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootSystem`, `RootAdmin`, `RootPowerUser`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/users/{orgid}/delete`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |

### Request body

Which users, and the status.

```json
{
  "ids": [
    "USR-4821"
  ],
  "status": "inactive"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/users/{orgid}/delete

**Delete organization users**

`operationId: OrgManagementController_deleteOrgUsers`

Permanently removes users from the named org. Deactivate instead unless the records genuinely should not exist — deletion loses the audit association with anything they did.

#### Signature

```http
POST /org-management/users/{orgid}/delete (orgid: string, body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootSystem`, `RootAdmin`, `RootPowerUser`.

#### Notes

- Irreversible; prefer deactivation.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/users/{orgid}/status`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |

### Request body

Which users.

```json
{
  "ids": [
    "USR-4821"
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/users/{orgid}/change-password

**Change an organization user's password**

`operationId: OrgManagementController_resetOrgUserPassword`

Sets a user's password directly, without their involvement. An administrative override — the user is not asked to confirm, and any session they hold may be invalidated. Prefer sending a reset link.

#### Signature

```http
POST /org-management/users/{orgid}/change-password (orgid: string, body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootSystem`, `RootAdmin`, `RootPowerUser`.

#### Notes

- Sensitive payload; prefer `send-reset`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/users/{orgid}/send-reset`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |

### Request body

The user and the new password.

```json
{
  "id": "USR-4821",
  "password": "<new password>"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/users/{orgid}/send-reset

**Send a password reset to an organization user**

`operationId: OrgManagementController_sendOrgUserReset`

Emails a reset link to the user, letting them set their own password. The preferred route — it sends a real email, so check the recipient.

#### Signature

```http
POST /org-management/users/{orgid}/send-reset (orgid: string, body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootSystem`, `RootAdmin`, `RootPowerUser`.

#### Notes

- Sends an email.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/users/{orgid}/change-password`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |

### Request body

Which user.

```json
{
  "id": "USR-4821"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/customers/{orgid}

**List an organization's customers**

`operationId: OrgManagementController_getOrgCustomers`

Customers belonging to the named org. Customers are the org's end users, distinct from its staff users.

#### Signature

```http
GET /org-management/customers/{orgid} (orgid: string) -> Customers
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootSystem`, `RootAdmin`, `RootPowerUser`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /org-management/users/{orgid}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Customers |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/customers/{orgid}/{customerId}

**Get an organization customer**

`operationId: OrgManagementController_getOrgCustomer`

One customer in the named org.

#### Signature

```http
GET /org-management/customers/{orgid}/{customerId} (orgid: string, customerId: string) -> The customer
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootSystem`, `RootAdmin`, `RootPowerUser`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/customers/{orgid}/update`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |
| `customerId` | path | string | yes | Customer id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The customer |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/customers/{orgid}/create

**Create an organization customer**

`operationId: OrgManagementController_createOrgCustomer`

Creates a customer in the named org.

#### Signature

```http
POST /org-management/customers/{orgid}/create (orgid: string, body) -> The customer
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootSystem`, `RootAdmin`, `RootPowerUser`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/customers/{orgid}/update`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |

### Request body

The customer.

```json
{
  "email": "ada@example.com",
  "firstName": "Ada",
  "lastName": "Lovelace"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The customer |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/customers/{orgid}/update

**Update an organization customer**

`operationId: OrgManagementController_updateOrgCustomer`

Updates a customer in the named org.

#### Signature

```http
POST /org-management/customers/{orgid}/update (orgid: string, body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootSystem`, `RootAdmin`, `RootPowerUser`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/customers/{orgid}/status`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |

### Request body

The customer id and fields to change.

```json
{
  "id": "CUST-4821",
  "phone": "+15551234567"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/customers/{orgid}/status

**Set organization customers' status**

`operationId: OrgManagementController_setOrgCustomersStatus`

Activates or deactivates customers in bulk. Deactivated customers cannot sign in.

#### Signature

```http
POST /org-management/customers/{orgid}/status (orgid: string, body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootSystem`, `RootAdmin`, `RootPowerUser`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/customers/{orgid}/delete`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |

### Request body

Which customers, and the status.

```json
{
  "ids": [
    "CUST-4821"
  ],
  "status": "inactive"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/customers/{orgid}/delete

**Delete organization customers**

`operationId: OrgManagementController_deleteOrgCustomers`

Permanently removes customers. Their orders, bookings and history may reference them — deactivate unless the records genuinely must go.

#### Signature

```http
POST /org-management/customers/{orgid}/delete (orgid: string, body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootSystem`, `RootAdmin`, `RootPowerUser`.

#### Notes

- Irreversible; breaks references from historical records.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/customers/{orgid}/status`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |

### Request body

Which customers.

```json
{
  "ids": [
    "CUST-4821"
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/customers/{orgid}/change-password

**Change an organization customer's password**

`operationId: OrgManagementController_resetOrgCustomerPassword`

Sets a customer's password directly. An administrative override, without the customer's involvement — prefer sending a reset link.

#### Signature

```http
POST /org-management/customers/{orgid}/change-password (orgid: string, body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootSystem`, `RootAdmin`, `RootPowerUser`.

#### Notes

- Sensitive payload; prefer `send-reset`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/customers/{orgid}/send-reset`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |

### Request body

The customer and the new password.

```json
{
  "id": "CUST-4821",
  "password": "<new password>"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/customers/{orgid}/send-reset

**Send a password reset to an organization customer**

`operationId: OrgManagementController_sendOrgCustomerReset`

Emails a reset link to the customer. Requires the customer to have an email on file — without one there is nowhere to send it.

#### Signature

```http
POST /org-management/customers/{orgid}/send-reset (orgid: string, body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootSystem`, `RootAdmin`, `RootPowerUser`.

#### Notes

- Sends an email.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ORG_ID | Invalid orgId | The org id is missing or not a real org. | Check the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /org-management/customers/{orgid}/change-password`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `orgid` | path | string | yes | The org being acted on — separate from the `orgid` **header**, which identifies the caller. |

### Request body

Which customer.

```json
{
  "id": "CUST-4821"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `400` | Invalid orgId — The org id is missing or not a real org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/transfer/requests

**List transfer requests**

`operationId: OrgTransferController_listRequests`

Requests where this org is the source (`outgoing`) or the target (`incoming`), newest first. A pending request past its expiry is reported as `expired` when read.

#### Signature

```http
GET /org-management/transfer/requests (direction?: string, status?: string, page?: integer, pageSize?: integer) -> { data, total }
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `RootPowerUser`, `ConfigAdmin`.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `direction` | query | "incoming" \| "outgoing" \| "all" | — |  |
| `status` | query | "pending" \| "accepted" \| "running" \| "completed" \| "partial" \| "failed" \| "rejected" \| "cancelled" \| "expired" | — |  |
| `page` | query | integer | — |  |
| `pageSize` | query | integer | — |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | { data, total } |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/transfer/requests

**Ask another org to accept a data transfer**

`operationId: OrgTransferController_createRequest`

The source org (the `orgid` header) asks a target org to accept a **copy** or **move** of records. Nothing moves until a ConfigAdmin of the target org accepts. Name what to send as `scope` — per collection, `select: all | filter | ids` — or with the older `assets: { datatype: [ids] }`. Every entry is counted up front; one request carries at most **100,000** records. The request expires after **7 days** if nobody decides. The target org gets an in-app notice and an email.

#### Signature

```http
POST /org-management/transfer/requests (body) -> The request as the caller sees it
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `RootPowerUser`, `ConfigAdmin`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | TARGET_REQUIRED | targetOrgId is required | No target org. | — |
| `404` | TARGET_NOT_FOUND | Target organization acme-eu not found | The target org does not exist. | — |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /org-management/transfer/requests/check-org/{targetOrgId}`
- `POST /org-management/transfer/requests/{id}/accept`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

What to send and to whom.

```json
{
  "targetOrgId": "acme-eu",
  "mode": "copy",
  "scope": [
    {
      "datatype": "sf_product",
      "select": "all"
    }
  ],
  "reason": "Opening the EU store"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The request as the caller sees it |
| `400` | targetOrgId is required — No target org. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Target organization acme-eu not found — The target org does not exist. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /org-management/transfer/requests/check-org/{targetOrgId}

**Check a target org before sending**

`operationId: OrgTransferController_checkOrg`

Whether a transfer could name this org, and its display name — so the sender learns before building a request. Returns existence and name only.

#### Signature

```http
GET /org-management/transfer/requests/check-org/{targetOrgId} (targetOrgId: string) -> { exists, orgId, name? , reason? }
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `RootPowerUser`, `ConfigAdmin`.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `targetOrgId` | path | string | yes | Org id to check. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | { exists, orgId, name? , reason? } |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

Example response:

```json
{
  "exists": true,
  "orgId": "acme-eu",
  "name": "Acme EU"
}
```

## GET /org-management/transfer/requests/{id}

**Get one transfer request**

`operationId: OrgTransferController_getRequest`

One request with its progress (`processedRecords` of `totalRecords`) and, once finished, `successCount`, `failCount` and `results`. Only the source or target org can read it; to anyone else it does not exist.

#### Signature

```http
GET /org-management/transfer/requests/{id} (id: string) -> The request
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `RootPowerUser`, `ConfigAdmin`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | TRANSFER_NOT_FOUND | Transfer request not found | No such request, or the caller's org is neither its source nor its target. | — |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Transfer request id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The request |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Transfer request not found — No such request, or the caller's org is neither its source nor its target. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/transfer/requests/{id}/accept

**Accept a transfer request**

`operationId: OrgTransferController_acceptRequest`

The target org accepts. The request switches to `running` and comes back at once; the records are copied (or moved) in batches of 200 in the background, writing progress onto the request, and both orgs are told when it ends. Poll `GET …/requests/{id}` for progress.

#### Signature

```http
POST /org-management/transfer/requests/{id}/accept (id: string) -> The request, now running
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `RootPowerUser`, `ConfigAdmin`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | TRANSFER_NOT_FOUND | Transfer request not found | No such request, or the caller's org is neither its source nor its target. | — |
| `400` | NOT_PENDING | Transfer request is running, not pending | The request has already been decided, cancelled or has expired. | — |
| `403` | NOT_TARGET | Only the target organization can accept a transfer request | The caller is the source org. | — |

Plus the standard platform errors: `401`, `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Transfer request id. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The request, now running |
| `400` | Transfer request is running, not pending — The request has already been decided, cancelled or has expired. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | Only the target organization can accept a transfer request — The caller is the source org. |
| `404` | Transfer request not found — No such request, or the caller's org is neither its source nor its target. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/transfer/requests/{id}/reject

**Reject a transfer request**

`operationId: OrgTransferController_rejectRequest`

The target org declines, optionally saying why. The source org is told.

#### Signature

```http
POST /org-management/transfer/requests/{id}/reject (id: string, body) -> The request, now rejected
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `RootPowerUser`, `ConfigAdmin`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | TRANSFER_NOT_FOUND | Transfer request not found | No such request, or the caller's org is neither its source nor its target. | — |
| `400` | NOT_PENDING | Transfer request is running, not pending | The request has already been decided, cancelled or has expired. | — |
| `403` | NOT_TARGET | Only the target organization can reject a transfer request | The caller is the source org. | — |

Plus the standard platform errors: `401`, `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Transfer request id. |

### Request body

Why.

```json
{
  "reason": "Wrong catalogue"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The request, now rejected |
| `400` | Transfer request is running, not pending — The request has already been decided, cancelled or has expired. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | Only the target organization can reject a transfer request — The caller is the source org. |
| `404` | Transfer request not found — No such request, or the caller's org is neither its source nor its target. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /org-management/transfer/requests/{id}/cancel

**Cancel a transfer request**

`operationId: OrgTransferController_cancelRequest`

The source org withdraws a request before the target decides. The target is told.

#### Signature

```http
POST /org-management/transfer/requests/{id}/cancel (id: string) -> The request, now cancelled
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`). Required role(s): `RootAdmin`, `RootPowerUser`, `ConfigAdmin`.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | TRANSFER_NOT_FOUND | Transfer request not found | No such request, or the caller's org is neither its source nor its target. | — |
| `400` | NOT_PENDING | Transfer request is running, not pending | The request has already been decided, cancelled or has expired. | — |
| `403` | NOT_SOURCE | Only the source organization can cancel a transfer request | The caller is the target org. | — |

Plus the standard platform errors: `401`, `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Transfer request id. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The request, now cancelled |
| `400` | Transfer request is running, not pending — The request has already been decided, cancelled or has expired. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | Only the source organization can cancel a transfer request — The caller is the target org. |
| `404` | Transfer request not found — No such request, or the caller's org is neither its source nor its target. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

