# Change the Co-Signer Settings

Save your tenant's own MPC co-signer: its mode, its nodes, the CA they are pinned to and the server credential it presents. The HMAC secret is shown when it is made, and never again.

## Overview

- **Every save writes every setting**: `mode`, `urls` and `serverCredentialId` are required, and a `caPem` left out removes the pinned CA. The rules: [Institution Callback & Co-Signer › The Settings](https://docs.aureahub.com/docs/guide-institution-callback.md).
- **`201` with `cosigner`, `created` and `hmacSecret`** the first time: store the secret on your co-signer's nodes now — it is never shown again. **`200`** after, with `hmacSecret` only when `"rotateSecret": true` made a new one.
- `mode` `on` only where co-signers can be switched on (`enabled` in Get the Co-Signer Settings): otherwise `409` `MPC_TENANT_COSIGNERS_DISABLED`. A co-signer saved `off` lets you start your nodes with the secret before you switch it on.
- The body is checked as sent: a field that doesn't belong, or a value of the wrong type, is refused rather than ignored or converted. A change your tenant's quorum holds is checked when it runs: a body the API refuses ends its request `failed` with that refusal.
- For `owner`, `tenantadmin`, `non_signing_admin` and `security_admin`, on their own tenant.

> Note: **Your tenant's quorum** [Coming soon, upon request](https://docs.aureahub.com/docs/feature-availability.md) — where it holds administrators' actions (a tenant on the institutional security profile by its profile; every other tenant's records them only): this call answers `202` `{ "state": "awaiting_quorum", "requestId" }` — the **202** tab below — and nothing is done until another administrator of your tenant approves it; the answer it would have given is then read once by who asked ([Read the Answer](https://docs.aureahub.com/docs/quorum-request-result.md)). With no other administrator able to approve it, it is done at once. [Your Tenant's Quorum](https://docs.aureahub.com/docs/guide-tenant-quorum.md). Every other tenant gets the answers below, unchanged.

## Endpoint

### `PUT /v1/admin/tenants/{id}/mpc-cosigner`

Authentication: bearer token required.

Saves the tenant's own MPC co-signer (201 with the HMAC secret the first time).

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | Tenant UUID |

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `mode` | string | yes | `off` or `on`: whether your new MPC wallets are made with it |
| `urls` | string[] | yes | One to three nodes: https, a public host, no credentials, query or fragment |
| `caPem` | string \| null | no | PEM certificates your nodes' TLS is pinned to, up to 16384 characters; left out or `null`: the system's CAs |
| `serverCredentialId` | string (uuid) | yes | An active server credential of your tenant whose role signs |
| `rotateSecret` | boolean | no | `true`: a new HMAC secret, answered once |

**Responses**

`201` Saved first

```json
{
  "cosigner": {
    "mode": "off",
    "urls": ["https://cosigner-a.example.com", "https://cosigner-b.example.com"],
    "caFingerprints": ["866807fcde9292fe40434e0ba408ffb389a4195842e9de91164991392f25f1f6"],
    "serverCredentialId": "2f6d8a4e-1c3b-4e5f-9a7d-0b2c4e6f8a1c",
    "hmacSecretHint": "Qx7v",
    "boundWallets": 0,
    "version": 1,
    "createdAt": "2026-10-14T08:10:41.502Z",
    "updatedAt": "2026-10-14T08:10:41.502Z"
  },
  "created": true,
  "hmacSecret": "… (43 characters of base64url, ending Qx7v)"
}
```

`202` Awaiting quorum

```json
{
  "state": "awaiting_quorum",
  "requestId": "4e2b9c17-8a3d-4f60-b5e1-7c9d0a2f6b38"
}
```

`200` Switched on

```json
{
  "cosigner": {
    "mode": "on",
    "urls": ["https://cosigner-a.example.com", "https://cosigner-b.example.com"],
    "caFingerprints": ["866807fcde9292fe40434e0ba408ffb389a4195842e9de91164991392f25f1f6"],
    "serverCredentialId": "2f6d8a4e-1c3b-4e5f-9a7d-0b2c4e6f8a1c",
    "hmacSecretHint": "Qx7v",
    "boundWallets": 0,
    "version": 2,
    "createdAt": "2026-10-14T08:10:41.502Z",
    "updatedAt": "2026-10-14T08:24:55.077Z"
  },
  "created": false
}
```

`400` Refused

```json
{
  "statusCode": 400,
  "error": "BadRequestError",
  "message": "serverCredentialId must have a role that signs (self.mpc.use)",
  "details": { "code": "MPC_TENANT_COSIGNER_INVALID", "field": "serverCredentialId" }
}
```

`409` Not available yet

```json
{
  "statusCode": 409,
  "error": "ConflictError",
  "message": "Tenant co-signers are not enabled on this platform yet: the co-signer cannot be switched on",
  "details": { "code": "MPC_TENANT_COSIGNERS_DISABLED" }
}
```

**Example request**

```bash
curl -X PUT "https://api.aureahub.com/v1/admin/tenants/6f1e2d3c-4b5a-4968-8776-a5b4c3d2e1f0/mpc-cosigner" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "off",
    "urls": ["https://cosigner-a.example.com", "https://cosigner-b.example.com"],
    "caPem": "-----BEGIN CERTIFICATE-----\nMIIB…\n-----END CERTIFICATE-----\n",
    "serverCredentialId": "2f6d8a4e-1c3b-4e5f-9a7d-0b2c4e6f8a1c"
  }'
```

The `hmacSecret` is the base64url of 32 random bytes; the example above shortens it.

## Refusals

Nothing is saved. `400` `MPC_TENANT_COSIGNER_INVALID`, with the field at fault in `details.field`:

- A body that does not fit — a required field missing, a field that doesn't belong, a value of the wrong type, no node or more than three, a `caPem` over 16384 characters —: `The co-signer settings are not valid`.
- A node (`urls.0` to `urls.2`): `urls.0 must be an absolute https URL`, `urls.0 must be https`, `urls.0 must not carry credentials`, `urls.0 must not carry a query or a fragment`, `urls.0 must be a public host`; `urls lists the same node twice`.
- `caPem`: `caPem must not carry a private key`, `caPem must be one or more PEM certificates`, `caPem holds a certificate that does not parse`.
- `serverCredentialId`: `serverCredentialId is not a credential of the tenant`, `serverCredentialId is revoked`, `serverCredentialId is expired`, `serverCredentialId must have a role that signs (self.mpc.use)`.
- `id`: `id is not valid`.

`409` `MPC_TENANT_COSIGNERS_DISABLED` — `mode` `on` where co-signers cannot be switched on yet. `404` `Tenant not found`.

---

Web version: https://docs.aureahub.com/#mpc-cosigner-put
