> For the complete documentation index, see [llms.txt](https://ghozylab.gitbook.io/plugins/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ghozylab.gitbook.io/plugins/details/luvre/developer/restapi.md).

# APIs

```
Click the button below to test in Postman:
```

[![Run in Postman](https://run.pstmn.io/button.svg)](https://god.gw.postman.com/run-collection/30505873-527be40b-f8d9-4ec8-b0d6-be848dd5ca0c?action=collection%2Ffork\&source=rip_markdown\&collection-url=entityId%3D30505873-527be40b-f8d9-4ec8-b0d6-be848dd5ca0c%26entityType%3Dcollection%26workspaceId%3Dc5dd2f9d-7fd9-4b9b-91e0-9fe3b8e1be7d)

### Authorization

To interact with the Luvre API, all requests must include a JWT access token for authentication and authorization. This ensures secure access control, allowing the system to verify user identity, roles, domain and permissions.

**How the Token Works**

The access token is generated using **JSON Web Token (JWT)** and includes the following payload:

```php
$payload = [ 
    'uid'    => $uid,        // User ID
    'uname'  => $uname,      // Username
    'uroles' => $uroles,     // User roles (e.g., admin, editor)
    'dom'    => $dom,        // Token domain (must match site domain)
    'iat'    => $iat,        // Issued at timestamp
    'exp'    => $exp,        // Expiration timestamp
];
```

**Key Features of the Token**

✅ **User Identification** – The token contains the **user ID** and **username** to authenticate the requester.\
✅ **Role-Based Access** – The **uroles** field defines user permissions, ensuring API access is restricted based on roles.\
✅ **Domain Validation** – The **dom** field ensures the token is only valid on the intended domain, preventing misuse.\
✅ **Expiration Control** – The **exp** field sets a time limit for token validity, improving security.

**Managing Access Tokens**

* Tokens must be sent in the **Authorization** header as a **Bearer token** in API requests:\
  `Authorization: Bearer YOUR_ACCESS_TOKEN`
* If the token is missing, expired, or invalid, the API will reject the request with an appropriate error response.
* Administrators can manage token expiration, role-based access, and domain restrictions easily.

This approach ensures a **secure and flexible authentication system**, making it easier to manage user access, roles, and permissions across the API. 🚀

<figure><img src="/files/g5TbUPH02qNskLVNggoO" alt=""><figcaption><p>Luvre Token Generator</p></figcaption></figure>

## Get All Folders

<mark style="color:blue;">`GET`</mark>`https://yoursite.com/wp-json/luvre/public/v1/folder/folders`

Retrieves a list of folders based on various filter parameters such as order, owner, and inclusion of attachment data.

**Headers**

| Name          | Type     | Value            |
| ------------- | -------- | ---------------- |
| Authorization | `string` | `Bearer <token>` |

**Parameters**

| Name             | Type      | Description                                           | Required |
| ---------------- | --------- | ----------------------------------------------------- | -------- |
| order            | `string`  | Sorting order: ASC or DESC                            | No       |
| orderby          | `string`  | Sorting field: ord, name, created                     | No       |
| owner-id         | `int`     | Get folders owned by a specific user (Admin-only)     | No       |
| all-folders      | `boolean` | If 1, retrieves all folders across users (Admin-only) | No       |
| attachments-data | `boolean` | If 1, includes attachment details                     | No       |

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "success": true,
    "data": {
        "folders": [{
            "id": 4,
            "name": "Products",
            "color": "#07C4B3",
            "parent": 0,
            "post_type": "attachment",
            "ord": 0,
            "created_by": 1,
            "created": "2025-03-25 15:37:18",
            "attachments_count": 1,
            "attachment_ids": [12249],
            "children": [{
                "id": 9,
                "name": "Polo",
                "color": "#03A9F4",
                "parent": 4,
                "post_type": "attachment",
                "ord": 0,
                "created_by": 1,
                "created": "2025-03-25 15:46:22",
                "attachments_count": 0,
                "attachment_ids": [],
                "children": []
            }]
        }, {
            "id": 1,
            "name": "My Posts",
            "color": "#2196F3",
            "parent": 0,
            "post_type": "post",
            "ord": 1,
            "created_by": 1,
            "created": "2025-03-04 18:11:44",
            "attachments_count": 1,
            "attachment_ids": [12337],
            "children": []
        }]
    }
}
```

{% endtab %}

{% tab title="401" %}

```json
{
  "errors": [
    {
      "code": "invalid_token",
      "message": "Invalid token",
      "status": 401
    },
    {
      "code": "token_expired",
      "message": "The token has expired",
      "status": 401
    },
    {
      "code": "invalid_user",
      "message": "Invalid user credentials",
      "status": 401
    },
    {
      "code": "user_mismatch",
      "message": "User ID mismatch",
      "status": 401
    }
  ]
}
```

{% endtab %}

{% tab title="403" %}

```json
{
  "errors": [
    {
      "code": "invalid_domain",
      "message": "The token domain does not match the site domain",
      "status": 403
    },
    {
      "code": "invalid_role",
      "message": "User does not have the required role(s)",
      "status": 403
    }
  ]
}
```

{% endtab %}
{% endtabs %}

## Get Folder by ID

<mark style="color:blue;">`GET`</mark>`https://yoursite.com/wp-json/luvre/public/v1/folder/get/:folder_id`

Fetches a specific folder by ID, with an option to include attachment data.

**Headers**

| Name          | Type     | Value            |
| ------------- | -------- | ---------------- |
| Authorization | `string` | `Bearer <token>` |

**Parameters**

| Name             | Type      | Description                       | Required |
| ---------------- | --------- | --------------------------------- | -------- |
| id               | `int`     | The folder ID to retrieve         | ✅ Yes    |
| attachments-data | `boolean` | If 1, includes attachment details | No       |

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "success": true,
    "data": {
        "folders": [{
            "id": 4,
            "name": "Parent",
            "color": "#07C4B3",
            "parent": 0,
            "post_type": "attachment",
            "ord": 0,
            "created_by": 1,
            "created": "2025-03-25 15:37:18",
            "attachments_count": 1,
            "attachment_ids": [12249],
            "children": []
        }]
    }
}
```

{% endtab %}

{% tab title="401" %}

```json
{
  "errors": [
    {
      "code": "invalid_token",
      "message": "Invalid token",
      "status": 401
    },
    {
      "code": "token_expired",
      "message": "The token has expired",
      "status": 401
    },
    {
      "code": "invalid_user",
      "message": "Invalid user credentials",
      "status": 401
    },
    {
      "code": "user_mismatch",
      "message": "User ID mismatch",
      "status": 401
    }
  ]
}
```

{% endtab %}

{% tab title="403" %}

```json
{
  "errors": [
    {
      "code": "invalid_domain",
      "message": "The token domain does not match the site domain",
      "status": 403
    },
    {
      "code": "invalid_role",
      "message": "User does not have the required role(s)",
      "status": 403
    }
  ]
}
```

{% endtab %}
{% endtabs %}

## Create a New Folder

<mark style="color:green;">`POST`</mark>`https://yoursite.com/wp-json/luvre/public/v1/folder/create`

Creates a new folder with a specified parent, name, and post type.

**Headers**

| Name          | Type     | Value            |
| ------------- | -------- | ---------------- |
| Authorization | `string` | `Bearer <token>` |

**Request Body**

| Name       | Type     | Description                                           | Required |
| ---------- | -------- | ----------------------------------------------------- | -------- |
| parent\_id | `int`    | ID of the parent folder. Set 0 to make as root folder | ✅ Yes    |
| name       | `string` | Name of the folder                                    | ✅ Yes    |
| post\_type | `string` | Post type (e.g., attachment)                          | ✅ Yes    |

**Example** Request **Body (json)**

```json
{
    "parent_id": 100,
    "name": "New Folder via Api",
    "post_type": "attachment"
}
```

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "success": true,
    "data": {
        "name": "New Folder via Api",
        "id": 107,
        "parent": 100
    }
}
```

{% endtab %}

{% tab title="400" %}

```json
{
  "errors": [
    {
      "code": "folder_name_exist",
      "message": "A folder with this name already exists. Please choose another one",
      "status": 400
    },
    {
      "code": "parent_not_exist",
      "message": "Parent folder not found",
      "status": 400
    }
  ]
}
```

{% endtab %}

{% tab title="401" %}

```json
{
  "errors": [
    {
      "code": "invalid_token",
      "message": "Invalid token",
      "status": 401
    },
    {
      "code": "token_expired",
      "message": "The token has expired",
      "status": 401
    },
    {
      "code": "invalid_user",
      "message": "Invalid user credentials",
      "status": 401
    },
    {
      "code": "user_mismatch",
      "message": "User ID mismatch",
      "status": 401
    }
  ]
}
```

{% endtab %}

{% tab title="403" %}

```json
{
  "errors": [
    {
      "code": "invalid_domain",
      "message": "The token domain does not match the site domain",
      "status": 403
    },
    {
      "code": "invalid_role",
      "message": "User does not have the required role(s)",
      "status": 403
    }
  ]
}
```

{% endtab %}
{% endtabs %}

## Assign Attachments to a Folder

<mark style="color:green;">`POST`</mark>`https://yoursite.com/wp-json/luvre/public/v1/attachment/add`&#x20;

