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

# Add New User

> Add a new user to your account by sending an invitation. The user will receive an email invitation to join your account with the specified role.

## Overview

Adds a new user to your account by sending them an invitation email. The user will receive an email invitation to join your account with the specified role and permissions.

## Purpose

### **User Invitation**

* **Invite Team Members**: Add colleagues to your account
* **Role Assignment**: Assign appropriate access levels
* **Email Invitations**: Send automated invitation emails
* **Access Control**: Control what users can do

### **Account Management**

* **Team Collaboration**: Enable team access to QR codes
* **Permission Management**: Assign specific roles and permissions
* **User Onboarding**: Streamline user addition process
* **Access Auditing**: Track who has access to what

## Request Body (Form Data)

| Field          | Type   | Required | Description                                       | Example                |
| -------------- | ------ | -------- | ------------------------------------------------- | ---------------------- |
| `name`         | string | Yes      | Name of the shared user                           | `"Jon Doe"`            |
| `email`        | string | Yes      | Email address of the shared user                  | `"jon.doe@scanova.io"` |
| `access_level` | string | Yes      | Access level ID (Manager: 1, Admin: 2, Viewer: 3) | `"1"`                  |

## Access Level Options

### **Default Roles**

* **Manager (ID: 1)**: Can create, edit, and manage QR codes
* **Admin (ID: 2)**: Full access including user management
* **Viewer (ID: 3)**: Read-only access to QR codes and analytics

### **Custom Roles**

* **Custom IDs**: Use custom role IDs created in your account
* **Specific Permissions**: Custom roles with tailored permissions
* **Flexible Access**: Create roles for specific use cases

## Examples

### **Add User with Manager Role**

```bash theme={null}
curl -X POST "https://management.scanova.io/multi-users/" \
  -H "Authorization: YOUR_API_KEY" \
  -F "name=John Manager" \
  -F "email=john.manager@company.com" \
  -F "access_level=1"
```

### **Add User with Admin Role**

```bash theme={null}
curl -X POST "https://management.scanova.io/multi-users/" \
  -H "Authorization: YOUR_API_KEY" \
  -F "name=Jane Admin" \
  -F "email=jane.admin@company.com" \
  -F "access_level=2"
```

### **Add User with Viewer Role**

```bash theme={null}
curl -X POST "https://management.scanova.io/multi-users/" \
  -H "Authorization: YOUR_API_KEY" \
  -F "name=Bob Viewer" \
  -F "email=bob.viewer@company.com" \
  -F "access_level=3"
```

### **Add User with Custom Role**

```bash theme={null}
curl -X POST "https://management.scanova.io/multi-users/" \
  -H "Authorization: YOUR_API_KEY" \
  -F "name=Custom User" \
  -F "email=custom.user@company.com" \
  -F "access_level=135"
```

## Response

### **Success Response (201 Created)**

```json theme={null}
{
  "id": 479,
  "shared_user": {
    "id": 1452,
    "first_name": "Jon Doe",
    "last_name": "",
    "full_name": "Jon Doe",
    "email": "jon.doe@scanova.io",
    "is_shared": true,
    "date_joined": "2023-09-11T16:28:22.113793+05:30",
    "is_social_signup": false,
    "is_sso_login": false,
    "has_usable_password": true,
    "language": "en",
    "last_login": null,
    "first_login": false,
    "enforce_mfa": false,
    "mfa_enabled": false,
    "mfa_status": "Disabled"
  },
  "access_level": {
    "id": 1,
    "name": "Manager",
    "permissions": [
      {
        "id": 22,
        "code": "QR_CODE_CAN_ADD",
        "name": "Can Add QR Code",
        "description": "Can add QR Code",
        "is_boolean": true
      },
      {
        "id": 23,
        "code": "QR_CODE_CAN_VIEW",
        "name": "Can view QR Code",
        "description": "Can view QR Code",
        "is_boolean": true
      },
      {
        "id": 24,
        "code": "QR_CODE_CAN_EDIT",
        "name": "Can edit QR Code",
        "description": "Can edit QR Code",
        "is_boolean": true
      },
      {
        "id": 26,
        "code": "QR_CODE_CAN_DOWNLOAD",
        "name": "Can download QR code",
        "description": "Can download QR Code",
        "is_boolean": true
      },
      {
        "id": 1,
        "code": "ANALYTICS_CAN_VIEW",
        "name": "Analytics Can View",
        "description": "Can view analytics",
        "is_boolean": true
      }
    ],
    "is_custom": false
  },
  "invitation_sent_on": "2023-09-11T16:28:22.227002+05:30",
  "invitation_accepted_on": null,
  "is_invitation_sent": true,
  "is_invitation_accepted": false,
  "created": "2023-09-11T16:28:22.223671+05:30",
  "modified": "2023-09-11T16:28:22.227109+05:30",
  "tags": []
}
```

