# Register an Approval Key

The public half of a P-256 key pair you made: the key your approvals are checked with. The private key stays with you.

## Overview

- `name`: your label, 1 to 100 characters, trimmed. `publicKey`: `{ "kty": "EC", "crv": "P-256", "x", "y" }`, `x` and `y` 32 bytes each in unpadded base64url. `alg` (`ES256`), `use` (`sig`), `kid`, `key_ops` and `ext` are accepted and dropped. How to make the key pair: [Approvals](https://docs.aureahub.com/docs/guide-approvals.md).
- `201` with the key: its `id` is the `kid` of the decisions it signs.
- `400` `APPROVAL_KEY_INVALID` for a key that is not a P-256 public key (the reason in the message); `APPROVAL_KEY_PRIVATE` for a JWK that carries `d` — never stored or echoed: don't use that key pair; `APPROVAL_KEY_NAME_INVALID`.
- `409` `APPROVAL_KEY_LIMIT` when you have two active keys — revoke one first; `APPROVAL_KEY_IN_USE` for a key registered before, also one revoked since: a key is registered once, ever.
- At most 10 a minute. Written to your tenant's audit trail (`approval_key.registered`) [Coming soon, upon request](https://docs.aureahub.com/docs/feature-availability.md).

## Endpoint

### `POST /v1/approval-keys`

Authentication: bearer token required.

Registers a P-256 public key you approve with.

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | 1–100 characters |
| `publicKey` | object | yes | The public key as a JWK: `kty` `EC`, `crv` `P-256`, `x`, `y` |

**Responses**

`201` Registered

```json
{
  "id": "7b2e4c91-5d3a-4f68-8e0b-1c9a7d3f5e24",
  "name": "Laptop key",
  "status": "active",
  "publicKey": {
    "kty": "EC",
    "crv": "P-256",
    "x": "oxctA6E_hib_b2IU2itzKLJ2wIh5f89eC4F5_-8jreA",
    "y": "HXPIR2nV0i74GXLTQpg6rHEbZ67c_D1xaJUIccZCrjg"
  },
  "thumbprint": "CFGfOpgdwqX6UnGU5dwiwVwsk9edRucCD8GDfAr9xrI",
  "createdAt": "2026-10-06T09:12:40.511Z",
  "lastUsedAt": null,
  "revokedAt": null,
  "revokeReason": null
}
```

`400` Private key

```json
{
  "statusCode": 400,
  "error": "BadRequestError",
  "message": "publicKey carries a private key (\"d\"): send the public key only, and do not use this key pair",
  "details": { "code": "APPROVAL_KEY_PRIVATE" }
}
```

`409` Limit

```json
{
  "statusCode": 409,
  "error": "ConflictError",
  "message": "At most 2 active approval keys: revoke one first",
  "details": { "code": "APPROVAL_KEY_LIMIT" }
}
```

**Example request**

```bash
curl -X POST https://api.aureahub.com/v1/approval-keys \
  -H "Authorization: Bearer $APPROVER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Laptop key",
    "publicKey": { "kty": "EC", "crv": "P-256", "x": "oxctA6E_hib_b2IU2itzKLJ2wIh5f89eC4F5_-8jreA", "y": "HXPIR2nV0i74GXLTQpg6rHEbZ67c_D1xaJUIccZCrjg" }
  }'
```

---

Web version: https://docs.aureahub.com/#approval-key-register
