> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getmillwork.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Replace an organization key

> Create a new application key before revoking the old one.

**Goal:** Replace a Millwork API key without interrupting the application.

**You are done when:** the application uses the new key and the old key returns
`401`.

<Warning>
  Do not revoke the old key until the new key works. Never paste either key
  into support, source control, logs, or documentation.
</Warning>

## 1. Find the old key

```bash theme={null}
curl --fail-with-body \
  --header "Authorization: Bearer $MILLWORK_API_KEY" \
  "$MILLWORK_API_URL/api-keys" \
  | jq '.api_keys[] | {
      api_key_id,
      display_name,
      key_prefix,
      status,
      created_at
    }'

export OLD_API_KEY_ID="<ID for the key you are replacing>"
```

Use the displayed prefix to identify the key. The full key is never returned
by the list endpoint.

## 2. Create and test the replacement

```bash theme={null}
umask 077

curl --fail-with-body \
  --request POST \
  --header "Authorization: Bearer $MILLWORK_API_KEY" \
  "$MILLWORK_API_URL/api-keys" > new-key.json

export NEW_MILLWORK_API_KEY="$(jq -er '.key' new-key.json)"

curl --fail-with-body \
  --header "Authorization: Bearer $NEW_MILLWORK_API_KEY" \
  "$MILLWORK_API_URL/model-catalog" > /dev/null
```

The full replacement key appears once. Store it in the application's secret
manager, update the application, and confirm the application works.

## 3. Revoke the old key

```bash theme={null}
curl --fail-with-body \
  --request POST \
  --header "Authorization: Bearer $NEW_MILLWORK_API_KEY" \
  "$MILLWORK_API_URL/api-keys/$OLD_API_KEY_ID/revoke"

OLD_KEY_STATUS="$(
  curl --silent \
    --output /dev/null \
    --write-out "%{http_code}" \
    --header "Authorization: Bearer $MILLWORK_API_KEY" \
    "$MILLWORK_API_URL/model-catalog"
)"

test "$OLD_KEY_STATUS" = "401"

rm -f new-key.json
unset NEW_MILLWORK_API_KEY
```

**Expected result:** the old key is `revoked`. A request using it returns `401`.

## If it fails

| What happened                          | What to do                                                                                   |
| -------------------------------------- | -------------------------------------------------------------------------------------------- |
| The new key was not saved              | Create another key. Millwork cannot recover it.                                              |
| The application fails with the new key | Restore the old key in the application and check the bearer header before revoking anything. |
| The old key may be exposed             | Move the application to the new key, then revoke the old key as soon as possible.            |
