# Organization management API

Human owner/admin HTTP endpoints for machine client credentials and tenant lifecycle.

These endpoints manage your organization's automation clients and tenants. Use a **human owner
or admin** bearer token and the public platform API origin. An automation client cannot call them,
even to rotate its own credentials. The organization ID comes from the path; no workspace
selection is needed for these organization-scoped operations.

For interactive administration, the [Console and M2M CLI](/guides/deploy/automation-credentials)
and [tenant commands](/guides/manage/tenants-and-environments) provide the same operations.

## Machine clients

All paths below are relative to `/v1/organizations/{organization_id}/m2m`.
`{client_id}` is the platform record ID (`client.id`), not the OAuth `client_id` returned for
credential use. `{credential_id}` is a credential metadata ID.

| Method | Path | Result |
|---|---|---|
| GET | base path | List `{clients: [...]}` without secrets. |
| GET | `/profiles` | Supported permission profiles, scopes, and catalog version. |
| POST | base path | Create a client and issue its first credential. |
| GET | `/{client_id}` | Inspect `{client, credentials}` without secrets. |
| PATCH | `/{client_id}` | Rename, change permissions, disable, or enable. |
| POST | `/{client_id}/credentials` | Add a credential for rotation. |
| DELETE | `/{client_id}/credentials/{credential_id}` | Revoke one credential. |
| DELETE | `/{client_id}` | Delete the client and withdraw access. |

### Create

Send `Content-Type: application/json` and an `Idempotency-Key` of 8–256 characters:

```json
{
  "name": "production-deployer",
  "profile": "deploy",
  "expires_in_days": 90
}
```

`description` is optional. Use `observe`, `invoke`, or `deploy`, or set `profile` to `custom` with an array of supported
`scopes` instead of a named profile. The default credential lifetime is 90 days and maximum 365.

A successful issue returns HTTP 201 with `{client, credential, client_id, client_secret}`. The
secret is returned once and cannot be read later. Retrying with the same idempotency key cannot
issue another secret; an already completed issue returns a conflict without disclosing it again.
Do not log or cache the response. Inspect metadata and rotate if a response was lost.

### Update

Fetch the client and send its current `version` with a PATCH:

```json
{"version": 3, "name": "release-deployer", "profile": "deploy"}
```

To disable, send `{"version": 3, "status": "disabled"}` instead. Use `active` to re-enable.
Do not combine a status transition with name or permission changes. A stale version conflicts;
fetch the record again before deciding whether to retry.

### Rotate and revoke

Credential creation also requires an `Idempotency-Key` and a non-empty label:

```json
{"label": "September rotation", "expires_in_days": 90}
```

At most two live, unexpired credentials are allowed per client. Switch consumers to the new
secret, then DELETE the old credential. At most 20 non-deleted clients are allowed per organization.

Updates can return 200 or 202; revocation and deletion can return 204 or 202. A 202 means cleanup
or application of a change is still pending. Inspect the resource for progress. Client disable/delete and scope removal
apply at the next platform authorization decision without waiting for token expiry. Revoking an
individual credential prevents new token issuance once provider cleanup completes; already-issued
tokens can remain valid until expiry. Disable the client if immediate withdrawal is required.

Machine management responses use `Cache-Control: no-store`. Mutations are rate-limited per
organization and human actor; handle HTTP 429 with backoff. A conflict can indicate a changed
version, lifecycle state, credential limit, or a completed one-time issue; inspect before retrying.

## Tenants

Paths are relative to `/v1/organizations/{organization_id}/tenants`.

| Method | Path | Operation |
|---|---|---|
| GET | base path | List organization tenants. |
| POST | base path | Create a tenant. |
| GET | `/{tenant_id}` | Inspect lifecycle and attachment state. |
| POST | `/{tenant_id}:retry` | Retry provisioning. |
| POST | `/{tenant_id}:offboard` | Withdraw access and start irreversible cleanup. |

Create with an `Idempotency-Key` and JSON body:

```json
{"display_name": "bluewater-bank", "mode": "saas"}
```

The deployment controls supported modes and quotas. Creation returns 202 while provisioning runs.
A tenant becomes usable only when `status` is `active` and attachment `state` is `ready`.
Organization machine clients gain reach automatically at that point.

Offboard with `{"confirm": "<exact-tenant-id>"}`. It returns 202, withdraws machine reach
immediately, and cleans up asynchronously. Preserve required data before confirming.

For runtime calls made **by** a machine client, see [Authenticate a backend](/guides/run/authenticate-your-backend)
and the [application API reference](/api).