## Invitation Process

### **Email Invitation**

1. **Invitation Sent**: User receives email invitation
2. **Account Creation**: User creates account or logs in
3. **Invitation Acceptance**: User accepts invitation
4. **Access Granted**: User gains access to your account

### **Invitation Status**

* **`is_invitation_sent: true`**: Invitation email has been sent
* **`is_invitation_accepted: false`**: User hasn't accepted yet
* **`invitation_sent_on`**: Timestamp when invitation was sent
* **`invitation_accepted_on: null`**: Will be set when user accepts

## Integration Examples

### **JavaScript - Add User Form**

```javascript theme={null}
async function addUser(userData) {
  try {
    const formData = new FormData();
    formData.append('name', userData.name);
    formData.append('email', userData.email);
    formData.append('access_level', userData.accessLevel);
    
    const response = await fetch('https://management.scanova.io/multi-users/', {
      method: 'POST',
      headers: {
        'Authorization': 'YOUR_API_KEY'
      },
      body: formData
    });
    
    if (response.ok) {
      const newUser = await response.json();
      console.log('User added successfully:', newUser);
      
      // Show success message
      showMessage(`User ${newUser.shared_user.full_name} has been invited!`);
      
      // Refresh user list
      refreshUserList();
      
      return newUser;
    } else {
      const error = await response.json();
      throw new Error(error.detail || 'Failed to add user');
    }
  } catch (error) {
    console.error('Error adding user:', error);
    showMessage('Error adding user: ' + error.message, 'error');
    return null;
  }
}

// Usage
const userData = {
  name: 'John Manager',
  email: 'john.manager@company.com',
  accessLevel: '1'
};

addUser(userData);
```

### **Python - Bulk User Addition**

```python theme={null}
import requests

def add_user(name, email, access_level):
    url = "https://management.scanova.io/multi-users/"
    headers = {"Authorization": "YOUR_API_KEY"}
    
    data = {
        'name': name,
        'email': email,
        'access_level': str(access_level)
    }
    
    try:
        response = requests.post(url, headers=headers, data=data)
        response.raise_for_status()
        
        user = response.json()
        print(f"User {user['shared_user']['full_name']} added successfully!")
        print(f"Invitation sent to: {user['shared_user']['email']}")
        print(f"Role: {user['access_level']['name']}")
        
        return user
        
    except requests.exceptions.RequestException as e:
        print(f"Error adding user {name}: {e}")
        return None

def add_multiple_users(users):
    """Add multiple users from a list"""
    results = []
    
    for user in users:
        result = add_user(user['name'], user['email'], user['access_level'])
        results.append(result)
    
    return results

# Usage
users_to_add = [
    {'name': 'John Manager', 'email': 'john@company.com', 'access_level': 1},
    {'name': 'Jane Admin', 'email': 'jane@company.com', 'access_level': 2},
    {'name': 'Bob Viewer', 'email': 'bob@company.com', 'access_level': 3}
]

results = add_multiple_users(users_to_add)
```

### **PHP - User Invitation Form**

```php theme={null}
<?php
function addUser($name, $email, $accessLevel) {
    $url = "https://management.scanova.io/multi-users/";
    $headers = [
        "Authorization: YOUR_API_KEY"
    ];
    
    $data = [
        'name' => $name,
        'email' => $email,
        'access_level' => (string)$accessLevel
    ];
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($httpCode === 201) {
        $user = json_decode($response, true);
        echo "User {$user['shared_user']['full_name']} added successfully!<br>";
        echo "Invitation sent to: {$user['shared_user']['email']}<br>";
        echo "Role: {$user['access_level']['name']}<br>";
        return $user;
    } else {
        echo "Error adding user: " . $response;
        return null;
    }
}

// Handle form submission
if ($_POST['submit']) {
    $name = $_POST['name'];
    $email = $_POST['email'];
    $accessLevel = $_POST['access_level'];
    
    $result = addUser($name, $email, $accessLevel);
}

// HTML Form
?>
<form method="POST">
    <label>Name: <input type="text" name="name" required></label><br>
    <label>Email: <input type="email" name="email" required></label><br>
    <label>Role: 
        <select name="access_level" required>
            <option value="1">Manager</option>
            <option value="2">Admin</option>
            <option value="3">Viewer</option>
        </select>
    </label><br>
    <input type="submit" name="submit" value="Add User">
</form>
```

