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

# Create User

Mint a per-user API key scoped to a single index. Requires RBAC enabled on the service (`CYBORGDB_SERVICE_ROOT_KEY` set) and the request must be authenticated with the root key.

<Note>See [Multi-Tenancy & RBAC](../../guides/advanced/multi-tenancy) for the full operator playbook.</Note>

## Authentication

Required — root API key in the `X-API-Key` header:

```http theme={null}
X-API-Key: cyborg_your_root_api_key_here
```

The core license key (`CYBORGDB_API_KEY`) is **not** a service credential; sending it as `X-API-Key` returns 401 ("Invalid API Key"). A 403 is returned only for a valid non-root credential (a `cdbk_` user token).

## Path Parameters

| Parameter | Type | Description |
| - | - | - |
| `index_name` | `string` | Name of the index the user will be scoped to. |

## Request Body

```json theme={null}
{
  "permissions": ["read", "write"],
  "index_key": "64_character_hex_string_representing_32_bytes"
}
```

<Note>For `POST`, the index key rides in the JSON body as `index_key` (alongside `permissions`). The sibling `GET /v1/indexes/{index_name}/users` and `DELETE /v1/indexes/{index_name}/users/{user_id}` endpoints have no request body, so they take the same key via the `X-Index-Key` header instead.</Note>

<Expandable title="parameters">
  <ParamField body="permissions" type="array[string]" required="true">
    Non-empty subset of `["read", "write"]`. The grant is enforced cryptographically by the service — the wrapped data-encryption keys that exist for a user *are* their permission set.
  </ParamField>

  <ParamField body="index_key" type="string">
    32-byte index KEK as a hex string. Required for SDK-supplied indexes (`provider: none`) so the service can unwrap the root DEK and re-wrap it under the new user. Omit for KMS-backed indexes — the service resolves the key from the index's stored key envelope.

    Note: the index KEK is needed only at mint time. The minted user then authenticates with their `cdbk_` token alone — the service opens the index via the user's own wrapped DEK, on KMS-backed and SDK-supplied indexes alike. One caveat for SDK-supplied indexes: auto-training after a user's upsert is skipped (the service holds no index KEK to train with) — see [SDK-supplied indexes](../../guides/advanced/multi-tenancy#sdk-supplied-indexes).
  </ParamField>
</Expandable>

## Response

```json theme={null}
{
  "user_id": "a1b2c3d4e5f6...",
  "api_key": "cdbk_..."
}
```

<Expandable title="response fields">
  <ResponseField name="user_id" type="string">
    Hex-encoded identifier for the new user.
  </ResponseField>

  <ResponseField name="api_key" type="string">
    The user's API key. Begins with `cdbk_`. **Returned exactly once and never stored** — capture it now, it cannot be recovered.
  </ResponseField>
</Expandable>

<Warning>
  The returned `api_key` is shown only in this response and is never persisted by the service. If you lose it, revoke the user (`DELETE`) and mint a new one.
</Warning>

## Exceptions

<AccordionGroup>
  <Accordion title="400 Bad Request">
    `permissions` is missing, empty, or contains values outside `{"read", "write"}`.
  </Accordion>

  <Accordion title="401 Unauthorized">
    Authentication failed (invalid root API key).
  </Accordion>

  <Accordion title="403 Forbidden">
    RBAC is not enabled (`CYBORGDB_SERVICE_ROOT_KEY` unset), or the caller is not using the root key.
  </Accordion>

  <Accordion title="404 Not Found">
    Index not found.
  </Accordion>

  <Accordion title="500 Internal Server Error">
    Internal server error.
  </Accordion>
</AccordionGroup>

## Example Usage

```bash theme={null}
curl -X POST "http://localhost:8000/v1/indexes/documents/users" \
     -H "X-API-Key: cyborg_your_root_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{
       "permissions": ["read", "write"]
     }'
```

**Read-only user:**

```bash theme={null}
curl -X POST "http://localhost:8000/v1/indexes/documents/users" \
     -H "X-API-Key: cyborg_your_root_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{
       "permissions": ["read"]
     }'
```

**SDK-supplied index (KEK in body):**

```bash theme={null}
curl -X POST "http://localhost:8000/v1/indexes/documents/users" \
     -H "X-API-Key: cyborg_your_root_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{
       "permissions": ["read", "write"],
       "index_key": "your_64_character_hex_key_here"
     }'
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.