# Create a user

> Source: https://docs.clonepartner.com/api-reference/users/create-user/

`POST /api/users`

Creates a new user account with a one-time invite token. Superadmin can create admins and viewers.
Admins can only create viewers. The invite token should be shared with the user so they can
set their own password and enroll TOTP via /invite/{token}.

**Operation ID:** `createUser`

## Authentication

### Option 1

- **BearerAuth** (`http bearer`)
  API key token. Create via POST /api/api-keys. Format: `envoy_<hex>`

### Option 2

- **CookieAuth** (`apiKey`)
  Session cookie set after login + TOTP verification

## Request body

The request body is required.

### `application/json`

- Type: `object`
- Properties:
  - `username` (`string`, `required`)
  - `role` (`string`)
    - Allowed values: `admin`, `viewer`
    - Default: `viewer`

## Success responses

### 201

User created with invite token

**Content type:** `application/json`

- Type: `UserSafe & object`
- All of:
  - Variant 1:
    - Reference: `UserSafe`
      - Type: `object`
      - Properties:
        - `id` (`integer`)
        - `username` (`string`)
        - `role` (`string`)
          - Allowed values: `superadmin`, `admin`, `viewer`
        - `totp_verified` (`integer`)
          - Allowed values: `0`, `1`
        - `invite_pending` (`boolean`)
        - `created_at` (`string`)
          - Format: `date-time`
        - `updated_at` (`string`)
          - Format: `date-time`
  - Variant 2:
    - Type: `object`
    - Properties:
      - `invite_token` (`string`) — One-time invite token (48h expiry)

## Error responses

### 400

Validation error

**Content type:** `application/json`

- Reference: `Error`
  - Type: `object`
  - Properties:
    - `error` (`string`)
      - Example: `NOT_FOUND`
    - `message` (`string`)
      - Example: `Resource not found`

Example:

```json
{
  "error": "VALIDATION_ERROR",
  "message": "Invalid input"
}
```

### 403

Insufficient permissions


## Examples

### cURL

```bash
curl --request POST \
  --url 'https://your-envoy.example.com/api/users' \
  --header 'Authorization: Bearer $API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "username": "string"
}'
```

### JavaScript (fetch)

```javascript
const response = await fetch('https://your-envoy.example.com/api/users', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "username": "string"
  }),
});

if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const data = response.status === 204 ? null : await response.json();
console.log(data);
```
