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

# Users API Reference

## Overview

The Users API offers tools for managing user accounts on your Publica.la platform. It includes functionality for creating, updating, deactivating, and reactivating users, as well as managing user sessions and permissions.

:::info
Make sure you generated the **api_token** on your store. More info in the [API Authentication guide](overview.md)
:::

## Endpoint Reference

| Endpoint                                                            | Method | Description              |
| ------------------------------------------------------------------- | ------ | ------------------------ |
| [/integration-api/v1/dashboard/users](#create)                      | POST   | Create a new user        |
| [/integration-api/v1/dashboard/users](#retrieve)                    | GET    | List or search for users |
| [/integration-api/v1/dashboard/users/(id)](#update)                 | PUT    | Update an existing user  |
| [/integration-api/v1/dashboard/users/(id)](#deactivate)             | DELETE | Deactivate a user        |
| [/integration-api/v1/dashboard/users/(id)/re-activate](#reactivate) | PUT    | Reactivate a user        |
| [/integration-api/v1/users/(id)/force-logout](#force-logout)        | POST   | Force user logout        |

## Create a User {#create}

Create a new user account on the platform.

**Endpoint:** `POST /integration-api/v1/dashboard/users`

### Request Fields

| Field                    | Type    | Description                                              | Required |
| ------------------------ | ------- | -------------------------------------------------------- | -------- |
| email                    | string  | User's email address                                     | Yes      |
| external_id              | string  | Your unique identifier for this user (max 64 characters) | Yes      |
| new_password             | string  | User's password (min 8, max 255 characters)              | Yes      |
| sessions_limit           | integer | Limit of simultaneous sessions (min 1, max 999999)       | No       |
| assign_new_plan          | integer | Plan ID to assign to the user                            | No       |
| new_plan_custom_valid_to | string  | Plan expiration date (YYYY-MM-DD format)                 | No       |
| admin                    | boolean | Whether user has admin privileges                        | No       |
| plan_admin               | boolean | Whether user has plan admin privileges                   | No       |
| only_sees_readable       | boolean | Whether user only sees readable content                  | No       |

#### Example Request

```json
{
  "email": "jhondoe@mail.com",
  "external_id": "user-id-in-your-platform",
  "new_password": "Abcd1234",
  "sessions_limit": null,
  "assign_new_plan": null,
  "new_plan_custom_valid_to": "",
  "admin": false,
  "plan_admin": false,
  "only_sees_readable": true
}
```

### Response Fields

| Field                   | Description                             | Type    |
| ----------------------- | --------------------------------------- | ------- |
| CODE                    | Response status code                    | string  |
| data.id                 | User ID                                 | integer |
| data.email              | User email                              | string  |
| data.uuid               | Unique user identifier                  | string  |
| data.picture            | User profile picture URL                | string  |
| data.admin              | Admin status                            | boolean |
| data.plan_admin         | Plan admin status                       | boolean |
| data.only_sees_readable | Whether user only sees readable content | boolean |
| data.sessions_limit     | User session limit                      | integer |
| data.created_at         | Creation timestamp                      | object  |
| data.updated_at         | Last update timestamp                   | object  |
| data.deleted_at         | Deletion timestamp (if applicable)      | object  |

#### Example Response

```json
{
  "CODE": "success",
  "data": {
    "id": 923242,
    "email": "jhondoe@mail.com",
    "uuid": "af5af4f9-9b8d-4d79-b162-0cec4279cae5",
    "picture": "https://www.gravatar.com/avatar/5c472faa5105266a3d41aee277eb9d0c?s=160&d=mm&r=g",
    "admin": false,
    "plan_admin": false,
    "only_sees_readable": false,
    "sessions_limit": null,
    "created_at": {
      "timestamp": 1620931649,
      "date": "2021-05-13 18:47:29",
      "timezone": "UTC"
    },
    "updated_at": {
      "timestamp": 1621256387,
      "date": "2021-05-17 12:59:47",
      "timezone": "UTC"
    },
    "deleted_at": null
  }
}
```

### Response Codes

| Code  | Description                            |
| :---- | :------------------------------------- |
| `201` | User created successfully              |
| `422` | Validation error (details in response) |
| `401` | Unauthorized (invalid API token)       |

## Retrieve Users {#retrieve}

List or search for users.

**Endpoint:** `GET /integration-api/v1/dashboard/users`

### Query Parameters

| Parameter         | Description                 | Example                                                      |
| ----------------- | --------------------------- | ------------------------------------------------------------ |
| query=email       | Filter by user email        | `/integration-api/v1/dashboard/users/?query=user@publica.la` |
| query=deactivated | Show only deactivated users | `/integration-api/v1/dashboard/users/?query=deactivated`     |
| query=admins      | Show only admin users       | `/integration-api/v1/dashboard/users/?query=admins`          |

### Response

The response includes detailed user information and pagination metadata when listing multiple users.

#### Example Response (List)

```json
{
  "CODE": "success",
  "data": {
    "paginator": {
      "current_page": 1,
      "data": [
        {
          "id": 923242,
          "uuid": "af5af4f9-9b8d-4d79-b162-0cec4279cae5",
          "admin": false,
          "plan_admin": false,
          "email": "jhondoe@mail.com",
          "sessions_limit": 1,
          "only_sees_readable": 1,
          "picture": "https://www.gravatar.com/avatar/98789c9d5825d6f6c6615313ffcaf1ac?s=160&d=mm&r=g",
          "created_at": "2021-05-18T13:28:53.000000Z",
          "updated_at": "2021-05-18T13:28:53.000000Z",
          "deleted_at": null,
          "purchased_issues_with_cancelled_count": 0,
          "user_plans_count": 0,
          "can_be_edited": true,
          "created_at_date_string": "2021-05-18",
          "impersonate": "https://{store_final_domain}/impersonate/take/53114",
          "sessions": null,
          "ip_ranges": [],
          "referrers": [],
          "purchased_issues_with_cancelled": [],
          "user_plans": []
        }
        // ... more users ...
      ]
      // ... pagination fields ...
    }
  }
}
```

### Response Codes

| Code  | Description                      |
| :---- | :------------------------------- |
| `200` | Success                          |
| `404` | User not found                   |
| `401` | Unauthorized (invalid API token) |

## Update a User {#update}

Update an existing user's information.

**Endpoint:** `PUT /integration-api/v1/dashboard/users/(id)`

:::warning External ID Restriction
The `external_id` field **cannot be modified** through the Integration API once a user is created. This restriction prevents breaking integrations with external systems. The `external_id` must be provided in update requests but must match the current value. To modify the `external_id`, use the Dashboard web interface.
:::

### Request Fields

| Field                    | Type    | Description                                                    | Required |
| ------------------------ | ------- | -------------------------------------------------------------- | -------- |
| email                    | string  | User's email address                                           | Yes      |
| external_id              | string  | Must match the current external_id (cannot be changed via API) | Yes      |
| new_password             | string  | User's new password (min 8, max 255 characters)                | No       |
| sessions_limit           | integer | Limit of simultaneous sessions (min 1, max 999999)             | No       |
| assign_new_plan          | integer | Plan ID to assign to the user                                  | No       |
| new_plan_custom_valid_to | string  | Plan expiration date (YYYY-MM-DD format)                       | No       |
| admin                    | boolean | Whether user has admin privileges                              | No       |
| plan_admin               | boolean | Whether user has plan admin privileges                         | No       |
| only_sees_readable       | boolean | Whether user only sees readable content                        | Yes      |
| user_plan_name           | string  | Name for the user's plan                                       | No       |

#### Example Request

```json
{
  "email": "updated@mail.com",
  "external_id": "existing-external-id",
  "sessions_limit": 3,
  "admin": false,
  "plan_admin": false,
  "only_sees_readable": true
}
```

### Response Codes

| Code  | Description                            |
| :---- | :------------------------------------- |
| `200` | User updated successfully              |
| `422` | Validation error (details in response) |
| `401` | Unauthorized (invalid API token)       |

### Common Validation Errors

| Error Field      | Message                                     | Cause                                    |
| ---------------- | ------------------------------------------- | ---------------------------------------- |
| `external_id`    | "The external id field is prohibited"       | Attempting to modify external_id via API |
| `email`          | "The email has already been taken"          | Email already exists for another user    |
| `sessions_limit` | "The sessions limit must be at most 999999" | Sessions limit exceeds maximum           |

## Deactivate a User {#deactivate}

Deactivate a user, preventing them from logging in.

**Endpoint:** `DELETE /integration-api/v1/dashboard/users/(id)`

:::important
A deactivated user cannot log in through any means until reactivated. When a user is deactivated, all their active manual orders are automatically cancelled.
:::

### Request Parameters

| Parameter | Type    | Description                                                    | Required |
| --------- | ------- | -------------------------------------------------------------- | -------- |
| anonymize | boolean | Whether to anonymize user data after deactivation (true/false) | No       |

### User Anonymization

When the `anonymize` parameter is set to `true`, the user's personal data will be permanently anonymized after deactivation. This process includes:

#### Data Changes During Anonymization

- **Email**: Changed to a generic anonymized format (`user-{id}@anonymized.publicala`)
- **Name**: Completely removed (set to null)
- **External ID**: Removed (set to null) to break external system references
- **Anonymized Flag**: Set to `true` to track the anonymization status
- **Subscriptions**: All active user subscriptions are automatically cancelled
- **Orders**: All active manual orders are cancelled with reason "deactivate_user"

#### Important Considerations

- **Irreversible Process**: Anonymization cannot be undone
- **External System Impact**: The `external_id` is removed, which may break references in your external systems
- **Subscription Cancellation**: All user subscriptions (recurring and prepaid) are cancelled automatically
- **No Restoration**: Anonymized users cannot be reactivated through any means

**Basic Deactivation:**

```
DELETE /integration-api/v1/dashboard/users/923242
```

**Deactivation with Anonymization:**

```
DELETE /integration-api/v1/dashboard/users/923242?anonymize=1
```

### Response

```json
{
  "CODE": "success",
  "data": []
}
```

### Response Codes

| Code  | Description                                    |
| :---- | :--------------------------------------------- |
| `200` | User deactivated successfully                  |
| `404` | User not found                                 |
| `422` | Validation error (invalid anonymize parameter) |
| `401` | Unauthorized (invalid API token)               |

## Reactivate a User {#reactivate}

Reactivate a previously deactivated user.

**Endpoint:** `PUT /integration-api/v1/dashboard/users/(id)/re-activate`

:::warning Anonymized Users
Users who have been anonymized cannot be reactivated. The reactivation endpoint will return a 403 error if attempted on an anonymized user.
:::

### Example Request

- `PUT /integration-api/v1/dashboard/users/923242/re-activate`

### Response

```json
{
  "CODE": "success",
  "data": 1
}
```

### Response Codes

| Code  | Description                      |
| :---- | :------------------------------- |
| `200` | User reactivated successfully    |
| `403` | Cannot restore anonymized users  |
| `404` | User not found                   |
| `401` | Unauthorized (invalid API token) |

## Force User Logout {#force-logout}

Force a user to log out of all active sessions.

**Endpoint:** `POST /integration-api/v1/users/(id)/force-logout`

:::important
After logging out, the user will be redirected to the initial URL on their next interaction with the system.
:::

### Example Request

- `POST /integration-api/v1/users/923242/force-logout`

### Response Codes

| Code  | Description                      |
| :---- | :------------------------------- |
| `200` | User logged out successfully     |
| `404` | User not found                   |
| `401` | Unauthorized (invalid API token) |

## API Limitations and Best Practices

### Resetting a User Account

To **reset** a user while keeping the same email address (such as when assigning a new **`external_id`**), follow these steps:

1. **Deactivate the existing user** using the `anonymize=1` parameter.  
   This will anonymize the account and retain only non-identifiable historical data.
2. **Create a new user** with the same email address.  
   The new user starts with a clean profile using the provided `external_id`.

**Important:** The new account will **not inherit** any previous orders or purchases from the anonymized user.

### External ID Management

- **Immutable via API**: The `external_id` field cannot be modified through the Integration API once a user is created
- **Dashboard Only**: Changes to `external_id` must be made through the Dashboard web interface
- **Consistency Required**: When updating users, always provide the current `external_id` value
- **External References**: This restriction prevents breaking integrations with external systems
- **Business Logic**: The restriction ensures data integrity and prevents orphaned references in third-party systems

### User Deactivation Strategies

- **Standard Deactivation**: User account is disabled but all data remains intact for potential reactivation
- **Deactivation with Anonymization**: User data is permanently anonymized while maintaining system integrity
- **Order Cancellation**: All active manual orders are cancelled automatically during deactivation
- **Subscription Management**: Anonymization process cancels all user subscriptions (both recurring and prepaid)

### Data Validation Rules

- **Email Format**: Must be a valid email address and unique within the tenant
- **Password Requirements**: Minimum 8 characters, maximum 255 characters (required for creation)
- **Sessions Limit**: Must be between 1 and 999,999 if specified
- **External ID**: Maximum 64 characters, required for API operations, must be unique within tenant
- **Plan Assignment**: Plan must exist and be subscribable when specified

### Error Handling

Common validation errors you may encounter:

| Error                    | Cause                                    | Solution                                             |
| ------------------------ | ---------------------------------------- | ---------------------------------------------------- |
| `external_id.prohibited` | Attempting to modify external_id via API | Use Dashboard web interface or provide current value |
| `external_id.required`   | Missing external_id in API request       | Always provide external_id for API operations        |
| `anonymize.boolean`      | Invalid anonymize parameter              | Use `true` or `false` only                           |
| `email.unique`           | Email already exists                     | Use a different email address                        |
| `sessions_limit.max`     | Sessions limit exceeds 999,999           | Use a value within the allowed range                 |
| `new_password.required`  | Missing password during creation         | Provide a password for new users                     |
| `new_password.min`       | Password too short                       | Use at least 8 characters                            |

## Related API Documentation

- [Orders API](../rest-api-v3/orders/orders-v3-overview.md): Manage customer orders and permissions
- [Content API](../rest-api-v3/content/content-v3-overview.md): Manage content products
- [Plans API](plans.md): Create and manage subscription plans
