# Suspend a tenant, or restore it

PUT

/v1/system/tenants/{tenantId}/suspended

```sh
curl --request PUT \
  --url https://example.com/v1/system/tenants/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/suspended \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{ "suspended": true, "reason": "example" }'
```

Reversible: a suspended tenant’s own keys and sessions still read and export it; nothing runs (its running runs are cancelled), and nothing is written but deletes. Its schedules and triggers are skipped, not changed, so restoring resumes exactly what was on. Nothing that came due meanwhile runs late: at the restore, a fire whose run or pass hadn’t started is recorded `skipped` (`tenant-suspended`), and a schedule that’s on fires next at its first occurrence after the restore, whatever its `catchUp`. A second suspend keeps the first one’s time and reason; restoring clears both. Takes `system:suspend`, which no other scope includes. A closing tenant is refused (`409 tenant-closing`).

## Authorizations

- **[bearerAuth](https://docs.kindgi.com/v0.1.9/reference/api.md#bearerauth)**

## Parameters

### Path Parameters

**tenantId**

required

string format: uuid

The tenant’s id.

### Header Parameters

**Idempotency-Key**

string

\>= 1 characters

Caller-supplied idempotency key, scoped to the caller: the same key from someone else in the tenant is their own request (from 0.1.5). Retries with the same key return the original response byte-identical (per `docs/API-ROUTE-CONVENTIONS.md` §3.1). A retry sent while the first request still runs is answered `409 idempotency-key-in-flight` with `Retry-After`, on a runtime whose store holds keys (from 0.1.5); retry after it, and you get the first request’s answer. An answer that carries a secret (a new API key or public run token, a session token, a generated signing secret) isn’t kept: a retry gets `409 idempotency-key-replay-withheld`, with the first request’s status and when it succeeded (from 0.1.5).

## Request Bodyrequired

application/json

object

**suspended**

required

boolean

**reason**

string

\>= 1 characters <= 500 characters

##### Examplegenerated

```json
{
  "suspended": true,
  "reason": "example"
}
```

## Responses

### 200

The tenant now.

application/json

A tenant, as the operator sees it: never its content.

object

**id**

required

string format: uuid

**name**

required

string

**slug**

required

string

**state**

required

`closing`: readable and exportable with its own keys for its window, nothing runs. `suspended`: the same, reversibly. `closing` wins over `suspended`.

string

Allowed values: active suspended closing

**createdAt**

required

string format: date-time

**test**

required

A test tenant: left out of usage, invoices and counts.

boolean

**productionAllowed**

required

boolean

**imagePrefix**

The repository its deployments’ images must sit at or under, `<host>/<path>`.

string

**closingAt**

string format: date-time

**suspendedAt**

string format: date-time

**suspendedReason**

string

##### Example

```json
{
  "state": "active"
}
```

### 400

Malformed request body.

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 401

Missing / malformed / expired / revoked bearer token.

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 403

A tenant’s key or session (`system-principal-required`), or a system key without `system:suspend` (`system-scope-missing`).

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 404

No tenant with that id, or a purged one (`tenant-not-found`).

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 409

The tenant is closing (`tenant-closing`); or an Idempotency-Key reused with another body.

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 413

The request body is over the API’s limit (`request-too-large`; `details.maxBytes` says how much).

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 500

Server error (unmapped domain code or framework crash).

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 503

The operator’s access record can’t be written, so nothing was done (`access-record-unavailable`).

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

## See also

- [`GET /v1/system/tenants`: List tenants](https://docs.kindgi.com/v0.1.9/reference/api/operations/systemtenantslist.md)
- [`POST /v1/system/tenants`: Create a tenant](https://docs.kindgi.com/v0.1.9/reference/api/operations/systemtenantscreate.md)
- [`GET /v1/system/tenants/{tenantId}`: Read a tenant](https://docs.kindgi.com/v0.1.9/reference/api/operations/systemtenantsget.md)
- [`POST /v1/system/tenants/{tenantId}/close`: Close a tenant](https://docs.kindgi.com/v0.1.9/reference/api/operations/systemtenantsclose.md)
- [Serve many tenants](https://docs.kindgi.com/v0.1.9/deploy/self-hosted/serve-many-tenants.md)
- [Error code `access-record-unavailable`](https://docs.kindgi.com/v0.1.9/reference/errors.md#access-record-unavailable)
- [Error code `request-too-large`](https://docs.kindgi.com/v0.1.9/reference/errors.md#request-too-large)
- [Error code `system-principal-required`](https://docs.kindgi.com/v0.1.9/reference/errors.md#system-principal-required)
- [Error code `system-scope-missing`](https://docs.kindgi.com/v0.1.9/reference/errors.md#system-scope-missing)
- [Error code `tenant-closing`](https://docs.kindgi.com/v0.1.9/reference/errors.md#tenant-closing)
- [Error code `tenant-not-found`](https://docs.kindgi.com/v0.1.9/reference/errors.md#tenant-not-found)
- [Every error code](https://docs.kindgi.com/v0.1.9/reference/errors.md)