Assigns attachments to a specific folder.

**Headers**

| Name          | Type     | Value            |
| ------------- | -------- | ---------------- |
| Authorization | `string` | `Bearer <token>` |

**Request Body**

| Name       | Type           | Description                         | Required |
| ---------- | -------------- | ----------------------------------- | -------- |
| folder\_id | `int`          | The folder ID to add attachments to | ✅ Yes    |
| ids        | `array or int` | Attachment ID(s)                    | ✅ Yes    |

**Example** Request **Body (json)**

***Single id***

```json
{
  "folder_id": 75,
  "ids": 12243
}
```

*Multiple ids*

```json
{
  "folder_id": 75,
  "ids": [12243, 12181, 11326, 11328]
}
```

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "success": true,
    "data": {
        "message": "insert_success",
        "folder_data": {
            "id": "75",
            "name": "New Folder",
            "color": "#03A9F4",
            "parent": "0",
            "post_type": "attachment",
            "ord": "1",
            "created_by": "1",
            "created": "2025-03-25 15:37:22",
            "attachments_count": "4",
            "attachment_ids": ["11326", "11328", "12181", "12243"]
        }
    }
}
```

{% endtab %}

{% tab title="400" %}

```json
{
  "errors": [
    {
      "code": "empty_ids",
      "message": "ids parameter cannot be empty",
      "status": 400
    },
    {
      "code": "folder_not_exist",
      "message": "The requested folder does not exist",
      "status": 400
    },
    {
      "code": "attachment_exists",
      "message": "Some attachment already exist in this folder",
      "status": 400
    }
  ]
}
```

{% endtab %}

{% tab title="401" %}

```json
{
  "errors": [
    {
      "code": "invalid_token",
      "message": "Invalid token",
      "status": 401
    },
    {
      "code": "token_expired",
      "message": "The token has expired",
      "status": 401
    },
    {
      "code": "invalid_user",
      "message": "Invalid user credentials",
      "status": 401
    },
    {
      "code": "user_mismatch",
      "message": "User ID mismatch",
      "status": 401
    }
  ]
}
```

{% endtab %}

{% tab title="403" %}

```json
{
  "errors": [
    {
      "code": "invalid_domain",
      "message": "The token domain does not match the site domain",
      "status": 403
    },
    {
      "code": "invalid_role",
      "message": "User does not have the required role(s)",
      "status": 403
    }
  ]
}
```

{% endtab %}
{% endtabs %}

### 🚫 Authentication Failed (403 Error) Even with Correct Token

If you're seeing an error like this when making a request to the REST API:

```json
{
  "code": "rest_forbidden",
  "message": "Authentication failed",
  "data": {
    "status": 403
  }
}
```

Even though your **Bearer Token** is correctly set in Postman (or any API client), this typically means that the token is not reaching WordPress due to how your server handles HTTP headers—especially the `Authorization` header.

#### 🛠️ Fix for Apache Servers

If you're using **Apache**, it's likely that the `Authorization` header is being stripped or not passed correctly to WordPress.

To fix this, you need to add the following line to your site’s `.htaccess` file:

```apacheconf
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
```

* Open your `.htaccess` file (usually located in your WordPress root directory).
* Add the line above just before the WordPress rules section.
* Save the file and try your API request again.
