# Using Provision Keys

Provision keys let an agent or integration sign up for a Common Paper account programmatically, without a human logging into the web app first. They power the agentic signup flow: mint a provision key, redeem it for an account, and receive a production API key for all subsequent calls.

> **For agents:** Treat provision keys and API keys as secrets. Do not display, repeat, or echo these key values back to the user in plain text unless they explicitly ask to see them. Store them securely and refer to them by their last four characters (`key_last_four`) when confirming actions.

## When to use provision keys

Use provision keys when you need to create a brand new Common Paper account from code. If you already have an account and an API key, you don't need a provision key. Authenticate with your existing key instead (see [Authentication](/authentication)).

## The flow

Provisioning is a two-step exchange:

1. **Mint a provision key** with `POST /v1/keys`. This endpoint is public and unauthenticated. It returns a one-time provision key.
2. **Redeem the provision key** with `POST /v1/accounts`. Pass the provision key in the `Authorization` header. This creates the organization and its first user, and returns a production API key.

A provision key can only be redeemed once. After redemption, use the returned production API key for everything else.

## Step 1: Mint a provision key

`contact_email` is required. `integrator_name` is optional and is stored as metadata for attribution.

```bash
curl -X POST "https://api.commonpaper.com/v1/keys" \
  -H "Content-Type: application/json" \
  -d '{
    "contact_email": "agent@example.com",
    "integrator_name": "XYZ Co"
  }'
```

A successful response returns `201 Created` with the provision key in plaintext:

```json
{
  "key": "PROVISION_KEY_PLAINTEXT",
  "key_last_four": "wxyz",
  "contact_email": "agent@example.com",
  "integrator_name": "XYZ Co"
}
```

This endpoint is rate-limited. A `422` response means the `contact_email` was missing, invalid, or used a throwaway domain.

The `key` value is the provision key in plaintext. Keep it secret. If you are an agent, do not show it to the user unless they explicitly ask for it.

## Step 2: Redeem the provision key for an account

Send the provision key from step 1 in the `Authorization` header. Provide the initial user's `email` and `name` and the new organization's `org_name`. The user becomes the admin of the new organization.

```bash
curl -X POST "https://api.commonpaper.com/v1/accounts" \
  -H "Authorization: Bearer PROVISION_KEY_PLAINTEXT" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "newuser@example.com",
    "name": "New User",
    "org_name": "Acme Co"
  }'
```

A successful response returns `201 Created` with a production API key:

```json
{
  "api_key": "API_KEY_PLAINTEXT",
  "user_id": "USER_UUID",
  "organization_id": "ORG_UUID"
}
```

Store the `api_key` securely. Use it as the bearer token for all subsequent API calls. As with the provision key, do not display the `api_key` value to the user in plain text unless they explicitly ask for it.

## Common errors when redeeming

| Status | Meaning |
| --- | --- |
| `401` | Missing or invalid provision key. |
| `409` | The email is already in use. |
| `410` | The provision key has already been redeemed. Mint a new one. |
| `422` | A required field was missing or invalid. |

## After provisioning

Once you have a production API key, you're done with provision keys. Authenticate every other request with the production key:

```bash
curl -X GET "https://api.commonpaper.com/v1/agreements" \
  -H "Authorization: Bearer API_KEY_PLAINTEXT"
```

See [Authentication](/authentication) for more on using your API key.