## Error Handling

### **Common Errors**

#### **Invalid Email Format**

```json theme={null}
{
  "email": ["Enter a valid email address."]
}
```

#### **Missing Required Fields**

```json theme={null}
{
  "name": ["This field is required."],
  "email": ["This field is required."],
  "access_level": ["This field is required."]
}
```

#### **Invalid Access Level**

```json theme={null}
{
  "access_level": ["Invalid access level ID."]
}
```

#### **User Already Exists**

```json theme={null}
{
  "email": ["User with this email already exists."]
}
```

## Best Practices

### **User Management**

* **Validate Email**: Ensure email addresses are valid
* **Choose Appropriate Roles**: Assign roles based on user needs
* **Monitor Invitations**: Track invitation acceptance
* **Regular Audits**: Review user access regularly

### **Security**

* **Principle of Least Privilege**: Give users minimum required access
* **Regular Reviews**: Periodically review user permissions
* **Remove Inactive Users**: Remove users who no longer need access
* **Monitor Activity**: Track user activity and access patterns

### **Communication**

* **Clear Instructions**: Provide clear instructions to invited users
* **Follow Up**: Follow up on pending invitations
* **Documentation**: Document user roles and permissions
* **Training**: Provide training on account features

<Note>
  When you add a user, they will receive an email invitation to join your account. The user must accept the invitation before they can access your account.
</Note>

<Warning>
  Make sure to assign appropriate roles to users. Admin users have full access to your account including the ability to add and remove other users.
</Warning>

<Info>
  You can add users with custom roles by using the custom role ID instead of the default role IDs (1, 2, 3). Use the Get User Roles endpoint to see available custom roles.
</Info>


## OpenAPI

````yaml POST /multi-users/
openapi: 3.1.0
info:
  title: Scanova Management API (v2)
  description: >-
    The complete Scanova Management API — every endpoint available at
    management.scanova.io (QR codes, folders, tags, leads, forms, analytics,
    plans, shared users & roles), plus the token-creation and usage-stats
    endpoints used to authenticate against it. Every path and request/response
    shape below was verified live against a real API key and the actual running
    backend (Phase 7, 2026-08-16) — not guessed from reading urls.py alone.
  version: 2.0.0
servers:
  - url: https://management.scanova.io
    description: Management API — QR/folder/tag/lead/form/analytics/plans endpoints
security:
  - apiKeyAuth: []
paths:
  /multi-users/:
    post:
      summary: Invite a shared user
      operationId: createManagedSharedUser
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  format: email
                name:
                  type: string
                  maxLength: 20
                access_level:
                  type: integer
                  description: Role ID from GET /multi-users/access-levels/.
                tags:
                  type: array
                  items:
                    type: integer
                enable_tag_permission:
                  type: boolean
                  default: false
                include_untagged:
                  type: boolean
                  default: true
              required:
                - email
                - name
                - access_level
            example:
              email: teammate@example.com
              name: Jordan Lee
              access_level: 5
      responses:
        '201':
          description: Invitation created — sends an invitation email to the shared user.
          content:
            application/json:
              example:
                id: 118
                shared_user:
                  id: 88213
                  first_name: Jordan
                  last_name: Lee
                  full_name: Jordan Lee
                  email: teammate@example.com
                  is_active: false
                  is_locked: false
                access_level:
                  id: 5
                  name: Manager
                  slug: manager
                  permissions: []
                  is_custom: false
                invitation_sent_on: null
                invitation_accepted_on: null
                is_invitation_sent: false
                is_invitation_accepted: false
                status: Invitation Sent
                is_active: false
                include_untagged: true
                enable_tag_permission: false
                tags: []
components:
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Send your Management API key as the raw value of the Authorization
        header — no "Bearer " or "Token " prefix, and no other characters.
        Example: `Authorization: 401f7ac837da42b97f613d789819ff93537bee6a`. A
        header containing more than one space-separated part is rejected
        outright. Requests also require the request's Host header to be the
        management API host (e.g. management.scanova.io) — the same key sent to
        the regular API host will not authenticate.

````