MENU

# Introduction

Base URL: `http://localhost:8000`

This documentation aims to provide all the information you need to work with our API.

As you scroll, you'll see code examples for working with the API in different programming languages in the dark area to the right (or as part of the content on mobile). You can switch the language used with the tabs at the top right (or from the nav menu at the top left on mobile).

# Authenticating requests

This API is not authenticated.

# Endpoints

## Update FCM Token.

This endpoint allows an authenticated user or client to update their FCM token for push notifications.

> Example request:

    curl --request PATCH \
        "https://dev-taskify.taskhub.company/api/user/fcm-token" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"fcm_token\": \"dXkJz7KYZ9o:APA91bGfLa_qwAeD...\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/user/fcm-token"
    );

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "fcm_token": "dXkJz7KYZ9o:APA91bGfLa_qwAeD..."
    };

    fetch(url, {
        method: "PATCH",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "FCM token updated successfully."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

PATCH `api/user/fcm-token`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`fcm_token` string

The new FCM token for push notifications. Example: `dXkJz7KYZ9o:APA91bGfLa_qwAeD...`

## GET api/leave-requests/get-calendar-data

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/leave-requests/get-calendar-data" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/leave-requests/get-calendar-data"
    );

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (404):

Show headers

    cache-control: no-cache, private
    content-type: application/json
    vary: Origin

    {
        "message": "The route api/leave-requests/get-calendar-data could not be found."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/leave-requests/get-calendar-data`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

## GET api/estimates-invoices/pdf/{id}

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/estimates-invoices/pdf/et" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/estimates-invoices/pdf/et"
    );

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (404):

Show headers

    cache-control: no-cache, private
    content-type: application/json
    vary: Origin

    {
        "message": "The route api/estimates-invoices/pdf/et could not be found."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/estimates-invoices/pdf/{id}`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` string

The ID of the pdf. Example: `et`

## Retrieve a specific lead stage.

requires authentication

This endpoint retrieves the details of a specific lead stage by its ID. The user must be authenticated and authorized to manage lead stages.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/lead-stages/get/5?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/lead-stages/get/5"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead stage retrieved successfully!",
        "data": {
            "id": 5,
            "name": "Qualified",
            "slug": "qualified",
            "color": "info",
            "order": 2,
            "workspace_id": 1,
            "created_at": "2025-05-10T12:30:00.000000Z",
            "updated_at": "2025-05-15T09:12:00.000000Z"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Lead stage not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while retrieving the lead stage."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/lead-stages/get/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the lead stage to retrieve. Must exist in the `lead_stages` table. Example: `5`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

## GET api/custom-fields/{id}/edit

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/custom-fields/42/edit" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/custom-fields/42/edit"
    );

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (404):

Show headers

    cache-control: no-cache, private
    content-type: application/json
    vary: Origin

    {
        "message": "The route api/custom-fields/42/edit could not be found."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/custom-fields/{id}/edit`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the custom field. Example: `42`

# User Authentication

## Register a new user.

This endpoint allows a new user to sign up by providing necessary details.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/users/signup" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"type\": \"member\",
        \"first_name\": \"John\",
        \"last_name\": \"Doe\",
        \"email\": \"john.doe@example.com\",
        \"password\": \"password123\",
        \"password_confirmation\": \"password123\",
        \"company\": \"Acme Inc.\",
        \"fcm_token\": \"cXJ1AqT6B...\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/users/signup"
    );

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "type": "member",
        "first_name": "John",
        "last_name": "Doe",
        "email": "john.doe@example.com",
        "password": "password123",
        "password_confirmation": "password123",
        "company": "Acme Inc.",
        "fcm_token": "cXJ1AqT6B..."
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Account created successfully.",
    "data": {
    "id": 225,
    "first_name": "Test",
    "last_name": "User",
    "role": "admin",
    "email": "test.user@example.com",
    "phone": null,
    "dob": null,
    "doj": null,
    "address": null,
    "city": null,
    "state": null,
    "country": null,
    "zip": null,
    "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg",
    "status": 0,
    "created_at": "13-08-2024 14:59:38",
    "updated_at": "13-08-2024 14:59:38"
    "assigned": {
    "projects": 0,
    "tasks": 0
    }
    }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "email": [
                "The email field is required.",
                "The email has already been taken."
            ],
            "password": [
                "The password must be at least 6 characters."
            ],
            "role": [
                "The role field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Account couldn't be created, please contact the admin for assistance."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/users/signup`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`type` string

The type of account ('member' for team member, 'client' for client). Example: `member`

`first_name` string

The first name of the user. Example: `John`

`last_name` string

The last name of the user. Example: `Doe`

`email` string

The email address of the user or client. Example: `john.doe@example.com`

`password` string

The password for the account. Example: `password123`

`password_confirmation` string

The confirmation of the password. Must match 'password'. Example: `password123`

`company` string optional

nullable The company name. Example: `Acme Inc.`

`fcm_token` string optional

nullable The optional FCM token for push notifications. Example: `cXJ1AqT6B...`

## Log in an existing user.

This endpoint allows a user to log in by providing their email and password. Upon successful authentication, a token is returned for accessing protected resources.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/users/login" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"email\": \"john.doe@example.com\",
        \"password\": \"password123\",
        \"fcm_token\": \"cXJ1AqT6B...\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/users/login"
    );

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "email": "john.doe@example.com",
        "password": "password123",
        "fcm_token": "cXJ1AqT6B..."
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Logged in successfully.",
        "token": "15|ANl9HwfqiiUxdOmNWba5qKhzfk3h1fyi8ZUoYbH8de8d3534",
        "data": {
            "user_id": 7,
            "workspace_id": 6,
            "my_locale": "en",
            "locale": "en"
        }
    }

> Example response (401):

    {
        "error": true,
        "message": "Unauthorized"
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "email": [
                "The email field is required."
            ],
            "password": [
                "The password field is required."
            ]
        }
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/users/login`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`email` string

The email of the user. Example: `john.doe@example.com`

`password` string

The password for the user. Example: `password123`

`fcm_token` string optional

nullable The optional FCM token for push notifications. Example: `cXJ1AqT6B...`

## Send Password Reset Link.

This endpoint allows a user or client to request a password reset link by providing their email and account type.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/password/reset-request" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"email\": \"john.doe@example.com\",
        \"account_type\": \"user\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/password/reset-request"
    );

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "email": "john.doe@example.com",
        "account_type": "user"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Password reset link emailed successfully."
    }

> Example response (404):

    {
        "error": true,
        "message": "Account not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "Password reset link couldn't be sent, please check email settings."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/password/reset-request`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`email` string

The email address of the user or client. Example: `john.doe@example.com`

`account_type` string

The type of account ('user' for normal users, 'client' for clients). Example: `user`

## Reset Password.

This endpoint allows a user or client to reset their password using a valid token.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/password/reset" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"token\": \"abc123\",
        \"email\": \"john.doe@example.com\",
        \"password\": \"newPassword123\",
        \"password_confirmation\": \"newPassword123\",
        \"account_type\": \"user\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/password/reset"
    );

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "token": "abc123",
        "email": "john.doe@example.com",
        "password": "newPassword123",
        "password_confirmation": "newPassword123",
        "account_type": "user"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Password has been reset successfully."
    }

> Example response (404):

    {
        "error": true,
        "message": "Account not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "Password reset failed. Please try again later."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/password/reset`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`token` string

The password reset token provided via the reset link. Example: `abc123`

`email` string

The email address of the user or client. Example: `john.doe@example.com`

`password` string

The new password for the account. Must be at least 6 characters and confirmed. Example: `newPassword123`

`password_confirmation` string

The confirmation of the new password. Must match 'password'. Example: `newPassword123`

`account_type` string

The type of account ('user' for normal users, 'client' for clients). Example: `user`

# Profile Management

## Retrieve the authenticated user's profile.

requires authentication

This endpoint returns the profile information of the currently authenticated user. The user must be authenticated to access their profile details.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/user" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/user"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Profile details retrieved successfully",
        "data": {
            "id": 7,
            "first_name": "Madhavan",
            "last_name": "Vaidya",
            "role": "admin",
            "email": "admin@gmail.com",
            "phone": "9099882203",
            "dob": "17-06-2024",
            "doj": "03-10-2022",
            "address": "Devonshire",
            "city": "Windsor",
            "state": "ON",
            "country": "Canada",
            "zip": "123654",
            "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png",
            "status": 1,
            "created_at": "03-01-2023 10:37:20",
            "updated_at": "13-08-2024 14:16:45",
            "assigned": {
                "projects": 11,
                "tasks": 9
            },
            "is_admin_or_leave_editor": true,
            "is_admin_or_has_all_data_access": true
        }
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/user`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

## Update the profile picture of a logged-in user or a specified user/client.

requires authentication

This endpoint allows the authenticated user to update their profile picture. If both `id` and `type` are provided, the profile picture for the specified user or client will be updated. If not, the profile picture of the logged-in user will be updated.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/users/photo" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: multipart/form-data" \
        --form "id=1"\
        --form "type=user"\
        --form "upload=@/tmp/phpaC3e0G"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/users/photo"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "multipart/form-data",
    };

    const body = new FormData();
    body.append('id', '1');
    body.append('type', 'user');
    body.append('upload', document.querySelector('input[name="upload"]').files[0]);

    fetch(url, {
        method: "POST",
        headers,
        body,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Profile picture updated successfully.",
        "data": {
            "id": 7,
            "first_name": "Madhavan",
            "last_name": "Vaidya",
            "role": "admin",
            "email": "admin@gmail.com",
            "phone": "9099882203",
            "dob": "17-06-2024",
            "doj": "03-10-2022",
            "address": "Devonshire",
            "city": "Windsor",
            "state": "ON",
            "country": "Canada",
            "zip": "123654",
            "photo": "https://test-taskify.infinitietech.com/storage/photos/atEj9NKCeAJhM5VqBN69mFKHntHbZkPUl2Sa22RA.webp",
            "status": 1,
            "created_at": "03-01-2023 10:37:20",
            "updated_at": "13-08-2024 18:58:34",
            "assigned": {
                "projects": 11,
                "tasks": 21
            }
        }
    }

> Example response (200):

    {
        "error": true,
        "message": "No profile picture selected!"
    }

> Example response (200):

    {
        "error": true,
        "message": "User not found",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "Profile picture couldn't be updated."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/users/photo`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `multipart/form-data`

#### Body Parameters

`id` integer

The ID of the user or client whose profile picture is being updated. Required if `type` is provided. Example: `1`

`type` string

The type of the entity whose profile picture is being updated. Must be either 'user' or 'client'. Example: `user`

`upload` file

The file of the new profile picture to be uploaded. Example: `/tmp/phpaC3e0G`

## Update the profile details of a logged-in user.

requires authentication

This endpoint allows the authenticated user to update their profile details such as name, email, address, and other relevant information.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/users/6/profile" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"first_name\": \"Madhavan\",
        \"last_name\": \"Vaidya\",
        \"email\": \"admin@gmail.com\",
        \"role\": 1,
        \"phone\": \"9099882203\",
        \"country_code\": \"+91\",
        \"country_iso_code\": \"in\",
        \"dob\": \"17-06-2024\",
        \"doj\": \"03-10-2022\",
        \"address\": \"Devonshire\",
        \"city\": \"Windsor\",
        \"state\": \"ON\",
        \"country\": \"Canada\",
        \"zip\": \"123654\",
        \"password\": \"12345678\",
        \"password_confirmation\": \"12345678\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/users/6/profile"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "first_name": "Madhavan",
        "last_name": "Vaidya",
        "email": "admin@gmail.com",
        "role": 1,
        "phone": "9099882203",
        "country_code": "+91",
        "country_iso_code": "in",
        "dob": "17-06-2024",
        "doj": "03-10-2022",
        "address": "Devonshire",
        "city": "Windsor",
        "state": "ON",
        "country": "Canada",
        "zip": "123654",
        "password": "12345678",
        "password_confirmation": "12345678"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Profile details updated successfully.",
        "data": {
            "id": 7,
            "first_name": "Madhavan",
            "last_name": "Vaidya",
            "role": "admin",
            "email": "admin@gmail.com",
            "phone": "9099882203",
            "dob": "17-06-2024",
            "doj": "03-10-2022",
            "address": "Devonshire",
            "city": "Windsor",
            "state": "ON",
            "country": "Canada",
            "zip": "123654",
            "photo": "https://test-taskify.infinitietech.com/storage/photos/atEj9NKCeAJhM5VqBN69mFKHntHbZkPUl2Sa22RA.webp",
            "status": 1,
            "created_at": "03-01-2023 10:37:20",
            "updated_at": "13-08-2024 18:58:34",
            "assigned": {
                "projects": 11,
                "tasks": 21
            }
        }
    }

> Example response (200):

    {
        "error": true,
        "message": "Validation error: The email has already been taken."
    }

> Example response (200):

    {
        "error": true,
        "message": "User not found",
        "data": []
    }

> Example response (500):

    {
      "error": true,
      "message": "Profile details couldn\'t be updated."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/users/{id}/profile`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the user whose profile is being updated. Example: `6`

#### Body Parameters

`first_name` string

The user's first name. Example: `Madhavan`

`last_name` string

The user's last name. Example: `Vaidya`

`email` string

The user's email address. Can only be edited if `is_admin_or_has_all_data_access` is true for the logged-in user. Example: `admin@gmail.com`

`role` integer optional

The ID of the role for the user. If the authenticated user is an admin, the provided role will be used. If the authenticated user is not an admin, the current role of the user will be used, regardless of the input. Example: `1`

`phone` string optional

The user's phone number. Example: `9099882203`

`country_code` string optional

The country code for the phone number. Example: `+91`

`country_iso_code` string optional

nullable The ISO code for the phone number. Example: `in`

`dob` date optional

The user's date of birth. Example: `17-06-2024`

`doj` date optional

The user's date of joining. Example: `03-10-2022`

`address` string optional

The user's address. Example: `Devonshire`

`city` string optional

The user's city. Example: `Windsor`

`state` string optional

The user's state. Example: `ON`

`country` string optional

The user's country. Example: `Canada`

`zip` string optional

The user's zip code. Example: `123654`

`password` string optional

The user's new password (if changing). Example: `12345678`

`password_confirmation` string optional

The password confirmation (if changing password). Example: `12345678`

## Delete account of a logged-in user.

requires authentication

This endpoint allows the authenticated user to delete their account.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/account/destroy" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/account/destroy"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
      "error": false,
      "message": "Account deleted successfully."
      "data": []
    }

> Example response (404):

    {
        "error": true,
        "message": "User not found",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "Account couldn't be deleted."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/account/destroy`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

# Dashboard Management

## List or search users with birthdays today or upcoming.

requires authentication

This endpoint retrieves a list of users with birthdays occurring today or within a specified range of days. The user must be authenticated to perform this action.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/upcoming-birthdays?search=John&order=DESC&upcoming_days=15&user_ids[]=123&user_ids[]=456&limit=10&offset=5" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/upcoming-birthdays"
    );

    const params = {
        "search": "John",
        "order": "DESC",
        "upcoming_days": "15",
        "user_ids[0]": "123",
        "user_ids[1]": "456",
        "limit": "10",
        "offset": "5",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Upcoming birthdays retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 1,
                "member": "John Doe",
                "photo": "http://example.com/storage/photos/john_doe.jpg",
                "birthday_count": 30,
                "days_left": 10,
                "dob": "Tue, 2024-08-08"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Upcoming birthdays not found.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/upcoming-birthdays`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### Query Parameters

`search` string optional

Optional. The search term to filter users by first name or last name or combination of first name and last name or User ID or date of birth. Example: `John`

`order` string optional

Optional. The sort order for the `dob` column. Acceptable values are `ASC` or `DESC`. Default is `ASC`. Example: `DESC`

`upcoming_days` integer optional

Optional. The number of days from today to consider for upcoming birthdays. Default is 30. Example: `15`

`user_ids` string[] optional

Optional. The specific user IDs to filter the results.

`limit` integer optional

Optional. The number of results to return per page. Default is 15. Example: `10`

`offset` integer optional

Optional. The number of results to skip before starting to collect the result set. Default is 0. Example: `5`

## List or search users with work anniversaries today or upcoming.

requires authentication

This endpoint retrieves a list of users with work anniversaries occurring today or within a specified range of days. The user must be authenticated to perform this action.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/upcoming-work-anniversaries?search=John&order=DESC&upcoming_days=15&user_ids[]=123&user_ids[]=456&limit=10&offset=5" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/upcoming-work-anniversaries"
    );

    const params = {
        "search": "John",
        "order": "DESC",
        "upcoming_days": "15",
        "user_ids[0]": "123",
        "user_ids[1]": "456",
        "limit": "10",
        "offset": "5",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Upcoming work anniversaries retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 1,
                "member": "John Doe",
                "photo": "http://example.com/storage/photos/john_doe.jpg",
                "anniversary_count": 5,
                "days_left": 10,
                "doj": "Tue, 2024-08-08"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Upcoming work anniversaries not found.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/upcoming-work-anniversaries`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### Query Parameters

`search` string optional

Optional. The search term to filter users by first name or last name or combination of first name and last name or User ID or date of joining. Example: `John`

`order` string optional

Optional. The sort order for the `doj` column. Acceptable values are `ASC` or `DESC`. Default is `ASC`. Example: `DESC`

`upcoming_days` integer optional

Optional. The number of days from today to consider for upcoming work anniversaries. Default is 30. Example: `15`

`user_ids` string[] optional

Optional. The specific user IDs to filter the results.

`limit` integer optional

Optional. The number of results to return per page. Default is 15. Example: `10`

`offset` integer optional

Optional. The number of results to skip before starting to collect the result set. Default is 0. Example: `5`

## List members currently on leave or scheduled to be on leave.

requires authentication

This endpoint retrieves a list of members who are currently on leave or scheduled to be on leave within a specified range of days. The user must be authenticated to perform this action.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/members-on-leave?search=John&sort=to_date&order=DESC&upcoming_days=15&user_ids[]=123&user_ids[]=456&limit=10&offset=5" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/members-on-leave"
    );

    const params = {
        "search": "John",
        "sort": "to_date",
        "order": "DESC",
        "upcoming_days": "15",
        "user_ids[0]": "123",
        "user_ids[1]": "456",
        "limit": "10",
        "offset": "5",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Members on leave retrieved successfully.",
        "total": 1,
        "data": [
            {
                "id": 1,
                "member": "John Doe",
                "photo": "http://example.com/storage/photos/john_doe.jpg",
                "from_date": "Mon, 2024-07-15",
                "to_date": "Fri, 2024-07-19",
                "type": "Full",
                "duration": "5 days",
                "days_left": 0
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Members on leave not found.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/members-on-leave`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### Query Parameters

`search` string optional

Optional. The search term to filter users by first name or last name or combination of first name and last name or User ID or date of joining. Example: `John`

`sort` string optional

Optional. The field to sort by. Acceptable values are `from_date` and `to_date`. Default is `from_date`. Example: `to_date`

`order` string optional

Optional. The sort order. Acceptable values are `ASC` or `DESC`. Default is `ASC`. Example: `DESC`

`upcoming_days` integer optional

Optional. The number of days from today to consider for upcoming leave. Default is 30. Example: `15`

`user_ids` string[] optional

Optional. The specific user IDs to filter the results.

`limit` integer optional

Optional. The number of results to return per page. Default is 15. Example: `10`

`offset` integer optional

Optional. The number of results to skip before starting to collect the result set. Default is 0. Example: `5`

## Get Statistics

requires authentication

This endpoint retrieves workspace-specific statistics related to projects, tasks, users, clients, todos, and meetings. The user must be authenticated and have the necessary permissions to manage (if applicable) each respective module.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/dashboard/statistics" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/dashboard/statistics"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Statistics retrieved successfully",
        "data": {
            "total_projects": 8,
            "total_tasks": 8,
            "total_users": 8,
            "total_clients": 8,
            "total_meetings": 8,
            "total_todos": 0,
            "completed_todos": 0,
            "pending_todos": 0,
            "status_wise_projects": [
                {
                    "id": 1,
                    "title": "In Progress",
                    "color": "primary",
                    "total_projects": 4
                },
                {
                    "id": 2,
                    "title": "Completed",
                    "color": "success",
                    "total_projects": 4
                }
            ],
            "status_wise_tasks": [
                {
                    "id": 1,
                    "title": "In Progress",
                    "color": "primary",
                    "total_tasks": 4
                },
                {
                    "id": 2,
                    "title": "Completed",
                    "color": "success",
                    "total_tasks": 4
                }
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while retrieving statistics: Internal server error message"
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/dashboard/statistics`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

# Project Management

## List or search projects.

requires authentication

This endpoint retrieves a list of projects based on various filters. The user must be authenticated to perform this action. The request allows filtering by status, user, client, priority, tag, date ranges, and other parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/projects/1?search=Project&sort=title&order=ASC&status_ids[]=2&status_ids[]=3&user_ids[]=1&user_ids[]=2&user_ids[]=3&client_ids[]=5&client_ids[]=6&priority_ids[]=1&priority_ids[]=2&tag_ids[]=1&tag_ids[]=2&project_start_date_from=2024-01-01&project_start_date_to=2024-12-31&project_end_date_from=2024-01-01&project_end_date_to=2024-12-31&is_favorites=1&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"user_ids\": [
            15
        ],
        \"client_ids\": [
            18
        ],
        \"priority_ids\": [
            7
        ],
        \"tag_ids\": [
            14
        ],
        \"status_ids\": [
            5
        ]
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/projects/1"
    );

    const params = {
        "search": "Project",
        "sort": "title",
        "order": "ASC",
        "status_ids[0]": "2",
        "status_ids[1]": "3",
        "user_ids[0]": "1",
        "user_ids[1]": "2",
        "user_ids[2]": "3",
        "client_ids[0]": "5",
        "client_ids[1]": "6",
        "priority_ids[0]": "1",
        "priority_ids[1]": "2",
        "tag_ids[0]": "1",
        "tag_ids[1]": "2",
        "project_start_date_from": "2024-01-01",
        "project_start_date_to": "2024-12-31",
        "project_end_date_from": "2024-01-01",
        "project_end_date_to": "2024-12-31",
        "is_favorites": "1",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "user_ids": [
            15
        ],
        "client_ids": [
            18
        ],
        "priority_ids": [
            7
        ],
        "tag_ids": [
            14
        ],
        "status_ids": [
            5
        ]
    };

    fetch(url, {
        method: "GET",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Projects retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 351,
                "title": "rwer",
                "status": "Rel test",
                "priority": "Default",
                "users": [
                    {
                        "id": 7,
                        "first_name": "Madhavan",
                        "last_name": "Vaidya",
                        "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png"
                    },
                    {
                        "id": 183,
                        "first_name": "Girish",
                        "last_name": "Thacker",
                        "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                    }
                ],
                "clients": [],
                "tags": [],
                "start_date": "14-06-2024",
                "end_date": "14-06-2024",
                "budget": "",
                "created_at": "14-06-2024 17:50:09",
                "updated_at": "17-06-2024 19:08:16"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Project not found",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Projects not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/projects/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer optional

optional The ID of the project to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter projects by title or id. Example: `Project`

`sort` string optional

optional The field to sort by. Defaults to "id". Sortable fields include: id, title, status, priority, start_date, end_date, budget, created_at, and updated_at. Example: `title`

`order` string optional

optional The sort order, either "ASC" or "DESC". Defaults to "DESC". Example: `ASC`

`status_ids` string[] optional

optional An array of status IDs to filter projects by.

`user_ids` string[] optional

optional An array of user IDs to filter projects by.

`client_ids` string[] optional

optional An array of client IDs to filter projects by.

`priority_ids` string[] optional

optional An array of priority IDs to filter projects by.

`tag_ids` string[] optional

optional An array of tag IDs to filter projects by.

`project_start_date_from` string optional

optional The start date range's start in YYYY-MM-DD format. Example: `2024-01-01`

`project_start_date_to` string optional

optional The start date range's end in YYYY-MM-DD format. Example: `2024-12-31`

`project_end_date_from` string optional

optional The end date range's start in YYYY-MM-DD format. Example: `2024-01-01`

`project_end_date_to` string optional

optional The end date range's end in YYYY-MM-DD format. Example: `2024-12-31`

`is_favorites` boolean optional `true` `false`

optional Filter projects marked as favorites. Example: `true`

`limit` integer optional

optional The number of projects per page for pagination. Example: `10`

`offset` integer optional

optional The offset for pagination, indicating the starting point of results. Example: `0`

#### Body Parameters

`user_ids` integer[] optional

The `id` of an existing record in the users table.

`client_ids` integer[] optional

The `id` of an existing record in the clients table.

`priority_ids` integer[] optional

The `id` of an existing record in the priorities table.

`tag_ids` integer[] optional

The `id` of an existing record in the tags table.

`status_ids` integer[] optional

The `id` of an existing record in the statuses table.

## Create a new project.

requires authentication

This endpoint creates a new project with the provided details. The user must be authenticated to perform this action. The request validates various fields, including title, status, priority, dates, and task accessibility.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/projects/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"New Website Launch\",
        \"status_id\": 1,
        \"priority_id\": 2,
        \"start_date\": \"2024-08-01\",
        \"end_date\": \"2024-08-31\",
        \"budget\": \"5000.00\",
        \"task_accessibility\": \"project_users\",
        \"description\": \"A project to launch a new company website.\",
        \"note\": \"Ensure all team members are informed.\",
        \"user_id\": \"[1, 2, 3]\",
        \"client_id\": \"[5, 6]\",
        \"tag_ids\": \"[10, 11]\",
        \"clientCanDiscuss\": \"on\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/projects/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "New Website Launch",
        "status_id": 1,
        "priority_id": 2,
        "start_date": "2024-08-01",
        "end_date": "2024-08-31",
        "budget": "5000.00",
        "task_accessibility": "project_users",
        "description": "A project to launch a new company website.",
        "note": "Ensure all team members are informed.",
        "user_id": "[1, 2, 3]",
        "client_id": "[5, 6]",
        "tag_ids": "[10, 11]",
        "clientCanDiscuss": "on"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Project created successfully.",
        "id": 438,
        "data": {
            "id": 438,
            "title": "Res Test",
            "status": "Default",
            "priority": "dsfdsf",
            "users": [
                {
                    "id": 7,
                    "first_name": "Madhavan",
                    "last_name": "Vaidya",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png"
                },
                {
                    "id": 185,
                    "first_name": "Admin",
                    "last_name": "Test",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                }
            ],
            "clients": [
                {
                    "id": 103,
                    "first_name": "Test",
                    "last_name": "Test",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                }
            ],
            "tags": [
                {
                    "id": 45,
                    "title": "Tag from update project"
                }
            ],
            "start_date": null,
            "end_date": null,
            "budget": "1000",
            "task_accessibility": "assigned_users",
            "description": null,
            "note": null,
            "favorite": 0,
            "created_at": "07-08-2024 14:38:51",
            "updated_at": "07-08-2024 14:38:51"
        }
    }

> Example response (200):

    {
        "error": true,
        "message": "You are not authorized to set this status."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "title": [
                "The title field is required."
            ],
            "status_id": [
                "The status_id field is required."
            ],
            "start_date": [
                "The start date must be before or equal to the end date."
            ],
            "budget": [
                "The budget format is invalid."
            ],
            "task_accessibility": [
                "The task accessibility must be either project_users or assigned_users."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the project."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/projects/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`title` string

The title of the project. Example: `New Website Launch`

`status_id` integer

The ID of the project's status. Example: `1`

`priority_id` integer optional

optional The ID of the project's priority. Example: `2`

`start_date` string|null optional

optional The start date of the project in the format specified in the general settings. Example: `2024-08-01`

`end_date` string|null optional

optional The end date of the project in the format specified in the general settings. Example: `2024-08-31`

`budget` string|null optional

optional Only digits, commas as thousand separators, and a single decimal point are allowed. digits can optionally be grouped in thousands with commas, where each group of digits must be exactly three digits long (e.g., 1,000 is correct; 10,0000 is not). Example: `5000.00`

`task_accessibility` string

Indicates who can access the task. Must be either 'project_users' or 'assigned_users'. Example: `project_users`

`description` string|null optional

optional A description of the project. Example: `A project to launch a new company website.`

`note` string|null optional

optional Additional notes for the project. Example: `Ensure all team members are informed.`

`user_id` array|null optional

optional Array of user IDs to be associated with the project. Example: `[1, 2, 3]`

`client_id` array|null optional

optional Array of client IDs to be associated with the project. Example: `[5, 6]`

`tag_ids` array|null optional

optional Array of tag IDs to be associated with the project. Example: `[10, 11]`

`clientCanDiscuss` string optional

optional Indicates if the client can participate in project discussions. Can only specify if `is_admin_or_has_all_data_access` is true for the logged-in user; otherwise, it will be considered 0 by default. The value should be 'on' to allow client participation. Example: `on`

## Update an existing project.

requires authentication

This endpoint updates an existing project with the provided details. The user must be authenticated to perform this action. The request validates various fields, including title, status, priority, dates, and task accessibility.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/projects/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 1,
        \"title\": \"Updated Project Title\",
        \"status_id\": 2,
        \"priority_id\": 3,
        \"budget\": \"5000.00\",
        \"task_accessibility\": \"assigned_users\",
        \"start_date\": \"2024-08-01\",
        \"end_date\": \"2024-08-31\",
        \"description\": \"Updated project description.\",
        \"note\": \"Updated note for the project.\",
        \"user_id\": \"[2, 3]\",
        \"client_id\": \"[5, 6]\",
        \"tag_ids\": \"[10, 11]\",
        \"clientCanDiscuss\": \"on\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/projects/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 1,
        "title": "Updated Project Title",
        "status_id": 2,
        "priority_id": 3,
        "budget": "5000.00",
        "task_accessibility": "assigned_users",
        "start_date": "2024-08-01",
        "end_date": "2024-08-31",
        "description": "Updated project description.",
        "note": "Updated note for the project.",
        "user_id": "[2, 3]",
        "client_id": "[5, 6]",
        "tag_ids": "[10, 11]",
        "clientCanDiscuss": "on"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Project updated successfully.",
        "id": 438,
        "data": {
            "id": 438,
            "title": "Res Test",
            "status": "Default",
            "priority": "dsfdsf",
            "users": [
                {
                    "id": 7,
                    "first_name": "Madhavan",
                    "last_name": "Vaidya",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png"
                },
                {
                    "id": 185,
                    "first_name": "Admin",
                    "last_name": "Test",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                }
            ],
            "clients": [
                {
                    "id": 103,
                    "first_name": "Test",
                    "last_name": "Test",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                }
            ],
            "tags": [
                {
                    "id": 45,
                    "title": "Tag from update project"
                }
            ],
            "start_date": null,
            "end_date": null,
            "budget": "1000",
            "task_accessibility": "assigned_users",
            "description": null,
            "note": null,
            "favorite": 0,
            "created_at": "07-08-2024 14:38:51",
            "updated_at": "07-08-2024 14:38:51"
        }
    }

> Example response (200):

    {
        "error": true,
        "message": "You are not authorized to set this status."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "id": [
                "The project ID is required.",
                "The project ID does not exist in our records."
            ],
            "status_id": [
                "The status field is required."
            ],
            "budget": [
                "The budget format is invalid."
            ],
            "task_accessibility": [
                "The task accessibility must be either project_users or assigned_users."
            ],
            "start_date": [
                "The start date must be before or equal to the end date."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the project."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/projects/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` integer

The ID of the project to update. Example: `1`

`title` string

The title of the project. Example: `Updated Project Title`

`status_id` integer

The ID of the project's status. Example: `2`

`priority_id` integer optional

optional The ID of the project's priority. Example: `3`

`budget` string|null optional

optional Only digits, commas as thousand separators, and a single decimal point are allowed. digits can optionally be grouped in thousands with commas, where each group of digits must be exactly three digits long (e.g., 1,000 is correct; 10,0000 is not). Example: `5000.00`

`task_accessibility` string

Indicates who can access the task. Must be either 'project_users' or 'assigned_users'. Example: `assigned_users`

`start_date` string|null optional

optional The start date of the project in the format specified in the general settings. Example: `2024-08-01`

`end_date` string|null optional

optional The end date of the project in the format specified in the general settings. Example: `2024-08-31`

`description` string|null optional

optional A description of the project. Example: `Updated project description.`

`note` string|null optional

optional Additional notes for the project. Example: `Updated note for the project.`

`user_id` array|null optional

optional Array of user IDs to be associated with the project. Example: `[2, 3]`

`client_id` array|null optional

optional Array of client IDs to be associated with the project. Example: `[5, 6]`

`tag_ids` array|null optional

optional Array of tag IDs to be associated with the project. Example: `[10, 11]`

`clientCanDiscuss` string optional

optional Indicates if the client can participate in project discussions. Can only specify if `is_admin_or_has_all_data_access` is true for the logged-in user; otherwise, it will be considered current value by default. The value should be 'on' to allow client participation. Example: `on`

## Update the favorite status of a project.

requires authentication

This endpoint updates whether a project is marked as a favorite or not. The user must be authenticated to perform this action.

> Example request:

    curl --request PATCH \
        "https://dev-taskify.taskhub.company/api/projects/4/favorite" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"is_favorite\": 18
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/projects/4/favorite"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "is_favorite": 18
    };

    fetch(url, {
        method: "PATCH",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Project favorite status updated successfully",
        "data": {
            "id": 438,
            "title": "Res Test",
            "status": "Default",
            "priority": "dsfdsf",
            "users": [
                {
                    "id": 7,
                    "first_name": "Madhavan",
                    "last_name": "Vaidya",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png"
                }
            ],
            "clients": [
                {
                    "id": 103,
                    "first_name": "Test",
                    "last_name": "Test",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                }
            ],
            "tags": [
                {
                    "id": 45,
                    "title": "Tag from update project"
                }
            ],
            "start_date": null,
            "end_date": null,
            "budget": "1000.00",
            "task_accessibility": "assigned_users",
            "description": null,
            "note": null,
            "favorite": 1,
            "created_at": "07-08-2024 14:38:51",
            "updated_at": "12-08-2024 13:36:10"
        }
    }

> Example response (200):

    {
        "error": true,
        "message": "Project not found",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "is_favorite": [
                "The is favorite field must be either 0 or 1."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the favorite status."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

PATCH `api/projects/{id}/favorite`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the project to update. Example: `4`

#### Body Parameters

`is_favorite` integer

Indicates whether the project is a favorite. Use 1 for true and 0 for false. Example: `18`

## Update the pinned status of a project.

requires authentication

This endpoint updates whether a project is marked as pinned or not. The user must be authenticated to perform this action.

> Example request:

    curl --request PATCH \
        "https://dev-taskify.taskhub.company/api/projects/1/pinned" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"is_pinned\": 3
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/projects/1/pinned"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "is_pinned": 3
    };

    fetch(url, {
        method: "PATCH",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Project pinned status updated successfully",
    "data": {
      "id": 438,
      "title": "Res Test"
      // Other project details will be included in the actual response
    }
    }

> Example response (200):

    {
        "error": true,
        "message": "Project not found",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "is_pinned": [
                "The is pinned field must be either 0 or 1."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the pinned status."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

PATCH `api/projects/{id}/pinned`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the project to update. Example: `1`

#### Body Parameters

`is_pinned` integer

Indicates whether the project is pinned. Use 1 for true and 0 for false. Example: `3`

## Update the status of a project.

requires authentication

This endpoint updates the status of a specified project. The user must be authenticated and have permission to set the new status. A notification will be sent to all users and clients associated with the project.

> Example request:

    curl --request PATCH \
        "https://dev-taskify.taskhub.company/api/projects/16/status" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"statusId\": 15,
        \"note\": \"laborum\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/projects/16/status"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "statusId": 15,
        "note": "laborum"
    };

    fetch(url, {
        method: "PATCH",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Status updated successfully.",
        "id": "438",
        "type": "project",
        "activity_message": "Madhavan Vaidya updated project status from Default to vbnvbnvbn",
        "data": {
            "id": 438,
            "title": "Res Test",
            "status": "vbnvbnvbn",
            "priority": "dsfdsf",
            "users": [
                {
                    "id": 7,
                    "first_name": "Madhavan",
                    "last_name": "Vaidya",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png"
                }
            ],
            "clients": [
                {
                    "id": 103,
                    "first_name": "Test",
                    "last_name": "Test",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                }
            ],
            "tags": [
                {
                    "id": 45,
                    "title": "Tag from update project"
                }
            ],
            "start_date": null,
            "end_date": null,
            "budget": "1000.00",
            "task_accessibility": "assigned_users",
            "description": null,
            "note": null,
            "favorite": 1,
            "created_at": "07-08-2024 14:38:51",
            "updated_at": "12-08-2024 13:49:33"
        }
    }

> Example response (200):

    {
        "error": true,
        "message": "You are not authorized to set this status."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "id": [
                "The selected id is invalid."
            ],
            "statusId": [
                "The selected status id is invalid."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Status couldn't be updated."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

PATCH `api/projects/{id}/status`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the project whose status is to be updated. Example: `16`

#### Body Parameters

`statusId` integer

The ID of the new status to set for the project. Example: `15`

`note` string optional

optional An optional note to attach to the project update. Example: `laborum`

## Update the priority of a project.

requires authentication

This endpoint updates the priority of a specified project. The user must be authenticated and have permission to set the new priority.

> Example request:

    curl --request PATCH \
        "https://dev-taskify.taskhub.company/api/projects/10/priority" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"priorityId\": 14
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/projects/10/priority"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "priorityId": 14
    };

    fetch(url, {
        method: "PATCH",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Priority updated successfully.",
        "id": "438",
        "type": "project",
        "activity_message": "Madhavan Vaidya updated project priority from Low to Medium",
        "data": {
            "id": 438,
            "title": "Res Test",
            "status": "Test From Pro",
            "priority": "Medium",
            "users": [
                {
                    "id": 7,
                    "first_name": "Madhavan",
                    "last_name": "Vaidya",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png"
                }
            ],
            "clients": [
                {
                    "id": 103,
                    "first_name": "Test",
                    "last_name": "Test",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                }
            ],
            "tags": [
                {
                    "id": 45,
                    "title": "Tag from update project"
                }
            ],
            "start_date": null,
            "end_date": null,
            "budget": "1000.00",
            "task_accessibility": "assigned_users",
            "description": null,
            "note": null,
            "favorite": 1,
            "created_at": "07-08-2024 14:38:51",
            "updated_at": "12-08-2024 13:58:55"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "id": [
                "The selected id is invalid."
            ],
            "priorityId": [
                "The selected priority id is invalid."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Priority couldn't be updated."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

PATCH `api/projects/{id}/priority`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the project whose priority is to be updated. Example: `10`

#### Body Parameters

`priorityId` integer

The ID of the new priority to set for the project. Example: `14`

## Remove the specified project.

requires authentication

This endpoint deletes a project based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/projects/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/projects/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Project deleted successfully.",
        "id": 1,
        "title": "Project Title",
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Project not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the project."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/projects/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the project to be deleted. Example: `1`

## Get project status timeline.

requires authentication

This endpoint retrieves the status change history of a project, sorted in descending order.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/projects/17/status-timelines" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/projects/17/status-timelines"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Status timeline retrieved successfully.",
        "status_timeline": [
            {
                "id": 1,
                "status": "In Progress",
                "previous_status": "Pending",
                "new_color": "#ffcc00",
                "old_color": "#cccccc",
                "changed_at": "2025-03-03"
            },
            {
                "id": 2,
                "status": "Completed",
                "previous_status": "In Progress",
                "new_color": "#00cc66",
                "old_color": "#ffcc00",
                "changed_at": "2025-03-05 16:00:00"
            }
        ]
    }

> Example response (404):

    {
        "error": true,
        "message": "Project not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "Could not retrieve status timeline."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/projects/{id}/status-timelines`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the project whose status timeline is to be retrieved. Example: `17`

## Get Mind Map Data of a specific project.

requires authentication

This endpoint retrieves mind map data of a specific project by its ID.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/projects/8/mind-map" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/projects/8/mind-map"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
      "error": false,
      "data":  {
          "id": "project_2",
          "topic": "hola",
    "link": "https://dev-taskify.taskhub.company/projects/information/2",
    "isroot": true,
    "level": 1,
    "children": [
    {
    "id": "tasks",
    "topic": "Tasks",
    "level": 2,
    "children": [
    {
    "id": "task_4",
    "topic": "Test",
    "link": "https://dev-taskify.taskhub.company/tasks/information/4",
    "children": [
    {
    "id": "task_users_4",
    "topic": "Users",
    "children": [
    {
    "id": "task_user_4_1",
    "topic": "Admin User",
    "link": "https://dev-taskify.taskhub.company/users/profile/1"
    }
    ]
    },
    {
    "id": "task_clients_4",
    "topic": "Clients",
    "children": []
    }
    ]
    },
    {
    "id": "task_5",
    "topic": "test",
    "link": "https://dev-taskify.taskhub.company/tasks/information/5",
    "children": [
    {
    "id": "task_users_5",
    "topic": "Users",
    "children": [
    {
    "id": "task_user_5_1",
    "topic": "Admin User",
    "link": "https://dev-taskify.taskhub.company/users/profile/1"
    }
    ]
    },
    {
    "id": "task_clients_5",
    "topic": "Clients",
    "children": []
    }
    ]
    },
    {
    "id": "task_6",
    "topic": "test 1",
    "link": "https://dev-taskify.taskhub.company/tasks/information/6",
    "children": [
    {
    "id": "task_users_6",
    "topic": "Users",
    "children": [
    {
    "id": "task_user_6_1",
    "topic": "Admin User",
    "link": "https://dev-taskify.taskhub.company/users/profile/1"
    }
    ]
    },
    {
    "id": "task_clients_6",
    "topic": "Clients",
    "children": []
    }
    ]
    }
    ]
    },
    {
    "id": "users",
    "topic": "Users",
    "children": [
    {
    "id": "user_1",
    "topic": "Admin User",
    "link": "https://dev-taskify.taskhub.company/users/profile/1"
    }
    ]
    },
    {
    "id": "clients",
    "topic": "Clients",
    "children": []
    },
    {
    "id": "milestones",
    "topic": "Milestones",
    "children": []
    },
    {
    "id": "media",
    "topic": "Media",
    "children": []
    }
    ]
    }

> Example response (404):

    {
        "error": true,
        "message": "Project not found."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/projects/{id}/mind-map`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the data to retrieve. Example: `8`

# Milestone Management

## Store a new milestone.

requires authentication

This endpoint creates a new milestone for a specified project. The user must be authenticated and have permission to create milestones.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/milestones/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"project_id\": 13,
        \"title\": \"commodi\",
        \"status\": \"quis\",
        \"start_date\": \"et\",
        \"end_date\": \"unde\",
        \"cost\": \"placeat\",
        \"description\": \"Accusamus doloribus eum accusamus aliquid.\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/milestones/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "project_id": 13,
        "title": "commodi",
        "status": "quis",
        "start_date": "et",
        "end_date": "unde",
        "cost": "placeat",
        "description": "Accusamus doloribus eum accusamus aliquid."
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Milestone created successfully.",
        "id": 12,
        "type": "milestone",
        "parent_type": "project",
        "parent_id": 438
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "project_id": [
                "The selected project_id is invalid."
            ],
            "title": [
                "The title field is required."
            ],
            "cost": [
                "The cost format is invalid."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Milestone couldn't be created."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/milestones/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`project_id` integer

The ID of the project to which the milestone belongs. Example: `13`

`title` string

The title of the milestone. Example: `commodi`

`status` string

The status of the milestone. Example: `quis`

`start_date` date optional

optional The start date of the milestone (YYYY-MM-DD). Example: `et`

`end_date` date optional

optional The end date of the milestone (YYYY-MM-DD). Example: `unde`

`cost` numeric

The cost of the milestone. Example: `placeat`

`description` string optional

optional A description of the milestone. Example: `Accusamus doloribus eum accusamus aliquid.`

## Get a list of milestones for a project.

requires authentication

This endpoint retrieves all milestones associated with a given project. It supports searching, filtering, and sorting functionalities.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/milestones/12?search=nesciunt&sort=dolor&order=aperiam&statuses[]=sunt&date_between_from=nostrum&date_between_to=molestiae&start_date_from=est&start_date_to=molestiae&end_date_from=soluta&end_date_to=expedita&limit=5" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/milestones/12"
    );

    const params = {
        "search": "nesciunt",
        "sort": "dolor",
        "order": "aperiam",
        "statuses[0]": "sunt",
        "date_between_from": "nostrum",
        "date_between_to": "molestiae",
        "start_date_from": "est",
        "start_date_to": "molestiae",
        "end_date_from": "soluta",
        "end_date_to": "expedita",
        "limit": "5",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
      "data": [
        {
          "id": 12,
          "title": "Design Phase",
          "status": Complete,
          "progress": "75",
          "cost": "₹1,500.00",
          "start_date": "2025-03-10",
          "end_date": "2025-03-20",
          "created_by": "John Doe",
          "description": "Initial design phase for the project.",
          "created_at": "2025-03-01",
          "updated_at": "2025-03-05",

        }
      ],
      "total": 1
    }

> Example response (404):

    {
        "error": true,
        "message": "Project not found."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/milestones/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the project whose milestones are to be retrieved. Example: `12`

#### Query Parameters

`search` string optional

optional Search for milestones by title, ID, cost, or description. Example: `nesciunt`

`sort` string optional

optional Field to sort by (default: "id"). Example: `dolor`

`order` string optional

optional Sorting order (ASC/DESC, default: "DESC"). Example: `aperiam`

`statuses` string[] optional

optional Filter by milestone statuses.

`date_between_from` string optional

date optional Filter milestones starting from this date. Example: `nostrum`

`date_between_to` string optional

date optional Filter milestones ending at this date. Example: `molestiae`

`start_date_from` string optional

date optional Filter milestones with a start date after this date. Example: `est`

`start_date_to` string optional

date optional Filter milestones with a start date before this date. Example: `molestiae`

`end_date_from` string optional

date optional Filter milestones with an end date after this date. Example: `soluta`

`end_date_to` string optional

date optional Filter milestones with an end date before this date. Example: `expedita`

`limit` integer optional

optional Number of records per page. Example: `5`

## Get details of a specific milestone.

requires authentication

This endpoint retrieves details of a specific milestone by its ID.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/milestones/get/2" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/milestones/get/2"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "milestone": {
            "id": 12,
            "title": "Design Phase",
            "status": "In Progress",
            "cost": "₹1,500.00",
            "start_date": "2025-03-10",
            "end_date": "2025-03-20",
            "description": "Initial design phase for the project.",
            "created_at": "2025-03-01",
            "updated_at": "2025-03-05"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Milestone not found."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/milestones/get/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the milestone to retrieve. Example: `2`

## Update an existing milestone.

requires authentication

This endpoint updates a specified milestone. The user must be authenticated and have permission to modify the milestone.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/milestones/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"beatae\",
        \"status\": \"ut\",
        \"start_date\": \"nobis\",
        \"end_date\": \"tempora\",
        \"cost\": \"magni\",
        \"progress\": 15,
        \"description\": \"Nihil est assumenda sapiente itaque et.\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/milestones/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "beatae",
        "status": "ut",
        "start_date": "nobis",
        "end_date": "tempora",
        "cost": "magni",
        "progress": 15,
        "description": "Nihil est assumenda sapiente itaque et."
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Milestone updated successfully.",
        "id": 12,
        "type": "milestone",
        "parent_type": "project",
        "parent_id": 438
    }

> Example response (404):

    {
        "error": true,
        "message": "Milestone not found."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "title": [
                "The title field is required."
            ],
            "cost": [
                "The cost format is invalid."
            ],
            "progress": [
                "The progress field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Milestone couldn't be updated."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/milestones/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the milestone to be updated. Example: `12`

#### Body Parameters

`title` string

The updated title of the milestone. Example: `beatae`

`status` string

The updated status of the milestone. Example: `ut`

`start_date` date optional

optional The updated start date of the milestone (YYYY-MM-DD). Example: `nobis`

`end_date` date optional

optional The updated end date of the milestone (YYYY-MM-DD). Example: `tempora`

`cost` numeric

The updated cost of the milestone. Example: `magni`

`progress` integer

The updated progress percentage of the milestone. Example: `15`

`description` string optional

optional An updated description of the milestone. Example: `Nihil est assumenda sapiente itaque et.`

## Delete a milestone.

requires authentication

This endpoint deletes a specified milestone. The user must be authenticated and have permission to delete milestones.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/milestones/destroy/8" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/milestones/destroy/8"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Milestone deleted successfully.",
        "id": 12,
        "title": "Design Phase",
        "type": "milestone",
        "parent_type": "project",
        "parent_id": 438
    }

> Example response (404):

    {
        "error": true,
        "message": "Milestone not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "Milestone couldn't be deleted."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/milestones/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the milestone to delete. Example: `8`

# Project Comments

## Add a comment.

requires authentication

This endpoint allows authenticated users to add comments to a specific model (e.g., tasks, projects). Users can also attach files and mention other users.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/projects/14/comments" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: multipart/form-data" \
        --form "model_type=qui"\
        --form "model_id=6"\
        --form "content=iste"\
        --form "parent_id=16"\
        --form "attachments[]=@/tmp/php2CSUrx"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/projects/14/comments"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "multipart/form-data",
    };

    const body = new FormData();
    body.append('model_type', 'qui');
    body.append('model_id', '6');
    body.append('content', 'iste');
    body.append('parent_id', '16');
    body.append('attachments[]', document.querySelector('input[name="attachments[]"]').files[0]);

    fetch(url, {
        method: "POST",
        headers,
        body,
    }).then(response => response.json());

> Example response (200):

    {
      "success": true,
      "message": "Comment Added Successfully",
      "comment": {
        "id": 45,
        "commentable_type": "App\Models\Project",
        "commentable_id": 438,
        "content": "This is a sample comment with a mention @JohnDoe",
        "commenter_id": 7,
        "commenter_type": "App\\Models\\User",
        "parent_id": null,
        "created_at": "2 minutes ago",
        "attachments": [
          {
            "id": 1,
            "file_name": "document.pdf",
            "file_path": "comment_attachments/document.pdf",
            "file_type": "application/pdf"
          }
        ]
      },
      "user": {
        "id": 7,
        "name": "John Doe"
      }
    }

> Example response (422):

    {
        "success": false,
        "message": "Validation errors occurred",
        "errors": {
            "content": [
                "Please enter a comment."
            ]
        }
    }

> Example response (500):

    {
        "success": false,
        "message": "Comment could not be added."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/projects/{id}/comments`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `multipart/form-data`

#### URL Parameters

`id` integer

The ID of the project to add a comment to. Example: `14`

#### Body Parameters

`model_type` string

The type of model being commented on (e.g., "Task", "Project"). Example: `qui`

`model_id` integer

The ID of the model being commented on. Example: `6`

`content` string

The comment text. Example: `iste`

`parent_id` integer optional

optional The ID of the parent comment (for replies). Example: `16`

`attachments[]` file optional

optional An array of files to attach to the comment. Maximum file size is defined in the config. Example: `/tmp/php2CSUrx`

## Get details of a specific comment.

requires authentication

This endpoint retrieves details of a specific comment by its ID, including any attachments.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/projects/comments/get/3" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/projects/comments/get/3"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "comment": {
            "id": 45,
            "commentable_type": "App\\Models\\Project",
            "commentable_id": 438,
            "content": "This is a sample comment with a mention @JohnDoe",
            "commenter_id": 7,
            "commenter_type": "App\\Models\\User",
            "parent_id": null,
            "created_at": "2025-03-03 14:00:00",
            "updated_at": "2025-03-03 16:00:00",
            "attachments": [
                {
                    "id": 1,
                    "file_name": "document.pdf",
                    "file_path": "comment_attachments/document.pdf",
                    "file_type": "application/pdf"
                }
            ]
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Comment not found."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/projects/comments/get/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the comment to retrieve. Example: `3`

## Update a comment.

requires authentication

This endpoint updates a specified comment. The user must be authenticated and have permission to modify the comment.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/projects/comments/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"comment_id\": 16,
        \"content\": \"autem\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/projects/comments/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "comment_id": 16,
        "content": "autem"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Comment updated successfully.",
        "id": 45,
        "type": "project"
    }

> Example response (404):

    {
        "error": true,
        "message": "Comment not found."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "content": [
                "Please enter a comment."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Comment couldn't be updated."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/projects/comments/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`comment_id` integer

The ID of the comment to be updated. Example: `16`

`content` string

The updated content of the comment. Example: `autem`

## Delete a comment.

requires authentication

This endpoint deletes a specified comment and removes its attachments from storage. The user must be authenticated and have permission to delete comments.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/projects/comments/destroy?comment_id=6" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/projects/comments/destroy"
    );

    const params = {
        "comment_id": "6",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Comment deleted successfully.",
        "id": 45,
        "type": "project"
    }

> Example response (404):

    {
        "error": true,
        "message": "Comment not found."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "comment_id": [
                "The comment_id field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Comment couldn't be deleted."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/projects/comments/destroy`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### Query Parameters

`comment_id` integer

The ID of the comment to delete. Example: `6`

# Project Media

## Upload media files to a project.

requires authentication

This endpoint allows authenticated users to upload media files related to a project.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/projects/upload-media" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: multipart/form-data" \
        --form "id=5"\
        --form "media_files[]=@/tmp/php2zY0J2"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/projects/upload-media"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "multipart/form-data",
    };

    const body = new FormData();
    body.append('id', '5');
    body.append('media_files[]', document.querySelector('input[name="media_files[]"]').files[0]);

    fetch(url, {
        method: "POST",
        headers,
        body,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "File(s) uploaded successfully.",
        "id": [
            101,
            102
        ],
        "type": "media",
        "parent_type": "project",
        "parent_id": 438
    }

> Example response (404):

    {
        "error": true,
        "message": "Project not found."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "id": [
                "The selected id is invalid."
            ],
            "media_files": [
                "The media file size exceeds the limit."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred during file upload."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/projects/upload-media`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `multipart/form-data`

#### Body Parameters

`id` integer

The ID of the project to which media files are being uploaded. Example: `5`

`media_files[]` file

An array of media files to be uploaded. Maximum file size is defined in the config. Example: `/tmp/php2zY0J2`

## Get project media files.

requires authentication

This endpoint retrieves all media files associated with a specific project, including sorting and search capabilities.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/projects/get-media/11?search=et&sort=sed&order=dolore" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/projects/get-media/11"
    );

    const params = {
        "search": "et",
        "sort": "sed",
        "order": "dolore",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
      "error": false,
      "message": "Media files retrieved successfully.",
      "rows": [
        {
          "id": 101,
          "file": "<a href='https://example.com/storage/project-media/image.jpg' data-lightbox='project-media'><img src='https://example.com/storage/project-media/image.jpg' alt='image.jpg' width='50'></a>",
          "file_name": "image.jpg",
          "file_size": "2 MB",
          "created_at": "2025-03-03",
          "updated_at": "2025-03-03",

        }
      ],
      "total": 1
    }

> Example response (404):

    {
        "error": true,
        "message": "Project not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "Could not retrieve media files."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/projects/get-media/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the project whose media files are to be retrieved. Example: `11`

#### Query Parameters

`search` string optional

optional A search query to filter media files by name, ID, or upload date. Example: `et`

`sort` string optional

optional The column to sort by (default: "id"). Example: `sed`

`order` string optional

optional The sorting order: "ASC" or "DESC" (default: "DESC"). Example: `dolore`

## Delete a media file.

requires authentication

This endpoint deletes a specified media file associated with a project. The user must be authenticated and have permission to delete media files.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/projects/delete-media/sunt" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/projects/delete-media/sunt"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "File deleted successfully.",
        "id": 101,
        "title": "image.jpg",
        "parent_id": 438,
        "type": "media",
        "parent_type": "project"
    }

> Example response (404):

    {
        "error": true,
        "message": "File not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "File couldn't be deleted."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/projects/delete-media/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` string

The ID of the delete medium. Example: `sunt`

`mediaId` integer

The ID of the media file to delete. Example: `17`

# Task Management

## Create a new task.

requires authentication

This endpoint creates a new task with the provided details. The user must be authenticated to perform this action. The request validates various fields, including title, status, priority, start and due dates, project association, and optional notes.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/tasks/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"New Task\",
        \"status_id\": 1,
        \"priority_id\": 2,
        \"start_date\": \"2024-07-20\",
        \"due_date\": \"2024-08-20\",
        \"description\": \"This is a detailed description of the task.\",
        \"project\": 10,
        \"note\": \"Urgent\",
        \"user_id\": [
            1,
            2,
            3
        ],
        \"clientCanDiscuss\": \"on\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tasks/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "New Task",
        "status_id": 1,
        "priority_id": 2,
        "start_date": "2024-07-20",
        "due_date": "2024-08-20",
        "description": "This is a detailed description of the task.",
        "project": 10,
        "note": "Urgent",
        "user_id": [
            1,
            2,
            3
        ],
        "clientCanDiscuss": "on"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Task created successfully.",
        "id": 280,
        "parent_id": "420",
        "parent_type": "project",
        "data": {
            "id": 280,
            "workspace_id": 6,
            "title": "Res Test",
            "status": "Default",
            "status_id": "0",
            "priority": "Default",
            "priority_id": "0",
            "users": [
                {
                    "id": 7,
                    "first_name": "Madhavan",
                    "last_name": "Vaidya",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png"
                }
            ],
            "user_id": [
                1,
                2
            ],
            "clients": [
                {
                    "id": 173,
                    "first_name": "666",
                    "last_name": "666",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                }
            ],
            "start_date": "07-08-2024",
            "due_date": "07-08-2024",
            "project": {
                "id": 420,
                "title": "Updated Project Title"
            },
            "description": "Test Desc",
            "note": "Test Note",
            "created_at": "07-08-2024 13:02:52",
            "updated_at": "07-08-2024 13:02:52"
        }
    }

> Example response (422):

    {
     "error": true,
     "message": "Validation errors occurred",
     "errors": {
       "title": ["The title field is required."],
       "status_id": ["The selected status_id is invalid."],
       ...
     }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the task."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/tasks/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`title` string

The title of the task. Example: `New Task`

`status_id` integer

The status of the task. Must exist in the `statuses` table. Example: `1`

`priority_id` integer optional

nullable The priority of the task. Must exist in the `priorities` table. Example: `2`

`start_date` string|null optional

optional The start date of the task in the format specified in the general settings. Example: `2024-07-20`

`due_date` string|null optional

optional The due date of the task in the format specified in the general settings. Example: `2024-08-20`

`description` string optional

nullable A description of the task. Example: `This is a detailed description of the task.`

`project` integer

The ID of the project associated with the task. Must exist in the `projects` table. Example: `10`

`note` string optional

nullable Additional notes about the task. Example: `Urgent`

`user_id` string[] optional

nullable An array of user IDs to be assigned to the task.

`clientCanDiscuss` string optional

optional Indicates if the client can participate in task discussions. Can only specify if `is_admin_or_has_all_data_access` is true for the logged-in user; otherwise, it will be considered 0 by default. The value should be 'on' to allow client participation. Example: `on`

## List or search tasks.

requires authentication

This endpoint retrieves a list of tasks based on various filters. The user must be authenticated to perform this action. The request allows filtering by multiple statuses, users, clients, projects, date ranges, and other parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/tasks/1?search=Task&sort=title&order=ASC&status_ids[]=2&status_ids[]=3&user_ids[]=1&user_ids[]=2&user_ids[]=3&client_ids[]=5&client_ids[]=6&priority_ids[]=1&priority_ids[]=2&project_ids[]=1&project_ids[]=2&task_start_date_from=2024-01-01&task_start_date_to=2024-12-31&task_end_date_from=2024-01-01&task_end_date_to=2024-12-31&is_favorites=1&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"user_ids\": [
            17
        ],
        \"client_ids\": [
            8
        ],
        \"priority_ids\": [
            19
        ],
        \"project_ids\": [
            9
        ],
        \"status_ids\": [
            19
        ]
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tasks/1"
    );

    const params = {
        "search": "Task",
        "sort": "title",
        "order": "ASC",
        "status_ids[0]": "2",
        "status_ids[1]": "3",
        "user_ids[0]": "1",
        "user_ids[1]": "2",
        "user_ids[2]": "3",
        "client_ids[0]": "5",
        "client_ids[1]": "6",
        "priority_ids[0]": "1",
        "priority_ids[1]": "2",
        "project_ids[0]": "1",
        "project_ids[1]": "2",
        "task_start_date_from": "2024-01-01",
        "task_start_date_to": "2024-12-31",
        "task_end_date_from": "2024-01-01",
        "task_end_date_to": "2024-12-31",
        "is_favorites": "1",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "user_ids": [
            17
        ],
        "client_ids": [
            8
        ],
        "priority_ids": [
            19
        ],
        "project_ids": [
            9
        ],
        "status_ids": [
            19
        ]
    };

    fetch(url, {
        method: "GET",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Tasks retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 268,
                "workspace_id": 6,
                "title": "sdff",
                "status": "Default",
                "priority": "Default",
                "users": [
                    {
                        "id": 7,
                        "first_name": "Madhavan",
                        "last_name": "Vaidya",
                        "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png"
                    }
                ],
                "clients": [
                    {
                        "id": 102,
                        "first_name": "Test",
                        "last_name": "Client",
                        "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                    }
                ],
                "start_date": "23-07-2024",
                "due_date": "24-07-2024",
                "project": {
                    "id": 379,
                    "title": "From API"
                },
                "description": "<p>Test Desc</p>",
                "note": "Test note",
                "created_at": "23-07-2024 17:50:09",
                "updated_at": "23-07-2024 19:08:16"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Task not found",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Tasks not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/tasks/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer optional

optional The ID of the task to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter tasks by title or id. Example: `Task`

`sort` string optional

optional The field to sort by. Defaults to "id". Sortable fields include: id, title, project, status, priority, start_date, due_date, created_at, and updated_at. Example: `title`

`order` string optional

optional The sort order, either "ASC" or "DESC". Defaults to "DESC". Example: `ASC`

`status_ids` string[] optional

optional An array of status IDs to filter tasks by.

`user_ids` string[] optional

optional An array of user IDs to filter tasks by.

`client_ids` string[] optional

optional An array of client IDs to filter tasks by.

`priority_ids` string[] optional

optional An array of priority IDs to filter tasks by.

`project_ids` string[] optional

optional An array of project IDs to filter tasks by.

`task_start_date_from` string optional

optional The start date range's start in YYYY-MM-DD format. Example: `2024-01-01`

`task_start_date_to` string optional

optional The start date range's end in YYYY-MM-DD format. Example: `2024-12-31`

`task_end_date_from` string optional

optional The end date range's start in YYYY-MM-DD format. Example: `2024-01-01`

`task_end_date_to` string optional

optional The end date range's end in YYYY-MM-DD format. Example: `2024-12-31`

`is_favorites` boolean optional `true` `false`

optional Filter projects marked as favorites. Example: `true`

`limit` integer optional

optional The number of tasks per page for pagination. Example: `10`

`offset` integer optional

optional The offset for pagination, indicating the starting point of results. Example: `0`

#### Body Parameters

`user_ids` integer[] optional

The `id` of an existing record in the users table.

`client_ids` integer[] optional

The `id` of an existing record in the clients table.

`priority_ids` integer[] optional

The `id` of an existing record in the priorities table.

`project_ids` integer[] optional

The `id` of an existing record in the projects table.

`status_ids` integer[] optional

The `id` of an existing record in the statuses table.

## Update an existing task.

requires authentication

This endpoint updates the details of an existing task. The user must be authenticated to perform this action. The request validates various fields including title, status, priority, start and due dates, and optional notes. It also handles user assignments and notifies relevant parties of any status changes.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/tasks/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 267,
        \"title\": \"Updated Task\",
        \"status_id\": 2,
        \"priority_id\": 1,
        \"start_date\": \"2024-07-20\",
        \"due_date\": \"2024-08-20\",
        \"description\": \"Updated task description.\",
        \"note\": \"Needs immediate attention.\",
        \"user_id\": [
            2,
            3
        ],
        \"clientCanDiscuss\": \"on\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tasks/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 267,
        "title": "Updated Task",
        "status_id": 2,
        "priority_id": 1,
        "start_date": "2024-07-20",
        "due_date": "2024-08-20",
        "description": "Updated task description.",
        "note": "Needs immediate attention.",
        "user_id": [
            2,
            3
        ],
        "clientCanDiscuss": "on"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Task updated successfully.",
        "id": 280,
        "parent_id": "420",
        "parent_type": "project",
        "data": {
            "id": 280,
            "workspace_id": 6,
            "title": "Res Test",
            "status": "Default",
            "priority": "Default",
            "users": [
                {
                    "id": 7,
                    "first_name": "Madhavan",
                    "last_name": "Vaidya",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png"
                }
            ],
            "clients": [
                {
                    "id": 173,
                    "first_name": "666",
                    "last_name": "666",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                }
            ],
            "start_date": "07-08-2024",
            "due_date": "07-08-2024",
            "project": {
                "id": 420,
                "title": "Updated Project Title"
            },
            "description": "Test Desc",
            "note": "Test Note",
            "created_at": "07-08-2024 13:02:52",
            "updated_at": "07-08-2024 13:02:52"
        }
    }

> Example response (422):

    {
     "error": true,
     "message": "Validation errors occurred",
     "errors": {
       "id": ["The selected id is invalid."],
       "title": ["The title field is required."],
       "status_id": ["The selected status_id is invalid."],
       ...
     }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the task."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/tasks/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` integer

The ID of the task to be updated. Must exist in the `tasks` table. Example: `267`

`title` string

The title of the task. Example: `Updated Task`

`status_id` integer

The status of the task. Must exist in the `statuses` table. Example: `2`

`priority_id` integer optional

nullable The priority of the task. Must exist in the `priorities` table. Example: `1`

`start_date` string|null optional

optional The start date of the task in the format specified in the general settings. Example: `2024-07-20`

`due_date` string|null optional

optional The due date of the task in the format specified in the general settings. Example: `2024-08-20`

`description` string optional

nullable A description of the task. Example: `Updated task description.`

`note` string optional

nullable Additional notes about the task. Example: `Needs immediate attention.`

`user_id` string[] optional

nullable An array of user IDs to be assigned to the task.

`clientCanDiscuss` string optional

optional Indicates if the client can participate in task discussions. Can only specify if `is_admin_or_has_all_data_access` is true for the logged-in user; otherwise, it will be considered current value by default. The value should be 'on' to allow client participation. Example: `on`

## Update the favorite status of a task.

requires authentication

This endpoint updates whether a task is marked as a favorite or not. The user must be authenticated to perform this action.

> Example request:

    curl --request PATCH \
        "https://dev-taskify.taskhub.company/api/tasks/12/favorite" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"is_favorite\": 16
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tasks/12/favorite"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "is_favorite": 16
    };

    fetch(url, {
        method: "PATCH",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Task favorite status updated successfully",
    "data": {
      "id": 438,
      "title": "Task Example"
      // Other task details will be included in the actual response
    }
    }

> Example response (200):

    {
        "error": true,
        "message": "Task not found",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "is_favorite": [
                "The is favorite field must be either 0 or 1."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the favorite status."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

PATCH `api/tasks/{id}/favorite`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the task to update. Example: `12`

#### Body Parameters

`is_favorite` integer

Indicates whether the task is a favorite. Use 1 for true and 0 for false. Example: `16`

## Update the pinned status of a task.

requires authentication

This endpoint updates whether a task is marked as pinned or not. The user must be authenticated to perform this action.

> Example request:

    curl --request PATCH \
        "https://dev-taskify.taskhub.company/api/tasks/17/pinned" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"is_pinned\": 20
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tasks/17/pinned"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "is_pinned": 20
    };

    fetch(url, {
        method: "PATCH",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Task pinned status updated successfully",
    "data": {
      "id": 438,
      "title": "Task Example"
      // Other task details will be included in the actual response
    }
    }

> Example response (200):

    {
        "error": true,
        "message": "Task not found",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "is_pinned": [
                "The is pinned field must be either 0 or 1."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the pinned status."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

PATCH `api/tasks/{id}/pinned`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the task to update. Example: `17`

#### Body Parameters

`is_pinned` integer

Indicates whether the task is pinned. Use 1 for true and 0 for false. Example: `20`

## Update the status of a task.

requires authentication

This endpoint updates the status of a specified task. The user must be authenticated and have permission to set the new status. A notification will be sent to all users and clients associated with the task.

> Example request:

    curl --request PATCH \
        "https://dev-taskify.taskhub.company/api/tasks/1/status" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"statusId\": 2,
        \"note\": \"Updated due to client request.\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tasks/1/status"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "statusId": 2,
        "note": "Updated due to client request."
    };

    fetch(url, {
        method: "PATCH",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Status updated successfully.",
        "id": "278",
        "type": "task",
        "activity_message": "Madhavan Vaidya updated task status from Ongoing to Completed",
        "data": {
            "id": 278,
            "workspace_id": 6,
            "title": "New Task",
            "status": "Completed",
            "priority": "dsfdsf",
            "users": [
                {
                    "id": 7,
                    "first_name": "Madhavan",
                    "last_name": "Vaidya",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png"
                }
            ],
            "clients": [
                {
                    "id": 173,
                    "first_name": "666",
                    "last_name": "666",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                }
            ],
            "start_date": "20-08-2024",
            "due_date": null,
            "project": {
                "id": 419,
                "title": "Updated Project Title"
            },
            "description": "This is a detailed description of the task.",
            "note": null,
            "created_at": "06-08-2024 11:42:13",
            "updated_at": "12-08-2024 15:18:09"
        }
    }

> Example response (200):

    {
        "error": true,
        "message": "You are not authorized to set this status."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "id": [
                "The selected id is invalid."
            ],
            "statusId": [
                "The selected status id is invalid."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Status couldn't be updated."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

PATCH `api/tasks/{id}/status`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the task whose status is to be updated. Example: `1`

#### Body Parameters

`statusId` integer

The ID of the new status to set for the task. Must exist in the `statuses` table. Example: `2`

`note` string optional

optional An optional note to attach to the task update. Example: `Updated due to client request.`

## Update the priority of a task.

requires authentication

This endpoint updates the priority of a specified task. The user must be authenticated and have permission to set the new priority.

> Example request:

    curl --request PATCH \
        "https://dev-taskify.taskhub.company/api/tasks/1/priority" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"priorityId\": 3
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tasks/1/priority"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "priorityId": 3
    };

    fetch(url, {
        method: "PATCH",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Priority updated successfully.",
        "id": "278",
        "type": "task",
        "activity_message": "Madhavan Vaidya updated task priority from Medium to High",
        "data": {
            "id": 278,
            "workspace_id": 6,
            "title": "New Task",
            "status": "Completed",
            "priority": "High",
            "users": [
                {
                    "id": 7,
                    "first_name": "Madhavan",
                    "last_name": "Vaidya",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png"
                }
            ],
            "clients": [
                {
                    "id": 173,
                    "first_name": "666",
                    "last_name": "666",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                }
            ],
            "start_date": "20-08-2024",
            "due_date": null,
            "project": {
                "id": 419,
                "title": "Updated Project Title"
            },
            "description": "This is a detailed description of the task.",
            "note": null,
            "created_at": "06-08-2024 11:42:13",
            "updated_at": "12-08-2024 15:40:41"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "id": [
                "The selected id is invalid."
            ],
            "priorityId": [
                "The selected priorityId is invalid."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Priority couldn't be updated."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

PATCH `api/tasks/{id}/priority`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the task whose priority is to be updated. Example: `1`

#### Body Parameters

`priorityId` integer

The ID of the new priority to set for the task. Must exist in the `priorities` table. Example: `3`

## Remove the specified task.

requires authentication

This endpoint deletes a task based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/tasks/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tasks/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Task deleted successfully.",
        "id": "262",
        "title": "From API",
        "parent_id": 377,
        "parent_type": "project",
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Task not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the task."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/tasks/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the task to be deleted. Example: `1`

## Get task status timeline.

requires authentication

This endpoint retrieves the status change history of a task, sorted in descending order.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/tasks/18/status-timelines" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tasks/18/status-timelines"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Status timeline retrieved successfully.",
        "status_timeline": [
            {
                "id": 1,
                "status": "In Progress",
                "previous_status": "Pending",
                "new_color": "#ffcc00",
                "old_color": "#cccccc",
                "changed_at": "2025-03-03"
            },
            {
                "id": 2,
                "status": "Completed",
                "previous_status": "In Progress",
                "new_color": "#00cc66",
                "old_color": "#ffcc00",
                "changed_at": "2025-03-05 16:00:00"
            }
        ]
    }

> Example response (404):

    {
        "error": true,
        "message": "Task not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "Could not retrieve status timeline."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/tasks/{id}/status-timelines`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the task whose status timeline is to be retrieved. Example: `18`

# Task Comments

## Add a comment with attachments.

requires authentication

This endpoint allows authenticated users to add comments to a specific model (e.g., tasks, projects). Users can also attach files and mention other users.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/tasks/information/dolorem/comments" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: multipart/form-data" \
        --form "model_type=eius"\
        --form "model_id=13"\
        --form "content=recusandae"\
        --form "parent_id=1"\
        --form "attachments[]=@/tmp/php0ArDng"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tasks/information/dolorem/comments"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "multipart/form-data",
    };

    const body = new FormData();
    body.append('model_type', 'eius');
    body.append('model_id', '13');
    body.append('content', 'recusandae');
    body.append('parent_id', '1');
    body.append('attachments[]', document.querySelector('input[name="attachments[]"]').files[0]);

    fetch(url, {
        method: "POST",
        headers,
        body,
    }).then(response => response.json());

> Example response (200):

    {
        "success": true,
        "message": "Comment Added Successfully",
        "comment": {
            "id": 45,
            "commentable_type": "App\\Models\\Task",
            "commentable_id": 438,
            "content": "This is a sample comment with a mention @JohnDoe",
            "user_id": 7,
            "parent_id": null,
            "created_at": "2 minutes ago",
            "attachments": [
                {
                    "id": 1,
                    "file_name": "document.pdf",
                    "file_path": "comment_attachments/document.pdf",
                    "file_type": "application/pdf"
                }
            ]
        },
        "user": {
            "id": 7,
            "name": "John Doe"
        }
    }

> Example response (422):

    {
        "success": false,
        "message": "Validation errors occurred",
        "errors": {
            "content": [
                "Please enter a comment."
            ]
        }
    }

> Example response (500):

    {
        "success": false,
        "message": "Comment could not be added."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/tasks/information/{id}/comments`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `multipart/form-data`

#### URL Parameters

`id` string

The ID of the information. Example: `dolorem`

#### Body Parameters

`model_type` string

The type of model being commented on (e.g., "Task", "Project"). Example: `eius`

`model_id` integer

The ID of the model being commented on. Example: `13`

`content` string

The comment text. Example: `recusandae`

`parent_id` integer optional

optional The ID of the parent comment (for replies). Example: `1`

`attachments[]` file optional

optional An array of files to attach to the comment. Supported formats: jpg, jpeg, png, pdf, xlsx, txt, docx (max size: 2MB). Example: `/tmp/php0ArDng`

## Get details of a specific comment.

requires authentication

This endpoint retrieves the details of a specific comment, including any attachments.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/tasks/comments/get/2" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tasks/comments/get/2"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Comment retrieved successfully.",
        "comment": {
            "id": 45,
            "commentable_type": "App\\Models\\Task",
            "commentable_id": 438,
            "content": "This is a sample comment with a mention @JohnDoe",
            "user_id": 7,
            "parent_id": null,
            "created_at": "2025-03-03 14:00:00",
            "updated_at": "2025-03-03 16:00:00",
            "attachments": [
                {
                    "id": 1,
                    "file_name": "document.pdf",
                    "file_path": "comment_attachments/document.pdf",
                    "file_type": "application/pdf"
                }
            ]
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Comment not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "Could not retrieve comment."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/tasks/comments/get/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the comment to retrieve. Example: `2`

## Update a comment.

requires authentication

This endpoint updates a specified comment. The user must be authenticated and have permission to modify the comment.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/tasks/comments/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"comment_id\": 16,
        \"content\": \"excepturi\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tasks/comments/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "comment_id": 16,
        "content": "excepturi"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Comment updated successfully.",
        "id": 45,
        "type": "task"
    }

> Example response (404):

    {
        "error": true,
        "message": "Comment not found."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "content": [
                "Please enter a comment."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Comment couldn't be updated."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/tasks/comments/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`comment_id` integer

The ID of the comment to be updated. Example: `16`

`content` string

The updated content of the comment. Example: `excepturi`

## Delete a comment.

requires authentication

This endpoint deletes a specified comment and removes its attachments from storage. The user must be authenticated and have permission to delete comments.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/tasks/comments/destroy?comment_id=19" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tasks/comments/destroy"
    );

    const params = {
        "comment_id": "19",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Comment deleted successfully.",
        "id": 45,
        "type": "task"
    }

> Example response (404):

    {
        "error": true,
        "message": "Comment not found."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "comment_id": [
                "The comment_id field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Comment couldn't be deleted."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/tasks/comments/destroy`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### Query Parameters

`comment_id` integer

The ID of the comment to delete. Example: `19`

# Task Media

## Upload media files for a task.

requires authentication

This endpoint allows authenticated users to upload media files and associate them with a specific task.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/tasks/upload-media" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: multipart/form-data" \
        --form "id=10"\
        --form "media_files[]=@/tmp/phptyHXPU"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tasks/upload-media"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "multipart/form-data",
    };

    const body = new FormData();
    body.append('id', '10');
    body.append('media_files[]', document.querySelector('input[name="media_files[]"]').files[0]);

    fetch(url, {
        method: "POST",
        headers,
        body,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "File(s) uploaded successfully.",
        "id": [
            201,
            202
        ],
        "type": "media",
        "parent_type": "task",
        "parent_id": 15
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred.",
        "errors": {
            "id": [
                "The selected id is invalid."
            ],
            "media_files": [
                "The media file must be a valid file."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred during file upload: [error details]"
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/tasks/upload-media`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `multipart/form-data`

#### Body Parameters

`id` integer

The ID of the task where the media will be uploaded. Example: `10`

`media_files[]` file

An array of media files to upload. Max size is defined by system settings. Example: `/tmp/phptyHXPU`

## Get Task media files.

requires authentication

This endpoint retrieves all media files associated with a specific project, including sorting and search capabilities.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/tasks/get-media/4?search=quisquam&sort=ducimus&order=quo" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tasks/get-media/4"
    );

    const params = {
        "search": "quisquam",
        "sort": "ducimus",
        "order": "quo",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
      "error": false,
      "message": "Media files retrieved successfully.",
      "rows": [
        {
          "id": 101,
          "file": "<a href='https://example.com/storage/task-media/image.jpg' data-lightbox='task-media'><img src='https://example.com/storage/project-media/image.jpg' alt='image.jpg' width='50'></a>",
          "file_name": "image.jpg",
          "file_size": "2 MB",
          "created_at": "2025-03-03",
          "updated_at": "2025-03-03",

        }
      ],
      "total": 1
    }

> Example response (404):

    {
        "error": true,
        "message": "Task not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "Could not retrieve media files."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/tasks/get-media/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the project whose media files are to be retrieved. Example: `4`

#### Query Parameters

`search` string optional

optional A search query to filter media files by name, ID, or upload date. Example: `quisquam`

`sort` string optional

optional The column to sort by (default: "id"). Example: `ducimus`

`order` string optional

optional The sorting order: "ASC" or "DESC" (default: "DESC"). Example: `quo`

## Delete a media file.

requires authentication

This endpoint allows authenticated users to delete a specific media file associated with a task.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/tasks/delete-media/nobis" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tasks/delete-media/nobis"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "File deleted successfully.",
        "id": 301,
        "title": "document.pdf",
        "parent_id": 15,
        "type": "media",
        "parent_type": "task"
    }

> Example response (404):

    {
        "error": true,
        "message": "File not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the file."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/tasks/delete-media/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` string

The ID of the delete medium. Example: `nobis`

`mediaId` integer

The ID of the media file to delete. Example: `18`

# Income vs Expense

## Get the Income vs Expense Statistics.

requires authentication

This endpoint provides the Income vs Expense Statistics. The user must be authenticated to access this data.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/reports/income-vs-expense-report-data" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/reports/income-vs-expense-report-data"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "total_income": "$ 705.00",
        "total_expenses": "$ 20,000.00",
        "profit_or_loss": "$ -19,295.00",
        "invoices": [
            {
                "id": 3,
                "view_route": "http://localhost:8000/estimates-invoices/view/3",
                "amount": "$ 105.00",
                "to_date": "05-02-2025",
                "from_date": "05-02-2025"
            },
            {
                "id": 4,
                "view_route": "http://localhost:8000/estimates-invoices/view/4",
                "amount": "$ 600.00",
                "to_date": "05-02-2025",
                "from_date": "05-02-2025"
            }
        ],
        "expenses": [
            {
                "id": 1,
                "title": "Salary",
                "amount": "$ 500.00",
                "expense_date": "31-01-2025"
            },
            {
                "id": 2,
                "title": "January Rent Pay",
                "amount": "$ 5,000.00",
                "expense_date": "04-02-2025"
            },
            {
                "id": 3,
                "title": "Salary to Karen",
                "amount": "$ 5,000.00",
                "expense_date": "31-01-2025"
            },
            {
                "id": 4,
                "title": "Internet Bill Payment",
                "amount": "$ 300.00",
                "expense_date": "31-01-2025"
            },
            {
                "id": 5,
                "title": "Office Refreshment Items",
                "amount": "$ 1,000.00",
                "expense_date": "31-01-2025"
            },
            {
                "id": 9,
                "title": "Transportation Fuel",
                "amount": "$ 2,000.00",
                "expense_date": "08-02-2025"
            },
            {
                "id": 10,
                "title": "Corporate Tax",
                "amount": "$ 1,200.00",
                "expense_date": "08-02-2025"
            },
            {
                "id": 11,
                "title": "Event Sponsorships",
                "amount": "$ 5,000.00",
                "expense_date": "08-02-2025"
            }
        ]
    }

> Example response (500):

    {
        "error": true,
        "message": "Something went wrong."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/reports/income-vs-expense-report-data`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

# Status Management

## List or search statuses.

requires authentication

This endpoint retrieves a list of statuses based on various filters. The user must be authenticated to perform this action. The request allows searching and sorting by different parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/statuses/1?search=Active&sort=title&order=ASC&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/statuses/1"
    );

    const params = {
        "search": "Active",
        "sort": "title",
        "order": "ASC",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Statuses retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 1,
                "title": "Active",
                "color": "primary",
                "created_at": "20-07-2024 17:50:09",
                "updated_at": "21-07-2024 19:08:16"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Status not found",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Statuses not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/statuses/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the status to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter statuses by title or id. Example: `Active`

`sort` string optional

optional The field to sort by. Defaults to "id". Sortable fields include: id, title, color, created_at, and updated_at. Example: `title`

`order` string optional

optional The sort order, either "ASC" or "DESC". Defaults to "DESC". Example: `ASC`

`limit` integer optional

optional The number of statuses per page for pagination. Example: `10`

`offset` integer optional

optional The offset for pagination, indicating the starting point of results. Example: `0`

## Create a new status.

requires authentication

This endpoint allows authenticated users to create a new status with a unique slug and assign roles to it.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/status/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"qui\",
        \"color\": \"doloribus\",
        \"role_ids\": [
            \"et\"
        ]
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/status/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "qui",
        "color": "doloribus",
        "role_ids": [
            "et"
        ]
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Status created successfully.",
        "id": 101,
        "status": {
            "id": 101,
            "title": "In Progress",
            "color": "primary",
            "slug": "in-progress"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred.",
        "errors": {
            "title": [
                "The title field is required."
            ],
            "color": [
                "The color field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Status couldn't be created."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/status/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`title` string

The title of the status. Example: `qui`

`color` string

The color code associated with the status. Example: `doloribus`

`role_ids` string[] optional

optional An array of role IDs to be associated with the status.

## Update an existing status.

requires authentication

This endpoint allows authenticated users to update a status, including modifying the title, color, and associated roles.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/status/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 1,
        \"title\": \"quia\",
        \"color\": \"quam\",
        \"role_ids\": [
            \"harum\"
        ]
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/status/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 1,
        "title": "quia",
        "color": "quam",
        "role_ids": [
            "harum"
        ]
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Status updated successfully.",
        "id": 101
    }

> Example response (404):

    {
        "error": true,
        "message": "Status not found."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred.",
        "errors": {
            "id": [
                "The id field is required."
            ],
            "title": [
                "The title field is required."
            ],
            "color": [
                "The color field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Status couldn't be updated."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/status/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` integer

The ID of the status to update. Example: `1`

`title` string

The updated title of the status. Example: `quia`

`color` string

The updated color code associated with the status. Example: `quam`

`role_ids` string[] optional

optional An array of role IDs to associate with the status.

## Get details of a specific status.

requires authentication

This endpoint retrieves the details of a specific status, including the roles associated with it.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/status/get/18" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/status/get/18"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Status retrieved successfully.",
        "status": {
            "id": 101,
            "title": "In Progress",
            "color": "primary",
            "slug": "in-progress"
        },
        "roles": [
            1,
            2,
            3
        ]
    }

> Example response (404):

    {
        "error": true,
        "message": "Status not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "Could not retrieve status."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/status/get/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the status to retrieve. Example: `18`

## Delete a status.

requires authentication

This endpoint allows authenticated users to delete a specific status. Before deletion, all associated projects and tasks will be updated to have a default status ID of `0`.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/status/destroy/15" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/status/destroy/15"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Status deleted successfully.",
        "id": 101,
        "title": "In Progress"
    }

> Example response (404):

    {
        "error": true,
        "message": "Status not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "Status couldn't be deleted."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/status/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the status to delete. Example: `15`

# Priority Management

## List or search priorities.

requires authentication

This endpoint retrieves a list of priorities based on various filters. The user must be authenticated to perform this action. The request allows searching and sorting by different parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/priorities/1?search=High&sort=title&order=ASC&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/priorities/1"
    );

    const params = {
        "search": "High",
        "sort": "title",
        "order": "ASC",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Priorities retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 1,
                "title": "High",
                "color": "primary",
                "created_at": "20-07-2024 17:50:09",
                "updated_at": "21-07-2024 19:08:16"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Priority not found",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Priorities not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/priorities/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the priority to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter priorities by title or id. Example: `High`

`sort` string optional

optional The field to sort by. Defaults to "id". Sortable fields include: id, title, color, created_at, and updated_at. Example: `title`

`order` string optional

optional The sort order, either "ASC" or "DESC". Defaults to "DESC". Example: `ASC`

`limit` integer optional

optional The number of priorities per page for pagination. Example: `10`

`offset` integer optional

optional The offset for pagination, indicating the starting point of results. Example: `0`

## Create a new priority.

requires authentication

This endpoint allows authenticated users to create a new priority with a unique slug.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/priority/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"est\",
        \"color\": \"deleniti\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/priority/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "est",
        "color": "deleniti"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Priority created successfully.",
        "id": 101,
        "priority": {
            "id": 101,
            "title": "High",
            "color": "primary",
            "slug": "high"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred.",
        "errors": {
            "title": [
                "The title field is required."
            ],
            "color": [
                "The color field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Priority couldn't be created."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/priority/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`title` string

The title of the priority. Example: `est`

`color` string

The color code associated with the priority. Example: `deleniti`

## Update an existing priority.

requires authentication

This endpoint allows authenticated users to update a priority, including modifying the title and color.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/priority/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 6,
        \"title\": \"dolor\",
        \"color\": \"dicta\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/priority/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 6,
        "title": "dolor",
        "color": "dicta"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Priority updated successfully.",
        "id": 101
    }

> Example response (404):

    {
        "error": true,
        "message": "Priority not found."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred.",
        "errors": {
            "id": [
                "The id field is required."
            ],
            "title": [
                "The title field is required."
            ],
            "color": [
                "The color field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Priority couldn't be updated."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/priority/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` integer

The ID of the priority to update. Example: `6`

`title` string

The updated title of the priority. Example: `dolor`

`color` string

The updated color code associated with the priority. Example: `dicta`

## Get details of a specific priority.

requires authentication

This endpoint retrieves the details of a specific priority.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/priority/get/16" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/priority/get/16"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Priority retrieved successfully.",
        "priority": {
            "id": 101,
            "title": "High",
            "color": "#ff0000",
            "slug": "high",
            "created_at": "2025-03-04 14:00:00",
            "updated_at": "2025-03-04 16:00:00"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Priority not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "Could not retrieve priority."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/priority/get/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the priority to retrieve. Example: `16`

## Delete a priority.

requires authentication

This endpoint allows authenticated users to delete a specific priority. Before deletion, all associated projects and tasks will have their `priority_id` set to `null`.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/priority/destroy/20" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/priority/destroy/20"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Priority deleted successfully.",
        "id": 101,
        "title": "High"
    }

> Example response (404):

    {
        "error": true,
        "message": "Priority not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "Priority couldn't be deleted."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/priority/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the priority to delete. Example: `20`

# Tag Management

## List or search tags.

requires authentication

This endpoint retrieves a list of tags based on various filters. The user must be authenticated to perform this action. The request allows searching and sorting by different parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/tags/1?search=Urgent&sort=title&order=ASC&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tags/1"
    );

    const params = {
        "search": "Urgent",
        "sort": "title",
        "order": "ASC",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Tags retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 1,
                "title": "Urgent",
                "color": "primary",
                "created_at": "20-07-2024 17:50:09",
                "updated_at": "21-07-2024 19:08:16"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Tag not found",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Tags not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/tags/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the tag to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter tags by title or id. Example: `Urgent`

`sort` string optional

optional The field to sort by. Defaults to "id". Sortable fields include: id, title, created_at, and updated_at. Example: `title`

`order` string optional

optional The sort order, either "ASC" or "DESC". Defaults to "DESC". Example: `ASC`

`limit` integer optional

optional The number of tags per page for pagination. Example: `10`

`offset` integer optional

optional The offset for pagination, indicating the starting point of results. Example: `0`

## Create a new tag.

requires authentication

This endpoint creates a new todo item with the specified title, color. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/tags/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"Finish report\",
        \"color\": \"secondary\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tags/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "Finish report",
        "color": "secondary"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Tag created successfully.",
        "id": 36,
        "data": {
            "id": 36,
            "title": "test",
            "color": "secondary",
            "created_at": "07-08-2024 16:30:09",
            "updated_at": "07-08-2024 16:30:09"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "title": [
                "The title field is required."
            ],
            "color": [
                "The color must be one of the following: primary, secondary, warning, info, dark, success, danger."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the todo."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/tags/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`title` string

The title of the tag. Example: `Finish report`

`color` string

The priority of the tag. Must be one of "primary", "secondary", or "warning". Example: `secondary`

## Update an existing tag.

requires authentication

This endpoint updates an existing tag item with the specified title, color. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/tags/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 1,
        \"title\": \"Finish report\",
        \"color\": \"secondary\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tags/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 1,
        "title": "Finish report",
        "color": "secondary"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Tag updated successfully.",
    "id": "36",
    "data": {
      "id": 36,
      "title": "test",
      "color": "secondary",
      "created_at": "07-08-2024 16:30:09",
      "updated_at": "07-08-2024 16:30:09"
    }
    }

    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "id": [
                "The id field is required."
            ],
            "title": [
                "The title field is required."
            ],
            "color": [
                "The color must be one of the following: secondary, primary, info, warning, dark, danger."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the tag."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/tags/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` integer

The ID of the todo to be updated. Example: `1`

`title` string

The new title of the todo. Example: `Finish report`

`color` string

The new priority of the todo. Must be one of "primary", "secondary", "warning", "dark", "info","danger" or "success". Example: `secondary`

## Remove the specified tag.

requires authentication

This endpoint deletes a tag item based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/tags/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/tags/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
      "error": false,
      "message": "Tag deleted successfully.",
      "id": 1,
      "title": "Tag Title"
      "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Tag not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the tag."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/tags/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the todo to be deleted. Example: `1`

# User Management

## List or search users.

requires authentication

This endpoint retrieves a list of users based on various filters. The user must be authenticated to perform this action. The request allows filtering by status, search term, role, type, type_id, and other parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/users/1?search=John&sort=id&order=ASC&status=1&role_ids[]=1&role_ids[]=2&type=project&type_id=3&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/users/1"
    );

    const params = {
        "search": "John",
        "sort": "id",
        "order": "ASC",
        "status": "1",
        "role_ids[0]": "1",
        "role_ids[1]": "2",
        "type": "project",
        "type_id": "3",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Users retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 219,
                "first_name": "Test",
                "last_name": "Test",
                "role": "Member",
                "email": "test@gmail.com",
                "phone": "+91 1111111111",
                "dob": "09-08-2024",
                "doj": "09-08-2024",
                "address": "Test",
                "city": "Test",
                "state": "Test",
                "country": "Test",
                "zip": "111-111",
                "photo": "https://test-taskify.infinitietech.com/storage/photos/K0OAOzWyoeD0ZXBzgsaeHZUZERbOTKRljRIYOEYU.png",
                "status": 1,
                "created_at": "09-08-2024 17:04:29",
                "updated_at": "09-08-2024 17:04:29",
                "assigned": {
                    "projects": 0,
                    "tasks": 0
                }
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "User not found",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Users not found",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Project not found",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Task not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/users/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the user to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter users by id, first name, last name, phone, or email. Example: `John`

`sort` string optional

optional The field to sort by. Defaults to "id". Sortable fields include: id, phone, dob, doj, created_at, and updated_at. Example: `id`

`order` string optional

optional The sort order, either "ASC" or "DESC". Defaults to "DESC". Example: `ASC`

`status` integer optional

optional The status ID to filter users by, either 0 or 1. Example: `1`

`role_ids` string[] optional

optional The role IDs to filter users by.

`type` string optional

optional The type of filter to apply, either "project" or "task". Example: `project`

`type_id` integer optional

optional The ID associated with the type filter. Example: `3`

`limit` integer optional

optional The number of users per page for pagination. Example: `10`

`offset` integer optional

optional The offset for pagination, indicating the starting point of results. Example: `0`

## Create a new user.

requires authentication

This endpoint creates a new user with the provided details. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/users/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: multipart/form-data" \
        --form "first_name=John"\
        --form "last_name=Doe"\
        --form "email=john.doe@example.com"\
        --form "password=password123"\
        --form "password_confirmation=password123"\
        --form "address=123 Main St"\
        --form "phone=1234567890"\
        --form "country_code=+91"\
        --form "country_iso_code=in"\
        --form "city=New York"\
        --form "state=NY"\
        --form "country=USA"\
        --form "zip=10001"\
        --form "dob=1990-01-01"\
        --form "doj=2024-01-01"\
        --form "role=1"\
        --form "status=1"\
        --form "require_ev=1"\
        --form "profile=@/tmp/phpIMrfhq"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/users/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "multipart/form-data",
    };

    const body = new FormData();
    body.append('first_name', 'John');
    body.append('last_name', 'Doe');
    body.append('email', 'john.doe@example.com');
    body.append('password', 'password123');
    body.append('password_confirmation', 'password123');
    body.append('address', '123 Main St');
    body.append('phone', '1234567890');
    body.append('country_code', '+91');
    body.append('country_iso_code', 'in');
    body.append('city', 'New York');
    body.append('state', 'NY');
    body.append('country', 'USA');
    body.append('zip', '10001');
    body.append('dob', '1990-01-01');
    body.append('doj', '2024-01-01');
    body.append('role', '1');
    body.append('status', '1');
    body.append('require_ev', '1');
    body.append('profile', document.querySelector('input[name="profile"]').files[0]);

    fetch(url, {
        method: "POST",
        headers,
        body,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "User created successfully.",
        "id": 219,
        "data": {
            "id": 219,
            "first_name": "Test",
            "last_name": "Test",
            "role": "Member",
            "email": "test@gmail.com",
            "phone": "+91 1111111111",
            "dob": "09-08-2024",
            "doj": "09-08-2024",
            "address": "Test",
            "city": "Test",
            "state": "Test",
            "country": "Test",
            "zip": "111-111",
            "photo": "https://test-taskify.infinitietech.com/storage/photos/K0OAOzWyoeD0ZXBzgsaeHZUZERbOTKRljRIYOEYU.png",
            "status": 1,
            "created_at": "09-08-2024 17:04:29",
            "updated_at": "09-08-2024 17:04:29",
            "assigned": {
                "projects": 0,
                "tasks": 0
            }
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "first_name": [
                "The first name field is required."
            ],
            "last_name": [
                "The last name field is required."
            ],
            "email": [
                "The email has already been taken."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "User couldn’t be created, please make sure email settings are operational."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/users/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `multipart/form-data`

#### Body Parameters

`first_name` string

The first name of the user. Example: `John`

`last_name` string

The last name of the user. Example: `Doe`

`email` string

The email address of the user. Example: `john.doe@example.com`

`password` string

The password for the user. Example: `password123`

`password_confirmation` string

The password confirmation. Example: `password123`

`address` string optional

nullable The address of the user. Example: `123 Main St`

`phone` string optional

nullable The phone number of the user. Example: `1234567890`

`country_code` string optional

nullable The country code for the phone number. Example: `+91`

`country_iso_code` string optional

nullable The ISO code for the phone number. Example: `in`

`city` string optional

nullable The city of the user. Example: `New York`

`state` string optional

nullable The state of the user. Example: `NY`

`country` string optional

nullable The country of the user. Example: `USA`

`zip` string optional

nullable The ZIP code of the user. Example: `10001`

`dob` string optional

nullable The date of birth of the user in the format specified in the general settings. Example: `1990-01-01`

`doj` string optional

nullable The date of joining in the format specified in the general settings. Example: `2024-01-01`

`role` integer

The ID of the role for the user. Example: `1`

`profile` file optional

nullable The profile photo of the user. Example: `/tmp/phpIMrfhq`

`status` boolean `true` `false`

0 or 1. If Deactivated (0), the user won't be able to log in to their account. Can only specify if `is_admin_or_has_all_data_access` is true for the logged-in user, else 0 will be considered by default. Example: `true`

`require_ev` boolean `true` `false`

0 or 1. If Yes (1) is selected, the user will receive a verification link via email. Can only specify if `is_admin_or_has_all_data_access` is true for the logged-in user, else 1 will be considered by default. Example: `true`

## Update an existing user.

requires authentication

This endpoint updates the details of an existing user. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/users/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: multipart/form-data" \
        --form "id=1"\
        --form "first_name=John"\
        --form "last_name=Doe"\
        --form "email=john.doe@example.com"\
        --form "password=newpassword123"\
        --form "password_confirmation=newpassword123"\
        --form "address=123 Main St"\
        --form "phone=1234567890"\
        --form "country_code=+91"\
        --form "country_iso_code=in"\
        --form "city=New York"\
        --form "state=NY"\
        --form "country=USA"\
        --form "zip=10001"\
        --form "dob=1990-01-01"\
        --form "doj=2024-01-01"\
        --form "role=1"\
        --form "status=1"\
        --form "profile=@/tmp/phpvj1zX0"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/users/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "multipart/form-data",
    };

    const body = new FormData();
    body.append('id', '1');
    body.append('first_name', 'John');
    body.append('last_name', 'Doe');
    body.append('email', 'john.doe@example.com');
    body.append('password', 'newpassword123');
    body.append('password_confirmation', 'newpassword123');
    body.append('address', '123 Main St');
    body.append('phone', '1234567890');
    body.append('country_code', '+91');
    body.append('country_iso_code', 'in');
    body.append('city', 'New York');
    body.append('state', 'NY');
    body.append('country', 'USA');
    body.append('zip', '10001');
    body.append('dob', '1990-01-01');
    body.append('doj', '2024-01-01');
    body.append('role', '1');
    body.append('status', '1');
    body.append('profile', document.querySelector('input[name="profile"]').files[0]);

    fetch(url, {
        method: "POST",
        headers,
        body,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "User updated successfully.",
        "id": 219,
        "data": {
            "id": 219,
            "first_name": "APII",
            "last_name": "User",
            "role": "Member",
            "email": "test@gmail.com",
            "phone": "+91 1111111111",
            "dob": "09-08-2024",
            "doj": "09-08-2024",
            "address": "Test adr",
            "city": "Test cty",
            "state": "Test ct",
            "country": "test ctr",
            "zip": "111-111",
            "photo": "https://test-taskify.infinitietech.com/storage/photos/28NcF6qzmIRiOhN9zrtEu5x1iN55OBspR9o1ONMO.webp",
            "status": "1",
            "created_at": "09-08-2024 17:04:29",
            "updated_at": "09-08-2024 18:32:10",
            "assigned": {
                "projects": 14,
                "tasks": 12
            }
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "first_name": [
                "The first name field is required."
            ],
            "last_name": [
                "The last name field is required."
            ],
            "email": [
                "The email has already been taken."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "User couldn't be updated."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/users/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `multipart/form-data`

#### Body Parameters

`id` integer

The ID of the user to be updated. Example: `1`

`first_name` string

The first name of the user. Example: `John`

`last_name` string

The last name of the user. Example: `Doe`

`email` string

The email address of the user. Example: `john.doe@example.com`

`password` string optional

nullable The new password for the user. Can only be updated if `is_admin_or_has_all_data_access` is true for the logged-in user. Example: `newpassword123`

`password_confirmation` string optional

required_with:password The password confirmation. Example: `newpassword123`

`address` string optional

nullable The address of the user. Example: `123 Main St`

`phone` string optional

nullable The phone number of the user. Example: `1234567890`

`country_code` string optional

nullable The country code for the phone number. Example: `+91`

`country_iso_code` string optional

nullable The ISO code for the phone number. Example: `in`

`city` string optional

nullable The city of the user. Example: `New York`

`state` string optional

nullable The state of the user. Example: `NY`

`country` string optional

nullable The country of the user. Example: `USA`

`zip` string optional

nullable The ZIP code of the user. Example: `10001`

`dob` string optional

nullable The date of birth of the user in the format specified in the general settings. Example: `1990-01-01`

`doj` string optional

nullable The date of joining in the format specified in the general settings. Example: `2024-01-01`

`role` integer

The ID of the role for the user. Example: `1`

`profile` file optional

nullable The new profile photo of the user. Example: `/tmp/phpvj1zX0`

`status` boolean `true` `false`

0 or 1. If Deactivated (0), the user won't be able to log in to their account. Can only specify status if `is_admin_or_has_all_data_access` is true for the logged-in user, else the current status will be considered by default. Example: `true`

## Remove the specified user.

requires authentication

This endpoint deletes a user based on the provided ID. The request must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/users/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/users/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "User deleted successfully.",
        "id": "1",
        "title": "John Doe",
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "User not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An internal server error occurred."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/users/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the user to be deleted. Example: `1`

# Client Management

## List or search clients.

requires authentication

This endpoint retrieves a list of clients based on various filters. The user must be authenticated to perform this action. The request allows filtering by status, search term, type, type_id, and other parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/clients/1?search=John&sort=id&order=ASC&status=1&type=project&type_id=3&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/clients/1"
    );

    const params = {
        "search": "John",
        "sort": "id",
        "order": "ASC",
        "status": "1",
        "type": "project",
        "type_id": "3",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Clients retrieved successfully",
        "total": 1,
        "clients": [
            {
                "id": 185,
                "first_name": "Client",
                "last_name": "Test",
                "company": "Test Company",
                "email": "client@test.com",
                "phone": "1 5555555555",
                "status": 1,
                "internal_purpose": 1,
                "created_at": "10-06-2024",
                "updated_at": "29-07-2024",
                "assigned": {
                    "projects": 0,
                    "tasks": 0
                }
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Client not found",
        "total": 0,
        "clients": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Clients not found",
        "total": 0,
        "clients": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Project not found",
        "total": 0,
        "clients": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Task not found",
        "total": 0,
        "clients": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/clients/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the client to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter clients by id, first name, last name, comapny, phone, or email. Example: `John`

`sort` string optional

optional The field to sort by. Defaults to "id". Sortable fields include: id, company, phone, created_at, and updated_at. Example: `id`

`order` string optional

optional The sort order, either "ASC" or "DESC". Defaults to "DESC". Example: `ASC`

`status` integer optional

optional The status ID to filter clients by, either 0 or 1. Example: `1`

`type` string optional

optional The type of filter to apply, either "project" or "task". Example: `project`

`type_id` integer optional

optional The ID associated with the type filter. Example: `3`

`limit` integer optional

optional The number of clients per page for pagination. Example: `10`

`offset` integer optional

optional The offset for pagination, indicating the starting point of results. Example: `0`

## Store a new client.

requires authentication

This endpoint creates a new client. The client must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/clients/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: multipart/form-data" \
        --form "first_name=John"\
        --form "last_name=Doe"\
        --form "company=Example Corp"\
        --form "email=john.doe@example.com"\
        --form "phone=1234567890"\
        --form "country_code=+91"\
        --form "country_iso_code=in"\
        --form "password=password123"\
        --form "password_confirmation=password123"\
        --form "address=123 Main St"\
        --form "city=New York"\
        --form "state=NY"\
        --form "country=USA"\
        --form "zip=10001"\
        --form "dob=1990-01-01"\
        --form "doj=2024-01-01"\
        --form "internal_purpose=on"\
        --form "status=1"\
        --form "require_ev=1"\
        --form "profile=@/tmp/phpErji6x"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/clients/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "multipart/form-data",
    };

    const body = new FormData();
    body.append('first_name', 'John');
    body.append('last_name', 'Doe');
    body.append('company', 'Example Corp');
    body.append('email', 'john.doe@example.com');
    body.append('phone', '1234567890');
    body.append('country_code', '+91');
    body.append('country_iso_code', 'in');
    body.append('password', 'password123');
    body.append('password_confirmation', 'password123');
    body.append('address', '123 Main St');
    body.append('city', 'New York');
    body.append('state', 'NY');
    body.append('country', 'USA');
    body.append('zip', '10001');
    body.append('dob', '1990-01-01');
    body.append('doj', '2024-01-01');
    body.append('internal_purpose', 'on');
    body.append('status', '1');
    body.append('require_ev', '1');
    body.append('profile', document.querySelector('input[name="profile"]').files[0]);

    fetch(url, {
        method: "POST",
        headers,
        body,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Client created successfully.",
        "data": {
            "id": 183,
            "first_name": "API",
            "last_name": "Client",
            "company": "test",
            "email": "777@gmail.com",
            "phone": "+91 1111111111",
            "address": "Test adr",
            "city": "Test cty",
            "state": "Test ct",
            "country": "test ctr",
            "zip": "111-111",
            "photo": "https://test-taskify.infinitietech.com/storage/photos/a5xT73btrbk7sybc0768Bv8xlBn16ROK1Znf1Ddc.webp",
            "status": "1",
            "internal_purpose": 0,
            "created_at": "09-08-2024 19:22:17",
            "updated_at": "09-08-2024 20:10:06",
            "assigned": {
                "projects": 0,
                "tasks": 0
            }
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "first_name": [
                "The first name field is required."
            ],
            "last_name": [
                "The last name field is required."
            ],
            "email": [
                "The email has already been taken."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Client couldn’t be created, please make sure email settings are operational."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/clients/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `multipart/form-data`

#### Body Parameters

`first_name` string

The first name of the client. Example: `John`

`last_name` string

The last name of the client. Example: `Doe`

`company` string optional

nullable The company of the client. Example: `Example Corp`

`email` string

The email address of the client. Example: `john.doe@example.com`

`phone` string optional

nullable The phone number of the client. Example: `1234567890`

`country_code` string optional

nullable The country code for the phone number. Example: `+91`

`country_iso_code` string optional

nullable The ISO code for the phone number. Example: `in`

`password` string

The password for the client. Must be confirmed and at least 6 characters long. Example: `password123`

`password_confirmation` string

The password confirmation. Required if password is provided. Example: `password123`

`address` string optional

nullable The address of the client. Example: `123 Main St`

`city` string optional

nullable The city of the client. Example: `New York`

`state` string optional

nullable The state of the client. Example: `NY`

`country` string optional

nullable The country of the client. Example: `USA`

`zip` string optional

nullable The ZIP code of the client. Example: `10001`

`dob` string optional

nullable The date of birth of the user in the format specified in the general settings. Example: `1990-01-01`

`doj` string optional

nullable The date of joining in the format specified in the general settings. Example: `2024-01-01`

`internal_purpose` string optional

nullable Set to 'on' if the client is for internal purposes. Example: `on`

`profile` file optional

nullable The profile photo of the client. Example: `/tmp/phpErji6x`

`status` boolean `true` `false`

0 or 1. If Deactivated (0), the client won't be able to log in to their account. Can only specify if `is_admin_or_has_all_data_access` is true for the logged-in user, else 0 will be considered by default. Example: `true`

`require_ev` boolean `true` `false`

0 or 1. If Yes (1) is selected, the client will receive a verification link via email. Can only specify if `is_admin_or_has_all_data_access` is true for the logged-in user, else 1 will be considered by default. Example: `true`

## Update an existing client.

requires authentication

This endpoint updates the details of an existing client. The client must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/clients/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: multipart/form-data" \
        --form "id=1"\
        --form "first_name=John"\
        --form "last_name=Doe"\
        --form "company=XYZ"\
        --form "email=john.doe@example.com"\
        --form "password=newpassword123"\
        --form "password_confirmation=newpassword123"\
        --form "address=123 Main St"\
        --form "phone=1234567890"\
        --form "country_code=+91"\
        --form "country_iso_code=in"\
        --form "city=New York"\
        --form "state=NY"\
        --form "country=USA"\
        --form "zip=10001"\
        --form "dob=1990-01-01"\
        --form "doj=2024-01-01"\
        --form "internal_purpose=on"\
        --form "status=1"\
        --form "require_ev=1"\
        --form "profile=@/tmp/phpEXBhAv"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/clients/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "multipart/form-data",
    };

    const body = new FormData();
    body.append('id', '1');
    body.append('first_name', 'John');
    body.append('last_name', 'Doe');
    body.append('company', 'XYZ');
    body.append('email', 'john.doe@example.com');
    body.append('password', 'newpassword123');
    body.append('password_confirmation', 'newpassword123');
    body.append('address', '123 Main St');
    body.append('phone', '1234567890');
    body.append('country_code', '+91');
    body.append('country_iso_code', 'in');
    body.append('city', 'New York');
    body.append('state', 'NY');
    body.append('country', 'USA');
    body.append('zip', '10001');
    body.append('dob', '1990-01-01');
    body.append('doj', '2024-01-01');
    body.append('internal_purpose', 'on');
    body.append('status', '1');
    body.append('require_ev', '1');
    body.append('profile', document.querySelector('input[name="profile"]').files[0]);

    fetch(url, {
        method: "POST",
        headers,
        body,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Client updated successfully.",
        "data": {
            "id": 183,
            "first_name": "API",
            "last_name": "Client",
            "company": "test",
            "email": "777@gmail.com",
            "phone": "+91 1111111111",
            "address": "Test adr",
            "city": "Test cty",
            "state": "Test ct",
            "country": "test ctr",
            "zip": "111-111",
            "photo": "https://test-taskify.infinitietech.com/storage/photos/a5xT73btrbk7sybc0768Bv8xlBn16ROK1Znf1Ddc.webp",
            "status": "1",
            "internal_purpose": 0,
            "created_at": "09-08-2024 19:22:17",
            "updated_at": "09-08-2024 20:10:06",
            "assigned": {
                "projects": 0,
                "tasks": 0
            }
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "first_name": [
                "The first name field is required."
            ],
            "last_name": [
                "The last name field is required."
            ],
            "email": [
                "The email has already been taken."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Client couldn't be updated."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/clients/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `multipart/form-data`

#### Body Parameters

`id` integer

The ID of the client to be updated. Example: `1`

`first_name` string

The first name of the client. Example: `John`

`last_name` string

The last name of the client. Example: `Doe`

`company` string optional

nullable The company of the client. Example: `XYZ`

`email` string

The email address of the client. Example: `john.doe@example.com`

`password` string optional

nullable The new password for the client. Can only be updated if `is_admin_or_has_all_data_access` is true for the logged-in user. Example: `newpassword123`

`password_confirmation` string optional

required_with:password The password confirmation. Example: `newpassword123`

`address` string optional

nullable The address of the client. Example: `123 Main St`

`phone` string optional

nullable The phone number of the client. Example: `1234567890`

`country_code` string optional

nullable The country code for the phone number. Example: `+91`

`country_iso_code` string optional

nullable The ISO code for the phone number. Example: `in`

`city` string optional

nullable The city of the client. Example: `New York`

`state` string optional

nullable The state of the client. Example: `NY`

`country` string optional

nullable The country of the client. Example: `USA`

`zip` string optional

nullable The ZIP code of the client. Example: `10001`

`dob` string optional

nullable The date of birth of the user in the format specified in the general settings. Example: `1990-01-01`

`doj` string optional

nullable The date of joining in the format specified in the general settings. Example: `2024-01-01`

`internal_purpose` string optional

nullable Set to 'on' if the client is for internal purposes. Example: `on`

`profile` file optional

nullable The new profile photo of the client. Example: `/tmp/phpEXBhAv`

`status` boolean `true` `false`

0 or 1. If Deactivated (0), the client won't be able to log in to their account. Can only specify if `is_admin_or_has_all_data_access` is true for the logged-in user, else the current status will be considered by default. Example: `true`

`require_ev` boolean `true` `false`

0 or 1. If Yes (1) is selected, the client will receive a verification link via email. Can only specify if `is_admin_or_has_all_data_access` is true for the logged-in user, else the current require_ev will be considered by default. Example: `true`

## Remove the specified client.

requires authentication

This endpoint deletes a client based on the provided ID. The request must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/clients/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/clients/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "data": {
            "error": false,
            "message": "Client deleted successfully.",
            "id": "1",
            "title": "Jane Doe",
            "data": []
        }
    }

> Example response (200):

    {
        "data": {
            "error": true,
            "message": "Client not found.",
            "data": []
        }
    }

> Example response (500):

    {
        "data": {
            "error": true,
            "message": "An internal server error occurred."
        }
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/clients/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the client to be deleted. Example: `1`

# Workspace Management

## Create a new workspace.

requires authentication

This endpoint creates a new workspace with the provided details. The user must be authenticated to perform this action. The request validates various fields, including title and participants.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/workspaces/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"Design Team\",
        \"user_ids\": \"[1, 2, 3]\",
        \"client_ids\": \"[5, 6]\",
        \"primaryWorkspace\": \"on\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/workspaces/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "Design Team",
        "user_ids": "[1, 2, 3]",
        "client_ids": "[5, 6]",
        "primaryWorkspace": "on"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Workspace created successfully.",
        "id": 438,
        "data": {
            "id": 438,
            "title": "Design Team",
            "is_primary": true,
            "users": [
                {
                    "id": 7,
                    "first_name": "Madhavan",
                    "last_name": "Vaidya",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png"
                }
            ],
            "clients": [
                {
                    "id": 103,
                    "first_name": "Test",
                    "last_name": "Test",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                }
            ],
            "created_at": "07-08-2024 14:38:51",
            "updated_at": "07-08-2024 14:38:51"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "title": [
                "The title field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the workspace."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/workspaces/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`title` string

The title of the workspace. Example: `Design Team`

`user_ids` array|null optional

optional Array of user IDs to be associated with the workspace. Example: `[1, 2, 3]`

`client_ids` array|null optional

optional Array of client IDs to be associated with the workspace. Example: `[5, 6]`

`primaryWorkspace` string optional

optional Indicates if this workspace should be set as primary. Can only specify if `is_admin_or_has_all_data_access` is true for the logged-in user, else it will be considered 0 by default. The value should be 'on' to set as primary. Example: `on`

## List or search workspaces.

requires authentication

This endpoint retrieves a list of workspaces based on various filters. The user must be authenticated to perform this action. The request allows filtering by user, client, and other parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/workspaces/1?search=Workspace&sort=title&order=ASC&user_id=1&client_id=5&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/workspaces/1"
    );

    const params = {
        "search": "Workspace",
        "sort": "title",
        "order": "ASC",
        "user_id": "1",
        "client_id": "5",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Workspaces retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 351,
                "title": "Workspace Title",
                "is_primary": 0,
                "users": [
                    {
                        "id": 7,
                        "first_name": "Madhavan",
                        "last_name": "Vaidya",
                        "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png"
                    }
                ],
                "clients": [
                    {
                        "id": 12,
                        "first_name": "Client",
                        "last_name": "Name",
                        "photo": "https://test-taskify.infinitietech.com/storage/photos/client-photo.png"
                    }
                ],
                "created_at": "20-07-2024 17:50:09",
                "updated_at": "21-07-2024 19:08:16"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Workspace not found",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Workspaces not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/workspaces/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the workspace to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter workspaces by title or id. Example: `Workspace`

`sort` string optional

optional The field to sort by. Defaults to "id". Sortable fields include: id, title, created_at, and updated_at. Example: `title`

`order` string optional

optional The sort order, either "ASC" or "DESC". Defaults to "DESC". Example: `ASC`

`user_id` integer optional

optional The user ID to filter workspaces by. Example: `1`

`client_id` integer optional

optional The client ID to filter workspaces by. Example: `5`

`limit` integer optional

optional The number of workspaces per page for pagination. Example: `10`

`offset` integer optional

optional The offset for pagination, indicating the starting point of results. Example: `0`

## Update an existing workspace.

requires authentication

This endpoint updates the details of an existing workspace. The user must be authenticated to perform this action. The request validates various fields, including title and participants.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/workspaces/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 438,
        \"title\": \"Design Team\",
        \"user_ids\": \"[1, 2, 3]\",
        \"client_ids\": \"[5, 6]\",
        \"primaryWorkspace\": \"on\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/workspaces/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 438,
        "title": "Design Team",
        "user_ids": "[1, 2, 3]",
        "client_ids": "[5, 6]",
        "primaryWorkspace": "on"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Workspace updated successfully.",
        "id": 438,
        "data": {
            "id": 438,
            "title": "Design Team",
            "is_primary": true,
            "users": [
                {
                    "id": 7,
                    "first_name": "Madhavan",
                    "last_name": "Vaidya",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png"
                }
            ],
            "clients": [
                {
                    "id": 103,
                    "first_name": "Test",
                    "last_name": "Test",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                }
            ],
            "created_at": "07-08-2024 14:38:51",
            "updated_at": "07-08-2024 14:38:51"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "title": [
                "The title field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the workspace."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/workspaces/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` integer

The ID of the workspace to update. Example: `438`

`title` string

The new title of the workspace. Example: `Design Team`

`user_ids` array|null optional

optional Array of user IDs to be associated with the workspace. Example: `[1, 2, 3]`

`client_ids` array|null optional

optional Array of client IDs to be associated with the workspace. Example: `[5, 6]`

`primaryWorkspace` string optional

optional Indicates if this workspace should be set as primary. Can only specify if `is_admin_or_has_all_data_access` is true for the logged-in user, else current value will be considered by default. The value should be 'on' to set as primary. Example: `on`

## Remove the specified workspace.

requires authentication

This endpoint deletes a workspace based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/workspaces/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/workspaces/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Workspace deleted successfully.",
        "id": "60",
        "title": "Workspace Title",
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Workspace not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the workspace."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/workspaces/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the workspace to be deleted. Example: `1`

## Set or remove a default workspace for the authenticated user.

requires authentication

This endpoint updates whether a workspace is set as the default workspace for the user. The user must be authenticated to perform this action.

> Example request:

    curl --request PATCH \
        "https://dev-taskify.taskhub.company/api/workspaces/5/default" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"is_default\": false
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/workspaces/5/default"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "is_default": false
    };

    fetch(url, {
        method: "PATCH",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Default status updated successfully"
    "data":[Workspace data here]
    }

> Example response (404):

    {
        "error": true,
        "message": "Workspace not found",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "Failed to update default workspace"
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

PATCH `api/workspaces/{id}/default`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the workspace to update. Example: `5`

#### Body Parameters

`is_default` boolean `true` `false`

Indicates whether the workspace should be set as default. Use 1 for setting as default and 0 for removing it as default. Example: `false`

## Remove the authenticated user from the current workspace.

requires authentication

This endpoint removes the authenticated user from the workspace they are currently in. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/workspaces/remove-participant" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/workspaces/remove-participant"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
      "error": false,
      "message": "Removed from workspace successfully.",
      "data": {
        "workspace_id": 1
      }
    }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while removing the participant from the workspace."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/workspaces/remove-participant`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

# Meeting Management

## Create a new meeting.

requires authentication

This endpoint creates a new meeting with the provided details. The user must be authenticated to perform this action. The request validates various fields, including title, start and end dates, start and end times, and participant IDs.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/meetings/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"Project Kickoff\",
        \"start_date\": \"25-07-2024\",
        \"end_date\": \"25-07-2024\",
        \"start_time\": \"10:00\",
        \"end_time\": \"11:00\",
        \"user_ids\": [
            1,
            2,
            3
        ],
        \"client_ids\": [
            4,
            5
        ]
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/meetings/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "Project Kickoff",
        "start_date": "25-07-2024",
        "end_date": "25-07-2024",
        "start_time": "10:00",
        "end_time": "11:00",
        "user_ids": [
            1,
            2,
            3
        ],
        "client_ids": [
            4,
            5
        ]
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Meeting created successfully.",
        "id": 119,
        "data": {
            "id": 119,
            "title": "From API",
            "start_date": "25-07-2024",
            "start_time": "15:00:00",
            "end_date": "25-08-2024",
            "end_time": "11:41:05",
            "users": [
                {
                    "id": 7,
                    "first_name": "Madhavan",
                    "last_name": "Vaidya",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png"
                }
            ],
            "clients": [
                {
                    "id": 173,
                    "first_name": "666",
                    "last_name": "666",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                }
            ],
            "status": "Ongoing",
            "created_at": "07-08-2024 17:11:05",
            "updated_at": "07-08-2024 17:11:05"
        }
    }

> Example response (422):

    {
     "error": true,
     "message": "Validation errors occurred",
     "errors": {
       "title": ["The title field is required."],
       "start_date": ["The start date field is required."],
       ...
     }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the meeting."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/meetings/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`title` string

The title of the meeting. Example: `Project Kickoff`

`start_date` string

The start date of the meeting in the format specified in the general settings. Example: `25-07-2024`

`end_date` string

The end date of the meeting in the format specified in the general settings. Example: `25-07-2024`

`start_time` string

The start time of the meeting in the format HH:MM. Example: `10:00`

`end_time` string

The end time of the meeting in the format HH:MM. Example: `11:00`

`user_ids` string[] optional

nullable An array of user IDs to be assigned to the meeting.

`client_ids` string[] optional

nullable An array of client IDs to be assigned to the meeting.

## List or search meetings.

requires authentication

This endpoint retrieves a list of meetings based on various filters. The user must be authenticated to perform this action. The request allows filtering by status, user, client, date ranges, and other parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/meetings/1?search=Meeting&sort=title&order=ASC&status=ongoing&user_id=1&client_id=5&start_date_from=2024-01-01&start_date_to=2024-12-31&end_date_from=2024-01-01&end_date_to=2024-12-31&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/meetings/1"
    );

    const params = {
        "search": "Meeting",
        "sort": "title",
        "order": "ASC",
        "status": "ongoing",
        "user_id": "1",
        "client_id": "5",
        "start_date_from": "2024-01-01",
        "start_date_to": "2024-12-31",
        "end_date_from": "2024-01-01",
        "end_date_to": "2024-12-31",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Meetings retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 351,
                "title": "Project Kickoff",
                "start_date": "2024-07-01",
                "start_time": "10:00:00",
                "end_date": "2024-07-01",
                "end_time": "11:00:00",
                "users": [
                    {
                        "id": 7,
                        "first_name": "Madhavan",
                        "last_name": "Vaidya",
                        "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png"
                    }
                ],
                "clients": [],
                "status": "Ongoing",
                "created_at": "14-06-2024 17:50:09",
                "updated_at": "17-06-2024 19:08:16"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Meeting not found",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Meetings not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/meetings/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the meeting to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter meetings by title or id. Example: `Meeting`

`sort` string optional

optional The field to sort by. Defaults to "id". Sortable fields include: id, title, start_date_time, end_date_time, created_at, and updated_at. Example: `title`

`order` string optional

optional The sort order, either "ASC" or "DESC". Defaults to "DESC". Example: `ASC`

`status` string optional

optional The status of the meeting to filter by. Can be "ongoing", "ended", or "yet_to_start". Example: `ongoing`

`user_id` integer optional

optional The user ID to filter meetings by. Example: `1`

`client_id` integer optional

optional The client ID to filter meetings by. Example: `5`

`start_date_from` string optional

optional The start date range's start in YYYY-MM-DD format. Example: `2024-01-01`

`start_date_to` string optional

optional The start date range's end in YYYY-MM-DD format. Example: `2024-12-31`

`end_date_from` string optional

optional The end date range's start in YYYY-MM-DD format. Example: `2024-01-01`

`end_date_to` string optional

optional The end date range's end in YYYY-MM-DD format. Example: `2024-12-31`

`limit` integer optional

optional The number of meetings per page for pagination. Example: `10`

`offset` integer optional

optional The offset for pagination, indicating the starting point of results. Example: `0`

## Update an existing meeting.

requires authentication

This endpoint updates an existing meeting with the provided details. The user must be authenticated to perform this action. The request validates various fields, including title, dates, and times.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/meetings/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 1,
        \"title\": \"Updated Meeting Title\",
        \"start_date\": \"2024-08-01\",
        \"end_date\": \"2024-08-31\",
        \"start_time\": \"09:00\",
        \"end_time\": \"10:00\",
        \"user_ids\": \"[2, 3]\",
        \"client_ids\": \"[5, 6]\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/meetings/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 1,
        "title": "Updated Meeting Title",
        "start_date": "2024-08-01",
        "end_date": "2024-08-31",
        "start_time": "09:00",
        "end_time": "10:00",
        "user_ids": "[2, 3]",
        "client_ids": "[5, 6]"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Meeting updated successfully.",
        "id": 119,
        "data": {
            "id": 119,
            "title": "From API",
            "start_date": "25-07-2024",
            "start_time": "15:00:00",
            "end_date": "25-08-2024",
            "end_time": "11:45:15",
            "users": [
                {
                    "id": 7,
                    "first_name": "Madhavan",
                    "last_name": "Vaidya",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png"
                }
            ],
            "clients": [
                {
                    "id": 173,
                    "first_name": "666",
                    "last_name": "666",
                    "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                }
            ],
            "status": "Ongoing",
            "created_at": "07-08-2024 17:11:05",
            "updated_at": "07-08-2024 17:15:15"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "id": [
                "The meeting ID is required.",
                "The meeting ID does not exist in our records."
            ],
            "start_date": [
                "The start date must be before or equal to the end date."
            ],
            "start_time": [
                "The start time field is required."
            ],
            "end_time": [
                "The end time field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the meeting."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/meetings/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` integer

The ID of the meeting to update. Example: `1`

`title` string

The title of the meeting. Example: `Updated Meeting Title`

`start_date` string

The start date of the meeting in the format specified in the general settings. Example: `2024-08-01`

`end_date` string

The end date of the meeting in the format specified in the general settings. Example: `2024-08-31`

`start_time` string

The start time of the meeting. Example: `09:00`

`end_time` string

The end time of the meeting. Example: `10:00`

`user_ids` array|null optional

optional Array of user IDs to be associated with the meeting. Example: `[2, 3]`

`client_ids` array|null optional

optional Array of client IDs to be associated with the meeting. Example: `[5, 6]`

## Remove the specified meeting.

requires authentication

This endpoint deletes a meeting based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/meetings/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/meetings/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Meeting deleted successfully.",
        "id": 1,
        "title": "Meeting Title",
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Meeting not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the meeting."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/meetings/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the meeting to be deleted. Example: `1`

# Todo Management

## Create a new todo.

requires authentication

This endpoint creates a new todo item with the specified title, priority, and description. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/todos/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"Finish report\",
        \"priority\": \"medium\",
        \"description\": \"Complete the report by end of day\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/todos/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "Finish report",
        "priority": "medium",
        "description": "Complete the report by end of day"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Todo created successfully.",
        "id": 36,
        "data": {
            "id": 36,
            "title": "test",
            "description": "test",
            "priority": "low",
            "is_completed": 0,
            "created_at": "07-08-2024 16:30:09",
            "updated_at": "07-08-2024 16:30:09"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "title": [
                "The title field is required."
            ],
            "priority": [
                "The priority must be one of the following: low, medium, high."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the todo."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/todos/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`title` string

The title of the todo. Example: `Finish report`

`priority` string

The priority of the todo. Must be one of "low", "medium", or "high". Example: `medium`

`description` string optional

optional A description of the todo. Example: `Complete the report by end of day`

## List or search todos.

requires authentication

This endpoint retrieves a list of todos based on various filters. The user must be authenticated to perform this action. The request allows filtering by search term, status, and pagination parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/todos/1?search=Test&sort=created_at&order=asc&status=completed&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/todos/1"
    );

    const params = {
        "search": "Test",
        "sort": "created_at",
        "order": "asc",
        "status": "completed",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Todos retrieved successfully.",
        "total": 1,
        "data": [
            {
                "id": 35,
                "title": "test",
                "description": "test",
                "priority": "low",
                "is_completed": 0,
                "created_at": "07-08-2024 15:28:22",
                "updated_at": "07-08-2024 15:28:22"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Todo not found.",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Todos not found",
        "total": 0,
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while retrieving the todos."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/todos/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the todo to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter todos by id, title, or description. Example: `Test`

`sort` string optional

optional The field to sort by. Defaults to "is_completed". All fields are sortable. Example: `created_at`

`order` string optional

optional The sort order, either "asc" or "desc". Defaults to "desc". Example: `asc`

`status` string optional

optional The status to filter todos by. Example: `completed`

`limit` integer optional

optional The number of todos per page for pagination. Defaults to 10. Example: `10`

`offset` integer optional

optional The offset for pagination, indicating the starting point of results. Defaults to 0. Example: `0`

## Update an existing todo.

requires authentication

This endpoint updates an existing todo item with the specified title, priority, and description. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/todos/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 1,
        \"title\": \"Finish report\",
        \"priority\": \"medium\",
        \"description\": \"Complete the report by end of day\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/todos/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 1,
        "title": "Finish report",
        "priority": "medium",
        "description": "Complete the report by end of day"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Todo updated successfully.",
    "id": "36",
    "data": {
      "id": 36,
      "is_completed": 0,
      "title": "test",
      "priority": "low",
      "description": "test",
      "created_at": "07-08-2024 16:30:09",
      "updated_at": "07-08-2024 16:30:09"
    }
    }

    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "id": [
                "The id field is required."
            ],
            "title": [
                "The title field is required."
            ],
            "priority": [
                "The priority must be one of the following: low, medium, high."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the todo."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/todos/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` integer

The ID of the todo to be updated. Example: `1`

`title` string

The new title of the todo. Example: `Finish report`

`priority` string

The new priority of the todo. Must be one of "low", "medium", or "high". Example: `medium`

`description` string optional

optional A new description for the todo. Example: `Complete the report by end of day`

## Update the completion status of a todo.

requires authentication

This endpoint updates the completion status of a specified todo item. The user must be authenticated to perform this action.

> Example request:

    curl --request PATCH \
        "https://dev-taskify.taskhub.company/api/todos/1/status" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"status\": true
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/todos/1/status"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "status": true
    };

    fetch(url, {
        method: "PATCH",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Status updated successfully.",
        "id": "60",
        "activity_message": "Madhavan Vaidya marked todo iouyhgyu as Completed",
        "data": {
            "id": 60,
            "title": "iouyhgyu",
            "description": "ty8uifyu",
            "priority": "medium",
            "is_completed": 1,
            "created_at": "10-08-2024 10:28:59",
            "updated_at": "12-08-2024 18:08:14"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "id": [
                "The id field is required."
            ],
            "status": [
                "The status field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Status couldn't be updated."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

PATCH `api/todos/{id}/status`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the todo whose status is to be updated. Example: `1`

#### Body Parameters

`status` boolean `true` `false`

The new completion status of the todo. Example: `true`

## Update the priority of a todo.

requires authentication

This endpoint updates the priority of a specified todo item. The user must be authenticated to perform this action. The priority must be one of 'low', 'medium', or 'high'.

> Example request:

    curl --request PATCH \
        "https://dev-taskify.taskhub.company/api/todos/1/priority" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"priority\": \"medium\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/todos/1/priority"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "priority": "medium"
    };

    fetch(url, {
        method: "PATCH",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Priority updated successfully.",
        "id": "60",
        "activity_message": "Madhavan Vaidya updated the priority of todo iouyhgyu from High to Low",
        "data": {
            "id": 60,
            "title": "iouyhgyu",
            "description": "ty8uifyu",
            "priority": "low",
            "is_completed": 1,
            "created_at": "10-08-2024 10:28:59",
            "updated_at": "12-08-2024 18:11:13"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "id": [
                "The id field is required."
            ],
            "priority": [
                "The priority field is required.",
                "The selected priority is invalid."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Priority couldn't be updated."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

PATCH `api/todos/{id}/priority`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the todo whose priority is to be updated. Example: `1`

#### Body Parameters

`priority` string

The new priority of the todo. Must be one of 'low', 'medium', or 'high'. Example: `medium`

## Remove the specified todo.

requires authentication

This endpoint deletes a todo item based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/todos/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/todos/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
      "error": false,
      "message": "Todo deleted successfully.",
      "id": 1,
      "title": "Todo Title"
      "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Todo not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the todo."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/todos/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the todo to be deleted. Example: `1`

# Note Management

## Create a new note.

requires authentication

This endpoint creates a new note item with the specified title, color, and description. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/notes/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"Meeting notes\",
        \"color\": \"warning\",
        \"description\": \"Notes from the client meeting\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/notes/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "Meeting notes",
        "color": "warning",
        "description": "Notes from the client meeting"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Note created successfully.",
    "id": 44,
    "data": {
      "id": 44,
      "title": "Test Note",
      "color": "info",
      "note_type" : "text|drawing",
      "drawing_data":"urlencoded(base64encoded(Svg)),
      "description": "test",
      "workspace_id": 6,
      "creator_id": "u_7",
      "created_at": "07-08-2024 16:24:57",
      "updated_at": "07-08-2024 16:24:57"
    }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "title": [
                "The title field is required."
            ],
            "color": [
                "The color must be one of the following: info, warning, danger."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the note."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/notes/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`title` string

The title of the note. Example: `Meeting notes`

`color` string

The color associated with the note. Must be one of "info", "warning", or "danger". Example: `warning`

`description` string optional

optional A description of the note. Example: `Notes from the client meeting`

## List or search notes.

requires authentication

This endpoint retrieves a list of notes based on various filters. The user must be authenticated to perform this action. The request allows filtering by search term and pagination parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/notes/1?search=Test&sort=created_at&order=asc&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/notes/1"
    );

    const params = {
        "search": "Test",
        "sort": "created_at",
        "order": "asc",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Notes retrieved successfully.",
        "total": 1,
        "data": [
            {
                "id": 43,
                "title": "upper",
                "color": "warning",
                "description": "jhdcsd",
                "workspace_id": 6,
                "creator_id": "u_7",
                "created_at": "07-08-2024 16:12:13",
                "updated_at": "07-08-2024 16:12:13"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Note not found.",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Notes not found",
        "total": 0,
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while retrieving the notes."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/notes/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the note to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter notes by id, title, or description. Example: `Test`

`sort` string optional

optional The field to sort by. Defaults to "is_completed". All fields are sortable. Example: `created_at`

`order` string optional

optional The sort order, either "asc" or "desc". Defaults to "desc". Example: `asc`

`limit` integer optional

optional The number of notes per page for pagination. Defaults to 10. Example: `10`

`offset` integer optional

optional The offset for pagination, indicating the starting point of results. Defaults to 0. Example: `0`

## Update an existing note.

requires authentication

This endpoint updates an existing note item with the specified title, color, and description. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/notes/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 1,
        \"title\": \"Meeting notes\",
        \"color\": \"warning\",
        \"description\": \"Notes from the client meeting\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/notes/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 1,
        "title": "Meeting notes",
        "color": "warning",
        "description": "Notes from the client meeting"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Note updated successfully.",
        "id": 44,
        "data": {
            "id": 44,
            "title": "Test Note",
            "color": "info",
            "description": "test",
            "workspace_id": 6,
            "creator_id": "u_7",
            "created_at": "07-08-2024 16:24:57",
            "updated_at": "07-08-2024 16:24:57"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "id": [
                "The id field is required."
            ],
            "title": [
                "The title field is required."
            ],
            "color": [
                "The color must be one of the following: info, warning, danger."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the note."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/notes/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` integer

The ID of the note to be updated. Example: `1`

`title` string

The new title of the note. Example: `Meeting notes`

`color` string

The new color of the note. Must be one of "info", "warning", or "danger". Example: `warning`

`description` string optional

optional A new description for the note. Example: `Notes from the client meeting`

## Remove the specified note.

requires authentication

This endpoint deletes a note item based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/notes/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/notes/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Note deleted successfully.",
        "id": 1,
        "title": "Note Title",
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Note not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the note."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/notes/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the note to be deleted. Example: `1`

# Leave Request Management

## Create a new leave request.

requires authentication

This endpoint creates a new leave request with the provided details. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/leave-requests/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"reason\": \"Family function\",
        \"from_date\": \"2024-08-05\",
        \"to_date\": \"2024-08-01\",
        \"from_time\": \"09:00\",
        \"to_time\": \"17:00\",
        \"status\": \"pending\",
        \"leaveVisibleToAll\": \"on\",
        \"visible_to_ids\": [
            1,
            2,
            3
        ],
        \"user_id\": 4,
        \"partialLeave\": \"on\",
        \"comment\": \"Approved due to exceptional circumstances\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/leave-requests/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "reason": "Family function",
        "from_date": "2024-08-05",
        "to_date": "2024-08-01",
        "from_time": "09:00",
        "to_time": "17:00",
        "status": "pending",
        "leaveVisibleToAll": "on",
        "visible_to_ids": [
            1,
            2,
            3
        ],
        "user_id": 4,
        "partialLeave": "on",
        "comment": "Approved due to exceptional circumstances"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Leave request created successfully.",
        "id": 187,
        "type": "leave_request",
        "data": {
            "id": 187,
            "user_name": "Madhavan Vaidya",
            "user_photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png",
            "action_by": null,
            "action_by_id": null,
            "from_date": "Wed, 07-08-2024",
            "to_date": "Wed, 07-08-2024",
            "type": "Full",
            "duration": "1 day",
            "reason": "Test",
            "status": "Pending",
            "visible_to": null,
            "created_at": "07-08-2024 18:31:28",
            "updated_at": "07-08-2024 18:31:28"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "reason": [
                "The reason field is required."
            ],
            "from_date": [
                "The from date field is required."
            ],
            "to_date": [
                "The to date field is required."
            ],
            "from_time": [
                "The from time field is required when partial leave is checked."
            ],
            "to_time": [
                "The to time field is required when partial leave is checked."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the leave request."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/leave-requests/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`reason` string

The reason for the leave. Example: `Family function`

`from_date` date

The start date of the leave in the format specified in the general settings. Example: `2024-08-05`

`to_date` date

The end date of the leave in the format specified in the general settings. Example: `2024-08-01`

`from_time` time optional

required_if:partialLeave,on The start time of the leave in HH:MM format. Example: `09:00`

`to_time` time optional

required_if:partialLeave,on The end time of the leave in HH:MM format. Example: `17:00`

`status` string optional

nullable The status of the leave request. Can be 'pending', 'approved', or 'rejected'. Example: `pending`

`leaveVisibleToAll` string optional

optional Set to 'on' if the leave should be visible to all users in the workspace. Example: `on`

`visible_to_ids` string[] optional

The IDs of users who can see the leave if it is not visible to all.

`user_id` integer optional

The ID of the user requesting the leave. Only admins or leave editors can specify this. Example: `4`

`partialLeave` string optional

optional Set to 'on' if the leave is partial (specific times within a day). Example: `on`

`comment` string optional

optional An optional comment that can only be set by admin or leave editor. Example: `Approved due to exceptional circumstances`

## List or search leave requests.

requires authentication

This endpoint retrieves a list of leave requests based on various filters. The user must be authenticated to perform this action. The request allows filtering by status, user, action_by, date ranges, type, and search term.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/leave-requests/1?search=Vacation&sort=id&order=ASC&status=pending&user_id=1&action_by_id=2&start_date_from=2024-01-01&start_date_to=2024-12-31&end_date_from=2024-01-01&end_date_to=2024-12-31&type=full&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/leave-requests/1"
    );

    const params = {
        "search": "Vacation",
        "sort": "id",
        "order": "ASC",
        "status": "pending",
        "user_id": "1",
        "action_by_id": "2",
        "start_date_from": "2024-01-01",
        "start_date_to": "2024-12-31",
        "end_date_from": "2024-01-01",
        "end_date_to": "2024-12-31",
        "type": "full",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Leave requests retrieved successfully",
        "total": 25,
        "data": [
            {
                "id": 175,
                "user_name": "Admin Test",
                "user_photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg",
                "action_by": null,
                "from_date": "Mon, 29-07-2024",
                "to_date": "Mon, 29-07-2024",
                "type": "Full",
                "duration": "1 day",
                "reason": "dsdsdsd",
                "status": "Pending",
                "visible_to": [
                    {
                        "id": 183,
                        "first_name": "Girish",
                        "last_name": "Thacker",
                        "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                    }
                ],
                "created_at": "29-07-2024 10:02:45",
                "updated_at": "29-07-2024 10:02:45"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Leave request not found",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Leave requests not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/leave-requests/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the leave request to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter leave requests by reason or id. Example: `Vacation`

`sort` string optional

optional The field to sort by. Defaults to "id". Sortable fields include: id, from_date, to_date, type, reason, status, action_by_id, created_at, and updated_at. Example: `id`

`order` string optional

optional The sort order, either "ASC" or "DESC". Defaults to "DESC". Example: `ASC`

`status` string optional

optional The status of the leave request to filter by. Can be "pending", "approved", "rejected", etc. Example: `pending`

`user_id` integer optional

optional The user ID to filter leave requests by. Example: `1`

`action_by_id` integer optional

optional The ID of the user who acted on the request to filter by. Example: `2`

`start_date_from` string optional

optional The start date range's start in YYYY-MM-DD format. Example: `2024-01-01`

`start_date_to` string optional

optional The start date range's end in YYYY-MM-DD format. Example: `2024-12-31`

`end_date_from` string optional

optional The end date range's start in YYYY-MM-DD format. Example: `2024-01-01`

`end_date_to` string optional

optional The end date range's end in YYYY-MM-DD format. Example: `2024-12-31`

`type` string optional

optional The type of leave request. Can be "full" or "partial". Example: `full`

`limit` integer optional

optional The number of leave requests per page for pagination. Example: `10`

`offset` integer optional

optional The offset for pagination, indicating the starting point of results. Example: `0`

## Update an existing leave request.

requires authentication

This endpoint updates an existing leave request with the provided details. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/leave-requests/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 1,
        \"reason\": \"Family function\",
        \"from_date\": \"2024-08-05\",
        \"to_date\": \"2024-08-01\",
        \"from_time\": \"09:00\",
        \"to_time\": \"17:00\",
        \"status\": \"pending\",
        \"leaveVisibleToAll\": \"on\",
        \"visible_to_ids\": [
            1,
            2,
            3
        ],
        \"partialLeave\": \"on\",
        \"comment\": \"Approved due to exceptional circumstances\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/leave-requests/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 1,
        "reason": "Family function",
        "from_date": "2024-08-05",
        "to_date": "2024-08-01",
        "from_time": "09:00",
        "to_time": "17:00",
        "status": "pending",
        "leaveVisibleToAll": "on",
        "visible_to_ids": [
            1,
            2,
            3
        ],
        "partialLeave": "on",
        "comment": "Approved due to exceptional circumstances"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Leave request updated successfully.",
        "id": 187,
        "type": "leave_request",
        "data": {
            "id": 187,
            "user_name": "Madhavan Vaidya",
            "user_photo": "https://test-taskify.infinitietech.com/storage/photos/yxNYBlFLALdLomrL0JzUY2USPLILL9Ocr16j4n2o.png",
            "action_by": null,
            "action_by_id": null,
            "from_date": "Wed, 07-08-2024",
            "to_date": "Wed, 07-08-2024",
            "type": "Full",
            "duration": "1 day",
            "reason": "Test",
            "status": "Pending",
            "visible_to": null,
            "created_at": "07-08-2024 18:31:28",
            "updated_at": "07-08-2024 18:31:28"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "id": [
                "The id field is required.",
                "The selected id is invalid."
            ],
            "reason": [
                "The reason field is required."
            ],
            "from_date": [
                "The from date field is required."
            ],
            "to_date": [
                "The to date field is required."
            ],
            "from_time": [
                "The from time field is required when partial leave is checked."
            ],
            "to_time": [
                "The to time field is required when partial leave is checked."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the leave request."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/leave-requests/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` integer

The ID of the leave request to be updated. Example: `1`

`reason` string

The reason for the leave. Example: `Family function`

`from_date` date

The start date of the leave in the format specified in the general settings. Example: `2024-08-05`

`to_date` date

The end date of the leave in the format specified in the general settings. Example: `2024-08-01`

`from_time` time optional

required_if:partialLeave,on The start time of the leave in HH:MM format. Example: `09:00`

`to_time` time optional

required_if:partialLeave,on The end time of the leave in HH:MM format. Example: `17:00`

`status` string optional

nullable The status of the leave request. Can be 'pending', 'approved', or 'rejected'. Example: `pending`

`leaveVisibleToAll` string optional

optional Set to 'on' if the leave should be visible to all users in the workspace. Example: `on`

`visible_to_ids` string[] optional

nullable The IDs of users who can see the leave if it is not visible to all.

`partialLeave` string optional

optional Set to 'on' if the leave is partial (specific times within a day). Example: `on`

`comment` string optional

optional An optional comment that can only be set by admin or leave editor. Example: `Approved due to exceptional circumstances`

## Remove the specified leave request.

requires authentication

This endpoint deletes a leave request item based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/leave-requests/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/leave-requests/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Leave request deleted successfully.",
        "id": 1,
        "type": "leave_request",
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Leave request not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the leave request."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/leave-requests/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the leave request to be deleted. Example: `1`

# Notification Management

## List or search notifications.

requires authentication

This endpoint retrieves a list of notifications based on various filters. The user must be authenticated to perform this action. The request allows filtering by status, type, user, client, and other parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/notifications/1?search=Alert&sort=title&order=ASC&status=unread&type=project&user_id=1&client_id=5&notification_type=system&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/notifications/1"
    );

    const params = {
        "search": "Alert",
        "sort": "title",
        "order": "ASC",
        "status": "unread",
        "type": "project",
        "user_id": "1",
        "client_id": "5",
        "notification_type": "system",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Notifications retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 116,
                "title": "Task Status Updated",
                "users": [
                    {
                        "id": 183,
                        "first_name": "Girish",
                        "last_name": "Thacker",
                        "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                    }
                ],
                "clients": [
                    {
                        "id": 102,
                        "first_name": "Test",
                        "last_name": "Client",
                        "photo": "https://test-taskify.infinitietech.com/storage/photos/no-image.jpg"
                    }
                ],
                "type": "Task",
                "type_id": 268,
                "message": "Madhavan Vaidya has updated the status of task sdff, ID:#268, from Default to Test From Pro.",
                "status": "Unread",
                "read_at": null,
                "created_at": "23-07-2024 17:50:09",
                "updated_at": "23-07-2024 19:08:16"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Notification not found",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Notifications not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/notifications/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the meeting to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter notifications by title, message and id. Example: `Alert`

`sort` string optional

optional The field to sort by. Defaults to "id". Sortable fields include: id, title, message, type, status, created_at, and updated_at. Example: `title`

`order` string optional

optional The sort order, either "ASC" or "DESC". Defaults to "DESC". Example: `ASC`

`status` string optional

optional The status of the notification to filter by. Can be "read" or "unread". Example: `unread`

`type` string optional

optional The type of notifications to filter by. Example: `project`

`user_id` integer optional

optional The user ID to filter notifications by. Example: `1`

`client_id` integer optional

optional The client ID to filter notifications by. Example: `5`

`notification_type` string optional

optional The notification type to filter by. Can be "system" or "push". Example: `system`

`limit` integer optional

optional The number of notifications per page for pagination. Example: `10`

`offset` integer optional

optional The offset for pagination, indicating the starting point of results. Example: `0`

## Remove the specified notification.

requires authentication

This endpoint deletes a notification based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/notifications/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/notifications/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Notification deleted successfully.",
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Notification not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the notification."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/notifications/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the notification to be deleted. Example: `1`

## Mark notification(s) as read.

requires authentication

This endpoint marks a specific notification as read if a notification ID is provided. If no ID is provided, it will mark all unread notifications as read for the authenticated user. The user must be authenticated to perform this action.

> Example request:

    curl --request PATCH \
        "https://dev-taskify.taskhub.company/api/notifications/mark-as-read/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/notifications/mark-as-read/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "PATCH",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Notification marked as read successfully."
    }

> Example response (200):

    {
        "error": false,
        "message": "All notifications marked as read successfully."
    }

> Example response (404):

    {
        "error": true,
        "message": "Notification not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "Failed to mark notifications as read."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

PATCH `api/notifications/mark-as-read/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the notification to mark as read. Example: `1`

# Activity Log Management

## List or search activity logs.

requires authentication

This endpoint retrieves a list of activity logs based on various filters. The user must be authenticated to perform this action. The request allows filtering by date ranges, user, client, activity type, and other parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/activity-log/1?search=update&sort=created_at&order=ASC&date_from=2024-01-01&date_to=2024-12-31&user_id=1&client_id=5&activity=update&type=task&type_id=10&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/activity-log/1"
    );

    const params = {
        "search": "update",
        "sort": "created_at",
        "order": "ASC",
        "date_from": "2024-01-01",
        "date_to": "2024-12-31",
        "user_id": "1",
        "client_id": "5",
        "activity": "update",
        "type": "task",
        "type_id": "10",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Activity logs retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 974,
                "actor_id": 183,
                "actor_name": "Girish Thacker",
                "actor_type": "User",
                "type_id": 31,
                "parent_type_id": "",
                "type": "Payslip",
                "parent_type": "",
                "type_title": "CTR-31",
                "parent_type_title": "",
                "activity": "Created",
                "message": "Girish Thacker created payslip PSL-31",
                "created_at": "06-08-2024 18:10:41",
                "updated_at": "06-08-2024 18:10:41"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Activity logs not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/activity-log/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the activity log to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter activity logs. Example: `update`

`sort` string optional

optional The field to sort by. Defaults to "id". Sortable fields include: id, created_at, and updated_at. Example: `created_at`

`order` string optional

optional The sort order, either "ASC" or "DESC". Defaults to "DESC". Example: `ASC`

`date_from` string optional

optional The start date range's start in YYYY-MM-DD format. Example: `2024-01-01`

`date_to` string optional

optional The end date range's end in YYYY-MM-DD format. Example: `2024-12-31`

`user_id` integer optional

optional The user ID to filter activity logs by. Example: `1`

`client_id` integer optional

optional The client ID to filter activity logs by. Example: `5`

`activity` string optional

optional The activity type to filter by. Example: `update`

`type` string optional

optional The type of activity to filter by. Example: `task`

`type_id` integer optional

optional The type ID to filter activity logs by. Example: `10`

`limit` integer optional

optional The number of logs per page for pagination. Example: `10`

`offset` integer optional

optional The offset for pagination. Example: `0`

## Remove the specified activity log.

requires authentication

This endpoint deletes a activity log based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/activity-log/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/activity-log/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Record deleted successfully.",
        "title": null,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Record not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the activity log."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/activity-log/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the activity log to be deleted. Example: `1`

# Role/Permission Management

## List or search roles.

This endpoint retrieves a list of roles based on various filters. The request allows filtering by search term and pagination parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/roles/1?search=Admin&sort=name&order=asc&limit=10&offset=0" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/roles/1"
    );

    const params = {
        "search": "Admin",
        "sort": "name",
        "order": "asc",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Roles retrieved successfully.",
        "total": 1,
        "data": [
            {
                "id": 1,
                "name": "Admin",
                "guard_name": "web",
                "created_at": "10-10-2023 17:50:09",
                "updated_at": "23-07-2024 19:08:16"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Role not found.",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Roles not found",
        "total": 0,
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while retrieving the roles."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/roles/{id?}`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the role to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter roles by id, name or guard_name. Example: `Admin`

`sort` string optional

optional The field to sort by. all fields are sortable. Defaults to "created_at". Example: `name`

`order` string optional

optional The sort order, either "asc" or "desc". Defaults to "desc". Example: `asc`

`limit` integer optional

optional The number of roles per page for pagination. Defaults to 10. Example: `10`

`offset` integer optional

optional The offset for pagination, indicating the starting point of results. Defaults to 0. Example: `0`

## Check user permissions.

requires authentication

This endpoint checks the module-wise permissions assigned to the authenticated user. If a specific permission is provided in the URL, it checks only that permission for the authenticated user. Otherwise, it returns all permissions for the authenticated user.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/permissions/&quot;edit-post&quot;

    Here is the module-wise permissions list.

    Activity Log:
    - manage_activity_log
    - delete_activity_log

    Allowances:
    - create_allowances
    - manage_allowances
    - edit_allowances
    - delete_allowances

    Clients:
    - create_clients
    - manage_clients
    - edit_clients
    - delete_clients

    Contract Types:
    - create_contract_types
    - manage_contract_types
    - edit_contract_types
    - delete_contract_types

    Contracts:
    - create_contracts
    - manage_contracts
    - edit_contracts
    - delete_contracts

    Deductions:
    - create_deductions
    - manage_deductions
    - edit_deductions
    - delete_deductions

    Estimates/Invoices:
    - create_estimates_invoices
    - manage_estimates_invoices
    - edit_estimates_invoices
    - delete_estimates_invoices

    Expense Types:
    - create_expense_types
    - manage_expense_types
    - edit_expense_types
    - delete_expense_types

    Expenses:
    - create_expenses
    - manage_expenses
    - edit_expenses
    - delete_expenses

    Items:
    - create_items
    - manage_items
    - edit_items
    - delete_items

    Media:
    - create_media
    - manage_media
    - delete_media

    Meetings:
    - create_meetings
    - manage_meetings
    - edit_meetings
    - delete_meetings

    Milestones:
    - create_milestones
    - manage_milestones
    - edit_milestones
    - delete_milestones

    Payment Methods:
    - create_payment_methods
    - manage_payment_methods
    - edit_payment_methods
    - delete_payment_methods

    Payments:
    - create_payments
    - manage_payments
    - edit_payments
    - delete_payments

    Payslips:
    - create_payslips
    - manage_payslips
    - edit_payslips
    - delete_payslips

    Priorities:
    - create_priorities
    - manage_priorities
    - edit_priorities
    - delete_priorities

    Projects:
    - create_projects
    - manage_projects
    - edit_projects
    - delete_projects

    Statuses:
    - create_statuses
    - manage_statuses
    - edit_statuses
    - delete_statuses

    System Notifications:
    - manage_system_notifications
    - delete_system_notifications

    Tags:
    - create_tags
    - manage_tags
    - edit_tags
    - delete_tags

    Tasks:
    - create_tasks
    - manage_tasks
    - edit_tasks
    - delete_tasks

    Taxes:
    - create_taxes
    - manage_taxes
    - edit_taxes
    - delete_taxes

    Timesheet:
    - create_timesheet
    - manage_timesheet
    - delete_timesheet

    Units:
    - create_units
    - manage_units
    - edit_units
    - delete_units

    Users:
    - create_users
    - manage_users
    - edit_users
    - delete_users

    Workspaces:
    - create_workspaces
    - manage_workspaces
    - edit_workspaces
    - delete_workspaces" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/permissions/&quot;edit-post&quot;

    Here is the module-wise permissions list.

    Activity Log:
    - manage_activity_log
    - delete_activity_log

    Allowances:
    - create_allowances
    - manage_allowances
    - edit_allowances
    - delete_allowances

    Clients:
    - create_clients
    - manage_clients
    - edit_clients
    - delete_clients

    Contract Types:
    - create_contract_types
    - manage_contract_types
    - edit_contract_types
    - delete_contract_types

    Contracts:
    - create_contracts
    - manage_contracts
    - edit_contracts
    - delete_contracts

    Deductions:
    - create_deductions
    - manage_deductions
    - edit_deductions
    - delete_deductions

    Estimates/Invoices:
    - create_estimates_invoices
    - manage_estimates_invoices
    - edit_estimates_invoices
    - delete_estimates_invoices

    Expense Types:
    - create_expense_types
    - manage_expense_types
    - edit_expense_types
    - delete_expense_types

    Expenses:
    - create_expenses
    - manage_expenses
    - edit_expenses
    - delete_expenses

    Items:
    - create_items
    - manage_items
    - edit_items
    - delete_items

    Media:
    - create_media
    - manage_media
    - delete_media

    Meetings:
    - create_meetings
    - manage_meetings
    - edit_meetings
    - delete_meetings

    Milestones:
    - create_milestones
    - manage_milestones
    - edit_milestones
    - delete_milestones

    Payment Methods:
    - create_payment_methods
    - manage_payment_methods
    - edit_payment_methods
    - delete_payment_methods

    Payments:
    - create_payments
    - manage_payments
    - edit_payments
    - delete_payments

    Payslips:
    - create_payslips
    - manage_payslips
    - edit_payslips
    - delete_payslips

    Priorities:
    - create_priorities
    - manage_priorities
    - edit_priorities
    - delete_priorities

    Projects:
    - create_projects
    - manage_projects
    - edit_projects
    - delete_projects

    Statuses:
    - create_statuses
    - manage_statuses
    - edit_statuses
    - delete_statuses

    System Notifications:
    - manage_system_notifications
    - delete_system_notifications

    Tags:
    - create_tags
    - manage_tags
    - edit_tags
    - delete_tags

    Tasks:
    - create_tasks
    - manage_tasks
    - edit_tasks
    - delete_tasks

    Taxes:
    - create_taxes
    - manage_taxes
    - edit_taxes
    - delete_taxes

    Timesheet:
    - create_timesheet
    - manage_timesheet
    - delete_timesheet

    Units:
    - create_units
    - manage_units
    - edit_units
    - delete_units

    Users:
    - create_users
    - manage_users
    - edit_users
    - delete_users

    Workspaces:
    - create_workspaces
    - manage_workspaces
    - edit_workspaces
    - delete_workspaces"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Permissions check completed.",
        "data": {
            "permissions": {
                "create_projects": true,
                "manage_projects": false,
                ...
            }
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while checking the permission."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/permissions/{permission?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`permission` string optional

optional The specific permission to check. Example: `"edit-post"

Here is the module-wise permissions list.

Activity Log:

- manage_activity_log
- delete_activity_log

Allowances:

- create_allowances
- manage_allowances
- edit_allowances
- delete_allowances

Clients:

- create_clients
- manage_clients
- edit_clients
- delete_clients

Contract Types:

- create_contract_types
- manage_contract_types
- edit_contract_types
- delete_contract_types

Contracts:

- create_contracts
- manage_contracts
- edit_contracts
- delete_contracts

Deductions:

- create_deductions
- manage_deductions
- edit_deductions
- delete_deductions

Estimates/Invoices:

- create_estimates_invoices
- manage_estimates_invoices
- edit_estimates_invoices
- delete_estimates_invoices

Expense Types:

- create_expense_types
- manage_expense_types
- edit_expense_types
- delete_expense_types

Expenses:

- create_expenses
- manage_expenses
- edit_expenses
- delete_expenses

Items:

- create_items
- manage_items
- edit_items
- delete_items

Media:

- create_media
- manage_media
- delete_media

Meetings:

- create_meetings
- manage_meetings
- edit_meetings
- delete_meetings

Milestones:

- create_milestones
- manage_milestones
- edit_milestones
- delete_milestones

Payment Methods:

- create_payment_methods
- manage_payment_methods
- edit_payment_methods
- delete_payment_methods

Payments:

- create_payments
- manage_payments
- edit_payments
- delete_payments

Payslips:

- create_payslips
- manage_payslips
- edit_payslips
- delete_payslips

Priorities:

- create_priorities
- manage_priorities
- edit_priorities
- delete_priorities

Projects:

- create_projects
- manage_projects
- edit_projects
- delete_projects

Statuses:

- create_statuses
- manage_statuses
- edit_statuses
- delete_statuses

System Notifications:

- manage_system_notifications
- delete_system_notifications

Tags:

- create_tags
- manage_tags
- edit_tags
- delete_tags

Tasks:

- create_tasks
- manage_tasks
- edit_tasks
- delete_tasks

Taxes:

- create_taxes
- manage_taxes
- edit_taxes
- delete_taxes

Timesheet:

- create_timesheet
- manage_timesheet
- delete_timesheet

Units:

- create_units
- manage_units
- edit_units
- delete_units

Users:

- create_users
- manage_users
- edit_users
- delete_users

Workspaces:

- create_workspaces
- manage_workspaces
- edit_workspaces
- delete_workspaces`

## Create a new role.

requires authentication

This endpoint allows authenticated users to create a new role and assign permissions.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/roles/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"name\": \"\\\"Supervisor\\\"\",
        \"permissions\": [
            1,
            2,
            3
        ]
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/roles/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "name": "\"Supervisor\"",
        "permissions": [
            1,
            2,
            3
        ]
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Role created successfully.",
        "role": {
            "id": 5,
            "name": "Supervisor",
            "permissions": [
                "edit_tasks",
                "assign_tasks"
            ]
        }
    }

> Example response (409):

    {
        "error": true,
        "message": "A role `Manager` already exists."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "errors": {
            "name": [
                "The name field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the role."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/roles/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`name` string

The updated name of the role. Example: `"Supervisor"`

`permissions` string[] optional

optional A list of permission IDs to assign to the role.

## Update an existing role.

requires authentication

This endpoint allows authenticated users to update a role name and modify its permissions.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/roles/update/5" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"name\": \"\\\"Supervisor\\\"\",
        \"permissions\": [
            1,
            2,
            3
        ]
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/roles/update/5"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "name": "\"Supervisor\"",
        "permissions": [
            1,
            2,
            3
        ]
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Role updated successfully."
    }

> Example response (404):

    {
        "error": true,
        "message": "Role not found."
    }

> Example response (409):

    {
        "error": true,
        "message": "A role `Manager` already exists."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "errors": {
            "name": [
                "The name field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the role."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/roles/update/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the role to update. Example: `5`

#### Body Parameters

`name` string

The updated name of the role. Example: `"Supervisor"`

`permissions` string[] optional

optional A list of permission IDs to assign to the role.

## Delete a role.

requires authentication

This endpoint allows authenticated users to delete a specific role.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/roles/destroy/17" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/roles/destroy/17"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Role deleted successfully."
    }

> Example response (404):

    {
        "error": true,
        "message": "Role not found."
    }

> Example response (409):

    {
        "error": true,
        "message": "Cannot delete this role because it is assigned to users."
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the role."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/roles/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the role to delete. Example: `17`

## Get a specific role with its permissions, grouped by category.

requires authentication

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/roles/get/7" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/roles/get/7"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "role": {
            "id": 1,
            "name": "Admin",
            "permissions": {
                "projects": {
                    "create_projects": true,
                    "delete_projects": false
                },
                "tasks": {
                    "create_tasks": true
                }
            }
        }
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/roles/get/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the role to retrieve. Example: `7`

## List all permissions.

This endpoint retrieves a list of all permissions.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/permissions-list" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/permissions-list"
    );

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
      "error": false,
      "message": "Permissions retrieved successfully.",
      "total": 5,
      "data": [
        {
          "id": 1,
          "name": "create_projects",
          "guard_name": "web",
          "created_at": "2023-10-10T17:50:09.000000Z",
          "updated_at": "2024-07-23T19:08:16.000000Z"
        },
        ...
      ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Permissions not found.",
        "total": 0,
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while retrieving the permissions."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/permissions-list`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

# Setting Management

## Retrieve the settings for a specific variable.

requires authentication

This endpoint returns the settings for a given variable. The user must be authenticated.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/settings/general_settings" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/settings/general_settings"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Settings retrieved successfully",
        "settings": {
            "company_title": "Taskify",
            "currency_full_form": "Indian Rupee",
            "currency_symbol": "₹",
            "currency_code": "INR",
            "currency_symbol_position": "before",
            "currency_formate": "comma_separated",
            "decimal_points_in_currency": "2",
            "allowed_max_upload_size": "2000",
            "allowSignup": 1,
            "timezone": "Asia/Kolkata",
            "date_format": "DD-MM-YYYY|d-m-Y",
            "time_format": "H:i:s",
            "toast_position": "toast-bottom-center",
            "toast_time_out": "2",
            "footer_text": "<p>made with ❤️ by <a href=\"https://www.infinitietech.com/\" target=\"_blank\" rel=\"noopener\">Infinitie Technologies</a></p>",
            "full_logo": "https://test-taskify.infinitietech.com/storage/logos/zEy4tSCAFSMczWbOoxBZ3B43Nc9eeqMlNBXDrOzn.png",
            "half_logo": null,
            "favicon": "https://test-taskify.infinitietech.com/storage/logos/2FZTNY1qDTz7CTtwWC8Hh1eY4l7cIHgOXG2stVIU.png"
        }
    }

> Example response (200):

    {
        "error": true,
        "message": "Un Authorized Action!"
    }

> Example response (200):

    {
        "error": true,
        "message": "Setting not found"
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/settings/{variable}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`variable` string

The variable type for which settings are to be retrieved. Must be one of the following: general_settings, pusher_settings, email_settings, media_storage_settings, sms_gateway_settings, whatsapp_settings, privacy_policy, about_us, terms_conditions. Example: `general_settings`

## Store the settings for a specific variable.

requires authentication

This endpoint stores the settings for a given variable. The user must be authenticated.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/settings/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"variable\": \"general_settings\",
        \"company_title\": \"Taskify\",
        \"site_url\": \"https:\\/\\/www.taskify.com\",
        \"timezone\": \"Asia\\/Kolkata\",
        \"currency_full_form\": \"Indian Rupee\",
        \"currency_symbol\": \"₹\",
        \"currency_code\": \"INR\",
        \"date_format\": \"DD-MM-YYYY|d-m-Y\",
        \"toast_time_out\": \"2\",
        \"allowed_max_upload_size\": \"2000\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/settings/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "variable": "general_settings",
        "company_title": "Taskify",
        "site_url": "https:\/\/www.taskify.com",
        "timezone": "Asia\/Kolkata",
        "currency_full_form": "Indian Rupee",
        "currency_symbol": "₹",
        "currency_code": "INR",
        "date_format": "DD-MM-YYYY|d-m-Y",
        "toast_time_out": "2",
        "allowed_max_upload_size": "2000"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Settings saved successfully."
    }

> Example response (200):

    {
        "error": true,
        "message": "Un Authorized Action!"
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/settings/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`variable` string

The variable type for which settings are to be stored. Must be one of the following: general_settings, pusher_settings, email_settings, media_storage_settings, sms_gateway_settings, whatsapp_settings, privacy_policy, about_us, terms_conditions. Example: `general_settings`

#### Body Parameters

`variable` string

The variable type for which settings are to be stored. Must be one of the following: general_settings, pusher_settings, email_settings, media_storage_settings, sms_gateway_settings, whatsapp_settings, privacy_policy, about_us, terms_conditions. Example: `general_settings`

`company_title` string

The title of the company. Example: `Taskify`

`site_url` string

The URL of the site. Example: `https://www.taskify.com`

`timezone` string

The timezone of the site. Example: `Asia/Kolkata`

`currency_full_form` string

The full form of the currency. Example: `Indian Rupee`

`currency_symbol` string

The symbol of the currency. Example: `₹`

`currency_code` string

The code of the currency. Example: `INR`

`date_format` string

The format of the date. Example: `DD-MM-YYYY|d-m-Y`

`toast_time_out` numeric optional

The time duration for the toast message to be displayed. Example: `2`

`allowed_max_upload_size` numeric optional

The maximum allowed upload size. Example: `2000`

# Expense Management

## Create a new expense.

requires authentication

This endpoint creates a new expense item with the specified title, expense_type_id,user_id,amount,expense_date,note. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/expenses/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"Finish report\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/expenses/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "Finish report"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Expense created successfully.",
    "id": 36,
    "data": {
              'id' => '1',
              'title' => 'Expense Title',
              'expense_type_id' => '1',
              'user_id' => '1',
              'amount' => '100.00',
              'expense_date' => '2023-10-01',
              'note' => 'Expense note',
              'created_by' => 'John Doe',
              'created_at' => format_date($exp->created_at, true),
             }

> Example response (422):

    {
      "error": true,
      "message": "Validation errors occurred",
      "errors": {
        "title": [
          "The title field is required."
        ],
        "expense_type_id": [
          "The expense type field is required."
        ],
       "user_id": [
         "The user id field is required."
       ],
       "amount": [
         "The amount field is required."
      ],
      "expense_date": [
        "The expense date field is required."
       ],
      }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the expense."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/expenses/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`title` string

The note of the expense. Example: `Finish report`

## List or search expenses.

requires authentication

Retrieve a paginated list of expenses or a single expense by ID.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/expenses/1?search=Lunch&sort=title&order=ASC&limit=10&offset=0&type_ids%5B%5D[]=1&type_ids%5B%5D[]=2&user_ids%5B%5D[]=3&user_ids%5B%5D[]=5&date_from=2023-01-01&date_to=2023-01-31" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/expenses/1"
    );

    const params = {
        "search": "Lunch",
        "sort": "title",
        "order": "ASC",
        "limit": "10",
        "offset": "0",
        "type_ids[][0]": "1",
        "type_ids[][1]": "2",
        "user_ids[][0]": "3",
        "user_ids[][1]": "5",
        "date_from": "2023-01-01",
        "date_to": "2023-01-31",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Expenses retrieved successfully",
        "total": 2,
        "data": [
            {
                "id": 1,
                "title": "Travel Reimbursement",
                "expense_type_id": 2,
                "expense_type": "Travel",
                "user_id": 5,
                "user": {
                    "id": 5,
                    "first_name": "Alice",
                    "last_name": "Smith",
                    "email": "alice@example.com",
                    "photo": "https://yourdomain.com/storage/photos/alice.jpg"
                },
                "amount": "150.00",
                "expense_date": "2023-10-01",
                "note": "Flight ticket",
                "created_by": "John Doe",
                "created_at": "2023-10-01"
            }
        ]
    }

> Example response (404):

    {
        "error": true,
        "message": "Expense not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/expenses/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the expense to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional Search keyword for title, amount, note, or ID. Example: `Lunch`

`sort` string optional

optional Column to sort by. Default: id. Allowed: id, title, created_at, updated_at. Example: `title`

`order` string optional

optional Sort order: ASC or DESC. Default: DESC. Example: `ASC`

`limit` integer optional

optional Number of records per page. Example: `10`

`offset` integer optional

optional Offset for pagination. Example: `0`

`type_ids[]` integer[] optional

optional Filter by expense type IDs.

`user_ids[]` integer[] optional

optional Filter by user IDs.

`date_from` string optional

date optional Start date for expense_date filtering. Example: `2023-01-01`

`date_to` string optional

date optional End date for expense_date filtering. Example: `2023-01-31`

## Update a existing expense.

requires authentication

This endpoint update existing expense item with the specified title, expense_type_id,user_id,amount,expense_date,note. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/expenses/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": \"1\",
        \"title\": \"Finish report\",
        \"expense_type_id\": \"1\",
        \"user_id\": \"1\",
        \"amount\": \"Finish report\",
        \"expense_date\": \"2024-08-07\",
        \"note\": \"Finish report\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/expenses/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": "1",
        "title": "Finish report",
        "expense_type_id": "1",
        "user_id": "1",
        "amount": "Finish report",
        "expense_date": "2024-08-07",
        "note": "Finish report"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Expense created successfully.",
    "id": 36,
    "data": {
              'id' => '1',
              'title' => 'Expense Title',
              'expense_type_id' => '1',
              'user_id' => '1',
              'amount' => '100.00',
              'expense_date' => '2023-10-01',
              'note' => 'Expense note',
              'created_by' => 'John Doe',
              'created_at' => format_date($exp->created_at, true),
             }

> Example response (422):

    {
      "error": true,
      "message": "Validation errors occurred",
      "errors": {
        "title": [
          "The title field is required."
        ],
        "expense_type_id": [
          "The expense type field is required."
        ],
       "user_id": [
         "The user id field is required."
       ],
       "amount": [
         "The amount field is required."
      ],
      "expense_date": [
        "The expense date field is required."
       ],
      }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the expense."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/expenses/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` string

The id of the expense. Example: `1`

`title` string

The title of the expense. Example: `Finish report`

`expense_type_id` string

The expense_type_id of the expense. Example: `1`

`user_id` string

The user_id of the expense. Example: `1`

`amount` string

The amount of the expense. Example: `Finish report`

`expense_date` string

The expense_date of the expense. Example: `2024-08-07`

`note` string

The note of the expense. Example: `Finish report`

## Remove the specified expense.

requires authentication

This endpoint deletes a expense item based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/expenses/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/expenses/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
      "error": false,
      "message": "Expense deleted successfully.",
      "id": 1,
      "title": "Expense Title"
      "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Expense not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the expense."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/expenses/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the todo to be deleted. Example: `1`

## Create a new expense type.

requires authentication

This endpoint creates a new expense type item with the specified title, description. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/expenses/expense-types/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"Finish report\",
        \"description\": \"Finish report\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/expenses/expense-types/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "Finish report",
        "description": "Finish report"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Expense Type created successfully.",
    "id": 1,
    "data": {
              'id' => '1',
              'title' => 'Expense Title',
              'description' => 'Expense Description',
              'created_at' => 2023-10-01 12:00:00',
             }

> Example response (422):

    {
      "error": true,
      "message": "Validation errors occurred",
      "errors": {
        "title": [
          "The title field is required."
        ],
      }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the expense type."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/expenses/expense-types/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`title` string

The title of the expense. Example: `Finish report`

`description` string

The description of the expense. Example: `Finish report`

## List or search expense types.

requires authentication

Retrieve a list of expense types, optionally filtered by search term or a specific ID. Supports sorting, pagination, and workspace scoping. Authentication is required.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/expenses/expense-types/list/1?search=Travel&sort=title&order=ASC&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/expenses/expense-types/list/1"
    );

    const params = {
        "search": "Travel",
        "sort": "title",
        "order": "ASC",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200, Single Expense Type Found):

    {
        "error": false,
        "message": "Expense type retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 1,
                "title": "Travel",
                "description": "Travel expenses",
                "created_at": "2023-10-01"
            }
        ]
    }

> Example response (200, Multiple Expense Types Found):

    {
        "error": false,
        "message": "Expense types retrieved successfully",
        "total": 2,
        "data": [
            {
                "id": 1,
                "title": "Travel",
                "description": "Travel expenses",
                "created_at": "2023-10-01"
            },
            {
                "id": 2,
                "title": "Office Supplies",
                "description": "Stationery and office supplies",
                "created_at": "2023-10-03"
            }
        ]
    }

> Example response (200, No Results Found):

    {
        "error": true,
        "message": "Expense type not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/expenses/expense-types/list/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the specific expense type to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional Search term for title, description, or ID. Example: `Travel`

`sort` string optional

optional Field to sort by. Defaults to `id`. Sortable fields: `id`, `title`, `created_at`, `updated_at`. Example: `title`

`order` string optional

optional Sort order: `ASC` or `DESC`. Defaults to `DESC`. Example: `ASC`

`limit` integer optional

optional Number of items per page. Default is 10. Example: `10`

`offset` integer optional

optional Number of items to skip (for pagination). Default is 0. Example: `0`

## Update an existing expense type.

requires authentication

This endpoint update an existing expense type item with the specified title, description. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/expenses/expense-types/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": \"1\",
        \"title\": \"Finish report\",
        \"description\": \"Finish report\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/expenses/expense-types/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": "1",
        "title": "Finish report",
        "description": "Finish report"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Expense Type created successfully.",
    "id": 1,
    "data": {
              'id' => '1',
              'title' => 'Expense Title',
              'description' => 'Expense Description',
              'created_at' => 2023-10-01 12:00:00',
             }

> Example response (422):

    {
      "error": true,
      "message": "Validation errors occurred",
      "errors": {
        "title": [
          "The title field is required."
        ],
      }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the expense type."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/expenses/expense-types/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` string

The id of the expense. Example: `1`

`title` string

The title of the expense. Example: `Finish report`

`description` string

The description of the expense. Example: `Finish report`

## Remove the specified expense type.

requires authentication

This endpoint deletes a expense type item based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/expenses/expense-types/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/expenses/expense-types/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
      "error": false,
      "message": "Expense Type deleted successfully.",
      "id": 1,
      "title": "Expense Type Title"
      "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Expense Type not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the expense type."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/expenses/expense-types/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the todo to be deleted. Example: `1`

# Payment Management

## Create a new payment.

requires authentication

This endpoint creates a new payment with the specified user_id, invoice_id,payment_method_id,amount,payment_date,note. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/payments/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"user_id\": \"1\",
        \"invoice_id\": \"1\",
        \"payment_method_id\": \"1\",
        \"amount\": \"100\",
        \"payment_date\": \"2024-08-07\",
        \"note\": \"Finish report\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/payments/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "user_id": "1",
        "invoice_id": "1",
        "payment_method_id": "1",
        "amount": "100",
        "payment_date": "2024-08-07",
        "note": "Finish report"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Payment created successfully.",
    "id": 36,
    "data": {
              'id' => '1',
              'user_id' => '1',
              'invoice_id' => '1',
              'payment_method_id' => '1',
              'amount' => '100.00',
              'payment_date' => '2023-10-01',
              'note' => 'Payment note',
              'created_at' => format_date($exp->created_at, true),
             }

> Example response (422):

    {
      "error": true,
      "message": "Validation errors occurred",
      "errors": {
        "user_id": [
          "The user_id field is required."
        ],
        "invoice_id": [
          "The invoice_id field is required."
        ],
       "payment_method_id": [
         "The payment method id field is required."
       ],
       "amount": [
         "The amount field is required."
      ],
      "payment_date": [
        "The payment date field is required."
       ],
      }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the payment."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/payments/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`user_id` string

The user_id of the payment. Example: `1`

`invoice_id` string

The invoice_id of the payment. Example: `1`

`payment_method_id` string

The payment_method_id of the payment methods. Example: `1`

`amount` string

The amount of the amount. Example: `100`

`payment_date` string

The payment_date of the payment. Example: `2024-08-07`

`note` string

The note of the note. Example: `Finish report`

## List or search payments.

requires authentication

This endpoint retrieves a list of payments based on various filters. The user must be authenticated to perform this action. The request allows searching and sorting by different parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/payments/1?search=Title&sort=id&order=ASC&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/payments/1"
    );

    const params = {
        "search": "Title",
        "sort": "id",
        "order": "ASC",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Payment retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 1,
                "user_id": 1,
                "user": {
                    "id": 1,
                    "first_name": "Admin",
                    "last_name": "User",
                    "email": "admin@gmail.com",
                    "photo": "https://dev-taskify.taskhub.company/storage/photos/C03PJmIQInts2j3O2on99Nilu45UcChrepcsIFxO.jpg"
                },
                "invoice_id": null,
                "invoice": "-",
                "payment_method_id": 1,
                "payment_method": "some",
                "amount": "₹ 100.00",
                "payment_date": "2025-04-16",
                "note": "123",
                "created_by": "Admin User",
                "created_at": "2025-04-16 09:41:57",
                "updated_at": "2025-04-16 09:41:57"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Payment not found",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Payments not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/payments/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the tag to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter tags by title or id. Example: `Title`

`sort` string optional

optional The field to sort by. Defaults to "id". Sortable fields include: id, created_at, and updated_at. Example: `id`

`order` string optional

optional The sort order, either "ASC" or "DESC". Defaults to "DESC". Example: `ASC`

`limit` integer optional

optional The number of tags per page for pagination. Example: `10`

`offset` integer optional

optional The offset for pagination, indicating the starting point of results. Example: `0`

## Update an existing payment.

requires authentication

This endpoint updates an existing payment with the specified user_id, invoice_id,payment_method_id,amount,payment_date,note. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/payments/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": \"quam\",
        \"user_id\": \"1\",
        \"invoice_id\": \"1\",
        \"payment_method_id\": \"1\",
        \"amount\": \"100\",
        \"payment_date\": \"2024-08-07\",
        \"note\": \"Finish report\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/payments/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": "quam",
        "user_id": "1",
        "invoice_id": "1",
        "payment_method_id": "1",
        "amount": "100",
        "payment_date": "2024-08-07",
        "note": "Finish report"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Payment created successfully.",
    "id": 36,
    "data": {
              'id' => '1',
              'user_id' => '1',
              'invoice_id' => '1',
              'payment_method_id' => '1',
              'amount' => '100.00',
              'payment_date' => '2023-10-01',
              'note' => 'Payment note',
              'created_at' => format_date($exp->created_at, true),
             }

> Example response (422):

    {
      "error": true,
      "message": "Validation errors occurred",
      "errors": {
        "user_id": [
          "The user_id field is required."
        ],
        "invoice_id": [
          "The invoice_id field is required."
        ],
       "payment_method_id": [
         "The payment method id field is required."
       ],
       "amount": [
         "The amount field is required."
      ],
      "payment_date": [
        "The payment date field is required."
       ],
      }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the payment."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/payments/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` string

The id of the payment. Example : 1 Example: `quam`

`user_id` string

The user_id of the payment. Example: `1`

`invoice_id` string

The invoice_id of the payment. Example: `1`

`payment_method_id` string

The payment_method_id of the payment methods. Example: `1`

`amount` string

The amount of the amount. Example: `100`

`payment_date` string

The payment_date of the payment. Example: `2024-08-07`

`note` string

The note of the note. Example: `Finish report`

## Remove the specified payment.

requires authentication

This endpoint deletes a payment based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/payments/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/payments/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Payment deleted successfully.",
        "id": 1,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Payment not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the Payment."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/payments/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the todo to be deleted. Example: `1`

# Payment Method Management

## List or search payments methods.

requires authentication

This endpoint retrieves a list of payments methods based on various filters. The user must be authenticated to perform this action. The request allows searching and sorting by different parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/payment-methods/1?search=Title&sort=id&order=ASC&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/payment-methods/1"
    );

    const params = {
        "search": "Title",
        "sort": "id",
        "order": "ASC",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Payment Method retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 1,
                "title": "Payment Method Title",
                "created_at": "2025-04-16 09:41:57",
                "updated_at": "2025-04-16 09:41:57"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Payment Method not found",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Payment Methods not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/payment-methods/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the tag to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter tags by title or id. Example: `Title`

`sort` string optional

optional The field to sort by. Defaults to "id". Sortable fields include: id, created_at, and updated_at. Example: `id`

`order` string optional

optional The sort order, either "ASC" or "DESC". Defaults to "DESC". Example: `ASC`

`limit` integer optional

optional The number of tags per page for pagination. Example: `10`

`offset` integer optional

optional The offset for pagination, indicating the starting point of results. Example: `0`

## Create a payment method.

requires authentication

This endpoint creates a payment method. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/payment-methods/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"Title\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/payment-methods/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "Title"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Payment Method created successfully.",
    "id": 36,
    "data": {
              'id' => '1',
              'title' => 'Title',
              'created_at =>'2025-04-16',
              'updated_at' =>'2025-04-16',
             }

> Example response (422):

    {
      "error": true,
      "message": "Validation errors occurred",
      "errors": {
        "id": [
          "The id field is required."
        ],
        "title": [
          "The title field is required."
        ],

      }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the payment method."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/payment-methods/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`title` string

The title of the payment method. Example: `Title`

## Update an existing payment method.

requires authentication

This endpoint updates an existing payment method with the specified id. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/payment-methods/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": \"quas\",
        \"title\": \"Title\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/payment-methods/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": "quas",
        "title": "Title"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Payment Method created successfully.",
    "id": 36,
    "data": {
              'id' => '1',
              'title' => 'Title',
              'created_at =>'2025-04-16',
              'updated_at' =>'2025-04-16',
             }

> Example response (422):

    {
      "error": true,
      "message": "Validation errors occurred",
      "errors": {
        "id": [
          "The id field is required."
        ],
        "title": [
          "The title field is required."
        ],

      }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the payment method."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/payment-methods/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` string

The id of the payment method. Example : 1 Example: `quas`

`title` string

The title of the payment method. Example: `Title`

## Remove the specified payment method.

requires authentication

This endpoint deletes a payment method based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/payment-methods/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/payment-methods/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Payment Method deleted successfully.",
        "id": 1,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Payment Method not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the Payment Method."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/payment-methods/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the todo to be deleted. Example: `1`

# Tax Management

## List or search taxes.

requires authentication

This endpoint retrieves a list of taxes based on various filters. The user must be authenticated to perform this action. It supports searching, sorting, filtering by type, and pagination.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/taxes/1?search=GST&sort=created_at&order=ASC&types[]=percentage&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/taxes/1"
    );

    const params = {
        "search": "GST",
        "sort": "created_at",
        "order": "ASC",
        "types[0]": "percentage",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Taxes retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 1,
                "title": "GST",
                "type": "percentage",
                "amount": null,
                "percentage": 18,
                "created_at": "2025-04-16",
                "updated_at": "2025-04-16"
            }
        ]
    }

> Example response (200):

    {
        "error": false,
        "message": "Tax retrieved successfully",
        "total": 1,
        "data": {
            "id": 1,
            "title": "GST",
            "type": "percentage",
            "amount": null,
            "percentage": 18,
            "created_at": "2025-04-16",
            "updated_at": "2025-04-16"
        }
    }

> Example response (200):

    {
        "error": true,
        "message": "Tax not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/taxes/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the tax to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The term to search taxes by title, amount, percentage, type, or ID. Example: `GST`

`sort` string optional

optional The field to sort by. Defaults to "id". Sortable fields include: id, created_at, updated_at. Example: `created_at`

`order` string optional

optional The sorting order, either ASC or DESC. Defaults to DESC. Example: `ASC`

`types` string[] optional

optional Filter taxes by type. Accepts an array of types such as "percentage" or "fixed".

`limit` integer optional

optional Number of records per page. Defaults to 10. Example: `10`

`offset` integer optional

optional The offset for pagination. Defaults to 0. Example: `0`

## Create a tax.

requires authentication

This endpoint creates a tax. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/taxes/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"Title\",
        \"type\": \"amount\",
        \"amount\": \"100\",
        \"percentage\": \"10\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/taxes/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "Title",
        "type": "amount",
        "amount": "100",
        "percentage": "10"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Tax created successfully.",
    "id": 36,
    "data": {
              'id' => '1',
              'title' => 'Title',
              'type' => 'amount',
              'amount' => '100',
              'percentage' => null,
              'created_at =>'2025-04-16',
              'updated_at' =>'2025-04-16',
             }

> Example response (422):

    {
      "error": true,
      "message": "Validation errors occurred",
      "errors": {
        "id": [
          "The id field is required."
        ],
        "title": [
          "The title field is required."
        ],
        "type": [
          "The type field is required."
        ],

      }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the tax."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/taxes/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`title` string

The title of the tax. Example: `Title`

`type` string

The type of the tax. Example: `amount`

`amount` string

if type is amount The amount of the tax. Example: `100`

`percentage` string

if type is percentage The percentage of the tax. Example: `10`

## Update a tax.

requires authentication

This endpoint updates an existing tax. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/taxes/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": \"1\",
        \"title\": \"Title\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/taxes/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": "1",
        "title": "Title"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Tax updated successfully.",
    "id": 36,
    "data": {
              'id' => '1',
              'title' => 'Title',
              'type' => 'amount',
              'amount' => '100',
              'percentage' => null,
              'created_at =>'2025-04-16',
              'updated_at' =>'2025-04-16',
             }

> Example response (422):

    {
      "error": true,
      "message": "Validation errors occurred",
      "errors": {
        "id": [
          "The id field is required."
        ],
        "title": [
          "The title field is required."
        ],

      }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the tax."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/taxes/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` string

The id of the tax. Example: `1`

`title` string

The title of the tax. Example: `Title`

## Remove the specified tax.

requires authentication

This endpoint deletes a tax based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/taxes/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/taxes/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Tax deleted successfully.",
        "id": 1,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Tax not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the Tax."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/taxes/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the todo to be deleted. Example: `1`

# Unit Management

## List or search units.

requires authentication

This endpoint retrieves a list of units based on various filters. The user must be authenticated to perform this action. The request allows searching and sorting by different parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/units/1?search=Title&sort=id&order=ASC&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/units/1"
    );

    const params = {
        "search": "Title",
        "sort": "id",
        "order": "ASC",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Unit retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 1,
                "title": "title",
                "description": "unit description",
                "created_at": "2025-04-16 09:41:57",
                "updated_at": "2025-04-16 09:41:57"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Unit not found",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Units not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/units/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the tag to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter tags by title or id. Example: `Title`

`sort` string optional

optional The field to sort by. Defaults to "id". Sortable fields include: id, created_at, and updated_at. Example: `id`

`order` string optional

optional The sort order, either "ASC" or "DESC". Defaults to "DESC". Example: `ASC`

`limit` integer optional

optional The number of tags per page for pagination. Example: `10`

`offset` integer optional

optional The offset for pagination, indicating the starting point of results. Example: `0`

## Create an unit.

requires authentication

This endpoint creates an unit. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/units/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"Title\",
        \"description\": \"amount\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/units/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "Title",
        "description": "amount"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Unit created successfully.",
    "id": 36,
    "data": {
              'id' => '1',
              'title' => 'Title',
              'description' => 'Unit Description',
              'created_at =>'2025-04-16',
              'updated_at' =>'2025-04-16',
             }

> Example response (422):

    {
      "error": true,
      "message": "Validation errors occurred",
      "errors": {

        "title": [
          "The title field is required."
        ],

      }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the unit."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/units/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`title` string

The title of the unit. Example: `Title`

`description` string optional

The description of the unit. Example: `amount`

## Update an unit.

requires authentication

This endpoint updates an unit. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/units/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": \"1\",
        \"title\": \"Title\",
        \"description\": \"unit description\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/units/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": "1",
        "title": "Title",
        "description": "unit description"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Unit created successfully.",
    "id": 36,
    "data": {
              'id' => '1',
              'title' => 'Title',
              'description' => 'Unit Description',
              'created_at =>'2025-04-16',
              'updated_at' =>'2025-04-16',
             }

> Example response (422):

    {
      "error": true,
      "message": "Validation errors occurred",
      "errors": {
        "id": [
          "The title id is required."
        ],
        "title": [
          "The title field is required."
        ],

      }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the unit."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/units/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` string

The id of the unit. Example: `1`

`title` string

The title of the unit. Example: `Title`

`description` string optional

The description of the unit. Example: `unit description`

## Remove the specified unit.

requires authentication

This endpoint deletes a unit based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/units/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/units/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Unit deleted successfully.",
        "id": 1,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Unit not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the Unit."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/units/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the todo to be deleted. Example: `1`

# Item Management

## Retrieve a list of items or a specific item.

requires authentication

This endpoint fetches item records associated with the authenticated user's workspace. You can retrieve a single item by its ID or fetch a paginated list using filters such as search terms, sorting, unit filters, and pagination controls.

Filters available:

- search: Filter by title, description, price, unit ID, or item ID (partial match).
- unit_ids: Filter by one or more unit IDs (exact match).
- id: If provided, fetches a single item record with detailed fields.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/items/5?search=Water+Bottle&sort=title&order=ASC&unit_ids[]=1&unit_ids[]=2&unit_ids[]=3&limit=15&offset=20" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/items/5"
    );

    const params = {
        "search": "Water Bottle",
        "sort": "title",
        "order": "ASC",
        "unit_ids[0]": "1",
        "unit_ids[1]": "2",
        "unit_ids[2]": "3",
        "limit": "15",
        "offset": "20",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
      "error": false,
      "message": "Items Retrieved Successfully",
      "total": 2,
      "data": [
        {
          "id": 1,
          "title": "Notebook",
          "price": "₹100.00",
          "unit_id": 2,
          "unit_name": "Piece",
          "description": "A ruled notebook",
          "created_at": "2025-05-01",
          "updated_at": "2025-05-04"
        },
        ...
      ]
    }

> Example response (200):

    {
        "error": false,
        "message": "Item Retrieved Successfully",
        "total": 1,
        "data": {
            "id": 1,
            "title": "Notebook",
            "price": "₹100.00",
            "unit_id": 2,
            "unit_name": "Piece",
            "description": "A ruled notebook",
            "created_at": "2025-05-01",
            "updated_at": "2025-05-04"
        }
    }

> Example response (200):

    {
        "error": true,
        "message": "Item not found",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Items Not Found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/items/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the item to retrieve a single record. If not provided, a list will be returned. Example: `5`

#### Query Parameters

`search` string optional

optional Filter items by title, description, price, unit_id, or item ID. Example: `Water Bottle`

`sort` string optional

optional Column to sort by. Defaults to "id". Available values: id, title, price, created_at, updated_at. Example: `title`

`order` string optional

optional Sort direction: ASC or DESC. Defaults to "DESC". Example: `ASC`

`unit_ids` string[] optional

optional Filter items by one or more unit IDs.

`limit` integer optional

optional Number of items to return. Default is 10. Example: `15`

`offset` integer optional

optional Offset for paginated data. Default is 0. Example: `20`

## Create an item.

requires authentication

This endpoint creates an item. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/items/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": \"1\",
        \"title\": \"Title\",
        \"description\": \"description\",
        \"price\": \"400\",
        \"unit_id\": \"4\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/items/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": "1",
        "title": "Title",
        "description": "description",
        "price": "400",
        "unit_id": "4"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Item created successfully.",
    "id": 36,
    "data": {
              "id": 1,
    "title": "title",
    "price" : 100,
    "unit_id": 1,
    "description" : "description",
    "created_at": "2025-04-16 09:41:57",
    "updated_at": "2025-04-16 09:41:57"
             }

> Example response (422):

    {
      "error": true,
      "message": "Validation errors occurred",
      "errors": {
        "id": [
          "The  id field is required."
        ],
        "title": [
          "The title field is required."
        ],

      }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the item."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/items/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` string

The id of the item. Example: `1`

`title` string

The title of the item. Example: `Title`

`description` string optional

The description of the item. Example: `description`

`price` string optional

The price of the item. Example: `400`

`unit_id` string optional

The unit_id of the item. Example: `4`

## Update an item.

requires authentication

This endpoint updates an item. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/items/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": \"1\",
        \"title\": \"Title\",
        \"description\": \"description\",
        \"price\": \"400\",
        \"unit_id\": \"4\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/items/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": "1",
        "title": "Title",
        "description": "description",
        "price": "400",
        "unit_id": "4"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
    "error": false,
    "message": "Item updated successfully.",
    "id": 36,
    "data": {
              "id": 1,
    "title": "title",
    "price" : 100,
    "unit_id": 1,
    "description" : "description",
    "created_at": "2025-04-16 09:41:57",
    "updated_at": "2025-04-16 09:41:57"
             }

> Example response (422):

    {
      "error": true,
      "message": "Validation errors occurred",
      "errors": {
        "id": [
          "The  id field is required."
        ],
        "title": [
          "The title field is required."
        ],

      }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the item."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/items/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` string

The id of the item. Example: `1`

`title` string

The title of the item. Example: `Title`

`description` string optional

The description of the item. Example: `description`

`price` string optional

The price of the item. Example: `400`

`unit_id` string optional

The unit_id of the item. Example: `4`

## Remove the specified item.

requires authentication

This endpoint deletes a item based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/items/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/items/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Item deleted successfully.",
        "id": 1,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Item not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the Item."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/items/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the item to be deleted. Example: `1`

# Estimate Invoice Management

## List or search estimate invoices.

requires authentication

This endpoint retrieves a list of estimate invoices based on various filters. The user must be authenticated to perform this action. The request allows searching and sorting by different parameters.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/estimates-invoices?search=INVC-1001&sort=id&order=ASC&limit=10&offset=0" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/estimates-invoices"
    );

    const params = {
        "search": "INVC-1001",
        "sort": "id",
        "order": "ASC",
        "limit": "10",
        "offset": "0",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Estimate invoice retrieved successfully",
        "total": 1,
        "data": [
            {
                "id": 1,
                "client": {
                    "id": 2,
                    "name": "John Doe",
                    "email": "client@example.com",
                    "photo": "https://example.com/storage/photos/client.jpg"
                },
                "total": "₹ 1,000.00",
                "status": "Pending",
                "due_date": "2025-04-30",
                "created_by": "Admin User",
                "created_at": "2025-04-15",
                "updated_at": "2025-04-15"
            }
        ]
    }

> Example response (200):

    {
        "error": true,
        "message": "Estimate invoice not found",
        "total": 0,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Estimate invoices not found",
        "total": 0,
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/estimates-invoices`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the estimate invoice to retrieve. Example: `1`

#### Query Parameters

`search` string optional

optional The search term to filter invoices by id or note. Example: `INVC-1001`

`sort` string optional

optional The field to sort by. Defaults to "id". Sortable fields include: id, created_at, and updated_at. Example: `id`

`order` string optional

optional The sort order, either "ASC" or "DESC". Defaults to "DESC". Example: `ASC`

`limit` integer optional

optional The number of items per page for pagination. Example: `10`

`offset` integer optional

optional The offset for pagination. Example: `0`

## Store a new invoice or estimate.

requires authentication

This endpoint allows the creation of a new invoice or estimate by providing details such as client, dates, items, amount, and tax info. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/estimates-invoices/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"type\": \"invoice\",
        \"client_id\": 1,
        \"name\": \"Website Development\",
        \"address\": \"123 Main St.\",
        \"city\": \"New York\",
        \"state\": \"NY\",
        \"country\": \"USA\",
        \"zip_code\": \"10001\",
        \"phone\": \"+1234567890\",
        \"note\": \"Handle with urgency\",
        \"personal_note\": \"Discussed pricing\",
        \"from_date\": \"2024-01-01\",
        \"to_date\": \"2024-01-31\",
        \"status\": \"draft\",
        \"total\": \"1000.00\",
        \"tax_amount\": \"100.00\",
        \"final_total\": \"1100.00\",
        \"item_ids\": [
            1,
            2
        ],
        \"item\": [
            1,
            2
        ],
        \"quantity\": [
            2,
            1
        ],
        \"unit\": [
            1,
            2
        ],
        \"rate\": [
            \"500.00\",
            \"1000.00\"
        ],
        \"tax\": [
            1,
            2
        ],
        \"amount\": [
            \"1000.00\",
            \"1000.00\"
        ]
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/estimates-invoices/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "type": "invoice",
        "client_id": 1,
        "name": "Website Development",
        "address": "123 Main St.",
        "city": "New York",
        "state": "NY",
        "country": "USA",
        "zip_code": "10001",
        "phone": "+1234567890",
        "note": "Handle with urgency",
        "personal_note": "Discussed pricing",
        "from_date": "2024-01-01",
        "to_date": "2024-01-31",
        "status": "draft",
        "total": "1000.00",
        "tax_amount": "100.00",
        "final_total": "1100.00",
        "item_ids": [
            1,
            2
        ],
        "item": [
            1,
            2
        ],
        "quantity": [
            2,
            1
        ],
        "unit": [
            1,
            2
        ],
        "rate": [
            "500.00",
            "1000.00"
        ],
        "tax": [
            1,
            2
        ],
        "amount": [
            "1000.00",
            "1000.00"
        ]
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
      "error": false,
      "message": "Estimate/Invoice created successfully.",
      "data": {
        "id": 1,
        "type": "invoice",
        "client_id": 1,
        "from_date": "2024-01-01",
        "to_date": "2024-01-31",
        "total": "1000.00",
        "tax_amount": "100.00",
        "final_total": "1100.00",
        "status": "draft",
        "created_at": "2024-01-01T10:00:00.000000Z",
        "items": [...]
      }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred",
        "errors": {
            "type": [
                "The type field is required."
            ],
            "client_id": [
                "The client field is required."
            ],
            "from_date": [
                "The from date field is required and must be before the to date."
            ],
            "to_date": [
                "The to date field is required and must be after the from date."
            ],
            "final_total": [
                "The final total field is required and must be a valid currency format."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the estimate/invoice."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/estimates-invoices/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`type` string

Type of the document. Accepted values: estimate, invoice. Example: `invoice`

`client_id` integer

The ID of the client. Example: `1`

`name` string

The name/title of the estimate or invoice. Example: `Website Development`

`address` string optional

optional The address for the client. Example: `123 Main St.`

`city` string optional

optional The city of the client. Example: `New York`

`state` string optional

optional The state of the client. Example: `NY`

`country` string optional

optional The country of the client. Example: `USA`

`zip_code` string optional

optional The postal code. Example: `10001`

`phone` string optional

optional The phone number. Example: `+1234567890`

`note` string optional

optional General note. Example: `Handle with urgency`

`personal_note` string optional

optional Internal note. Example: `Discussed pricing`

`from_date` date

Start date. Format: Y-m-d. Example: `2024-01-01`

`to_date` date

End date. Format: Y-m-d. Example: `2024-01-31`

`status` string optional

optional Status of the document. Accepted values for invoice: not_specified, partially_paid, fully_paid, draft, cancelled, due. For estimate: not_specified, sent, accepted, draft, declined, expired. Example: `draft`

`total` string

Sub total amount. Format: currency. Example: `1000.00`

`tax_amount` string optional

optional Tax amount. Format: currency. Example: `100.00`

`final_total` string

Final total after taxes. Format: currency. Example: `1100.00`

`item_ids` string[] optional

optional IDs of selected items.

`item` string[]

Item IDs.

`quantity` string[]

Quantity per item.

`unit` string[] optional

optional Unit IDs for each item.

`rate` string[]

Rate per item.

`tax` string[] optional

optional Tax ID per item.

`amount` string[]

Total amount per item.

## Update an existing estimate or invoice.

requires authentication

This endpoint updates an existing estimate or invoice record with provided details including type, client, date range, financials, items, and notes. The request must be authenticated.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/estimates-invoices/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 5,
        \"type\": \"invoice\",
        \"client_id\": 2,
        \"name\": \"Invoice April 2024\",
        \"address\": \"123 Main St\",
        \"city\": \"New York\",
        \"state\": \"NY\",
        \"country\": \"USA\",
        \"zip_code\": \"10001\",
        \"phone\": \"+1 1234567890\",
        \"note\": \"Payment due within 15 days\",
        \"personal_note\": \"Send reminder after 10 days\",
        \"from_date\": \"2024-04-01\",
        \"to_date\": \"2024-04-30\",
        \"status\": \"due\",
        \"total\": \"1000.00\",
        \"tax_amount\": \"100.00\",
        \"final_total\": \"1100.00\",
        \"item\": [
            1,
            2,
            3
        ]
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/estimates-invoices/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 5,
        "type": "invoice",
        "client_id": 2,
        "name": "Invoice April 2024",
        "address": "123 Main St",
        "city": "New York",
        "state": "NY",
        "country": "USA",
        "zip_code": "10001",
        "phone": "+1 1234567890",
        "note": "Payment due within 15 days",
        "personal_note": "Send reminder after 10 days",
        "from_date": "2024-04-01",
        "to_date": "2024-04-30",
        "status": "due",
        "total": "1000.00",
        "tax_amount": "100.00",
        "final_total": "1100.00",
        "item": [
            1,
            2,
            3
        ]
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Estimate/Invoice updated successfully.",
        "data": {
            "id": 5,
            "type": "invoice",
            "client_id": 2,
            "from_date": "2024-04-01",
            "to_date": "2024-04-30",
            "total": "1000.00",
            "tax_amount": "100.00",
            "final_total": "1100.00"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation errors occurred.",
        "errors": {
            "client_id": [
                "The client field is required."
            ],
            "from_date": [
                "The from date must be a valid date."
            ],
            "to_date": [
                "The to date must be a valid date."
            ],
            "total": [
                "The total format is invalid."
            ],
            "final_total": [
                "The final total format is invalid."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the estimate or invoice."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/estimates-invoices/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` integer

The ID of the estimate or invoice to update. Example: `5`

`type` string

The type of the document. Accepted values: estimate, invoice. Example: `invoice`

`client_id` integer

The client ID associated with this document. Example: `2`

`name` string

The name or title of the document. Example: `Invoice April 2024`

`address` string optional

The billing address. Example: `123 Main St`

`city` string optional

The city name. Example: `New York`

`state` string optional

The state name. Example: `NY`

`country` string optional

The country name. Example: `USA`

`zip_code` string optional

The postal/zip code. Example: `10001`

`phone` string optional

The phone number. Example: `+1 1234567890`

`note` string optional

Additional notes. Example: `Payment due within 15 days`

`personal_note` string optional

A personal/internal note. Example: `Send reminder after 10 days`

`from_date` date

The start date for the invoice or estimate. Example: `2024-04-01`

`to_date` date

The end date for the invoice or estimate. Example: `2024-04-30`

`status` string optional

The status of the document depending on its type. For invoice: not_specified, partially_paid, fully_paid, draft, cancelled, due. For estimate: not_specified, sent, accepted, draft, declined, expired. Example: `due`

`total` string

The total before tax. Example: `1000.00`

`tax_amount` string optional

The tax amount. Example: `100.00`

`final_total` string

The final total after tax. Example: `1100.00`

`item` string[] optional

List of item IDs.

`quantity` object optional
`*` numeric

Quantity for each item. Example: `[2, 1, 3]`

`unit` object optional
`*` integer optional

Unit ID for each item. Example: `0`

`rate` object optional
`*` string

Rate for each item. Example: `["500.00", "200.00", "100.00"]`

`tax` object optional
`*` integer optional

Tax ID for each item. Example: `0`

`amount` object optional
`*` string

Calculated amount for each item. Example: `["1000.00", "200.00", "300.00"]`

## Remove the specified estimate invoice.

requires authentication

This endpoint deletes a estimate invoice based on the provided ID. The user must be authenticated to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/estimates-invoices/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/estimates-invoices/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Estimate Invoice deleted successfully.",
        "id": 1,
        "data": []
    }

> Example response (200):

    {
        "error": true,
        "message": "Estimate Invoice not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the Estimate Invoice."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/estimates-invoices/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the todo to be deleted. Example: `1`

# Email Management

## Generate a preview of an email.

requires authentication

This endpoint generates a preview of an email by replacing placeholders in the provided subject and body, and listing any attachments. The user must be authenticated to perform this action. The content can be base64-encoded if specified.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/emails/preview?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"subject\": \"Welcome Email\",
        \"body\": \"<p>Hello USER_NAME!<\\/p>\",
        \"placeholders\": null,
        \"attachments\": null,
        \"is_encoded\": \"1\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/emails/preview"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "subject": "Welcome Email",
        "body": "<p>Hello USER_NAME!<\/p>",
        "placeholders": null,
        "attachments": null,
        "is_encoded": "1"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "preview generated successfully!",
        "data": "<div><p>Hello John Doe!</p></div><hr><div><strong>Attachments:</strong><ul><li>attachment.pdf</li></ul></div>"
    }

> Example response (500):

    {
        "error": true,
        "message": "Failed to generate preview"
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/emails/preview`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`subject` string optional

optional The subject of the email. Defaults to 'No Subject'. Example: `Welcome Email`

`body` string

The body of the email, optionally base64-encoded. Example: `<p>Hello USER_NAME!</p>`

`placeholders` string[] optional

optional Key-value pairs of placeholders to replace in the subject and body.

`attachments` string[] optional

optional An array of files to include as attachments. Each file must not exceed the configured size limit.

`is_encoded` string optional

optional Indicates if the body is base64-encoded (value: '1'). Defaults to false. Example: `1`

## Send or schedule emails.

requires authentication

This endpoint sends or schedules emails to one or more recipients, using either a template or custom content. The user must be authenticated to perform this action. Attachments are supported, and scheduling is optional. Certain file extensions (e.g., zip, exe) are blocked for security.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/emails/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"emails\": [
            \"john.doe@example.com\"
        ],
        \"email_template_id\": 1,
        \"placeholders\": null,
        \"subject\": \"Welcome Email\",
        \"body\": \"<p>Hello!<\\/p>\",
        \"attachments\": null,
        \"scheduled_at\": \"2025-05-16 10:00:00\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/emails/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "emails": [
            "john.doe@example.com"
        ],
        "email_template_id": 1,
        "placeholders": null,
        "subject": "Welcome Email",
        "body": "<p>Hello!<\/p>",
        "attachments": null,
        "scheduled_at": "2025-05-16 10:00:00"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Emails sent successfully."
    }

> Example response (200):

    {
        "error": false,
        "message": "Emails scheduled successfully!"
    }

> Example response (422):

    {
        "error": true,
        "message": "The emails field is required."
    }

> Example response (422):

    {
        "error": true,
        "message": "Attachments with .zip, .exe and similar file types are not allowed for security reasons."
    }

> Example response (500):

    {
        "error": true,
        "message": "An unexpected error occurred while sending/scheduling the emails."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/emails/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`emails` string[]

An array of recipient email addresses. Each must be a valid email.

`email_template_id` integer optional

nullable The ID of the email template to use. Required if not sending a custom email. Must exist in the `email_templates` table. Example: `1`

`placeholders` string[] optional

nullable Key-value pairs of placeholders to replace in the template. Required if using a template.

`subject` string optional

nullable The subject of the email. Required if not using a template. Maximum length is 255 characters. Example: `Welcome Email`

`body` string optional

nullable The body of the email. Required if not using a template. Example: `<p>Hello!</p>`

`attachments` string[] optional

nullable An array of files to attach. Each file must not exceed the configured size limit and must not have blocked extensions (e.g., zip, exe).

`scheduled_at` string optional

nullable The date and time to schedule the email (format: YYYY-MM-DD HH:MM:SS). Must be in the future. Example: `2025-05-16 10:00:00`

## List scheduled emails or retrieve a single email.

requires authentication

This endpoint retrieves a paginated list of scheduled emails or a single email by ID, with optional search, sorting, and pagination parameters. The user must be authenticated, and access is restricted based on permissions (admin/all-data-access or user-owned emails). The response includes permission details for editing and deletion.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/emails/historyList/1?search=john.doe&sort=subject&order=ASC&limit=20&offset=10" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/emails/historyList/1"
    );

    const params = {
        "search": "john.doe",
        "sort": "subject",
        "order": "ASC",
        "limit": "20",
        "offset": "10",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Emails retrieved successfully.",
        "data": {
            "total": 5,
            "data": [
                {
                    "id": 1,
                    "to_email": "john.doe@example.com",
                    "subject": "Welcome Email",
                    "body": "<p>Hello John!</p>",
                    "status": "sent",
                    "scheduled_at": "2025-05-15 16:30:00",
                    "created_at": "2025-05-15 16:30:00",
                    "updated_at": "2025-05-15 16:30:00",
                    "user_id": 7,
                    "can_edit": true,
                    "can_delete": true
                }
            ],
            "permissions": {
                "can_edit": true,
                "can_delete": true
            }
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Email not found.",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed: The search field must be a string.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/emails/historyList/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the scheduled email to retrieve. If provided, returns a single email. Must exist in the `scheduled_emails` table. Example: `1`

#### Query Parameters

`search` string optional

optional Filters emails by recipient email or subject. Example: `john.doe`

`sort` string optional

optional The field to sort by (id, to_email, subject, scheduled_at, created_at, updated_at). Defaults to id. Example: `subject`

`order` string optional

optional The sort order (ASC, DESC). Defaults to DESC. Example: `ASC`

`limit` integer optional

optional The number of emails per page (1-100). Defaults to 10. Example: `20`

`offset` integer optional

optional The number of emails to skip. Defaults to 0. Example: `10`

## Delete a scheduled email.

requires authentication

This endpoint deletes a specific scheduled email record. The user must be authenticated and have appropriate permissions to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/emails/history/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/emails/history/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Scheduled Email deleted successfully!"
    }

> Example response (404):

    {
        "error": true,
        "message": "Scheduled Email not found"
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the scheduled email."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/emails/history/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the scheduled email to delete. Must exist in the `scheduled_emails` table. Example: `1`

## Retrieve email template data.

requires authentication

This endpoint fetches the details of a specific email template, including its subject, body, and placeholders (excluding default ones like CURRENT_YEAR, COMPANY_TITLE). The user must be authenticated to perform this action.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/emails/template-data/1?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/emails/template-data/1"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Template data retrieved successfully!",
        "data": {
            "id": 1,
            "subject": "Welcome Email",
            "body": "<p>Hello USER_NAME, welcome to COMPANY_TITLE!</p>",
            "placeholders": [
                "USER_NAME"
            ],
            "created_at": "2025-05-15 16:30:00",
            "updated_at": "2025-05-15 16:30:00"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Template not found"
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while retrieving the template data."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/emails/template-data/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the email template to retrieve. Must exist in the `email_templates` table. Example: `1`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

# Leads Management

## Create a new lead.

requires authentication

This endpoint creates a new lead in the system. The user must be authenticated and belong to the workspace. All required fields must be provided, and the email must be unique.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/leads/store?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"first_name\": \"John\",
        \"last_name\": \"Doe\",
        \"email\": \"john.doe@example.com\",
        \"phone\": \"1234567890\",
        \"country_code\": \"+1\",
        \"country_iso_code\": \"US\",
        \"source_id\": 3,
        \"stage_id\": 2,
        \"assigned_to\": 7,
        \"job_title\": \"Marketing Manager\",
        \"industry\": \"Technology\",
        \"company\": \"Acme Corp\",
        \"website\": \"https:\\/\\/acme.com\",
        \"linkedin\": \"https:\\/\\/linkedin.com\\/in\\/johndoe\",
        \"instagram\": \"https:\\/\\/instagram.com\\/johndoe\",
        \"facebook\": \"https:\\/\\/facebook.com\\/johndoe\",
        \"pinterest\": \"https:\\/\\/pinterest.com\\/johndoe\",
        \"city\": \"New York\",
        \"state\": \"NY\",
        \"zip\": \"10001\",
        \"country\": \"United States\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/leads/store"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "first_name": "John",
        "last_name": "Doe",
        "email": "john.doe@example.com",
        "phone": "1234567890",
        "country_code": "+1",
        "country_iso_code": "US",
        "source_id": 3,
        "stage_id": 2,
        "assigned_to": 7,
        "job_title": "Marketing Manager",
        "industry": "Technology",
        "company": "Acme Corp",
        "website": "https:\/\/acme.com",
        "linkedin": "https:\/\/linkedin.com\/in\/johndoe",
        "instagram": "https:\/\/instagram.com\/johndoe",
        "facebook": "https:\/\/facebook.com\/johndoe",
        "pinterest": "https:\/\/pinterest.com\/johndoe",
        "city": "New York",
        "state": "NY",
        "zip": "10001",
        "country": "United States"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead created successfully!",
        "data": {
            "id": 1,
            "first_name": "John",
            "last_name": "Doe",
            "email": "john.doe@example.com",
            "phone": "1234567890",
            "company": "Acme Corp",
            "stage_id": 2,
            "source_id": 3,
            "assigned_to": 7,
            "created_at": "2025-05-15T10:00:00.000000Z",
            "updated_at": "2025-05-15T10:00:00.000000Z"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "errors": {
            "email": [
                "The email field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the lead."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/leads/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`first_name` string

The first name of the lead. Max 255 characters. Example: `John`

`last_name` string

The last name of the lead. Max 255 characters. Example: `Doe`

`email` string

The email address of the lead. Must be unique. Example: `john.doe@example.com`

`phone` string

The phone number of the lead. Max 20 characters. Example: `1234567890`

`country_code` string

The country code for the phone number. Max 5 characters. Example: `+1`

`country_iso_code` string

The ISO 2-letter country code. Example: `US`

`source_id` integer

The ID of the lead source. Must exist in `lead_sources`. Example: `3`

`stage_id` integer

The ID of the lead stage. Must exist in `lead_stages`. Example: `2`

`assigned_to` integer

The ID of the user assigned to this lead. Must exist in `users`. Example: `7`

`job_title` string optional

optional The lead’s job title. Max 255 characters. Example: `Marketing Manager`

`industry` string optional

optional The industry the lead belongs to. Max 255 characters. Example: `Technology`

`company` string

The company name. Max 255 characters. Example: `Acme Corp`

`website` string optional

optional The company website URL. Must be a valid URL. Example: `https://acme.com`

`linkedin` string optional

optional The LinkedIn profile URL. Must be a valid URL. Example: `https://linkedin.com/in/johndoe`

`instagram` string optional

optional The Instagram profile URL. Must be a valid URL. Example: `https://instagram.com/johndoe`

`facebook` string optional

optional The Facebook profile URL. Must be a valid URL. Example: `https://facebook.com/johndoe`

`pinterest` string optional

optional The Pinterest profile URL. Must be a valid URL. Example: `https://pinterest.com/johndoe`

`city` string optional

optional The city of the lead. Max 255 characters. Example: `New York`

`state` string optional

optional The state of the lead. Max 255 characters. Example: `NY`

`zip` string optional

optional The zip/postal code. Max 20 characters. Example: `10001`

`country` string optional

optional The country of the lead. Max 255 characters. Example: `United States`

## Retrieve a specific lead.

requires authentication

This endpoint retrieves the details of a specific lead by its ID. The user must be authenticated and authorized to access the lead.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/leads/get/5" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/leads/get/5"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead retrieved successfully!",
        "data": {
            "id": 5,
            "first_name": "John",
            "last_name": "Doe",
            "email": "john.doe@example.com",
            "phone": "1234567890",
            "company": "Acme Corp",
            "stage_id": 2,
            "source_id": 3,
            "assigned_to": 7,
            "created_at": "2025-05-10T12:30:00.000000Z",
            "updated_at": "2025-05-15T09:12:00.000000Z"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Lead not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while retrieving the lead."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/leads/get/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the lead to retrieve. Must exist in the `leads` table. Example: `5`

## List leads with optional filters, sorting, and pagination.

requires authentication

This endpoint retrieves a paginated list of leads accessible to the authenticated user, with optional search, source and stage filters, date range filtering, and sorting. Permissions for editing and deleting are included in the response.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/leads/list?search=John&source_ids[]=1&source_ids[]=2&stage_ids[]=3&stage_ids[]=4&start_date=2025-01-01&end_date=2025-05-01&sort=newest&limit=20" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/leads/list"
    );

    const params = {
        "search": "John",
        "source_ids[0]": "1",
        "source_ids[1]": "2",
        "stage_ids[0]": "3",
        "stage_ids[1]": "4",
        "start_date": "2025-01-01",
        "end_date": "2025-05-01",
        "sort": "newest",
        "limit": "20",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Leads retrieved successfully!",
        "data": {
            "total": 50,
            "data": [
                {
                    "id": 1,
                    "first_name": "John",
                    "last_name": "Doe",
                    "email": "john.doe@example.com",
                    "phone": "1234567890",
                    "company": "Acme Corp",
                    "job_title": "Manager",
                    "source": {
                        "id": 1,
                        "name": "Website"
                    },
                    "stage": {
                        "id": 2,
                        "name": "Negotiation",
                        "color": "primary"
                    },
                    "assigned_user": {
                        "id": 5,
                        "name": "Jane Smith"
                    },
                    "created_at": "2025-01-10T12:00:00.000000Z",
                    "updated_at": "2025-05-15T10:00:00.000000Z",
                    "can_edit": true,
                    "can_delete": true
                }
            ],
            "permissions": {
                "can_edit": true,
                "can_delete": true
            }
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while retrieving the leads."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/leads/list`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### Query Parameters

`search` string optional

optional Filters leads by first name, last name, email, phone, company, job title, or ID. Example: `John`

`source_ids` string[] optional

optional Filters leads by one or more source IDs.

`stage_ids` string[] optional

optional Filters leads by one or more stage IDs.

`start_date` string optional

optional Filters leads created on or after this date (YYYY-MM-DD). Example: `2025-01-01`

`end_date` string optional

optional Filters leads created on or before this date (YYYY-MM-DD). Example: `2025-05-01`

`sort` string optional

optional Sorts leads by criteria (newest, oldest, recently-updated, earliest-updated). Defaults to newest. Example: `newest`

`limit` integer optional

optional Number of leads per page (1-100). Defaults to 10. Example: `20`

## Update a specific lead.

requires authentication

This endpoint updates the details of an existing lead. The user must be authenticated and belong to the workspace. The email must remain unique among other leads.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/leads/update/5?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"first_name\": \"John\",
        \"last_name\": \"Doe\",
        \"email\": \"john.doe@example.com\",
        \"phone\": \"1234567890\",
        \"country_code\": \"+1\",
        \"country_iso_code\": \"US\",
        \"source_id\": 3,
        \"stage_id\": 2,
        \"assigned_to\": 7,
        \"job_title\": \"CTO\",
        \"industry\": \"SaaS\",
        \"company\": \"Acme Corp\",
        \"website\": \"https:\\/\\/acme.com\",
        \"linkedin\": \"https:\\/\\/linkedin.com\\/in\\/johndoe\",
        \"instagram\": \"https:\\/\\/instagram.com\\/johndoe\",
        \"facebook\": \"https:\\/\\/facebook.com\\/johndoe\",
        \"pinterest\": \"https:\\/\\/pinterest.com\\/johndoe\",
        \"city\": \"San Francisco\",
        \"state\": \"CA\",
        \"zip\": \"94107\",
        \"country\": \"United States\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/leads/update/5"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "first_name": "John",
        "last_name": "Doe",
        "email": "john.doe@example.com",
        "phone": "1234567890",
        "country_code": "+1",
        "country_iso_code": "US",
        "source_id": 3,
        "stage_id": 2,
        "assigned_to": 7,
        "job_title": "CTO",
        "industry": "SaaS",
        "company": "Acme Corp",
        "website": "https:\/\/acme.com",
        "linkedin": "https:\/\/linkedin.com\/in\/johndoe",
        "instagram": "https:\/\/instagram.com\/johndoe",
        "facebook": "https:\/\/facebook.com\/johndoe",
        "pinterest": "https:\/\/pinterest.com\/johndoe",
        "city": "San Francisco",
        "state": "CA",
        "zip": "94107",
        "country": "United States"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead updated successfully!",
        "data": {
            "id": 5,
            "first_name": "John",
            "last_name": "Doe",
            "email": "john.doe@example.com",
            "phone": "1234567890",
            "company": "Acme Corp",
            "stage_id": 2,
            "source_id": 3,
            "assigned_to": 7,
            "created_at": "2025-05-10T12:30:00.000000Z",
            "updated_at": "2025-05-15T09:12:00.000000Z"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Lead not found."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "errors": {
            "email": [
                "The email has already been taken."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the lead."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/leads/update/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the lead to update. Must exist in the `leads` table. Example: `5`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`first_name` string

The first name of the lead. Max 255 characters. Example: `John`

`last_name` string

The last name of the lead. Max 255 characters. Example: `Doe`

`email` string

The email address. Must be unique except for this lead. Example: `john.doe@example.com`

`phone` string

The phone number. Max 20 characters. Example: `1234567890`

`country_code` string

The country code for the phone number. Max 5 characters. Example: `+1`

`country_iso_code` string

The ISO 2-letter country code. Example: `US`

`source_id` integer

The ID of the lead source. Must exist in `lead_sources`. Example: `3`

`stage_id` integer

The ID of the lead stage. Must exist in `lead_stages`. Example: `2`

`assigned_to` integer

The ID of the user assigned to this lead. Must exist in `users`. Example: `7`

`job_title` string optional

optional The lead’s job title. Max 255 characters. Example: `CTO`

`industry` string optional

optional The industry the lead belongs to. Max 255 characters. Example: `SaaS`

`company` string

The company name. Max 255 characters. Example: `Acme Corp`

`website` string optional

optional The company website URL. Must be a valid URL. Example: `https://acme.com`

`linkedin` string optional

optional The LinkedIn profile URL. Must be a valid URL. Example: `https://linkedin.com/in/johndoe`

`instagram` string optional

optional The Instagram profile URL. Must be a valid URL. Example: `https://instagram.com/johndoe`

`facebook` string optional

optional The Facebook profile URL. Must be a valid URL. Example: `https://facebook.com/johndoe`

`pinterest` string optional

optional The Pinterest profile URL. Must be a valid URL. Example: `https://pinterest.com/johndoe`

`city` string optional

optional The city of the lead. Max 255 characters. Example: `San Francisco`

`state` string optional

optional The state of the lead. Max 255 characters. Example: `CA`

`zip` string optional

optional The zip/postal code. Max 20 characters. Example: `94107`

`country` string optional

optional The country of the lead. Max 255 characters. Example: `United States`

## Delete a specific lead.

requires authentication

This endpoint deletes a specific lead by its ID. The user must be authenticated and have appropriate permissions to perform the deletion.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/leads/destroy/5" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/leads/destroy/5"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead deleted successfully!"
    }

> Example response (404):

    {
        "error": true,
        "message": "Lead not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the lead."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/leads/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the lead to delete. Must exist in the `leads` table. Example: `5`

## Create a new lead follow-up.

requires authentication

This endpoint creates a follow-up activity (such as call, email, or meeting) for a specific lead. The date and time are converted to UTC before storing.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/leads/follow-up/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"lead_id\": 12,
        \"assigned_to\": 5,
        \"type\": \"call\",
        \"status\": \"pending\",
        \"follow_up_at\": \"2025-06-20T14:30\",
        \"note\": \"Call scheduled with client to discuss proposal.\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/leads/follow-up/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "lead_id": 12,
        "assigned_to": 5,
        "type": "call",
        "status": "pending",
        "follow_up_at": "2025-06-20T14:30",
        "note": "Call scheduled with client to discuss proposal."
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Follow Up Created Successfully",
        "data": {
            "id": 101,
            "type": "lead_follow_up"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "The given data was invalid.",
        "errors": {
            "lead_id": [
                "The lead id field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Follow Up Couldn't Created.",
        "data": {
            "error": "...",
            "line": 123,
            "file": "/app/Http/Controllers/LeadFollowUpController.php"
        }
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/leads/follow-up/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`lead_id` integer

The ID of the lead to associate the follow-up with. Example: `12`

`assigned_to` integer

The ID of the user assigned to the follow-up. Example: `5`

`type` string

The type of follow-up. One of: email, sms, call, meeting, other. Example: `call`

`status` string

The current status of the follow-up. One of: pending, completed, rescheduled. Example: `pending`

`follow_up_at` string

The follow-up date and time in local format (Y-m-d\TH:i). Example: `2025-06-20T14:30`

`note` string optional

optional Additional notes for the follow-up. Max 255 characters. Example: `Call scheduled with client to discuss proposal.`

## Retrieve a specific lead follow-up.

requires authentication

This endpoint fetches the details of a lead follow-up for editing or displaying, including the related lead and assigned user.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/leads/follow-up/get/101" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/leads/follow-up/get/101"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Follow Up Retrived Successfully",
        "follow_up": {
            "id": 101,
            "lead_id": 12,
            "assigned_to": 5,
            "type": "call",
            "status": "pending",
            "follow_up_at": "2025-06-20T09:00:00.000000Z",
            "note": "Discuss proposal",
            "lead": {
                "id": 12,
                "first_name": "John",
                "last_name": "Doe"
            },
            "assigned_to_user": {
                "id": 5,
                "name": "Jane Smith"
            }
        }
    }

> Example response (404):

    {
        "message": "No query results for model [App\\Models\\LeadFollowUp] 101"
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/leads/follow-up/get/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the follow-up to retrieve. Example: `101`

## Update an existing lead follow-up.

requires authentication

This endpoint updates the details of an existing follow-up activity for a lead, including reassignment, type, and follow-up date.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/leads/follow-up/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 101,
        \"assigned_to\": 6,
        \"type\": \"email\",
        \"status\": \"completed\",
        \"follow_up_at\": \"2025-06-21T16:00\",
        \"note\": \"Follow-up completed.\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/leads/follow-up/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 101,
        "assigned_to": 6,
        "type": "email",
        "status": "completed",
        "follow_up_at": "2025-06-21T16:00",
        "note": "Follow-up completed."
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Follow Up Updated Successfully",
        "data": {
            "id": 101,
            "type": "lead_follow_up"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "The given data was invalid.",
        "errors": {
            "follow_up_at": [
                "The follow up at must be a valid date."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Follow Up Couldn't Be Updated.",
        "data": {
            "error": "...",
            "line": 123,
            "file": "/app/Http/Controllers/LeadFollowUpController.php"
        }
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/leads/follow-up/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` integer

The ID of the follow-up to update. Example: `101`

`assigned_to` integer

The ID of the user assigned to the follow-up. Example: `6`

`type` string

The type of follow-up. One of: email, sms, call, meeting, other. Example: `email`

`status` string

The current status. One of: pending, completed, rescheduled. Example: `completed`

`follow_up_at` string

The updated follow-up datetime in local format (Y-m-d\TH:i). Example: `2025-06-21T16:00`

`note` string optional

optional Optional follow-up notes. Max 255 characters. Example: `Follow-up completed.`

## Delete a lead follow-up.

requires authentication

This endpoint deletes a follow-up record permanently from the system.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/leads/follow-up/destroy/101" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/leads/follow-up/destroy/101"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead Follow Up deleted successfully"
    }

> Example response (404):

    {
        "error": true,
        "message": "Lead Follow Up not found"
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting Lead Follow Up.",
        "data": {
            "error": "...",
            "line": 123,
            "file": "/app/Services/DeletionService.php"
        }
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/leads/follow-up/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the follow-up to delete. Example: `101`

## Change the stage of a lead.

requires authentication

This endpoint updates the stage of a specific lead by its ID. The user must be authenticated and authorized to modify the lead.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/leads/stage-change?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 123,
        \"stage_id\": 5
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/leads/stage-change"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 123,
        "stage_id": 5
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead stage updated successfully!",
        "data": {
            "id": 123,
            "type": "lead",
            "activity_message": "Lead Stage Changed to Negotiation"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Lead not found."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "errors": {
            "stage_id": [
                "The selected stage_id is invalid."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the lead stage."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/leads/stage-change`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`id` integer

The ID of the lead to update. Must exist in the `leads` table. Example: `123`

`stage_id` integer

The ID of the new lead stage. Must exist in the `lead_stages` table. Example: `5`

## Convert a lead to a client.

requires authentication

This endpoint converts a lead to a client by creating a new client record with the lead's data. The user must be authenticated, and the lead must not already be converted.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/leads/43/convert-to-client" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/leads/43/convert-to-client"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "POST",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead converted to client successfully!",
        "data": {
            "id": 5,
            "first_name": "John",
            "last_name": "Doe",
            "email": "john.doe@example.com",
            "company": "Acme Corp"
        }
    }

> Example response (400):

    {
        "error": true,
        "message": "Lead is already converted to the client.",
        "id": 5
    }

> Example response (404):

    {
        "error": true,
        "message": "Lead not found."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "errors": {
            "email": [
                "The email has already been taken."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while converting the lead."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/leads/{lead_id}/convert-to-client`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`lead_id` integer

The ID of the lead. Example: `43`

`lead` integer

The ID of the lead to convert. Must exist in the `leads` table. Example: `5`

## Save the default view preference for leads.

requires authentication

This endpoint sets the default view preference (e.g., list or Kanban) for the authenticated user or client when viewing leads.

> Example request:

    curl --request PUT \
        "https://dev-taskify.taskhub.company/api/save-leads-view-preference?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"view\": \"kanban\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/save-leads-view-preference"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "view": "kanban"
    };

    fetch(url, {
        method: "PUT",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Default view set successfully!"
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while setting the default view."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

PUT `api/save-leads-view-preference`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`view` string

The preferred view type (e.g., list, kanban). Example: `kanban`

# Leads Source Management

## Create a new lead source.

requires authentication

This endpoint creates a new lead source with the provided name under the current workspace. The user must be authenticated and authorized to manage lead sources.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/lead-sources/store?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"name\": \"Referral\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/lead-sources/store"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "name": "Referral"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead source created successfully!",
        "data": {
            "id": 1,
            "name": "Referral",
            "workspace_id": 10,
            "created_at": "2025-05-20T10:00:00.000000Z",
            "updated_at": "2025-05-20T10:00:00.000000Z"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "errors": {
            "name": [
                "The name field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the lead source."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/lead-sources/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`name` string

The name of the lead source. Max 255 characters. Example: `Referral`

## Retrieve a specific lead source.

requires authentication

This endpoint retrieves the details of a specific lead source by its ID. The user must be authenticated and authorized to manage lead sources.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/lead-sources/get/1?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/lead-sources/get/1"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead source retrieved successfully!",
        "data": {
            "id": 1,
            "name": "Referral",
            "workspace_id": 10,
            "created_at": "2025-05-20T10:00:00.000000Z",
            "updated_at": "2025-05-20T10:00:00.000000Z"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Lead source not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while retrieving the lead source."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/lead-sources/get/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the lead source to retrieve. Must exist in the `lead_sources` table. Example: `1`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

## List lead sources with optional filters, sorting, and pagination.

requires authentication

This endpoint retrieves a paginated list of lead sources or a specific lead source by ID, with optional search, sorting, and pagination parameters. The response includes permission details for editing and deletion. The user must be authenticated and authorized to manage lead sources.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/lead-sources/list?id=1&search=Referral&sort=name&order=ASC&limit=20&offset=10" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/lead-sources/list"
    );

    const params = {
        "id": "1",
        "search": "Referral",
        "sort": "name",
        "order": "ASC",
        "limit": "20",
        "offset": "10",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead sources retrieved successfully!",
        "total": 25,
        "data": [
            {
                "id": 1,
                "name": "Referral",
                "workspace_id": 10,
                "created_at": "2025-05-20T10:00:00.000000Z",
                "updated_at": "2025-05-20T10:00:00.000000Z",
                "can_edit": true,
                "can_delete": true
            }
        ],
        "permissions": {
            "can_edit": true,
            "can_delete": true
        }
    }

> Example response (404):

    {
        "error": false,
        "message": "Lead source(s) not found.",
        "total": 0,
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while retrieving the lead sources."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/lead-sources/list`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### Query Parameters

`id` integer optional

optional The ID of a specific lead source to retrieve. Example: `1`

`search` string optional

optional Filters lead sources by name or ID. Example: `Referral`

`sort` string optional

optional The column to sort by (id, name, created_at, updated_at). Defaults to id. Example: `name`

`order` string optional

optional The sort order (ASC, DESC). Defaults to DESC. Example: `ASC`

`limit` integer optional

optional Number of lead sources per page (1-100). Defaults to 10. Example: `20`

`offset` integer optional

optional Number of lead sources to skip. Defaults to 0. Example: `10`

## Update a specific lead source.

requires authentication

This endpoint updates the name of an existing lead source identified by its ID. The user must be authenticated and authorized to manage lead sources.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/lead-sources/update?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 1,
        \"name\": \"Referral\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/lead-sources/update"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 1,
        "name": "Referral"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead source updated successfully!",
        "data": {
            "id": 1,
            "name": "Referral",
            "workspace_id": 10,
            "created_at": "2025-05-20T10:00:00.000000Z",
            "updated_at": "2025-05-20T10:05:00.000000Z"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Lead source not found."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "errors": {
            "id": [
                "The selected id is invalid."
            ],
            "name": [
                "The name field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the lead source."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/lead-sources/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`id` integer

The ID of the lead source to update. Must exist in the `lead_sources` table. Example: `1`

`name` string

The new name for the lead source. Max 255 characters. Example: `Referral`

## Delete a specific lead source.

requires authentication

This endpoint deletes a specific lead source by its ID. The user must be authenticated and authorized to manage lead sources.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/lead-sources/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/lead-sources/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead source deleted successfully!"
    }

> Example response (404):

    {
        "error": true,
        "message": "Lead source not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the lead source."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/lead-sources/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the lead source to delete. Must exist in the `lead_sources` table. Example: `1`

# Leads Stage Management

## Create a new lead stage.

requires authentication

This endpoint creates a new lead stage within the current workspace. It assigns a unique slug, sets the display order, and saves the provided name and color. The user must be authenticated and authorized to manage lead stages.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/lead-stages/store?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"name\": \"Contacted\",
        \"color\": \"success\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/lead-stages/store"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "name": "Contacted",
        "color": "success"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead stage created successfully!",
        "data": {
            "id": 12,
            "name": "Contacted",
            "slug": "contacted",
            "color": "success",
            "order": 3,
            "workspace_id": 1,
            "created_at": "2025-05-15T10:00:00.000000Z",
            "updated_at": "2025-05-15T10:00:00.000000Z"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "errors": {
            "name": [
                "The name field is required."
            ],
            "color": [
                "The color field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the lead stage."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/lead-stages/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`name` string

The name of the lead stage. Max 255 characters. Example: `Contacted`

`color` string

The color badge for the lead stage. Must be one of: primary, secondary, success, danger, info, dark, warning. Example: `success`

## List lead stages with optional filters, sorting, and pagination.

requires authentication

This endpoint retrieves a paginated list of lead stages for the current workspace, with optional search, sorting, and pagination parameters. The response includes permission details for editing and deletion. The user must be authenticated and authorized to manage lead stages.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/lead-stages/list?search=Proposal&sort=name&order=ASC&limit=20" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/lead-stages/list"
    );

    const params = {
        "search": "Proposal",
        "sort": "name",
        "order": "ASC",
        "limit": "20",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead stages retrieved successfully!",
        "data": {
            "total": 3,
            "data": [
                {
                    "id": 1,
                    "name": "New Lead",
                    "slug": "new-lead",
                    "color": "primary",
                    "order": 1,
                    "workspace_id": 1,
                    "created_at": "2025-05-10T12:30:00.000000Z",
                    "updated_at": "2025-05-15T09:12:00.000000Z",
                    "can_edit": true,
                    "can_delete": true
                },
                {
                    "id": 2,
                    "name": "Qualified",
                    "slug": "qualified",
                    "color": "success",
                    "order": 2,
                    "workspace_id": 1,
                    "created_at": "2025-05-10T12:30:00.000000Z",
                    "updated_at": "2025-05-15T09:12:00.000000Z",
                    "can_edit": true,
                    "can_delete": true
                }
            ],
            "permissions": {
                "can_edit": true,
                "can_delete": true
            }
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while retrieving the lead stages."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/lead-stages/list`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### Query Parameters

`search` string optional

optional Filters lead stages by name or ID. Example: `Proposal`

`sort` string optional

optional The column to sort by (id, name, order). Defaults to id. Example: `name`

`order` string optional

optional The sort order (ASC, DESC). Defaults to DESC. Example: `ASC`

`limit` integer optional

optional Number of lead stages per page (1-100). Defaults to 10. Example: `20`

## Update a specific lead stage.

requires authentication

This endpoint updates the details of an existing lead stage, including its name, slug, and color. The user must be authenticated and authorized to manage lead stages.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/lead-stages/update?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 3,
        \"name\": \"Proposal Sent\",
        \"color\": \"warning\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/lead-stages/update"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 3,
        "name": "Proposal Sent",
        "color": "warning"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead stage updated successfully!",
        "data": {
            "id": 3,
            "name": "Proposal Sent",
            "slug": "proposal-sent",
            "color": "warning",
            "order": 2,
            "workspace_id": 1,
            "created_at": "2025-05-10T12:30:00.000000Z",
            "updated_at": "2025-05-15T09:12:00.000000Z"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Lead stage not found."
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "errors": {
            "id": [
                "The selected id is invalid."
            ],
            "name": [
                "The name field is required."
            ],
            "color": [
                "The selected color is invalid."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the lead stage."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/lead-stages/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`id` integer

The ID of the lead stage to update. Must exist in the `lead_stages` table. Example: `3`

`name` string

The name of the lead stage. Max 255 characters. Example: `Proposal Sent`

`color` string

The color badge for the lead stage. Must be one of: primary, secondary, success, danger, info, dark, warning. Example: `warning`

## Delete a specific lead stage.

requires authentication

This endpoint deletes a specific lead stage by its ID and reorders the remaining stages to maintain sequence. The user must be authenticated and authorized to manage lead stages.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/lead-stages/destroy/4" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/lead-stages/destroy/4"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead stage deleted successfully!"
    }

> Example response (404):

    {
        "error": true,
        "message": "Lead stage not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the lead stage."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/lead-stages/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the lead stage to delete. Must exist in the `lead_stages` table. Example: `4`

## Reorder lead stages.

requires authentication

This endpoint updates the order of lead stages based on the provided array of IDs and positions. The user must be authenticated and authorized to manage lead stages.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/lead-stages/reorder?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"order\": [
            {
                \"id\": 1,
                \"position\": 1
            },
            {
                \"id\": 2,
                \"position\": 2
            }
        ]
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/lead-stages/reorder"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "order": [
            {
                "id": 1,
                "position": 1
            },
            {
                "id": 2,
                "position": 2
            }
        ]
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Lead stages reordered successfully!",
        "data": [
            {
                "id": 1,
                "name": "Qualified",
                "slug": "qualified",
                "color": "success",
                "order": 1,
                "workspace_id": 1,
                "created_at": "2025-05-10T12:30:00.000000Z",
                "updated_at": "2025-05-15T09:12:00.000000Z"
            },
            {
                "id": 2,
                "name": "Contacted",
                "slug": "contacted",
                "color": "info",
                "order": 2,
                "workspace_id": 1,
                "created_at": "2025-05-10T12:30:00.000000Z",
                "updated_at": "2025-05-15T09:12:00.000000Z"
            }
        ]
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "errors": {
            "order": [
                "The order field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while reordering the lead stages."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/lead-stages/reorder`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`order` string[]

An array of objects containing lead stage IDs and their new positions.

`id` integer

The ID of the lead stage to reorder. Must exist in the `lead_stages` table. Example: `1`

`position` integer

The new position for the lead stage. Example: `1`

# Custom Field Management

## Create a new custom field.

requires authentication

This endpoint allows the creation of a new custom field for either the project or task module. Depending on the field type, options may be required (for example: radio, checkbox, select). User must be authenticated.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/custom-fields" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"module\": \"task\",
        \"field_label\": \"Priority\",
        \"field_type\": \"select\",
        \"options\": \"High\\\\nMedium\\\\nLow\",
        \"required\": \"1\",
        \"visibility\": \"1\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/custom-fields"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "module": "task",
        "field_label": "Priority",
        "field_type": "select",
        "options": "High\\nMedium\\nLow",
        "required": "1",
        "visibility": "1"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Custom Field Created Successfully",
        "data": {
            "id": 12,
            "type": "custom_field"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "data": {
            "field_label": [
                "The field label field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Custom Field Couldn't Created.",
        "data": {
            "error": "Exception message",
            "line": 85,
            "file": "/var/www/html/app/Http/Controllers/CustomFieldController.php"
        }
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/custom-fields`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`module` string

The module this custom field belongs to. Must be one of: `project`, `task`. Example: `task`

`field_label` string

The label for the custom field. Example: `Priority`

`field_type` string

The type of the custom field. Must be one of: `text`, `number`, `password`, `textarea`, `radio`, `date`, `checkbox`, `select`. Example: `select`

`options` string optional

optional Required if field_type is `radio`, `checkbox`, or `select`. Provide one option per line. Example: `High\nMedium\nLow`

`required` string optional

optional Whether this field is required. Example: `1`

`visibility` string optional

optional Whether this field is visible to end users. Example: `1`

## List custom fields or retrieve a single custom field.

requires authentication

This endpoint retrieves a paginated list of custom fields or a single custom field by ID. Supports optional search, sorting, pagination, and filtering by module, label, or field type. User must be authenticated to access this endpoint.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/custom-fields/list?search=priority&sort=field_label&order=ASC&limit=20&offset=5" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/custom-fields/list"
    );

    const params = {
        "search": "priority",
        "sort": "field_label",
        "order": "ASC",
        "limit": "20",
        "offset": "5",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "CustomFields retrieved successfully!",
        "data": {
            "total": 2,
            "data": [
                {
                    "id": 3,
                    "module": "task",
                    "field_type": "select",
                    "field_label": "Priority",
                    "options": [
                        "High",
                        "Medium",
                        "Low"
                    ],
                    "required": "1",
                    "visibility": "1"
                }
            ]
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "CustomField not found",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed: The search field must be a string.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/custom-fields/list`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the custom field to retrieve. If provided, returns a single custom field. Example: `3`

#### Query Parameters

`search` string optional

optional Filter custom fields by module, field label, or field type. Example: `priority`

`sort` string optional

optional Field to sort by. Default is id. Example: `field_label`

`order` string optional

optional Sort direction: ASC or DESC. Default is DESC. Example: `ASC`

`limit` integer optional

optional Number of custom fields to return per page. Default is 10. Example: `20`

`offset` integer optional

optional The number of custom fields to skip. Default is 0. Example: `5`

## Update an existing custom field.

requires authentication

This endpoint updates the details of a custom field identified by its ID. Options are required if the field type is `radio`, `checkbox`, or `select`. User must be authenticated.

> Example request:

    curl --request PUT \
        "https://dev-taskify.taskhub.company/api/custom-fields/update/12" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"module\": \"project\",
        \"field_label\": \"Status\",
        \"field_type\": \"radio\",
        \"options\": \"Active\\\\nInactive\",
        \"required\": \"1\",
        \"visibility\": \"0\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/custom-fields/update/12"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "module": "project",
        "field_label": "Status",
        "field_type": "radio",
        "options": "Active\\nInactive",
        "required": "1",
        "visibility": "0"
    };

    fetch(url, {
        method: "PUT",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Custom field updated successfully",
        "data": {
            "id": 12,
            "type": "custom_field"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "data": {
            "field_label": [
                "The field label field is required."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": {
            "error": "Exception message",
            "line": 78,
            "file": "/var/www/html/app/Http/Controllers/CustomFieldController.php"
        }
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

PUT `api/custom-fields/update/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the custom field to update. Example: `12`

#### Body Parameters

`module` string

The module this custom field belongs to. Must be one of: `project`, `task`. Example: `project`

`field_label` string

The label for the custom field. Example: `Status`

`field_type` string

The type of the custom field. Must be one of: `text`, `number`, `password`, `textarea`, `radio`, `date`, `checkbox`, `select`. Example: `radio`

`options` string optional

optional Required if field_type is `radio`, `checkbox`, or `select`. Provide one option per line. Example: `Active\nInactive`

`required` string optional

optional Whether this field is required. Example: `1`

`visibility` string optional

optional Whether this field is visible to end users. Example: `0`

## Delete a custom field.

requires authentication

This endpoint deletes a specific custom field by ID. User must be authenticated.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/custom-fields/destroy/15" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/custom-fields/destroy/15"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "CustomField deleted successfully",
        "data": []
    }

> Example response (404):

    {
        "error": true,
        "message": "CustomField not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/custom-fields/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the custom field to delete. Example: `15`

# Payslip Management

## Create a new payslip.

Creates a new payslip with salary details, allowances, and deductions. Requires valid user ID, salary components, and optional payment information if marked as paid.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/payslips/store" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"user_id\": 3,
        \"month\": \"2025-05\",
        \"basic_salary\": 50000,
        \"working_days\": 22,
        \"lop_days\": 2,
        \"paid_days\": 20,
        \"bonus\": 2000,
        \"incentives\": 1500,
        \"leave_deduction\": 500,
        \"ot_hours\": 5,
        \"ot_rate\": 100,
        \"ot_payment\": 500,
        \"total_allowance\": 3500,
        \"total_deductions\": 500,
        \"total_earnings\": 53500,
        \"net_pay\": 53000,
        \"payment_method_id\": 2,
        \"payment_date\": \"2025-05-20\",
        \"status\": 1,
        \"note\": \"Bonus included for performance.\",
        \"allowances\": [
            1,
            2
        ],
        \"deductions\": [
            3,
            4
        ],
        \"isApi\": true
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/payslips/store"
    );

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "user_id": 3,
        "month": "2025-05",
        "basic_salary": 50000,
        "working_days": 22,
        "lop_days": 2,
        "paid_days": 20,
        "bonus": 2000,
        "incentives": 1500,
        "leave_deduction": 500,
        "ot_hours": 5,
        "ot_rate": 100,
        "ot_payment": 500,
        "total_allowance": 3500,
        "total_deductions": 500,
        "total_earnings": 53500,
        "net_pay": 53000,
        "payment_method_id": 2,
        "payment_date": "2025-05-20",
        "status": 1,
        "note": "Bonus included for performance.",
        "allowances": [
            1,
            2
        ],
        "deductions": [
            3,
            4
        ],
        "isApi": true
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Payslip created successfully.",
        "data": {
            "id": 10,
            "user_id": 3,
            "user_name": "John Doe",
            "month": "2025-05-01",
            "basic_salary": 50000,
            "working_days": 22,
            "lop_days": 2,
            "paid_days": 20,
            "bonus": 2000,
            "incentives": 1500,
            "leave_deduction": 500,
            "ot_hours": 5,
            "ot_rate": 100,
            "ot_payment": 500,
            "total_allowance": 3500,
            "total_deductions": 500,
            "total_earnings": 53500,
            "net_pay": 53000,
            "status": 1,
            "status_label": "Paid",
            "payment_method_id": 2,
            "payment_method": "Bank Transfer",
            "payment_date": "2025-05-20",
            "note": "Bonus included for performance.",
            "created_at": "2025-05-15",
            "updated_at": "2025-05-15"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "The given data was invalid.",
        "data": {
            "errors": {
                "user_id": [
                    "The user field is required."
                ],
                "basic_salary": [
                    "The basic salary must be a valid number with or without decimals."
                ]
            }
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/payslips/store`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`user_id` integer

The user ID. Example: `3`

`month` string

Month of payslip. Format: YYYY-MM. Example: `2025-05`

`basic_salary` number

Basic salary. Example: `50000`

`working_days` integer

Working days in the month. Example: `22`

`lop_days` integer

Loss of pay days. Example: `2`

`paid_days` integer

Paid days. Example: `20`

`bonus` number

Bonus amount. Example: `2000`

`incentives` number

Incentives amount. Example: `1500`

`leave_deduction` number

Leave deduction amount. Example: `500`

`ot_hours` integer

Overtime hours. Example: `5`

`ot_rate` number

Overtime rate per hour. Example: `100`

`ot_payment` number

Overtime payment. Example: `500`

`total_allowance` number

Total allowance amount. Example: `3500`

`total_deductions` number

Total deductions. Example: `500`

`total_earnings` number

Total earnings. Example: `53500`

`net_pay` number

Final payable amount. Example: `53000`

`payment_method_id` integer optional

optional Required if status is 1 (paid). Example: `2`

`payment_date` date optional

optional Required if status is 1 (paid). Format: Y-m-d. Example: `2025-05-20`

`status` integer

Payslip status (0 = Unpaid, 1 = Paid). Example: `1`

`note` string optional

optional Additional notes. Example: `Bonus included for performance.`

`allowances` string[] optional

optional Array of allowance IDs to associate with the payslip.

`deductions` string[] optional

optional Array of deduction IDs to associate with the payslip.

`isApi` boolean optional `true` `false`

optional Whether to return a formatted API response. Defaults to false. Example: `true`

## Update an existing payslip.

Updates an existing payslip by ID with revised salary and payment details. Fields must be validated as in creation.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/payslips/update" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 7,
        \"user_id\": 3,
        \"month\": \"2025-05\",
        \"basic_salary\": 50000,
        \"working_days\": 22,
        \"lop_days\": 2,
        \"paid_days\": 20,
        \"bonus\": 2000,
        \"incentives\": 1500,
        \"leave_deduction\": 500,
        \"ot_hours\": 5,
        \"ot_rate\": 100,
        \"ot_payment\": 500,
        \"total_allowance\": 3500,
        \"total_deductions\": 500,
        \"total_earnings\": 53500,
        \"net_pay\": 53000,
        \"payment_method_id\": 2,
        \"payment_date\": \"2025-05-20\",
        \"status\": 1,
        \"note\": \"Updated after bonus revision.\",
        \"allowances\": [
            1,
            2
        ],
        \"deductions\": [
            3,
            4
        ],
        \"isApi\": true
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/payslips/update"
    );

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 7,
        "user_id": 3,
        "month": "2025-05",
        "basic_salary": 50000,
        "working_days": 22,
        "lop_days": 2,
        "paid_days": 20,
        "bonus": 2000,
        "incentives": 1500,
        "leave_deduction": 500,
        "ot_hours": 5,
        "ot_rate": 100,
        "ot_payment": 500,
        "total_allowance": 3500,
        "total_deductions": 500,
        "total_earnings": 53500,
        "net_pay": 53000,
        "payment_method_id": 2,
        "payment_date": "2025-05-20",
        "status": 1,
        "note": "Updated after bonus revision.",
        "allowances": [
            1,
            2
        ],
        "deductions": [
            3,
            4
        ],
        "isApi": true
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Payslip updated successfully.",
        "data": {
            "id": 7,
            "user_id": 3,
            "user_name": "John Doe",
            "month": "2025-05-01",
            "basic_salary": 50000,
            "working_days": 22,
            "lop_days": 2,
            "paid_days": 20,
            "bonus": 2000,
            "incentives": 1500,
            "leave_deduction": 500,
            "ot_hours": 5,
            "ot_rate": 100,
            "ot_payment": 500,
            "total_allowance": 3500,
            "total_deductions": 500,
            "total_earnings": 53500,
            "net_pay": 53000,
            "status": 1,
            "status_label": "Paid",
            "payment_method_id": 2,
            "payment_method": "Bank Transfer",
            "payment_date": "2025-05-20",
            "note": "Updated after bonus revision.",
            "created_at": "2025-05-15",
            "updated_at": "2025-05-15"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Payslip not found.",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "The given data was invalid.",
        "data": {
            "errors": {
                "user_id": [
                    "The user field is required."
                ],
                "basic_salary": [
                    "The basic salary must be a valid number with or without decimals."
                ]
            }
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/payslips/update`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` integer

The ID of the payslip to update. Must exist in the `payslips` table. Example: `7`

`user_id` integer

The user ID. Example: `3`

`month` string

Month of payslip. Format: YYYY-MM. Example: `2025-05`

`basic_salary` number

Basic salary. Example: `50000`

`working_days` integer

Working days in the month. Example: `22`

`lop_days` integer

Loss of pay days. Example: `2`

`paid_days` integer

Paid days. Example: `20`

`bonus` number

Bonus amount. Example: `2000`

`incentives` number

Incentives amount. Example: `1500`

`leave_deduction` number

Leave deduction. Example: `500`

`ot_hours` integer

Overtime hours. Example: `5`

`ot_rate` number

Overtime rate. Example: `100`

`ot_payment` number

Overtime payment. Example: `500`

`total_allowance` number

Allowance total. Example: `3500`

`total_deductions` number

Deductions total. Example: `500`

`total_earnings` number

Earnings total. Example: `53500`

`net_pay` number

Net pay. Example: `53000`

`payment_method_id` integer optional

optional Required if status is 1 (paid). Example: `2`

`payment_date` date optional

optional Required if status is 1 (paid). Format: Y-m-d. Example: `2025-05-20`

`status` integer

Status (0 = Unpaid, 1 = Paid). Example: `1`

`note` string optional

optional Note text. Example: `Updated after bonus revision.`

`allowances` string[] optional

optional Array of allowance IDs to associate with the payslip.

`deductions` string[] optional

optional Array of deduction IDs to associate with the payslip.

`isApi` boolean optional `true` `false`

optional Whether to return a formatted API response. Defaults to false. Example: `true`

## Delete a payslip.

requires authentication

This endpoint deletes the specified payslip and detaches all associated allowances and deductions.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/payslips/destroy/10" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/payslips/destroy/10"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Payslip deleted successfully."
    }

> Example response (404):

    {
        "error": true,
        "message": "Payslip not found."
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/payslips/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the payslip to delete. Example: `10`

## List payslips with filtering (API format).

Retrieves a list of payslips in API format with support for searching, filtering by user, status, and month.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/payslips/list?search=PSL-5&sort=month&order=ASC&limit=20&statuses[]=0&statuses[]=1&user_ids[]=3&user_ids[]=4&created_by_user_ids[]=2&created_by_client_ids[]=1&month=2025-05" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/payslips/list"
    );

    const params = {
        "search": "PSL-5",
        "sort": "month",
        "order": "ASC",
        "limit": "20",
        "statuses[0]": "0",
        "statuses[1]": "1",
        "user_ids[0]": "3",
        "user_ids[1]": "4",
        "created_by_user_ids[0]": "2",
        "created_by_client_ids[0]": "1",
        "month": "2025-05",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Payslips retrieved successfully.",
        "data": {
            "total": 5,
            "data": [
                {
                    "id": 7,
                    "user_id": 3,
                    "user_name": "John Doe",
                    "month": "2025-05-01",
                    "basic_salary": 50000,
                    "working_days": 22,
                    "lop_days": 2,
                    "paid_days": 20,
                    "bonus": 2000,
                    "incentives": 1500,
                    "leave_deduction": 500,
                    "ot_hours": 5,
                    "ot_rate": 100,
                    "ot_payment": 500,
                    "total_allowance": 3500,
                    "total_deductions": 500,
                    "total_earnings": 53500,
                    "net_pay": 53000,
                    "status": 1,
                    "status_label": "Paid",
                    "payment_method_id": 2,
                    "payment_method": "Bank Transfer",
                    "payment_date": "2025-05-20",
                    "note": "Bonus included for performance.",
                    "created_at": "2025-05-15",
                    "updated_at": "2025-05-15"
                }
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/payslips/list`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### Query Parameters

`search` string optional

optional Search term to filter payslips by ID, note, or payment method. Example: `PSL-5`

`sort` string optional

optional Field to sort by. Defaults to id. Example: `month`

`order` string optional

optional Sort order: ASC or DESC. Defaults to DESC. Example: `ASC`

`limit` integer optional

optional Number of records to return. Default: 10. Example: `20`

`statuses` string[] optional

optional Filter by status values (0 = Unpaid, 1 = Paid).

`user_ids` string[] optional

optional Filter by user IDs.

`created_by_user_ids` string[] optional

optional Filter by user IDs who created the payslip.

`created_by_client_ids` string[] optional

optional Filter by client IDs who created the payslip.

`month` string optional

optional Filter by month. Format: YYYY-MM. Example: `2025-05`

# Deduction Management

## Create a new deduction.

Creates a deduction in the current workspace. Deductions can be of type `amount` or `percentage`.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/deductions/store" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"Income Tax\",
        \"type\": \"percentage\",
        \"amount\": \"150.00\",
        \"percentage\": \"5\",
        \"isApi\": true
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/deductions/store"
    );

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "Income Tax",
        "type": "percentage",
        "amount": "150.00",
        "percentage": "5",
        "isApi": true
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Deduction created successfully.",
        "data": {
            "id": 9,
            "title": "Income Tax",
            "type": "Percentage",
            "percentage": 5,
            "amount": "0.00",
            "created_at": "30 May, 2025",
            "updated_at": "30 May, 2025"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "The given data was invalid.",
        "data": {
            "errors": {
                "title": [
                    "The title field is required."
                ],
                "type": [
                    "The type field is required."
                ]
            }
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/deductions/store`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`title` string

The name/title of the deduction. Must be unique. Example: `Income Tax`

`type` string

The type of deduction. Either "amount" or "percentage". Example: `percentage`

`amount` string optional

The fixed amount for the deduction. Required if type is "amount". Example: `150.00`

`percentage` numeric optional

The percentage value of the deduction. Required if type is "percentage". Example: `5`

`isApi` boolean optional `true` `false`

optional Whether to return a formatted API response. Defaults to false. Example: `true`

## Get a deduction by ID.

Retrieves a specific deduction using its ID.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/deductions/get/1?isApi=1" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/deductions/get/1"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Deduction retrieved successfully.",
        "data": {
            "id": 1,
            "title": "Income Tax",
            "type": "Percentage",
            "percentage": 5,
            "amount": "0.00",
            "created_at": "30 May, 2025",
            "updated_at": "30 May, 2025"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "No query results for model [App\\Models\\Deduction] 9999",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/deductions/get/{id}`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the deduction to retrieve. Must exist in the `deductions` table. Example: `1`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Whether to return a formatted API response. Defaults to false. Example: `true`

## Get list of deductions.

Returns a list of deductions for the current workspace in API format, with optional filtering and sorting.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/deductions/list?search=Tax&sort=title&order=ASC&limit=25&types%5B%5D[]=percentage" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/deductions/list"
    );

    const params = {
        "search": "Tax",
        "sort": "title",
        "order": "ASC",
        "limit": "25",
        "types[][0]": "percentage",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
      "error": false,
      "message": "Deductions retrieved successfully.",
        "total": 1,
        "data": [
          {
            "id": 1
            "title": "Income Tax",
            "type": "Percentage",
            "percentage": 5,
            "amount": "0.00",
            "created_at": "30 May, 2025",
            "updated_at": "30 May, 2025"
          }
        ]
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/deductions/list`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### Query Parameters

`search` string optional

optional Search keyword to filter deductions. Example: `Tax`

`sort` string optional

optional Field to sort by. Defaults to "id". Example: `title`

`order` string optional

optional Sort order: ASC or DESC. Defaults to DESC. Example: `ASC`

`limit` integer optional

optional Number of records to return. Defaults to 10. Example: `25`

`types[]` string[] optional

optional Filter by deduction types. Options: amount, percentage.

## Update an existing deduction.

Updates the specified deduction in the current workspace.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/deductions/update" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 1,
        \"title\": \"Updated Income Tax\",
        \"type\": \"amount\",
        \"amount\": \"100.00\",
        \"percentage\": \"10\",
        \"isApi\": true
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/deductions/update"
    );

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 1,
        "title": "Updated Income Tax",
        "type": "amount",
        "amount": "100.00",
        "percentage": "10",
        "isApi": true
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Deduction updated successfully.",
        "data": {
            "id": 1,
            "title": "Updated Income Tax",
            "type": "Amount",
            "percentage": null,
            "amount": "100.00",
            "created_at": "30 May, 2025",
            "updated_at": "30 May, 2025"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "No query results for model [App\\Models\\Deduction] 9999",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "The given data was invalid.",
        "data": {
            "errors": {
                "title": [
                    "The title has already been taken."
                ]
            }
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/deductions/update`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` integer

The ID of the deduction to update. Must exist in the `deductions` table. Example: `1`

`title` string

The name/title of the deduction. Must be unique. Example: `Updated Income Tax`

`type` string

The type of deduction. Either "amount" or "percentage". Example: `amount`

`amount` string optional

optional The fixed amount for the deduction. Required if type is "amount". Example: `100.00`

`percentage` numeric optional

optional The percentage value of the deduction. Required if type is "percentage". Example: `10`

`isApi` boolean optional `true` `false`

optional Whether to return a formatted API response. Defaults to false. Example: `true`

## Delete a deduction.

Deletes the deduction with the given ID and detaches associated payslips.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/deductions/destroy/2" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/deductions/destroy/2"
    );

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Deduction deleted successfully.",
        "data": []
    }

> Example response (404):

    {
        "error": true,
        "message": "Deduction not found.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/deductions/destroy/{id}`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the deduction to delete. Must exist in the `deductions` table. Example: `2`

# Allowance Management

## Create a new allowance.

requires authentication

This endpoint creates a new allowance with the given title and amount. The user must be authenticated to perform this action. The request can be made via API or non-API calls, with an optional `isApi` parameter to format the response accordingly.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/allowances/store?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"Transport Allowance\",
        \"amount\": \"1500.00\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/allowances/store"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "Transport Allowance",
        "amount": "1500.00"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Allowance created successfully.",
        "data": {
            "id": 6,
            "title": "Transport Allowance",
            "amount": "$1,500.00",
            "created_at": "01 Dec 2024",
            "updated_at": "15:45:22"
        }
    }

> Example response (422):

    {
        "message": "The given data was invalid.",
        "errors": {
            "title": [
                "The title field is required."
            ],
            "amount": [
                "The amount format is invalid."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Allowance couldn't created.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/allowances/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`title` string

The title of the allowance. Must be unique. Example: `Transport Allowance`

`amount` string

The amount in currency format. Example: `1500.00`

## Update an existing allowance.

requires authentication

This endpoint allows you to update the title and amount of an existing allowance. The user must be authenticated and authorized to perform this action. The title must remain unique across all allowances. The request can be made via API or non-API calls, with an optional `isApi` parameter to format the response accordingly.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/allowances/update?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 5,
        \"title\": \"Housing Allowance\",
        \"amount\": \"1200.00\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/allowances/update"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 5,
        "title": "Housing Allowance",
        "amount": "1200.00"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Allowance updated successfully.",
        "data": {
            "id": 5,
            "title": "Housing Allowance",
            "amount": "$1,200.00",
            "created_at": "01 Dec 2024",
            "updated_at": "16:30:45"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Allowance not found!",
        "data": []
    }

> Example response (422):

    {
        "message": "The given data was invalid.",
        "errors": {
            "title": [
                "The title has already been taken."
            ],
            "amount": [
                "The amount format is invalid."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Allowance couldn't updated.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/allowances/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`id` integer

The ID of the allowance to update. Must exist in the `allowances` table. Example: `5`

`title` string

The title of the allowance. Must be unique in the `allowances` table. Example: `Housing Allowance`

`amount` string

The amount of the allowance. Must be a valid currency format. Example: `1200.00`

## Get allowances list

requires authentication

This endpoint returns a filtered and limited list of allowances, specifically formatted for API use. The user must be authenticated to perform this action. This endpoint provides search, sort, and limit functionality optimized for API consumers.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/allowances/list?search=Bonus&sort=amount&order=ASC&limit=5" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/allowances/list"
    );

    const params = {
        "search": "Bonus",
        "sort": "amount",
        "order": "ASC",
        "limit": "5",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Allowances retrieved successfully.",
        "total": 2,
        "data": [
            {
                "id": 1,
                "title": "Bonus",
                "amount": "$500.00",
                "created_at": "01 Dec 2024",
                "updated_at": "10:30:15"
            },
            {
                "id": 2,
                "title": "Medical",
                "amount": "$300.00",
                "created_at": "01 Dec 2024",
                "updated_at": "11:45:22"
            }
        ]
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/allowances/list`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### Query Parameters

`search` string optional

optional Search by ID, title, or amount. Example: `Bonus`

`sort` string optional

optional Column to sort by. Defaults to "id". Example: `amount`

`order` string optional

optional Sort order: ASC or DESC. Defaults to "DESC". Example: `ASC`

`limit` integer optional

optional Maximum number of records to return. Defaults to 10. Example: `5`

## Retrieve an allowance's details.

requires authentication

This endpoint fetches detailed information about a specific allowance by its ID. The user must be authenticated to perform this action. The request can be made via API or non-API calls, with an optional `isApi` parameter to format the response accordingly.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/allowances/get/5?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/allowances/get/5"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Allowance retrieved successfully.",
        "data": {
            "id": 5,
            "title": "Fuel Allowance",
            "amount": "$200.00",
            "created_at": "01 Dec 2024",
            "updated_at": "10:30:15"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Allowance not found!",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/allowances/get/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the allowance to retrieve. Must exist in the `allowances` table. Example: `5`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

## Delete an allowance.

requires authentication

This endpoint deletes a specific allowance by its ID and automatically detaches any related payslips. The user must be authenticated and authorized to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/allowances/destroy/7" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/allowances/destroy/7"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Allowance deleted successfully.",
        "data": []
    }

> Example response (404):

    {
        "error": true,
        "message": "Allowance not found!",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/allowances/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the allowance to delete. Must exist in the `allowances` table. Example: `7`

# Time Tracker Management

## Start a new time tracker.

Creates a new time tracking record for the authenticated user with the current start time and an optional message.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/time-tracker/store" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"message\": \"Working on project X\",
        \"isApi\": true
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/time-tracker/store"
    );

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "message": "Working on project X",
        "isApi": true
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Timer has been started successfully.",
        "data": {
            "id": 1,
            "user": "<a href=\"/users/3\">John Doe</a>",
            "start_date_time": "30 May, 2025 14:34:00",
            "end_date_time": "-",
            "message": "Working on project X",
            "created_at": "30 May, 2025",
            "updated_at": "30 May, 2025"
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/time-tracker/store`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`message` string optional

optional A description or note for the time tracking session. Example: `Working on project X`

`isApi` boolean optional `true` `false`

optional Whether to return a formatted API response. Defaults to false. Example: `true`

## Stop an existing time tracker.

Updates an existing time tracking record with the current end time and an optional message.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/time-tracker/update" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"record_id\": 1,
        \"message\": \"Completed project X task\",
        \"isApi\": true
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/time-tracker/update"
    );

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "record_id": 1,
        "message": "Completed project X task",
        "isApi": true
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Timer has been stopped successfully.",
        "data": {
            "id": 1,
            "user": "<a href=\"/users/3\">John Doe</a>",
            "start_date_time": "30 May, 2025 14:34:00",
            "end_date_time": "30 May, 2025 16:34:00",
            "message": "Completed project X task",
            "created_at": "30 May, 2025",
            "updated_at": "30 May, 2025"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "No query results for model [App\\Models\\TimeTracker] 9999",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/time-tracker/update`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`record_id` integer

The ID of the time tracker to stop. Must exist in the `time_trackers` table. Example: `1`

`message` string optional

optional A description or note for the time tracking session. Example: `Completed project X task`

`isApi` boolean optional `true` `false`

optional Whether to return a formatted API response. Defaults to false. Example: `true`

## Get list of time trackers.

Returns a list of time tracking records for the current workspace in API format, with optional filtering and sorting.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/time-tracker/list?search=project&sort=start_date_time&order=ASC&limit=20&offset=10&user_id=3&date_between_from=2025-05-01&date_between_to=2025-05-31&start_date_from=2025-05-01&start_date_to=2025-05-31&end_date_from=2025-05-01&end_date_to=2025-05-31" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/time-tracker/list"
    );

    const params = {
        "search": "project",
        "sort": "start_date_time",
        "order": "ASC",
        "limit": "20",
        "offset": "10",
        "user_id": "3",
        "date_between_from": "2025-05-01",
        "date_between_to": "2025-05-31",
        "start_date_from": "2025-05-01",
        "start_date_to": "2025-05-31",
        "end_date_from": "2025-05-01",
        "end_date_to": "2025-05-31",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Record(s) retrieved successfully!",
        "total": 1,
        "data": [
            {
                "id": 1,
                "user": "<a href=\"/users/3\">John Doe</a>",
                "start_date_time": "30 May, 2025 14:34:00",
                "end_date_time": "30 May, 2025 16:34:00",
                "message": "Working on project X",
                "created_at": "30 May, 2025",
                "updated_at": "30 May, 2025"
            }
        ]
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/time-tracker/list`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### Query Parameters

`search` string optional

optional Search term to filter time trackers by message. Example: `project`

`sort` string optional

optional Field to sort by. Defaults to id. Example: `start_date_time`

`order` string optional

optional Sort order: ASC or DESC. Defaults to DESC. Example: `ASC`

`limit` integer optional

optional Number of records to return. Defaults to 10. Example: `20`

`offset` integer optional

optional Number of records to skip. Defaults to 0. Example: `10`

`user_id` integer optional

optional Filter by user ID. Example: `3`

`date_between_from` string optional

optional Start date for filtering records (YYYY-MM-DD). Example: `2025-05-01`

`date_between_to` string optional

optional End date for filtering records (YYYY-MM-DD). Example: `2025-05-31`

`start_date_from` string optional

optional Start date for filtering start_date_time (YYYY-MM-DD). Example: `2025-05-01`

`start_date_to` string optional

optional End date for filtering start_date_time (YYYY-MM-DD). Example: `2025-05-31`

`end_date_from` string optional

optional Start date for filtering end_date_time (YYYY-MM-DD). Example: `2025-05-01`

`end_date_to` string optional

optional End date for filtering end_date_time (YYYY-MM-DD). Example: `2025-05-31`

## Delete a time tracker.

Deletes the specified time tracking record.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/time-tracker/destroy/1" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"isApi\": true
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/time-tracker/destroy/1"
    );

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "isApi": true
    };

    fetch(url, {
        method: "DELETE",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
      "error": false,
      "message": "Record deleted successfully.",

    }

> Example response (404):

    {
      "error": true,
      "message": "No query results for model [App\\Models\\TimeTracker] 9999",

    }

> Example response (500):

    {
      "error": true,
      "message": "An error occurred.",
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/time-tracker/destroy/{id}`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the time tracker to delete. Must exist in the `time_trackers` table. Example: `1`

#### Body Parameters

`isApi` boolean optional `true` `false`

optional Whether to return a formatted API response. Defaults to false. Example: `true`

# Task List Management

## Create a new task list.

Creates a new task list associated with a specific project.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/task-lists/store?isApi=1" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"name\": \"UI Tasks\",
        \"project_id\": 5
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/task-lists/store"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "name": "UI Tasks",
        "project_id": 5
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Task list created successfully.",
        "data": {
            "id": 1,
            "name": "UI Tasks",
            "project": "Website Redesign",
            "created_at": "30 May, 2025",
            "updated_at": "30 May, 2025"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "The given data was invalid.",
        "data": {
            "errors": {
                "name": [
                    "The name field is required."
                ],
                "project_id": [
                    "The selected project id is invalid."
                ]
            }
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Task list couldn't be created.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/task-lists/store`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Whether to return a JSON API response. Defaults to false. Example: `true`

#### Body Parameters

`name` string

The name of the task list. Max 255 characters. Example: `UI Tasks`

`project_id` integer

The ID of the project this task list belongs to. Must exist in the `projects` table. Example: `5`

## Update a task list.

Updates the name of an existing task list.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/task-lists/update?isApi=1" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 1,
        \"name\": \"Backend Tasks\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/task-lists/update"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 1,
        "name": "Backend Tasks"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Task list updated successfully.",
        "data": {
            "id": 1,
            "name": "Backend Tasks",
            "project": "Website Redesign",
            "created_at": "30 May, 2025",
            "updated_at": "30 May, 2025"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Task list not found.",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "The given data was invalid.",
        "data": {
            "errors": {
                "id": [
                    "The selected id is invalid."
                ],
                "name": [
                    "The name field is required."
                ]
            }
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "Task lists couldn't be updated.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/task-lists/update`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Whether to return a JSON API response. Defaults to false. Example: `true`

#### Body Parameters

`id` integer

The ID of the task list to update. Must exist in the `task_lists` table. Example: `1`

`name` string

The new name for the task list. Max 255 characters. Example: `Backend Tasks`

## Retrieve a specific task list.

Fetches a task list by its ID, including associated project details.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/task-lists/get/1?isApi=1" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/task-lists/get/1"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Task list retrieved successfully.",
        "data": {
            "id": 1,
            "name": "UI Tasks",
            "project": "Website Redesign",
            "created_at": "30 May, 2025",
            "updated_at": "30 May, 2025"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Task list not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/task-lists/get/{id}`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the task list to retrieve. Must exist in the `task_lists` table. Example: `1`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Whether to return a JSON API response. Defaults to false. Example: `true`

## Delete a task list.

Permanently deletes a task list by its ID.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/task-lists/destroy/1?isApi=1" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/task-lists/destroy/1"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Task list deleted successfully.",
        "data": []
    }

> Example response (404):

    {
        "error": true,
        "message": "Task list not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/task-lists/destroy/{id}`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the task list to delete. Must exist in the `task_lists` table. Example: `1`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Whether to return a JSON API response. Defaults to false. Example: `true`

## Get list of task lists (API format).

Returns a list of task lists for the current workspace in API format, with optional filtering and sorting.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/task-lists/list?search=UI&sort=name&order=ASC&limit=20" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/task-lists/list"
    );

    const params = {
        "search": "UI",
        "sort": "name",
        "order": "ASC",
        "limit": "20",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Task lists retrieved successfully.",
        "total": 1,
        "data": [
            {
                "id": 1,
                "name": "UI Tasks",
                "project": "Website Redesign",
                "created_at": "30 May, 2025",
                "updated_at": "30 May, 2025"
            }
        ]
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/task-lists/list`

#### Headers

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### Query Parameters

`search` string optional

optional Search keyword to filter task lists by name, ID, or project title. Example: `UI`

`sort` string optional

optional Field to sort by. Defaults to id. Example: `name`

`order` string optional

optional Sort order: ASC or DESC. Defaults to DESC. Example: `ASC`

`limit` integer optional

optional Number of records to return. Defaults to 10. Example: `20`

# Candidate Management

## Create a new candidate.

requires authentication

This endpoint creates a new candidate record with optional file attachments. The user must be authenticated to perform this action. The request validates candidate details and ensures the email is unique.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/candidate/store?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"name\": \"John Doe\",
        \"email\": \"john.doe@example.com\",
        \"phone\": \"+1234567890\",
        \"position\": \"Software Engineer\",
        \"source\": \"LinkedIn\",
        \"status_id\": 1,
        \"attachments\": null
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/candidate/store"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "name": "John Doe",
        "email": "john.doe@example.com",
        "phone": "+1234567890",
        "position": "Software Engineer",
        "source": "LinkedIn",
        "status_id": 1,
        "attachments": null
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (201):

    {
        "error": false,
        "message": "Candidate Created Successfully!",
        "data": {
            "id": 101,
            "name": "John Doe",
            "email": "john.doe@example.com",
            "phone": "+1234567890",
            "position": "Software Engineer",
            "source": "LinkedIn",
            "status_id": 1,
            "created_at": "2025-05-15 15:55:00"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "A candidate with this email already exists."
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the candidate."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/candidate/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`name` string

The name of the candidate. Maximum length is 255 characters. Example: `John Doe`

`email` string

The email address of the candidate. Must be a valid email and unique in the `candidates` table. Example: `john.doe@example.com`

`phone` string optional

nullable The phone number of the candidate. Maximum length is 15 characters. Example: `+1234567890`

`position` string

The position the candidate is applying for. Maximum length is 255 characters. Example: `Software Engineer`

`source` string

The source of the candidate (e.g., LinkedIn, Job Board). Maximum length is 255 characters. Example: `LinkedIn`

`status_id` integer

The ID of the candidate's status. Must exist in the `candidate_statuses` table. Example: `1`

`attachments` string[] optional

nullable An array of files to upload. Each file must be a valid type (pdf, doc, docx, jpg, jpeg, png) and not exceed the maximum size (configured in media-library.max_file_size).

## Update a candidate's details.

requires authentication

This endpoint updates the details of an existing candidate, with optional file attachments. The user must be authenticated to perform this action. The request validates candidate details and ensures the email remains unique.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/candidate/update/101?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"name\": \"John Doe\",
        \"email\": \"john.doe@example.com\",
        \"phone\": \"+1234567890\",
        \"position\": \"Software Engineer\",
        \"source\": \"LinkedIn\",
        \"status_id\": 1,
        \"attachments\": null
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/candidate/update/101"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "name": "John Doe",
        "email": "john.doe@example.com",
        "phone": "+1234567890",
        "position": "Software Engineer",
        "source": "LinkedIn",
        "status_id": 1,
        "attachments": null
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Candidate Created Successfully!",
        "data": {
            "id": 101,
            "name": "John Doe",
            "email": "john.doe@example.com",
            "phone": "+1234567890",
            "position": "Software Engineer",
            "source": "LinkedIn",
            "status_id": 1,
            "updated_at": "2025-05-15 16:00:00"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Candidate not found"
    }

> Example response (422):

    {
        "error": true,
        "message": "The email field must be a valid email address."
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the candidate."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/candidate/update/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the candidate to update. Must exist in the `candidates` table. Example: `101`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`name` string

The name of the candidate. Maximum length is 255 characters. Example: `John Doe`

`email` string

The email address of the candidate. Must be a valid email and unique in the `candidates` table (except for the current candidate). Example: `john.doe@example.com`

`phone` string optional

nullable The phone number of the candidate. Maximum length is 15 characters. Example: `+1234567890`

`position` string

The position the candidate is applying for. Maximum length is 255 characters. Example: `Software Engineer`

`source` string

The source of the candidate (e.g., LinkedIn, Job Board). Maximum length is 255 characters. Example: `LinkedIn`

`status_id` integer

The ID of the candidate's status. Must exist in the `candidate_statuses` table. Example: `1`

`attachments` string[] optional

nullable An array of files to upload. Each file must be a valid type (pdf, doc, docx, jpg, jpeg, png) and not exceed the maximum size (configured in media-library.max_file_size).

## Update a candidate's status.

requires authentication

This endpoint updates the status of a specific candidate. The user must be authenticated to perform this action. The request requires a valid status ID.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/candidate/101/update_status?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"status_id\": 2
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/candidate/101/update_status"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "status_id": 2
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Candidate Status Updated Successfully!",
        "data": []
    }

> Example response (404):

    {
        "error": true,
        "message": "Candidate not found"
    }

> Example response (422):

    {
        "error": true,
        "message": "The status_id field is required."
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the candidate status."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/candidate/{id}/update_status`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the candidate to update. Must exist in the `candidates` table. Example: `101`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`status_id` integer

The ID of the new status. Must exist in the `candidate_statuses` table. Example: `2`

## Delete a candidate.

requires authentication

This endpoint deletes a specific candidate record. The user must be authenticated and have appropriate permissions to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/candidate/destroy/101" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/candidate/destroy/101"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Candidate deleted successfully!"
    }

> Example response (404):

    {
        "error": true,
        "message": "Candidate not found"
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the candidate."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/candidate/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the candidate to delete. Must exist in the `candidates` table. Example: `101`

## List candidates or retrieve a single candidate.

requires authentication

This endpoint retrieves a paginated list of candidates or a single candidate by ID, with optional search, sorting, and status filtering. The user must be authenticated to perform this action. The response includes permission details for editing and deletion.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/candidate/list/101?search=John&sort=newest&limit=20&offset=10&candidate_status[]=1&candidate_status[]=2" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/candidate/list/101"
    );

    const params = {
        "search": "John",
        "sort": "newest",
        "limit": "20",
        "offset": "10",
        "candidate_status[0]": "1",
        "candidate_status[1]": "2",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Candidates retrieved successfully.",
        "total": 50,
        "data": [
            {
                "id": 101,
                "name": "John Doe",
                "email": "john.doe@example.com",
                "phone": "+1234567890",
                "position": "Software Engineer",
                "source": "LinkedIn",
                "status": {
                    "id": 1,
                    "name": "Applied"
                },
                "can_edit": true,
                "can_delete": true
            }
        ],
        "permissions": {
            "can_edit": true,
            "can_delete": true
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Candidate not found.",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed: The search field must be a string.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/candidate/list/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the candidate to retrieve. If provided, returns a single candidate. Must exist in the `candidates` table. Example: `101`

#### Query Parameters

`search` string optional

optional Filters candidates by name, position, source, or status name. Example: `John`

`sort` string optional

optional The field to sort by (id, newest, oldest, recently-updated, earliest-updated). Defaults to id. Example: `newest`

`limit` integer optional

optional The number of candidates per page (1-100). Defaults to 10. Example: `20`

`offset` integer optional

optional The number of candidates to skip. Defaults to 0. Example: `10`

`candidate_status` string[] optional

optional Filters candidates by status IDs. Each ID must exist in the `candidate_statuses` table.

## Retrieve a candidate's interview details.

requires authentication

This endpoint fetches the interview details for a specific candidate, including a rendered HTML partial for display. The user must be authenticated to perform this action. The request can be made via API or non-API calls, with an optional `isApi` parameter to format the response.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/candidate/101/interviews?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/candidate/101/interviews"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Interview details retrieved successfully!",
        "data": {
            "candidate": {
                "id": 101,
                "name": "John Doe",
                "email": "john.doe@example.com",
                "phone": "+1234567890",
                "position": "Software Engineer",
                "source": "LinkedIn",
                "status_id": 1
            },
            "html": "<div>...</div>"
        }
    }

> Example response (400):

    {
        "error": true,
        "message": "Invalid candidate ID!",
        "data": []
    }

> Example response (404):

    {
        "error": true,
        "message": "Candidate not found!",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred!",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/candidate/{id}/interviews`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the candidate whose interview details are to be retrieved. Must exist in the `candidates` table. Example: `101`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

## Upload attachments for a candidate.

requires authentication

This endpoint allows uploading one or more files as attachments for a specific candidate. The user must be authenticated to perform this action. The files must be of allowed types (PDF, DOC, DOCX, JPG, JPEG, PNG) and within the configured size limit.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/candidate/101/upload-attachment?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"attachments\": null
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/candidate/101/upload-attachment"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "attachments": null
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Files uploaded successfully!",
        "data": [
            {
                "id": 1,
                "name": "resume-1623456789_1234.pdf",
                "collection_name": "candidate-media",
                "mime_type": "application/pdf",
                "size": 512
            }
        ]
    }

> Example response (404):

    {
        "error": true,
        "message": "Candidate not found",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed: The attachments must be a file of type: pdf, doc, docx, jpg, jpeg, png.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/candidate/{id}/upload-attachment`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the candidate to associate the attachments with. Must exist in the `candidates` table. Example: `101`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`attachments` string[]

An array of files to upload. Each file must be a valid type (pdf, doc, docx, jpg, jpeg, png) and not exceed the maximum size (configured in media-library.max_file_size).

## Delete a candidate's attachment.

requires authentication

This endpoint deletes a specific media attachment associated with a candidate. The user must be authenticated and have appropriate permissions to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/candidate/candidate-media/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/candidate/candidate-media/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Attachment deleted successfully!"
    }

> Example response (404):

    {
        "error": true,
        "message": "Attachment not found"
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the attachment."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/candidate/candidate-media/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the media attachment to delete. Must exist in the `media` table. Example: `1`

## List attachments for a candidate.

requires authentication

This endpoint retrieves a paginated list of media attachments for a specific candidate, with optional search, sorting, and pagination parameters. The user must be authenticated to perform this action. The response includes permission details for deletion.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/candidate/101/attachments/list?search=resume&sort=name&order=ASC&limit=20&offset=10" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/candidate/101/attachments/list"
    );

    const params = {
        "search": "resume",
        "sort": "name",
        "order": "ASC",
        "limit": "20",
        "offset": "10",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Attachments retrieved successfully.",
        "data": {
            "total": 2,
            "data": [
                {
                    "id": 1,
                    "name": "resume.pdf",
                    "mime_type": "application/pdf",
                    "size": "512.34 KB",
                    "created_at": "15 May 2025",
                    "download_url": "https://example.com/candidate/101/attachment/1/download",
                    "view_url": "https://example.com/candidate/101/attachment/1/view",
                    "can_delete": true
                }
            ],
            "permissions": {
                "can_delete": true
            }
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Candidate not found.",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed: The search field must be a string.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/candidate/{id}/attachments/list`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the candidate whose attachments are to be listed. Must exist in the `candidates` table. Example: `101`

#### Query Parameters

`search` string optional

optional Filters attachments by name or mime type. Example: `resume`

`sort` string optional

optional The field to sort by (id, name, mime_type, size, created_at). Defaults to id. Example: `name`

`order` string optional

optional The sort order (ASC, DESC). Defaults to DESC. Example: `ASC`

`limit` integer optional

optional The number of attachments per page (1-100). Defaults to 10. Example: `20`

`offset` integer optional

optional The number of attachments to skip. Defaults to 0. Example: `10`

## Download a candidate's attachment.

requires authentication

This endpoint allows downloading a specific media attachment associated with a candidate. The user must be authenticated to perform this action. The response is a file download stream.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/candidate/101/attachment/1/download?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/candidate/101/attachment/1/download"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "content_type": "application/pdf",
        "disposition": "attachment; filename=resume.pdf"
    }

> Example response (404):

    {
        "error": true,
        "message": "Candidate not found",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/candidate/{candidateId}/attachment/{mediaId}/download`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`candidateId` integer

The ID of the candidate associated with the attachment. Must exist in the `candidates` table. Example: `101`

`mediaId` integer

The ID of the media attachment to download. Must exist in the `media` table. Example: `1`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use (returns JSON error if applicable). Defaults to false. Example: `true`

## View a candidate's attachment.

requires authentication

This endpoint allows viewing a specific media attachment associated with a candidate, if the file type is supported (PDF, DOC, DOCX, JPG, JPEG, PNG). The user must be authenticated to perform this action. The response is a file stream for viewable files or an error for unsupported types.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/candidate/101/attachment/1/view?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/candidate/101/attachment/1/view"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "content_type": "application/pdf",
        "disposition": "inline"
    }

> Example response (404):

    {
        "error": true,
        "message": "Candidate not found",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "File type not supported for viewing",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/candidate/{candidateId}/attachment/{mediaId}/view`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`candidateId` integer

The ID of the candidate associated with the attachment. Must exist in the `candidates` table. Example: `101`

`mediaId` integer

The ID of the media attachment to view. Must exist in the `media` table. Example: `1`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use (returns JSON error if applicable). Defaults to false. Example: `true`

## Retrieve a candidate's details.

requires authentication

This endpoint fetches detailed information about a specific candidate, including their status, interviews, and media attachments. The user must be authenticated to perform this action. The request can be made via API or non-API calls, with an optional `isApi` parameter to format the response accordingly.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/candidate/101/quick-view?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/candidate/101/quick-view"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Candidate details retrieved successfully!",
        "data": {
            "candidate": {
                "id": 101,
                "name": "John Doe",
                "email": "john.doe@example.com",
                "phone": "+1234567890",
                "position": "Software Engineer",
                "source": "LinkedIn",
                "status": "Applied",
                "created_at": "15 May 2025",
                "avatar": "https://example.com/storage/candidate-media/avatar.jpg"
            },
            "attachments": [
                {
                    "id": 1,
                    "name": "resume.pdf",
                    "type": "application/pdf",
                    "size": "512.34 KB",
                    "created_at": "15 May 2025",
                    "url": "https://example.com/storage/candidate-media/resume.pdf",
                    "is_image": false
                }
            ],
            "interviews": [
                {
                    "id": 1,
                    "candidate_name": "John Doe",
                    "interviewer": "Jane Smith",
                    "round": "Technical",
                    "scheduled_at": "2025-05-20 10:00:00",
                    "status": "Scheduled",
                    "location": "Online",
                    "mode": "Video",
                    "created_at": "15 May 2025",
                    "updated_at": "15 May 2025"
                }
            ]
        }
    }

> Example response (400):

    {
        "error": true,
        "message": "Candidate ID not found.",
        "data": []
    }

> Example response (404):

    {
        "error": true,
        "message": "Candidate not found!",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/candidate/{id}/quick-view`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the candidate to retrieve. Must exist in the `candidates` table. Example: `101`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

# Candidate Status Management

## Create a new candidate status.

requires authentication

This endpoint creates a new candidate status with a specified name and color. The user must be authenticated to perform this action. The status is automatically assigned an order based on the highest existing order plus one.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/candidate_status/store?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"name\": \"Interviewing\",
        \"color\": \"primary\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/candidate_status/store"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "name": "Interviewing",
        "color": "primary"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (201):

    {
        "error": false,
        "message": "Candidate status retrieved successfully!",
        "data": {
            "id": 1,
            "name": "Interviewing",
            "color": "primary",
            "order": 1,
            "created_at": "2025-05-15 16:11:00",
            "updated_at": "2025-05-15 16:11:00"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "The name field is required."
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the candidate status."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/candidate_status/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`name` string

The name of the candidate status. Maximum length is 255 characters. Example: `Interviewing`

`color` string

The color associated with the status (e.g., primary, success). Example: `primary`

## Update a candidate status.

requires authentication

This endpoint updates the name and color of an existing candidate status. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/candidate_status/update/1?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"name\": \"Interviewing\",
        \"color\": \"success\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/candidate_status/update/1"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "name": "Interviewing",
        "color": "success"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Candidate status updated successfully!",
        "data": {
            "id": 1,
            "name": "Interviewing",
            "color": "success",
            "order": 1,
            "created_at": "2025-05-15 16:11:00",
            "updated_at": "2025-05-15 16:12:00"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Candidate status not found"
    }

> Example response (422):

    {
        "error": true,
        "message": "The name field is required."
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the candidate status."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/candidate_status/update/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the candidate status to update. Must exist in the `candidate_statuses` table. Example: `1`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`name` string

The name of the candidate status. Maximum length is 255 characters. Example: `Interviewing`

`color` string optional

optional The color associated with the status (e.g., primary, success). Example: `success`

## Delete a candidate status.

requires authentication

This endpoint deletes a specific candidate status. The user must be authenticated and have appropriate permissions. The status cannot be deleted if it is assigned to one or more candidates.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/candidate_status/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/candidate_status/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Candidate Status deleted successfully!"
    }

> Example response (400):

    {
        "error": false,
        "message": "Cannot delete. This status is assigned to one or more candidates."
    }

> Example response (404):

    {
        "error": true,
        "message": "Candidate status not found"
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the candidate status."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/candidate_status/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the candidate status to delete. Must exist in the `candidate_statuses` table. Example: `1`

## Reorder candidate statuses.

requires authentication

This endpoint updates the order of candidate statuses based on the provided array of IDs and positions. The user must be authenticated to perform this action.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/candidate_status/reorder" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"order\": [
            {
                \"id\": 1,
                \"position\": 1
            },
            {
                \"id\": 2,
                \"position\": 2
            }
        ]
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/candidate_status/reorder"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "order": [
            {
                "id": 1,
                "position": 1
            },
            {
                "id": 2,
                "position": 2
            }
        ]
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Order updated successfully!",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "The order field is required."
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while reordering the candidate statuses."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/candidate_status/reorder`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`order` string[]

An array of objects containing status IDs and their new positions.

## List candidate statuses or retrieve a single status.

requires authentication

This endpoint retrieves a paginated list of candidate statuses or a single status by ID, with optional search, sorting, and pagination parameters. The user must be authenticated to perform this action. The response includes permission details for editing and deletion.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/candidate_status/list/1?search=Interview&sort=name&order=ASC&limit=20&offset=10" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/candidate_status/list/1"
    );

    const params = {
        "search": "Interview",
        "sort": "name",
        "order": "ASC",
        "limit": "20",
        "offset": "10",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Candidate statuses retreived successfully!",
        "data": {
            "total": 5,
            "data": [
                {
                    "id": 1,
                    "name": "Interviewing",
                    "color": "primary",
                    "order": 1,
                    "created_at": "2025-05-15 16:11:00",
                    "updated_at": "2025-05-15 16:11:00",
                    "can_edit": true,
                    "can_delete": true
                }
            ],
            "permissions": {
                "can_edit": true,
                "can_delete": true
            }
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Candidate stutus not found.",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed: The search field must be a string.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/candidate_status/list/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the candidate status to retrieve. If provided, returns a single status. Must exist in the `candidate_statuses` table. Example: `1`

#### Query Parameters

`search` string optional

optional Filters statuses by name. Example: `Interview`

`sort` string optional

optional The field to sort by (id, name, color, order, created_at, updated_at). Defaults to id. Example: `name`

`order` string optional

optional The sort order (ASC, DESC). Defaults to DESC. Example: `ASC`

`limit` integer optional

optional The number of statuses per page (1-100). Defaults to 10. Example: `20`

`offset` integer optional

optional The number of statuses to skip. Defaults to 0. Example: `10`

# Contract Management

## Create a new contract.

requires authentication

This endpoint creates a new contract with the specified details. The user must be authenticated to perform this action. If the user is a client, the client_id will be automatically set to their ID.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/contracts/store" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"title\": \"Web Development Contract\",
        \"value\": \"15,000.00\",
        \"start_date\": \"2024-01-01\",
        \"end_date\": \"2024-12-31\",
        \"client_id\": 5,
        \"project_id\": 12,
        \"contract_type_id\": 3,
        \"description\": \"Full-stack web development project\",
        \"isApi\": true
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/contracts/store"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "title": "Web Development Contract",
        "value": "15,000.00",
        "start_date": "2024-01-01",
        "end_date": "2024-12-31",
        "client_id": 5,
        "project_id": 12,
        "contract_type_id": 3,
        "description": "Full-stack web development project",
        "isApi": true
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Contract created successfully.",
        "data": {
            "id": 15,
            "title": "Web Development Contract",
            "value": "15000.00",
            "formatted_value": "$15,000.00",
            "start_date": "2024-01-01",
            "end_date": "2024-12-31",
            "client": {
                "id": 5,
                "name": "John Doe"
            },
            "project": {
                "id": 12,
                "title": "Company Website"
            },
            "contract_type": {
                "id": 3,
                "type": "Fixed Price"
            },
            "description": "Full-stack web development project",
            "status": "not_signed",
            "created_at": "2024-01-15T10:30:00Z"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "data": {
            "title": [
                "The title field is required."
            ],
            "value": [
                "The value field is required."
            ],
            "start_date": [
                "The start date must be before end date."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/contracts/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`title` string

The title of the contract. Example: `Web Development Contract`

`value` string

The contract value in currency format. Must be a valid currency format. Example: `15,000.00`

`start_date` string

The start date of the contract. Format depends on API usage (Y-m-d for API, system format for web). Example: `2024-01-01`

`end_date` string

The end date of the contract. Must be after start_date. Example: `2024-12-31`

`client_id` integer

The ID of the client. Must exist in the clients table. Example: `5`

`project_id` integer

The ID of the project. Must exist in the projects table. Example: `12`

`contract_type_id` integer

The ID of the contract type. Must exist in the contract_types table. Example: `3`

`description` string optional

optional Description of the contract. Example: `Full-stack web development project`

`isApi` boolean optional `true` `false`

optional Set to true for API requests to handle date format properly. Example: `true`

## Update an existing contract.

requires authentication

This endpoint updates an existing contract with new details. The user must be authenticated and have permission to edit contracts.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/contracts/update" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: multipart/form-data" \
        --form "id=15"\
        --form "title=Updated Web Development Contract"\
        --form "value=18,000.00"\
        --form "start_date=2024-01-01"\
        --form "end_date=2024-12-31"\
        --form "client_id=5"\
        --form "project_id=12"\
        --form "contract_type_id=3"\
        --form "description=Updated full-stack web development project"\
        --form "isApi=1"\
        --form "signed_pdf=@/tmp/phposkI2w"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/contracts/update"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "multipart/form-data",
    };

    const body = new FormData();
    body.append('id', '15');
    body.append('title', 'Updated Web Development Contract');
    body.append('value', '18,000.00');
    body.append('start_date', '2024-01-01');
    body.append('end_date', '2024-12-31');
    body.append('client_id', '5');
    body.append('project_id', '12');
    body.append('contract_type_id', '3');
    body.append('description', 'Updated full-stack web development project');
    body.append('isApi', '1');
    body.append('signed_pdf', document.querySelector('input[name="signed_pdf"]').files[0]);

    fetch(url, {
        method: "POST",
        headers,
        body,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Contract updated successfully.",
        "data": {
            "id": 15,
            "title": "Updated Web Development Contract",
            "value": "18000.00",
            "formatted_value": "$18,000.00",
            "start_date": "2024-01-01",
            "end_date": "2024-12-31",
            "client": {
                "id": 5,
                "name": "John Doe"
            },
            "project": {
                "id": 12,
                "title": "Company Website"
            },
            "contract_type": {
                "id": 3,
                "type": "Fixed Price"
            },
            "description": "Updated full-stack web development project",
            "status": "partially_signed",
            "signed_pdf_url": "storage/contracts/signed_contract_123.pdf",
            "updated_at": "2024-01-20T14:45:00Z"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Contract not found.",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "data": {
            "signed_pdf": [
                "The file must be a PDF.",
                "The file size must be less than 10 MB."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/contracts/update`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `multipart/form-data`

#### Body Parameters

`id` integer

The ID of the contract to update. Must exist in the contracts table. Example: `15`

`title` string

The title of the contract. Example: `Updated Web Development Contract`

`value` string

The contract value in currency format. Must be a valid currency format. Example: `18,000.00`

`start_date` string

The start date of the contract. Format depends on API usage. Example: `2024-01-01`

`end_date` string

The end date of the contract. Must be after start_date. Example: `2024-12-31`

`client_id` integer

The ID of the client. Must exist in the clients table. Example: `5`

`project_id` integer

The ID of the project. Must exist in the projects table. Example: `12`

`contract_type_id` integer

The ID of the contract type. Must exist in the contract_types table. Example: `3`

`description` string optional

optional Description of the contract. Example: `Updated full-stack web development project`

`signed_pdf` file optional

optional The signed PDF file. Must be a PDF file, max 10MB. No example required. Example: `/tmp/phposkI2w`

`isApi` boolean optional `true` `false`

optional Set to true for API requests to handle date format properly. Example: `true`

## List contracts with filtering and pagination.

requires authentication

This endpoint retrieves a paginated list of contracts with optional search, sorting, and filtering capabilities. The user must be authenticated to perform this action. Access is restricted based on user permissions.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/contracts/list?search=Web+Development&sort=start_date&order=ASC&limit=20&statuses[]=signed&statuses[]=partially_signed&type_ids[]=1&type_ids[]=3&type_ids[]=5&project_ids[]=12&project_ids[]=15&project_ids[]=18&client_ids[]=5&client_ids[]=8&date_between_from=2024-01-01&date_between_to=2024-12-31&start_date_from=2024-01-01&start_date_to=2024-06-30&end_date_from=2024-06-01&end_date_to=2024-12-31" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/contracts/list"
    );

    const params = {
        "search": "Web Development",
        "sort": "start_date",
        "order": "ASC",
        "limit": "20",
        "statuses[0]": "signed",
        "statuses[1]": "partially_signed",
        "type_ids[0]": "1",
        "type_ids[1]": "3",
        "type_ids[2]": "5",
        "project_ids[0]": "12",
        "project_ids[1]": "15",
        "project_ids[2]": "18",
        "client_ids[0]": "5",
        "client_ids[1]": "8",
        "date_between_from": "2024-01-01",
        "date_between_to": "2024-12-31",
        "start_date_from": "2024-01-01",
        "start_date_to": "2024-06-30",
        "end_date_from": "2024-06-01",
        "end_date_to": "2024-12-31",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Contracts retrieved successfully!",
        "total": 25,
        "data": [
            {
                "id": 15,
                "title": "Web Development Contract",
                "value": "15000.00",
                "formatted_value": "$15,000.00",
                "start_date": "2024-01-01",
                "end_date": "2024-12-31",
                "duration": "Jan 01, 2024 To Dec 31, 2024",
                "client": {
                    "id": 5,
                    "name": "John Doe",
                    "email": "john@example.com"
                },
                "project": {
                    "id": 12,
                    "title": "Company Website"
                },
                "contract_type": {
                    "id": 3,
                    "type": "Fixed Price"
                },
                "description": "Full-stack web development project",
                "status": "signed",
                "promisor_signed": true,
                "promisee_signed": true,
                "signed_pdf_url": "storage/contracts/signed_contract_123.pdf",
                "created_by": {
                    "id": 1,
                    "name": "Admin User",
                    "type": "user"
                },
                "created_at": "2024-01-15T10:30:00Z",
                "updated_at": "2024-01-20T14:45:00Z"
            }
        ]
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "data": {
            "limit": [
                "The limit must be between 1 and 100."
            ],
            "start_date_from": [
                "The start date from must be a valid date."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/contracts/list`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### Query Parameters

`search` string optional

optional Filters contracts by title, value, description, or contract ID. Example: `Web Development`

`sort` string optional

optional The field to sort by (id, title, value, start_date, end_date, created_at). Defaults to id. Example: `start_date`

`order` string optional

optional The sort order (ASC or DESC). Defaults to DESC. Example: `ASC`

`limit` integer optional

optional The number of contracts per page (1-100). Defaults to 10. Example: `20`

`statuses` string[] optional

optional Filters contracts by status (signed, partially_signed, not_signed).

`type_ids` string[] optional

optional Filters contracts by contract type IDs. Each ID must exist in contract_types table.

`project_ids` string[] optional

optional Filters contracts by project IDs. Each ID must exist in projects table.

`client_ids` string[] optional

optional Filters contracts by client IDs. Each ID must exist in clients table.

`date_between_from` string optional

optional Filter contracts that start on or after this date. Format: Y-m-d. Example: `2024-01-01`

`date_between_to` string optional

optional Filter contracts that end on or before this date. Format: Y-m-d. Example: `2024-12-31`

`start_date_from` string optional

optional Filter contracts with start date from this date. Format: Y-m-d. Example: `2024-01-01`

`start_date_to` string optional

optional Filter contracts with start date until this date. Format: Y-m-d. Example: `2024-06-30`

`end_date_from` string optional

optional Filter contracts with end date from this date. Format: Y-m-d. Example: `2024-06-01`

`end_date_to` string optional

optional Filter contracts with end date until this date. Format: Y-m-d. Example: `2024-12-31`

## Retrieve a single contract by ID.

requires authentication

This endpoint retrieves detailed information about a specific contract. The user must be authenticated and have access to the contract based on their permissions.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/contracts/get/15?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/contracts/get/15"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Contract retrieved successfully.",
        "data": {
            "id": 15,
            "title": "Web Development Contract",
            "value": "15000.00",
            "formatted_value": "$15,000.00",
            "start_date": "2024-01-01",
            "end_date": "2024-12-31",
            "client": {
                "id": 5,
                "name": "John Doe",
                "email": "john@example.com",
                "phone": "+1234567890"
            },
            "project": {
                "id": 12,
                "title": "Company Website",
                "description": "Modern responsive website"
            },
            "contract_type": {
                "id": 3,
                "type": "Fixed Price"
            },
            "description": "Full-stack web development project",
            "status": "signed",
            "promisor_signed": true,
            "promisee_signed": true,
            "promisor_sign_date": "2024-01-18T09:15:00Z",
            "promisee_sign_date": "2024-01-19T14:22:00Z",
            "signed_pdf_url": "storage/contracts/signed_contract_123.pdf",
            "created_by": {
                "id": 1,
                "name": "Admin User",
                "type": "user"
            },
            "workspace_id": 1,
            "created_at": "2024-01-15T10:30:00Z",
            "updated_at": "2024-01-20T14:45:00Z"
        }
    }

> Example response (403):

    {
        "error": true,
        "message": "Access denied.",
        "data": []
    }

> Example response (404):

    {
        "error": true,
        "message": "Contract not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/contracts/get/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the contract to retrieve. Must exist in the contracts table. Example: `15`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Set to true for API requests. Example: `true`

## Sign a contract with a base64 image.

requires authentication

This endpoint allows an authenticated user to sign a contract by uploading a base64-encoded signature image. The user must have appropriate permissions based on their role (admin or client). The image is saved, and the corresponding signature field in the contract is updated.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/contracts/create-sign?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 12,
        \"signatureImage\": \"data:image\\/png;base64,iVBORw0KGgoAAAANSUhEUgAA...\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/contracts/create-sign"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 12,
        "signatureImage": "data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "id": 12,
        "activity_message": "John Doe signed contract NDA Agreement"
    }

> Example response (422):

    {
        "error": true,
        "message": "The id field is required. (and 1 more error)"
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/contracts/create-sign`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional If true, returns a formatted API response instead of a regular JSON response. Example: `true`

#### Body Parameters

`id` integer

The ID of the contract to sign. Example: `12`

`signatureImage` string

A base64-encoded PNG image string of the signature. Must include the data URI prefix (e.g., "data:image/png;base64,..."). Example: `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...`

## Delete a contract and associated files.

requires authentication

This endpoint deletes a contract by its ID, including associated signature images and the signed PDF file (if any). Only authorized users can perform this operation.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/contracts/destroy/15" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/contracts/destroy/15"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Contract deleted successfully!",
        "data": []
    }

> Example response (404):

    {
        "error": true,
        "message": "Contract not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/contracts/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the contract to delete. Example: `15`

## Remove signature from a contract.

requires authentication

This endpoint allows authorized users to remove their signature from a contract, effectively "unsigned" the contract.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/contracts/delete-sign/15?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/contracts/delete-sign/15"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "John Doe unsigned contract Web Development Contract",
        "id": 15
    }

> Example response (403):

    {
        "error": true,
        "message": "Unauthorized access.",
        "data": []
    }

> Example response (404):

    {
        "error": true,
        "message": "Contract not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/contracts/delete-sign/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the contract to remove signature from. Must exist in the contracts table. Example: `15`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Set to true for API requests. Example: `true`

# Contract Type Management

## Create a new contract type.

requires authentication

This endpoint creates a new contract type that can be used when creating contracts. The user must be authenticated and have permission to create contract types.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/contracts/store-contract-type" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"type\": \"Hourly Rate\",
        \"isApi\": true
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/contracts/store-contract-type"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "type": "Hourly Rate",
        "isApi": true
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Contract type created successfully.",
        "data": {
            "id": 5,
            "type": "Hourly Rate",
            "workspace_id": 1,
            "created_at": "2024-01-15T10:30:00Z",
            "updated_at": "2024-01-15T10:30:00Z"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "data": {
            "type": [
                "The type field is required.",
                "The type has already been taken."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/contracts/store-contract-type`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`type` string

The name of the contract type. Must be unique. Example: `Hourly Rate`

`isApi` boolean optional `true` `false`

optional Set to true for API requests. Example: `true`

## Update an existing contract type.

requires authentication

This endpoint updates an existing contract type with new details. The user must be authenticated and have permission to edit contract types.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/contracts/update-contract-type" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"id\": 3,
        \"type\": \"Updated Monthly Retainer\",
        \"isApi\": true
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/contracts/update-contract-type"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "id": 3,
        "type": "Updated Monthly Retainer",
        "isApi": true
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Contract type updated successfully.",
        "data": {
            "id": 3,
            "type": "Updated Monthly Retainer",
            "workspace_id": 1,
            "created_at": "2024-01-03T10:30:00Z",
            "updated_at": "2024-01-20T15:45:00Z"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Contract type not found.",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "data": {
            "type": [
                "The type field is required.",
                "The type has already been taken."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/contracts/update-contract-type`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Body Parameters

`id` integer

The ID of the contract type to update. Must exist in the contract_types table. Example: `3`

`type` string

The updated name of the contract type. Must be unique (excluding current record). Example: `Updated Monthly Retainer`

`isApi` boolean optional `true` `false`

optional Set to true for API requests. Example: `true`

## List contract types with filtering and pagination.

requires authentication

This endpoint retrieves a paginated list of contract types with optional search and sorting capabilities. The user must be authenticated to perform this action.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/contracts/contract-types-list?search=Fixed&sort=type&order=ASC&limit=20" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/contracts/contract-types-list"
    );

    const params = {
        "search": "Fixed",
        "sort": "type",
        "order": "ASC",
        "limit": "20",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Contract types retrieved successfully.",
        "total": 8,
        "data": [
            {
                "id": 1,
                "type": "Fixed Price",
                "workspace_id": 1,
                "created_at": "2024-01-01T08:00:00Z",
                "updated_at": "2024-01-01T08:00:00Z"
            },
            {
                "id": 2,
                "type": "Time & Materials",
                "workspace_id": 1,
                "created_at": "2024-01-02T09:15:00Z",
                "updated_at": "2024-01-02T09:15:00Z"
            },
            {
                "id": 3,
                "type": "Monthly Retainer",
                "workspace_id": 1,
                "created_at": "2024-01-03T10:30:00Z",
                "updated_at": "2024-01-03T10:30:00Z"
            }
        ]
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed.",
        "data": {
            "limit": [
                "The limit must be between 1 and 100."
            ]
        }
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/contracts/contract-types-list`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### Query Parameters

`search` string optional

optional Filters contract types by type name or ID. Example: `Fixed`

`sort` string optional

optional The field to sort by (id, type, created_at, updated_at). Defaults to id. Example: `type`

`order` string optional

optional The sort order (ASC or DESC). Defaults to DESC. Example: `ASC`

`limit` integer optional

optional The number of contract types per page (1-100). Defaults to 10. Example: `20`

## Retrieve a single contract type by ID.

requires authentication

This endpoint retrieves detailed information about a specific contract type. The user must be authenticated and have access to the contract type.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/contracts/get-contract-type/3?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/contracts/get-contract-type/3"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Contract type retrieved successfully.",
        "data": {
            "id": 3,
            "type": "Monthly Retainer",
            "workspace_id": 1,
            "created_at": "2024-01-03T10:30:00Z",
            "updated_at": "2024-01-03T10:30:00Z"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Contract type not found.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/contracts/get-contract-type/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the contract type to retrieve. Must exist in the contract_types table. Example: `3`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Set to true for API requests. Example: `true`

## Delete a contract type.

requires authentication

This endpoint deletes a contract type. Any contracts using this type will be updated to use the default contract type (ID: 0). The user must be authenticated and have permission to delete contract types.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/contracts/delete-contract-type/5?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/contracts/delete-contract-type/5"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Contract type deleted successfully.",
        "data": {
            "id": 5,
            "type": "Hourly Rate",
            "workspace_id": 1
        }
    }

> Example response (403):

    {
        "error": true,
        "message": "Default contract type cannot be deleted.",
        "data": []
    }

> Example response (404):

    {
        "error": true,
        "message": "Contract type not found.",
        "data": []
    }

> Example response (409):

    {
        "error": true,
        "message": "Cannot delete contract type as it is being used by existing contracts.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/contracts/delete-contract-type/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the contract type to delete. Must exist in the contract_types table and cannot be the default type (ID: 0). Example: `5`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Set to true for API requests. Example: `true`

# Email Template Management

## Create a new email template.

requires authentication

This endpoint creates a new email template with a specified name, subject, and body. The user must be authenticated to perform this action. The body can be base64-encoded if specified. Placeholders are automatically extracted from the body, excluding system constants like COMPANY_LOGO.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/email-templates/store?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"name\": \"Welcome Template\",
        \"subject\": \"Welcome to Our Company\",
        \"body\": \"<p>Hello USER_NAME!<\\/p>\",
        \"is_encoded\": \"1\",
        \"content\": \"PGh0bWw+PHA+SGVsbG8ge1VTRVJfTkFNRX0hPC9wPjwvaHRtbD4=\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/email-templates/store"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "name": "Welcome Template",
        "subject": "Welcome to Our Company",
        "body": "<p>Hello USER_NAME!<\/p>",
        "is_encoded": "1",
        "content": "PGh0bWw+PHA+SGVsbG8ge1VTRVJfTkFNRX0hPC9wPjwvaHRtbD4="
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (201):

    {
        "error": false,
        "message": "Email Template Created Successfully!",
        "data": {
            "id": 1,
            "name": "Welcome Template",
            "subject": "Welcome to Our Company",
            "body": "<p>Hello USER_NAME!</p>",
            "placeholders": [
                "USER_NAME"
            ],
            "workspace_id": 1,
            "created_at": "2025-05-15 17:00:00",
            "updated_at": "2025-05-15 17:00:00"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "The name field is required."
    }

> Example response (500):

    {
        "error": "Detailed error message",
        "message": "Failed to create email template",
        "code": 0,
        "file": "path/to/file.php",
        "line": 123,
        "trace": "Stack trace"
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/email-templates/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`name` string

The name of the email template. Maximum length is 255 characters. Example: `Welcome Template`

`subject` string

The subject of the email template. Maximum length is 255 characters. Example: `Welcome to Our Company`

`body` string optional

nullable The body of the email template, optionally base64-encoded. Example: `<p>Hello USER_NAME!</p>`

`is_encoded` string optional

optional Indicates if the body is base64-encoded (value: '1'). Defaults to false. Example: `1`

`content` string optional

optional The base64-encoded body content, used if is_encoded is '1'. Example: `PGh0bWw+PHA+SGVsbG8ge1VTRVJfTkFNRX0hPC9wPjwvaHRtbD4=`

## Update an existing email template.

requires authentication

This endpoint updates the name, subject, and body of an existing email template. The user must be authenticated to perform this action. The body can be base64-encoded if specified. Placeholders are automatically extracted from the body, excluding system constants like COMPANY_LOGO.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/email-templates/update/1?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"name\": \"Welcome Template\",
        \"subject\": \"Welcome to Our Company\",
        \"body\": \"<p>Hello USER_NAME!<\\/p>\",
        \"is_encoded\": \"1\",
        \"content\": \"PGh0bWw+PHA+SGVsbG8ge1VTRVJfTkFNRX0hPC9wPjwvaHRtbD4=\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/email-templates/update/1"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "name": "Welcome Template",
        "subject": "Welcome to Our Company",
        "body": "<p>Hello USER_NAME!<\/p>",
        "is_encoded": "1",
        "content": "PGh0bWw+PHA+SGVsbG8ge1VTRVJfTkFNRX0hPC9wPjwvaHRtbD4="
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Email Template Updated Successfully!",
        "data": {
            "id": 1,
            "name": "Welcome Template",
            "subject": "Welcome to Our Company",
            "body": "<p>Hello USER_NAME!</p>",
            "placeholders": [
                "USER_NAME"
            ],
            "workspace_id": 1,
            "created_at": "2025-05-15 17:00:00",
            "updated_at": "2025-05-15 17:05:00"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Email template not found"
    }

> Example response (422):

    {
        "error": true,
        "message": "The name field is required."
    }

> Example response (500):

    {
        "error": true,
        "message": "Something went wrong."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/email-templates/update/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the email template to update. Must exist in the `email_templates` table. Example: `1`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`name` string

The name of the email template. Maximum length is 255 characters. Example: `Welcome Template`

`subject` string

The subject of the email template. Maximum length is 255 characters. Example: `Welcome to Our Company`

`body` string

The body of the email template, optionally base64-encoded. Example: `<p>Hello USER_NAME!</p>`

`is_encoded` string optional

optional Indicates if the body is base64-encoded (value: '1'). Defaults to false. Example: `1`

`content` string optional

optional The base64-encoded body content, used if is_encoded is '1'. Example: `PGh0bWw+PHA+SGVsbG8ge1VTRVJfTkFNRX0hPC9wPjwvaHRtbD4=`

## Delete an email template.

requires authentication

This endpoint deletes a specific email template. The user must be authenticated and have appropriate permissions to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/email-templates/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/email-templates/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Email Template deleted successfully!"
    }

> Example response (404):

    {
        "error": true,
        "message": "Email template not found"
    }

> Example response (500):

    {
        "error": true,
        "message": "Something went wrong."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/email-templates/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the email template to delete. Must exist in the `email_templates` table. Example: `1`

## List email templates or retrieve a single template.

requires authentication

This endpoint retrieves a paginated list of email templates or a single template by ID, with optional search, sorting, and pagination parameters. The user must be authenticated to perform this action. The response includes permission details for editing and deletion.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/email-templates/list/1?search=Welcome&sort=name&order=ASC&limit=20&offset=10" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/email-templates/list/1"
    );

    const params = {
        "search": "Welcome",
        "sort": "name",
        "order": "ASC",
        "limit": "20",
        "offset": "10",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Email templates retrieved successfully.",
        "data": {
            "total": 5,
            "data": [
                {
                    "id": 1,
                    "name": "Welcome Template",
                    "subject": "Welcome to Our Company",
                    "body": "<p>Hello USER_NAME!</p>",
                    "placeholders": [
                        "USER_NAME"
                    ],
                    "workspace_id": 1,
                    "created_at": "2025-05-15 17:00:00",
                    "updated_at": "2025-05-15 17:00:00",
                    "can_edit": true,
                    "can_delete": true
                }
            ],
            "permissions": {
                "can_edit": true,
                "can_delete": true
            }
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Email template not found.",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed: The search field must be a string.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/email-templates/list/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the email template to retrieve. If provided, returns a single template. Must exist in the `email_templates` table. Example: `1`

#### Query Parameters

`search` string optional

optional Filters templates by name, subject, or body. Example: `Welcome`

`sort` string optional

optional The field to sort by (id, name, subject, created_at, updated_at). Defaults to id. Example: `name`

`order` string optional

optional The sort order (ASC, DESC). Defaults to DESC. Example: `ASC`

`limit` integer optional

optional The number of templates per page (1-100). Defaults to 10. Example: `20`

`offset` integer optional

optional The number of templates to skip. Defaults to 0. Example: `10`

# Interview Management

## Create a new interview.

requires authentication

This endpoint creates a new interview record for a candidate, with details such as the interviewer, round, schedule, mode, and status. The user must be authenticated to perform this action. A notification is triggered to inform the candidate and interviewer.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/interviews/store?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"candidate_id\": 101,
        \"interviewer_id\": 7,
        \"round\": \"Technical\",
        \"scheduled_at\": \"2025-05-20 10:00:00\",
        \"mode\": \"Online\",
        \"location\": \"Zoom\",
        \"status\": \"scheduled\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/interviews/store"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "candidate_id": 101,
        "interviewer_id": 7,
        "round": "Technical",
        "scheduled_at": "2025-05-20 10:00:00",
        "mode": "Online",
        "location": "Zoom",
        "status": "scheduled"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (201):

    {
        "error": false,
        "message": "Interview Created Successfully!",
        "data": {
            "id": 1,
            "candidate_id": 101,
            "interviewer_id": 7,
            "round": "Technical",
            "scheduled_at": "2025-05-20 10:00:00",
            "mode": "Online",
            "location": "Zoom",
            "status": "scheduled",
            "created_at": "2025-05-15 16:15:00",
            "updated_at": "2025-05-15 16:15:00"
        }
    }

> Example response (422):

    {
        "error": true,
        "message": "The candidate_id field is required."
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while creating the interview."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/interviews/store`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`candidate_id` integer

The ID of the candidate for the interview. Must exist in the `candidates` table. Example: `101`

`interviewer_id` integer

The ID of the interviewer. Must exist in the `users` table. Example: `7`

`round` string

The interview round (e.g., Technical, HR). Maximum length is 255 characters. Example: `Technical`

`scheduled_at` string

The date and time of the interview (format: YYYY-MM-DD HH:MM:SS). Example: `2025-05-20 10:00:00`

`mode` string

The mode of the interview (e.g., Online, In-Person). Maximum length is 255 characters. Example: `Online`

`location` string optional

nullable The location of the interview (if applicable). Maximum length is 255 characters. Example: `Zoom`

`status` string

The status of the interview. Must be one of: scheduled, completed, cancelled. Example: `scheduled`

## Update an interview.

requires authentication

This endpoint updates the details of an existing interview, such as the candidate, interviewer, round, schedule, mode, location, or status. The user must be authenticated to perform this action. A notification is triggered if the status changes.

> Example request:

    curl --request POST \
        "https://dev-taskify.taskhub.company/api/interviews/update/1?isApi=1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1" \
        --header "Content-Type: application/json" \
        --data "{
        \"candidate_id\": 101,
        \"interviewer_id\": 7,
        \"round\": \"Technical\",
        \"scheduled_at\": \"2025-05-20 10:00:00\",
        \"mode\": \"Online\",
        \"location\": \"Zoom\",
        \"status\": \"completed\"
    }"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/interviews/update/1"
    );

    const params = {
        "isApi": "1",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
        "Content-Type": "application/json",
    };

    let body = {
        "candidate_id": 101,
        "interviewer_id": 7,
        "round": "Technical",
        "scheduled_at": "2025-05-20 10:00:00",
        "mode": "Online",
        "location": "Zoom",
        "status": "completed"
    };

    fetch(url, {
        method: "POST",
        headers,
        body: JSON.stringify(body),
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Interview Updated Successfully!",
        "data": {
            "id": 1,
            "candidate_id": 101,
            "interviewer_id": 7,
            "round": "Technical",
            "scheduled_at": "2025-05-20 10:00:00",
            "mode": "Online",
            "location": "Zoom",
            "status": "completed",
            "created_at": "2025-05-15 16:15:00",
            "updated_at": "2025-05-15 16:20:00"
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Interview not found"
    }

> Example response (422):

    {
        "error": true,
        "message": "The candidate_id field is required."
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while updating the interview."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

POST `api/interviews/update/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

`Content-Type`

Example: `application/json`

#### URL Parameters

`id` integer

The ID of the interview to update. Must exist in the `interviews` table. Example: `1`

#### Query Parameters

`isApi` boolean optional `true` `false`

optional Indicates if the response should be formatted for API use. Defaults to false. Example: `true`

#### Body Parameters

`candidate_id` integer

The ID of the candidate for the interview. Must exist in the `candidates` table. Example: `101`

`interviewer_id` integer

The ID of the interviewer. Must exist in the `users` table. Example: `7`

`round` string

The interview round (e.g., Technical, HR). Maximum length is 255 characters. Example: `Technical`

`scheduled_at` string

The date and time of the interview (format: YYYY-MM-DD HH:MM:SS). Example: `2025-05-20 10:00:00`

`mode` string

The mode of the interview (e.g., Online, In-Person). Maximum length is 255 characters. Example: `Online`

`location` string optional

nullable The location of the interview (if applicable). Maximum length is 255 characters. Example: `Zoom`

`status` string

The status of the interview. Must be one of: scheduled, completed, cancelled. Example: `completed`

## Delete an interview.

requires authentication

This endpoint deletes a specific interview record. The user must be authenticated and have appropriate permissions to perform this action.

> Example request:

    curl --request DELETE \
        "https://dev-taskify.taskhub.company/api/interviews/destroy/1" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/interviews/destroy/1"
    );

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "DELETE",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Interview deleted successfully!"
    }

> Example response (404):

    {
        "error": false,
        "message": "Interview not found",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred while deleting the interview."
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

DELETE `api/interviews/destroy/{id}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer

The ID of the interview to delete. Must exist in the `interviews` table. Example: `1`

## List interviews or retrieve a single interview.

requires authentication

This endpoint retrieves a paginated list of interviews or a single interview by ID, with optional search, sorting, and status filtering. The user must be authenticated to perform this action. The response includes permission details for editing and deletion.

> Example request:

    curl --request GET \
        --get "https://dev-taskify.taskhub.company/api/interviews/list/1?search=Technical&sort=newest&limit=20&offset=10&status=scheduled" \
        --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
        --header "Accept: application/json" \
        --header "workspace_id: 1"

    const url = new URL(
        "https://dev-taskify.taskhub.company/api/interviews/list/1"
    );

    const params = {
        "search": "Technical",
        "sort": "newest",
        "limit": "20",
        "offset": "10",
        "status": "scheduled",
    };
    Object.keys(params)
        .forEach(key => url.searchParams.append(key, params[key]));

    const headers = {
        "Authorization": "Bearer {YOUR_AUTH_KEY}",
        "Accept": "application/json",
        "workspace_id": "1",
    };

    fetch(url, {
        method: "GET",
        headers,
    }).then(response => response.json());

> Example response (200):

    {
        "error": false,
        "message": "Interviews retrieved successfully",
        "data": {
            "total": 10,
            "data": [
                {
                    "id": 1,
                    "candidate_id": 101,
                    "candidate_name": "John Doe",
                    "interviewer_id": 7,
                    "interviewer_name": "Jane Smith",
                    "round": "Technical",
                    "scheduled_at": "2025-05-20 10:00:00",
                    "mode": "Online",
                    "location": "Zoom",
                    "status": "scheduled",
                    "created_at": "2025-05-15 16:15:00",
                    "updated_at": "2025-05-15 16:15:00",
                    "can_edit": true,
                    "can_delete": true
                }
            ],
            "permissions": {
                "can_edit": true,
                "can_delete": true
            }
        }
    }

> Example response (404):

    {
        "error": true,
        "message": "Interview not found.",
        "data": []
    }

> Example response (422):

    {
        "error": true,
        "message": "Validation failed: The search field must be a string.",
        "data": []
    }

> Example response (500):

    {
        "error": true,
        "message": "An error occurred.",
        "data": []
    }

> Received response:

> Request failed with error:

    Tip: Check that you're properly connected to the network.
    If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
    You can check the Dev Tools console for debugging information.

### Request

GET `api/interviews/list/{id?}`

#### Headers

`Authorization`

Example: `Bearer {YOUR_AUTH_KEY}`

`Accept`

Example: `application/json`

`workspace_id`

Example: `1`

#### URL Parameters

`id` integer optional

optional The ID of the interview to retrieve. If provided, returns a single interview. Must exist in the `interviews` table. Example: `1`

#### Query Parameters

`search` string optional

optional Filters interviews by candidate name, interviewer name, round, status, location, or mode. Example: `Technical`

`sort` string optional

optional The field to sort by (id, newest, oldest, recently-updated, earliest-updated). Defaults to id. Example: `newest`

`limit` integer optional

optional The number of interviews per page (1-100). Defaults to 10. Example: `20`

`offset` integer optional

optional The number of interviews to skip. Defaults to 0. Example: `10`

`status` string optional

optional Filters interviews by status (e.g., scheduled, completed, cancelled). Example: `scheduled`