{
  "openapi": "3.1.0",
  "info": {
    "title": "COR API",
    "description": "The COR API lets you integrate with projectcor.com applications using simple HTTP methods, in either XML or JSON formats, making this an ideal API for developing integrations with other softwares, external clients or mobile applications",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.projectcor.com/v1",
      "description": "Production server"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/oauth/token": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "JWT Authorization by Client credentials",
        "description": "We'll be using the OAuth2 Client Credentials workflow as an authentication strategy and JWTs for the format of the tokens.",
        "security": [],
        "parameters": [
          {
            "name": "grant_type",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "client_credentials"
              ],
              "default": "client_credentials"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successfully authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/oauth2/token": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "JWT Authorization by Authorization code",
        "description": "The authorization code is obtained by using an authorization server (COR) as an intermediary between the client and resource owner.",
        "security": [],
        "parameters": [
          {
            "name": "grant_type",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "authorization_code"
              ],
              "default": "authorization_code"
            }
          },
          {
            "name": "code",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Authorization code obtained from consent screen"
          }
        ],
        "responses": {
          "200": {
            "description": "Successfully authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/auth/login": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "JWT Authorization by User Credentials",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "email",
                  "password"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "User E-Mail"
                  },
                  "password": {
                    "type": "string",
                    "format": "password",
                    "description": "User Password"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/me": {
      "get": {
        "tags": [
          "Auth"
        ],
        "summary": "Get Authenticated User",
        "description": "Returns information about the currently authenticated user",
        "responses": {
          "200": {
            "description": "User information",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          }
        }
      }
    },
    "/oauth/refreshtoken": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "JWT Refresh Token",
        "description": "Refresh the user token",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "refresh_token"
                ],
                "properties": {
                  "refresh_token": {
                    "type": "string",
                    "description": "Refresh token"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token refreshed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/contacts": {
      "get": {
        "tags": [
          "Contacts"
        ],
        "summary": "Get contacts",
        "description": "Retrieves a paginated list of contacts. By default, responses are paginated with 20 items per page.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": 1
            },
            "description": "Page number (default: 1). Set to `false` to disable pagination."
          },
          {
            "name": "perPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page (default: 20)."
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of contacts",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedContactsResponse"
                }
              }
            }
          }
        }
      }
    },
    "/contacts/{id}": {
      "get": {
        "tags": [
          "Contacts"
        ],
        "summary": "Get contact by ID",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Contact details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          }
        }
      }
    },
    "/contacts/search-by-name/{name}": {
      "get": {
        "tags": [
          "Contacts"
        ],
        "summary": "Get contact by name",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Contact details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          }
        }
      }
    },
    "/contracts": {
      "get": {
        "tags": [
          "Contracts"
        ],
        "summary": "Get contracts",
        "description": "Retrieves a paginated list of contracts.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": 1
            },
            "description": "Page number (default: 1). Set to `false` to disable pagination."
          },
          {
            "name": "perPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page (default: 20)."
          },
          {
            "name": "filters",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "URL-encoded JSON object with filter criteria."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContractListBodyInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Paginated list of contracts",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedContractsResponse"
                }
              }
            }
          }
        }
      }
    },
    "/contracts/{contract_id}": {
      "post": {
        "tags": [
          "Contracts"
        ],
        "summary": "Create contract",
        "description": "Creates a contract using the provided contract identifier. The authenticated user is automatically attached as a contract member from the contract `start` date through an open-ended end date, so the creator can immediately see and manage the contract even when they do not have global access.",
        "parameters": [
          {
            "name": "contract_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContractCreateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contract created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contract"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Contracts"
        ],
        "summary": "Update contract",
        "description": "Updates the specified contract.",
        "parameters": [
          {
            "name": "contract_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContractUpdateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contract updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contract"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Contracts"
        ],
        "summary": "Delete contract",
        "description": "Deletes the specified contract.",
        "parameters": [
          {
            "name": "contract_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Contract deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contract"
                }
              }
            }
          }
        }
      }
    },
    "/contracts/{contract_id}/users": {
      "post": {
        "tags": [
          "Contracts Users"
        ],
        "summary": "Attach users to a contract",
        "description": "Attaches one or more users to a contract, each with one or more date ranges. Access to this endpoint is governed by the caller's `contracts` permission (`edit`), not by their `users` permission. The `users` sub-resource under a contract is treated as part of the parent contract for authorization.",
        "parameters": [
          {
            "name": "contract_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContractAttachUsersInput"
              },
              "example": {
                "users": [
                  {
                    "id": 123,
                    "dates": [
                      {
                        "start": "2026-01-01",
                        "end": "2026-02-01"
                      },
                      {
                        "start": "2026-01-01",
                        "end": "2026-02-02"
                      }
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Users attached to contract with full or partial success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContractAttachUsersResponse"
                },
                "example": {
                  "status": "partial_success",
                  "company_id": 999,
                  "contract_id": 777,
                  "records_received": 8,
                  "records_created": 2,
                  "records_rejected": 8,
                  "assigned": [
                    {
                      "id": 501,
                      "user_id": 88001,
                      "start_date": "2024-01-01T00:00:00.000Z",
                      "end_date": "2024-12-31T00:00:00.000Z"
                    },
                    {
                      "id": 502,
                      "user_id": 88001,
                      "start_date": "2024-03-01T00:00:00.000Z",
                      "end_date": "2024-06-30T00:00:00.000Z"
                    }
                  ],
                  "errors": [
                    {
                      "id": 88001,
                      "dates": [
                        {
                          "start": "2024-06-01",
                          "end": "2024-04-01",
                          "message": "Date malformatted. Start date must be before end date"
                        },
                        {
                          "start": null,
                          "end": null,
                          "message": "Date malformatted"
                        },
                        {
                          "start": "2024-02-01",
                          "end": null,
                          "message": "Date malformatted. Start and end date are required"
                        },
                        {
                          "start": "not-a-date",
                          "end": "2024-12-31",
                          "message": "Invalid date"
                        },
                        {
                          "start": "1990-01-01",
                          "end": "1990-06-30",
                          "message": "Invalid contract periods. Range must be within contract start and end dates"
                        }
                      ],
                      "message": "Partial success. Some dates were rejected"
                    },
                    {
                      "id": "hello",
                      "dates": [
                        {
                          "start": "2024-01-01",
                          "end": "2024-12-31"
                        }
                      ],
                      "message": "User malformatted"
                    },
                    {
                      "id": 88002,
                      "start": "2024-01-01",
                      "end": "2024-12-31",
                      "message": "Legacy format detected. Use \"dates\" array instead of \"start\" and \"end\" fields"
                    },
                    {
                      "id": 88003,
                      "dates": [],
                      "message": "Date malformatted or empty"
                    },
                    {
                      "id": 88004,
                      "dates": [
                        {
                          "start": "2024-07-01",
                          "end": "2024-07-01",
                          "message": "Date malformatted. Start date must be before end date"
                        }
                      ],
                      "message": "Dates are malformatted or empty"
                    },
                    {
                      "id": 88005,
                      "dates": [
                        {
                          "start": null,
                          "end": null,
                          "message": "Date malformatted"
                        }
                      ],
                      "message": "Partial success. Some dates were rejected"
                    },
                    {
                      "id": 999999,
                      "dates": [
                        {
                          "start": "2024-01-01",
                          "end": "2024-12-31"
                        }
                      ],
                      "message": "User malformatted"
                    },
                    {
                      "id": 88005,
                      "dates": [
                        {
                          "start": "2024-01-01",
                          "end": "2024-06-30"
                        }
                      ],
                      "message": "User malformatted"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/contracts/{contract_id}/positions": {
      "get": {
        "tags": [
          "Contract Positions"
        ],
        "summary": "Get contract positions",
        "description": "Retrieves all positions associated with a contract.",
        "parameters": [
          {
            "name": "contract_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": 1
            },
            "description": "Page number (default: 1). Set to `false` to disable pagination."
          },
          {
            "name": "perPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page (default: 20)."
          }
        ],
        "responses": {
          "200": {
            "description": "List of contract positions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedContractPositionRatesResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Contract Positions"
        ],
        "summary": "Create contract position",
        "description": "Creates a new position rate for the specified contract.",
        "parameters": [
          {
            "name": "contract_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContractPositionCreateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contract position created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContractPositionRate"
                }
              }
            }
          }
        }
      }
    },
    "/contracts/{contract_id}/positions/{contract_position_rate_id}": {
      "put": {
        "tags": [
          "Contract Positions"
        ],
        "summary": "Update contract position",
        "description": "Updates rate and/or hours for a contract position.",
        "parameters": [
          {
            "name": "contract_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "contract_position_rate_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContractPositionUpdateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contract position updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContractPositionRate"
                }
              }
            }
          }
        }
      }
    },
    "/clients": {
      "get": {
        "tags": [
          "Clients"
        ],
        "summary": "Get clients",
        "description": "Retrieves a paginated list of clients. By default, responses are paginated with 20 items per page.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": 1
            },
            "description": "Page number (default: 1). Set to `false` to disable pagination."
          },
          {
            "name": "perPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page (default: 20)."
          },
          {
            "name": "filters",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "URL-encoded JSON object with filter criteria."
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of clients",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedClientsResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Clients"
        ],
        "summary": "Create a new client",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/ClientInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Client created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            }
          }
        }
      }
    },
    "/clients/{id}": {
      "get": {
        "tags": [
          "Clients"
        ],
        "summary": "Get client by ID",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Client details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Clients"
        ],
        "summary": "Update client",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/ClientInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Client updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            }
          }
        }
      }
    },
    "/clients/search-by-name/{name}": {
      "get": {
        "tags": [
          "Clients"
        ],
        "summary": "Get clients by name",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of clients",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Client"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/clients/{id}/favorite": {
      "post": {
        "tags": [
          "Clients"
        ],
        "summary": "Set/Unset client as favorite",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "favorited"
                ],
                "properties": {
                  "favorited": {
                    "type": "boolean",
                    "description": "Whether to set as favorite"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Favorite status updated"
          }
        }
      }
    },
    "/clients/{client_id}/fees": {
      "get": {
        "tags": [
          "Fees"
        ],
        "summary": "Get Fees from a client",
        "parameters": [
          {
            "name": "client_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of fees",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Fee"
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Fees"
        ],
        "summary": "Create a fee",
        "parameters": [
          {
            "name": "client_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FeeInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Fee created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Fee"
                }
              }
            }
          }
        }
      }
    },
    "/clients/{client_id}/fees/{fee_id}": {
      "put": {
        "tags": [
          "Fees"
        ],
        "summary": "Update fee",
        "parameters": [
          {
            "name": "client_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "fee_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FeeInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Fee updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Fee"
                }
              }
            }
          }
        }
      }
    },
    "/clients/{client_id}/fees/{fee_id}/historicals": {
      "get": {
        "tags": [
          "Fees"
        ],
        "summary": "Get Historical fees",
        "parameters": [
          {
            "name": "client_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "fee_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Historical fees",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Fee"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/fees": {
      "get": {
        "tags": [
          "Fees"
        ],
        "summary": "Get Fees",
        "description": "Retrieves a paginated list of fees. By default, responses are paginated with 20 items per page.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": 1
            },
            "description": "Page number (default: 1). Set to `false` to disable pagination."
          },
          {
            "name": "perPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page (default: 20)."
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of fees",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedFeesResponse"
                }
              }
            }
          }
        }
      }
    },
    "/projects": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "Get Projects",
        "description": "Retrieves a paginated list of projects for the company. Supports filtering by client, dates, status, health, and more. By default, responses are paginated with 20 items per page.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": 1
            },
            "description": "Page number (default: 1). Set to `false` to disable pagination and return all results."
          },
          {
            "name": "perPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page when pagination is active (default: 20)."
          },
          {
            "name": "filters",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "URL-encoded JSON object with filter criteria. Available fields: `dateStart` (YYYY-MM-DD), `dateEnd` (YYYY-MM-DD), `client_id` (number), `team_id` (number), `user_id` (number), `brand_id` (number), `product_id` (number), `status` (\"finished\"|\"in_process\"|\"suspended\"), `health` (1-4), `archived` (1=archived, 2=active)."
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of projects",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedProjectsResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Projects"
        ],
        "summary": "Create a project",
        "description": "Create a new project entity.\n\n**Time estimation modes** — Projects support three mutually exclusive ways to estimate time (set via the Profitability tab in the UI):\n\n1. **Total hours** (default): send only `estimated_time`.\n2. **By positions**: set `estimated_by_position: true` and provide `users_positions` with `estimated_time` per position.\n3. **By categories**: set `estimation_by_categories: 1` (or `true`) and provide `categories` with `estimated_time` per category.\n\nWhen using `income_type: \"hourly_rate\"`, also set `estimated_by_hourly_rates: true` and assign a ratecard via `ratecard_id`.\n\n> **Note:** These fields are unrelated to the **Project Estimates** endpoints (`/projects/{project_id}/project_estimate`), which manage budget line items (title, cost, fee).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectInput"
              },
              "examples": {
                "totalHours": {
                  "summary": "Total hours estimation",
                  "value": {
                    "name": "Website Redesign",
                    "client_id": 10,
                    "start": "2026-05-01",
                    "estimated_time": 120,
                    "income_type": "fee",
                    "fee_id": 5,
                    "currency_id": 1
                  }
                },
                "byPositions": {
                  "summary": "Estimation by positions",
                  "value": {
                    "name": "Mobile App",
                    "client_id": 10,
                    "start": "2026-05-01",
                    "estimated_by_position": true,
                    "income_type": "hourly_rate",
                    "estimated_by_hourly_rates": true,
                    "ratecard_id": 3,
                    "currency_id": 1,
                    "users_positions": [
                      {
                        "id": 1,
                        "estimated_time": 80
                      },
                      {
                        "id": 2,
                        "estimated_time": 40
                      }
                    ]
                  }
                },
                "byCategories": {
                  "summary": "Estimation by categories",
                  "value": {
                    "name": "Brand Campaign",
                    "client_id": 10,
                    "start": "2026-06-01",
                    "estimation_by_categories": 1,
                    "income_type": "fee",
                    "fee_id": 5,
                    "currency_id": 1,
                    "categories": [
                      {
                        "id": 7,
                        "estimated_time": 60
                      },
                      {
                        "id": 8,
                        "estimated_time": 30
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Project created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          }
        }
      }
    },
    "/projects/{project_id}": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "Get project by ID",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Project details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Projects"
        ],
        "summary": "Update a project",
        "description": "Update a project entity. Include only the fields you want to change.\n\n**Time estimation** — You can switch estimation mode by updating `estimated_by_position` / `estimation_by_categories` together with `users_positions` / `categories`. Positions present in the project but absent from the `users_positions` array will have their estimated hours reset to 0 (or be soft-deleted if no hours have been logged against them).\n\n> These fields are unrelated to **Project Estimates** (`/projects/{project_id}/project_estimate`), which manage budget line items.",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectPutUpdateBody"
              },
              "examples": {
                "updateLabels": {
                  "summary": "Update labels only",
                  "value": {
                    "labels": []
                  }
                },
                "switchToByPositions": {
                  "summary": "Switch to estimation by positions",
                  "value": {
                    "estimated_by_position": true,
                    "estimation_by_categories": false,
                    "users_positions": [
                      {
                        "id": 1,
                        "estimated_time": 80
                      },
                      {
                        "id": 2,
                        "estimated_time": 40
                      }
                    ]
                  }
                },
                "updateHourlyRates": {
                  "summary": "Enable hourly rates with ratecard",
                  "value": {
                    "estimated_by_hourly_rates": true,
                    "ratecard_id": 3,
                    "income_type": "hourly_rate"
                  }
                }
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/ProjectPutUpdateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Project updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Projects"
        ],
        "summary": "Delete a project",
        "description": "Destroy a project entity.",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Project deleted successfully"
          }
        }
      }
    },
    "/projects/search-by-name/{project_name}": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "Get projects by name",
        "parameters": [
          {
            "name": "project_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of projects",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Project"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{id}/messages": {
      "post": {
        "tags": [
          "Projects",
          "Messages"
        ],
        "summary": "Post project message",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/MessageInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Message posted successfully"
          }
        }
      }
    },
    "/projects/{project_id}/messages": {
      "get": {
        "tags": [
          "Projects",
          "Messages"
        ],
        "summary": "Get messages by project",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of messages",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Message"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{project_id}/project_cost": {
      "get": {
        "tags": [
          "Projects",
          "Costs"
        ],
        "summary": "Get Project Costs",
        "description": "Get a list of associated project costs",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of project costs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ProjectCost"
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Projects",
          "Costs"
        ],
        "summary": "Add Project Cost",
        "description": "Create an associated project cost",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectCostInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Project cost created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectCost"
                }
              }
            }
          }
        }
      }
    },
    "/projects/{project_id}/project_cost/{project_cost_id}": {
      "put": {
        "tags": [
          "Projects",
          "Costs"
        ],
        "summary": "Update Project Cost",
        "description": "Update an associated project cost",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "project_cost_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectCostInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Project cost updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectCost"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Projects",
          "Costs"
        ],
        "summary": "Delete Project Cost",
        "description": "Delete an associated project cost",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "project_cost_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Project cost deleted successfully"
          }
        }
      }
    },
    "/projects/{project_id}/attachments": {
      "get": {
        "tags": [
          "Projects",
          "Attachments"
        ],
        "summary": "Get attachment by Project",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of attachments",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Attachment"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{project_id}/labels": {
      "get": {
        "tags": [
          "Projects",
          "Labels"
        ],
        "summary": "Get project labels",
        "description": "Returns project label categories and available labels for the company (same shape as grouped categories for the project entity type), plus the labels currently assigned to the given project in **`selected`**.\n\nUse **`GET /categories/labels-model?model=project`** for a simpler category tree without per-project selection. To **assign or remove** labels on a project, use **`PUT /projects/{project_id}`** with a `labels` array.",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "Project ID. Must belong to the authenticated user's company."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": false
            },
            "description": "Pagination page number. Set to false (the default) to disable pagination."
          },
          {
            "name": "perPage",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Page size when pagination is enabled."
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "{}"
            },
            "description": "JSON object as a string (must be valid JSON) for sort criteria passed to the label query."
          },
          {
            "name": "filters",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "{}"
            },
            "description": "JSON object as a string (must be valid JSON) with filter criteria for the grouped labels query (e.g. `ids`, `name`, `limit`)."
          }
        ],
        "responses": {
          "200": {
            "description": "Grouped project labels and labels assigned to this project",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectLabelsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error (e.g. invalid JSON in `order` or `filters`, or project not found / not in company)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CORCustomError"
                }
              }
            }
          }
        }
      }
    },
    "/projects/{project_id}/collaborators": {
      "get": {
        "tags": [
          "Projects",
          "Collaborators"
        ],
        "summary": "Get project collaborators",
        "description": "Get users and teams collaborators from project.",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of project collaborators",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ProjectCollaborator"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error (e.g. project not found or not in company)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "example": "CORCustomError"
                    },
                    "code": {
                      "type": "string",
                      "example": "PC001"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Projects",
          "Collaborators"
        ],
        "summary": "Add project collaborators",
        "description": "Add individual collaborators to project.",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "usersIds": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Array of user IDs to add as collaborators"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Collaborators added successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Collaborators added successfully"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error (e.g. project or users invalid)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "example": "CORCustomError"
                    },
                    "code": {
                      "type": "string",
                      "example": "PC001"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{project_id}/collaborators/{user_id}": {
      "delete": {
        "tags": [
          "Projects",
          "Collaborators"
        ],
        "summary": "Delete project collaborator",
        "description": "Delete individual collaborator from project.",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Collaborator deleted successfully"
          },
          "400": {
            "description": "Validation error (e.g. project or user not found)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "example": "CORCustomError"
                    },
                    "code": {
                      "type": "string",
                      "example": "PC001"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{project_id}/project_estimate": {
      "get": {
        "tags": [
          "Projects",
          "Estimates"
        ],
        "summary": "Get Project Estimates",
        "description": "Get a list of associated project estimates",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of project estimates",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ProjectEstimate"
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Projects",
          "Estimates"
        ],
        "summary": "Add Project Estimate",
        "description": "Create an associated project estimates",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectEstimateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Project estimate created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectEstimate"
                }
              }
            }
          }
        }
      }
    },
    "/projects/{project_id}/project_estimate/{project_estimate_id}": {
      "put": {
        "tags": [
          "Projects",
          "Estimates"
        ],
        "summary": "Update a Project Estimate",
        "description": "Modify an associated project estimates",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "project_estimate_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectEstimateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Project estimate updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectEstimate"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Projects",
          "Estimates"
        ],
        "summary": "Delete a Project Estimate",
        "description": "Delete an associated project estimates",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "project_estimate_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Project estimate deleted successfully"
          }
        }
      }
    },
    "/projects/{project_id}/ratecard": {
      "get": {
        "tags": [
          "Projects",
          "Ratecards"
        ],
        "summary": "Get project ratecard",
        "description": "Returns the ratecard currently assigned to the project, or `null` if none is assigned. The ratecard defines pricing configurations (positions, rates, custom percentages) used when `estimated_by_hourly_rates` is enabled.",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Ratecard assigned to the project (or null)",
            "content": {
              "application/json": {
                "schema": {
                  "nullable": true,
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Ratecard"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/brands": {
      "get": {
        "tags": [
          "Brands"
        ],
        "summary": "Get Brands",
        "description": "Retrieves a paginated list of brands. By default, responses are paginated with 20 items per page.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": 1
            },
            "description": "Page number (default: 1). Set to `false` to disable pagination."
          },
          {
            "name": "perPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page (default: 20)."
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of brands",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedBrandsResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Brands"
        ],
        "summary": "Create a brand",
        "description": "Create a new brand entity.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BrandInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Brand created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Brand"
                }
              }
            }
          }
        }
      }
    },
    "/brands/{brand_id}": {
      "get": {
        "tags": [
          "Brands"
        ],
        "summary": "Get brand by ID",
        "parameters": [
          {
            "name": "brand_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Brand details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Brand"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Brands"
        ],
        "summary": "Update a brand",
        "description": "Update a brand entity.",
        "parameters": [
          {
            "name": "brand_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Brand Name"
                  },
                  "client_id": {
                    "type": "integer",
                    "description": "Client ID"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Brand updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Brand"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Brands"
        ],
        "summary": "Delete a brand",
        "description": "Destroy a brand entity.",
        "parameters": [
          {
            "name": "brand_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Brand deleted successfully"
          }
        }
      }
    },
    "/userPosition": {
      "post": {
        "tags": [
          "User Positions"
        ],
        "summary": "Create a user position",
        "description": "Creates a new user position.\n\nIf company has the feature flag to manage positions by labels enabled, Field `segmentLabel` is required. For companies without this feature enabled, `segmentLabel` is ignored.\n\nFied `company_id` is automatically set from the authenticated user's company.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserPositionInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "User position created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserPosition"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or missing segmentLabel when feature flag is enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validationError": {
                    "value": {
                      "status": 400,
                      "name": "CORCustomError",
                      "code": "F010",
                      "message": "Validation error message"
                    }
                  },
                  "missingSegmentLabel": {
                    "value": {
                      "status": 400,
                      "name": "CORCustomError",
                      "code": "UP001",
                      "message": "Segment label is required"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/userPosition/{id}": {
      "put": {
        "tags": [
          "User Positions"
        ],
        "summary": "Update a user position",
        "description": "Updates an existing user position.\n\nIf company has the feature flag to manage positions by labels enabled, field `segmentLabel` is required and will be used to group the position by label.\n\nAll fields in the request body are optional. Only provided fields will be updated.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "User position ID",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserPositionUpdateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "User position updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserPosition"
                }
              }
            }
          },
          "400": {
            "description": "Validation error or missing segmentLabel when feature flag is enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validationError": {
                    "value": {
                      "status": 400,
                      "name": "CORCustomError",
                      "code": "UC010",
                      "message": "Validation error message"
                    }
                  },
                  "missingSegmentLabel": {
                    "value": {
                      "status": 400,
                      "name": "CORCustomError",
                      "code": "UP001",
                      "message": "Segment label is required"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/userPosition/getPositionsOnly": {
      "get": {
        "tags": [
          "User Positions"
        ],
        "summary": "Get active user positions",
        "description": "Returns all active user positions for the authenticated user's company. Only active positions and active categories are returned. The company scope always comes from the authenticated user and cannot be set manually.\n\nResults are ordered by category name, then by position name. This endpoint does not paginate.\n\n**Query parameters**\n\n- **`lang`** (optional): Language for localized names. If omitted, uses the authenticated user's configured language; if none is set, defaults to **EN**. Examples: `EN`, `ES`, `BR`, `FR`.\n- **`groupedByCategory`** (optional): When present with a **truthy** value, returns positions grouped by category. When omitted or falsy, returns a flat array. For predictable behavior, use `groupedByCategory=true` to group, and omit the parameter for a flat list.",
        "parameters": [
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Language code for position and category names. Defaults to the authenticated user's language, or EN if not set.",
            "schema": {
              "type": "string",
              "example": "ES"
            }
          },
          {
            "name": "groupedByCategory",
            "in": "query",
            "required": false,
            "description": "If truthy, returns positions grouped by category. Omit or use a falsy value for a flat list.",
            "schema": {
              "type": "boolean",
              "example": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Active positions as a flat list, or grouped by category when `groupedByCategory` is truthy",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "title": "Flat list",
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/UserPositionActiveFlatItem"
                      }
                    },
                    {
                      "title": "Grouped by category",
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/UserPositionsGroupedByCategoryItem"
                      }
                    }
                  ]
                },
                "examples": {
                  "Flat list": {
                    "summary": "Flat list",
                    "description": "GET /userPosition/getPositionsOnly?lang=ES",
                    "value": [
                      {
                        "id": 101,
                        "name": "Diseñador Senior",
                        "category_id": 10,
                        "category_name": "Diseño"
                      },
                      {
                        "id": 102,
                        "name": "Desarrollador Semi Senior",
                        "category_id": 11,
                        "category_name": "Desarrollo"
                      }
                    ]
                  },
                  "Grouped by category": {
                    "summary": "Grouped by category",
                    "description": "GET /userPosition/getPositionsOnly?lang=ES&groupedByCategory=true",
                    "value": [
                      {
                        "categoryName": "Desarrollo",
                        "categoryId": 11,
                        "positions": [
                          {
                            "id": 102,
                            "name": "Desarrollador Semi Senior"
                          }
                        ]
                      },
                      {
                        "categoryName": "Diseño",
                        "categoryId": 10,
                        "positions": [
                          {
                            "id": 101,
                            "name": "Diseñador Senior"
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — missing or invalid access token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": 401,
                  "message": "Unauthorized"
                }
              }
            }
          }
        }
      }
    },
    "/userPosition/labels/groupers": {
      "get": {
        "tags": [
          "User Positions"
        ],
        "summary": "Get position segment labels",
        "description": "Returns list of segment labels used to group user positions.\n\nThis endpoint is only available for companies with feature flag to manage positions by labels enabled. The endpoint requires authentication and will return a 403 error if the feature is not enabled for company.",
        "x-mint": {
          "content": "<Warning>\n\nThese labels are not user positions (e.g., \"Backend Developer\", \"Analista de datos\"). They are the classification criteria used to group positions (e.g., by seniority, area, or department). To retrieve actual user positions grouped by category, use [GET /userPosition/getPositionsOnly](/api-reference/user-positions/get-active-user-positions).\n\n</Warning>"
        },
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": true,
            "description": "Defines whether labels are retrieved for positions or categories. Must be 'c' for categories or 'p' for positions",
            "schema": {
              "type": "string",
              "enum": [
                "c",
                "p"
              ],
              "example": "p"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of segment labels",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SegmentLabel"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid type parameter",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "status": 400,
                  "name": "CORCustomError",
                  "code": "CTR002",
                  "message": "Invalid type data"
                }
              }
            }
          },
          "403": {
            "description": "Feature flag to manage positions by labels not enabled for company",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/products": {
      "get": {
        "tags": [
          "Products"
        ],
        "summary": "Get Products",
        "description": "Retrieves a paginated list of products. By default, responses are paginated with 20 items per page.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": 1
            },
            "description": "Page number (default: 1). Set to `false` to disable pagination."
          },
          {
            "name": "perPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page (default: 20)."
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of products",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedProductsResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Products"
        ],
        "summary": "Create a product",
        "description": "Create a new product entity.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Product created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            }
          }
        }
      }
    },
    "/products/{product_id}": {
      "get": {
        "tags": [
          "Products"
        ],
        "summary": "Get product by ID",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Product details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Products"
        ],
        "summary": "Update a product",
        "description": "Update a product entity.",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Product Name"
                  },
                  "client_id": {
                    "type": "integer",
                    "description": "Client ID"
                  },
                  "brand_id": {
                    "type": "integer",
                    "description": "Brand ID"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Product updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Products"
        ],
        "summary": "Delete a product",
        "description": "Destroy a product entity.",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Product deleted successfully"
          }
        }
      }
    },
    "/projectTemplates": {
      "get": {
        "tags": [
          "Project Templates"
        ],
        "summary": "Get Project Templates",
        "description": "Retrieves a paginated list of project templates. By default, responses are paginated with 20 items per page.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": 1
            },
            "description": "Page number (default: 1). Set to `false` to disable pagination."
          },
          {
            "name": "perPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page (default: 20)."
          },
          {
            "name": "filters",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "URL-encoded JSON object with filter criteria. Available fields: `name` (string)."
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of project templates",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedProjectTemplatesResponse"
                }
              }
            }
          }
        }
      }
    },
    "/tasks": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "Get Tasks",
        "description": "Retrieves a paginated list of tasks. By default, responses are paginated with 20 items per page.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": 1
            },
            "description": "Page number (default: 1). Set to `false` to disable pagination."
          },
          {
            "name": "perPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page (default: 20)."
          },
          {
            "name": "filters",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filters for the task list, expressed as a JSON object **URL-encoded** into this query string.\n\n**Examples of common keys**\n\n- **`projects`** — One project ID, or an array of project IDs.\n- **`pm`** — One user ID, or an array of user IDs for the task PM.\n- **`status`** — One status or several; examples: `nueva`, `en_proceso`, `finalizada`.\n\n**Other supported keys** in the same object include `labels`, `categories`, `clients`, `collaborator`, `priority`, and `sprints`.\n\n**Important:** Use only this parameter for filtering. Do **not** add extra query parameters such as `?project_id=` or `?user_id=`."
          },
          {
            "name": "order",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Optional sort specification as a JSON object **URL-encoded** into this query string.\n\nFor each field you want to sort by, set the value to **`ASC`** or **`DESC`** (where supported).\n\n**Sortable fields** include `client`, `project`, `task`, `deadline`, `datetime`, `pm`, `priority`, and `sprint`.\n\nThe response also uses a default tie-breaker: the task's defined order ascending."
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of tasks",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedTasksResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Tasks"
        ],
        "summary": "Create a task",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Task created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Task"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/{task_id}": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "Get task by ID",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Task"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Tasks"
        ],
        "summary": "Update a Task",
        "description": "Update Task attributes",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskUpdateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Task updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Task"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Tasks"
        ],
        "summary": "Delete a Task",
        "description": "Delete a Task",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Task deleted successfully"
          }
        }
      }
    },
    "/tasks/search-by-title/{title}": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "Get tasks by title",
        "parameters": [
          {
            "name": "title",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of tasks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Task"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/tasks/{task_id}/messages": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "Get messages by Task",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of messages",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Message"
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Tasks"
        ],
        "summary": "Post task message",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MessageInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Message posted successfully"
          }
        }
      }
    },
    "/tasks/{task_id}/attachments": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "Get task attachments",
        "description": "Lists attachments for a task (paginated), excluding child versions.",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID of the task"
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1
            },
            "description": "Current page number"
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page"
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "schema": {
              "type": "object",
              "default": {
                "created_at": "DESC"
              }
            },
            "description": "Sort criteria (e.g. `{\"created_at\": \"DESC\"}`)"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of attachments",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskAttachmentListResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "nullable": true,
                  "example": null
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Tasks"
        ],
        "summary": "Upload task attachments",
        "description": "Uploads one or more files to a task via multipart/form-data.",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID of the task (task_log_id)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "File(s) to upload"
                  },
                  "available": {
                    "type": "boolean",
                    "default": true,
                    "description": "Whether the file is visible"
                  },
                  "session_token": {
                    "type": "string",
                    "nullable": true,
                    "default": null,
                    "description": "Session token to group uploads and defer notification"
                  },
                  "attachment_parent_id": {
                    "type": "integer",
                    "nullable": true,
                    "default": null,
                    "description": "ID of the parent attachment (for versioning)"
                  },
                  "status": {
                    "type": "string",
                    "nullable": true,
                    "default": null,
                    "enum": [
                      "approved",
                      "pending",
                      "required",
                      null
                    ],
                    "description": "Attachment status"
                  },
                  "created_from": {
                    "type": "string",
                    "default": "task_panel",
                    "enum": [
                      "task_panel",
                      "rework",
                      "feedback"
                    ],
                    "description": "Origin of the upload"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Files uploaded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskAttachmentUploadResponse"
                }
              }
            }
          },
          "400": {
            "description": "No files could be uploaded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AttachmentUploadBadRequest"
                }
              }
            }
          },
          "417": {
            "description": "Task not found (validation failed)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorArray"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Tasks"
        ],
        "summary": "Delete task attachments",
        "description": "Deletes one or more attachments from a task.",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID of the task"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "attachments"
                ],
                "properties": {
                  "attachments": {
                    "oneOf": [
                      {
                        "type": "array",
                        "items": {
                          "type": "integer"
                        }
                      },
                      {
                        "type": "integer"
                      }
                    ],
                    "description": "ID(s) of the attachment(s) to delete"
                  },
                  "lastPage": {
                    "type": "integer",
                    "description": "Last page number (used for re-pagination)"
                  },
                  "order": {
                    "type": "object",
                    "default": {
                      "created_at": "DESC"
                    },
                    "description": "Sort criteria for replacement elements"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Attachments deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskAttachmentDeleteResponse"
                }
              }
            }
          },
          "404": {
            "description": "Attachment not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CORErrorResponse"
                },
                "example": {
                  "status": "ERROR",
                  "code": "FS003",
                  "message": "Undefined attachment"
                }
              }
            }
          },
          "417": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CORCustomError"
                },
                "example": {
                  "status": 417,
                  "name": "CORCustomError",
                  "code": "AC001",
                  "message": "exists validation failed on taskId"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/{task_id}/attachments/source/{source_type}": {
      "post": {
        "tags": [
          "Tasks"
        ],
        "summary": "Create task attachment from external source",
        "description": "Creates an attachment from an external source (Google Drive, Dropbox, OneDrive).",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID of the task"
          },
          {
            "name": "source_type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "GoogleDrive",
                "DropBox",
                "OneDrive"
              ]
            },
            "description": "External file source: `GoogleDrive`, `DropBox`, or `OneDrive`"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "filename",
                  "originalname"
                ],
                "properties": {
                  "filename": {
                    "type": "string",
                    "description": "URL or path of the file in the external provider"
                  },
                  "originalname": {
                    "type": "string",
                    "description": "Original file name with extension"
                  },
                  "size": {
                    "type": "integer",
                    "default": 0,
                    "description": "File size in bytes"
                  },
                  "available": {
                    "type": "boolean",
                    "default": true,
                    "description": "Whether the file is visible"
                  },
                  "session_token": {
                    "type": "string",
                    "nullable": true,
                    "default": null,
                    "description": "Token to group uploads"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Attachment created from external source",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskAttachmentSourceResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid source_type",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CORCustomError"
                },
                "example": {
                  "status": 400,
                  "name": "CORCustomError",
                  "code": "AC001",
                  "message": "Invalid source type"
                }
              }
            }
          },
          "417": {
            "description": "Task not found (validation failed)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorArray"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/{task_id}/members": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "GET task members",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of task members",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/User"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/tasks/{task_id}/collaborators": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "Get task collaborators",
        "description": "Returns only the collaborators assigned to a task — users directly assigned to work on it.",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The ID of the task"
          }
        ],
        "responses": {
          "200": {
            "description": "List of task collaborators",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TaskCollaboratorSummary"
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Tasks"
        ],
        "summary": "Assign collaborators to a task",
        "description": "Sets the list of collaborators assigned to a task. The operation is a **sync** — the array provided represents the desired final state. Users present in the array but not yet assigned will be added; users currently assigned but absent from the array will be removed.",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The ID of the task"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskCollaboratorsInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns the updated array of collaborators",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TaskCollaborator"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid task ID or invalid users array"
          },
          "417": {
            "description": "Validation error (task not found in company, or one or more user IDs are invalid)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "message": {
                        "type": "string",
                        "example": "exists validation failed on task_id"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/hours": {
      "get": {
        "tags": [
          "Hours"
        ],
        "summary": "Get Hours",
        "description": "Retrieves a paginated list of time entries. By default, responses are paginated with 20 items per page.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": 1
            },
            "description": "Page number (default: 1). Set to `false` to disable pagination."
          },
          {
            "name": "perPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page (default: 20)."
          },
          {
            "name": "filters",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "URL-encoded JSON object with filter criteria. Available fields: `dateStart` (YYYY-MM-DD), `dateDeadline` (YYYY-MM-DD), `clients` (array), `projects` (array), `users` (array), `labels` (array), `teams` (array)."
          },
          {
            "name": "orderBy",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "URL-encoded JSON object for sorting. Example: {\"by\":\"start\",\"order\":\"ASC\"}."
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of time entries",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedHoursResponse"
                },
                "example": {
                  "total_hours": "4.0000000000000000",
                  "total_cost": 4714.285714285714,
                  "data": [
                    {
                      "id": 39517591,
                      "start": "2026-02-06 00:00:00",
                      "stop": "2026-02-06 02:00:00",
                      "duration": "2.0000000000000000",
                      "cost": 2357.142857142857,
                      "user_id": 8546,
                      "task_log_id": 11122850,
                      "project_id": null,
                      "client_id": null,
                      "created_at": "2026-02-06 12:50:12",
                      "status": "pending",
                      "status_changed_by": null,
                      "status_changed_at": null,
                      "type": "TASK",
                      "task_log_rework_id": null,
                      "comments": null,
                      "user": {
                        "id": 8546,
                        "first_name": "Daniel",
                        "last_name": "Guzman",
                        "picture": "https://user-images.projectcor.com/production/Upload/ProfilePictures/50x50/c-2336-248213441263.jpeg",
                        "remaining_hours": 88,
                        "timezone": "America/Buenos_Aires",
                        "gmt": "-03:00"
                      },
                      "client": null,
                      "project": null,
                      "task": {
                        "id": 11122850,
                        "title": "Armado de contenido v1",
                        "project_id": 878491,
                        "task_father": null,
                        "status": "nueva",
                        "father": null,
                        "project": {
                          "id": 878491,
                          "name": "Creacion de Contenido",
                          "client_id": 31405,
                          "contract_id": null,
                          "client": {
                            "id": 31405,
                            "name": "Cloud Solution",
                            "client_status_id": 1
                          },
                          "has_expired_contract": false
                        },
                        "labels": []
                      },
                      "userPosition": null,
                      "billInput": null
                    }
                  ],
                  "total": "1",
                  "perPage": 20,
                  "page": "1",
                  "lastPage": 1
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Hours"
        ],
        "summary": "Post hours",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HourInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Hours logged successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Hour"
                }
              }
            }
          }
        }
      }
    },
    "/hours/status-change": {
      "post": {
        "tags": [
          "Hours"
        ],
        "summary": "Change status",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "status",
                  "counters"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "pending",
                      "approved",
                      "discarded",
                      "under_review",
                      "invoiced",
                      "paid"
                    ],
                    "description": "Hour status"
                  },
                  "counters": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Array of counter IDs"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Status changed successfully"
          }
        }
      }
    },
    "/hours/status-bills-change": {
      "post": {
        "tags": [
          "Hours"
        ],
        "summary": "Status bill change",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "receiptNumber",
                  "counters"
                ],
                "properties": {
                  "receiptNumber": {
                    "type": "integer",
                    "description": "Receipt Number"
                  },
                  "counters": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Array of counters"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Status changed successfully"
          }
        }
      }
    },
    "/hours/by-day/{datetime}": {
      "get": {
        "tags": [
          "Hours"
        ],
        "summary": "Get Hours By Date",
        "description": "datetime: datetime in unix format",
        "parameters": [
          {
            "name": "datetime",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "description": "In UNIX Time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Hours for the specified date",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Hour"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/hours/by-day/weigh": {
      "post": {
        "tags": [
          "Hours"
        ],
        "summary": "Update status of weigh hours",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "task_log_id",
                  "start"
                ],
                "properties": {
                  "task_log_id": {
                    "type": "integer",
                    "description": "Task ID"
                  },
                  "start": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Start Timestamp"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Status updated successfully"
          }
        }
      }
    },
    "/hours/accept-suggested/{datetime}": {
      "post": {
        "tags": [
          "Hours"
        ],
        "summary": "Accept suggested hours",
        "description": "datetime: datetime in unix format",
        "parameters": [
          {
            "name": "datetime",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "description": "In Unix Time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Suggested hours accepted successfully"
          }
        }
      }
    },
    "/users": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Get Users",
        "description": "Retrieves a paginated list of users with optional filtering. By default, responses are paginated with 20 items per page.\n\n**Filter options:**\n- `withHiddenUsers` (boolean): Include hidden users in the response\n- `withPosition` (boolean): Include user positions in the response\n- `createdAt` (string): Filter users created on or after this date (YYYY-MM-DD)\n- `updatedAt` (string): Filter users updated on or after this date (YYYY-MM-DD)",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": 1
            },
            "description": "Page number (default: 1). Set to `false` to disable pagination."
          },
          {
            "name": "perPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page (default: 20)."
          },
          {
            "name": "filters",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "URL-encoded JSON filters object. Available fields: `withHiddenUsers`, `withPosition`, `createdAt`, `updatedAt`.",
            "example": "{\"withHiddenUsers\":true, \"withPosition\":true, \"createdAt\": \"2024-01-01\", \"updatedAt\": \"2024-01-31\"}"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of users",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserListResponse"
                },
                "example": {
                  "total": "100",
                  "perPage": 20,
                  "page": 1,
                  "lastPage": 20,
                  "data": [
                    {
                      "id": 123,
                      "first_name": "Jane",
                      "picture": "https://user-images.staging.projectcor.com/local/Upload/ProfilePictures/50x50/user.png",
                      "last_name": "Doe",
                      "email": "jane.doe@example.com",
                      "cuil": "",
                      "remaining_hours": 100,
                      "user_position_id": 3,
                      "role_id": 2,
                      "daily_hours": 0,
                      "labels": [],
                      "plan_id": 5,
                      "plan_name": "Capacity Planning",
                      "hidden": false,
                      "position_name": null,
                      "category_id": null,
                      "category_name": null,
                      "gmt": "-03:00",
                      "leaves": []
                    },
                    {
                      "id": 456,
                      "first_name": "John",
                      "picture": "https://user-images.staging.projectcor.com/local/Upload/ProfilePictures/50x50/user.png",
                      "last_name": "Smith",
                      "email": "john.smith@example.com",
                      "cuil": "",
                      "remaining_hours": 80,
                      "user_position_id": 2,
                      "role_id": 4,
                      "daily_hours": 8,
                      "labels": [
                        {
                          "id": 210595,
                          "lang": "es",
                          "name": "Desarrollo web"
                        }
                      ],
                      "plan_id": 5,
                      "plan_name": "Capacity Planning",
                      "hidden": false,
                      "position_name": null,
                      "category_id": null,
                      "category_name": null,
                      "gmt": "-03:00",
                      "leaves": []
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Users"
        ],
        "summary": "Create a user",
        "description": "Creates a user using a POST http method. The user will receive an invitation email.\n\n**Required properties:**\n- `first_name` — User given name\n- `last_name` — User family name\n- `email` — User email\n- `role_id` — ID of the user's role:\n  - **1**: C-Level\n  - **2**: Director\n  - **3**: Project Manager\n  - **4**: Collaborator\n  - **5**: Freelancer\n  - **6**: Client",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserCreateInput"
              },
              "example": {
                "first_name": "John",
                "last_name": "Doe",
                "email": "john.doe@example.com",
                "role_id": 1,
                "user_position_id": 2,
                "phone": "123-456-7890",
                "description": "Senior Developer",
                "birthday": "1990-01-01",
                "work_in": "Engineering",
                "hourly_rate": 50.00,
                "monthly_hours": 160,
                "daily_hours": 8,
                "salary": 4500
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "User created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          }
        }
      }
    },
    "/users/{user_id}": {
      "put": {
        "tags": [
          "Users"
        ],
        "summary": "Update a user",
        "description": "Updates a user using a PUT http method.\n\n⚠️ **Important:** Use caution when using this endpoint. The system will replace the existing user with the values passed in the request body.\n\n**Available properties:**\n- `first_name` — User given name\n- `last_name` — User family name\n- `email` — User email\n- `role_id` — ID of the user's role (1-6)\n- `user_position_id` — ID of the user's position\n- `phone`, `description`, `birthday`, `work_in`\n- `hourly_rate`, `monthly_hours`, `daily_hours`\n- `plan_id` — 4: Project Management, 5: Capacity Planning\n- `hidden`, `charge_hours` — Boolean values\n- `salary` — New monthly salary amount\n- `salary_from` — Month from which salary should apply (MM-YYYY). Defaults to the current month if `salary` is provided.",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "User ID",
            "example": 123
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserUpdateInput"
              },
              "example": {
                "first_name": "John",
                "last_name": "Doe",
                "email": "john.doe@example.com",
                "role_id": 3,
                "salary": 5200,
                "salary_from": "01-2026"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "User updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Users"
        ],
        "summary": "Delete a user",
        "description": "Deletes a user from the system.",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "User ID to delete",
            "example": 123
          }
        ],
        "responses": {
          "200": {
            "description": "User deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "boolean"
                },
                "example": true
              }
            }
          }
        }
      }
    },
    "/users/{user_id}/labels": {
      "put": {
        "tags": [
          "Users"
        ],
        "summary": "Assign or unassign user label",
        "description": "Updates a label for a specified user by their user ID. It assigns a new label to the user or unassigns the existing label with the specified `labelId`.\n\n**To assign a label:** Omit the `unassign` property or set it to `false`.\n\n**To remove a label:** Set `unassign` to `true`.",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "User ID",
            "example": 123
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserLabelInput"
              },
              "examples": {
                "assign_label": {
                  "summary": "Assign a label to user",
                  "value": {
                    "labelId": 3003
                  }
                },
                "unassign_label": {
                  "summary": "Remove a label from user",
                  "value": {
                    "labelId": 3003,
                    "unassign": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Label updated successfully"
          }
        }
      }
    },
    "/users/search-by-name/{name}": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Get users by Name",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": 1
            },
            "description": "Page number (default: 1). Set to `false` to disable pagination."
          },
          {
            "name": "perPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page (default: 20)."
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of users",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserListResponse"
                },
                "example": {
                  "total": "1",
                  "perPage": 20,
                  "page": 1,
                  "lastPage": 1,
                  "data": [
                    {
                      "id": 123,
                      "first_name": "Jane",
                      "picture": "https://user-images.staging.projectcor.com/local/Upload/ProfilePictures/50x50/user.png",
                      "last_name": "Doe",
                      "email": "jane.doe@example.com",
                      "cuil": "",
                      "remaining_hours": 100,
                      "user_position_id": 3,
                      "role_id": 2,
                      "daily_hours": 0,
                      "labels": [
                        {
                          "id": 210595,
                          "lang": "es",
                          "name": "Desarrollo web"
                        }
                      ],
                      "plan_id": 5,
                      "plan_name": "Capacity Planning",
                      "hidden": false,
                      "position_name": null,
                      "category_id": null,
                      "category_name": null,
                      "gmt": "-03:00",
                      "leaves": []
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/categories/labels-model": {
      "get": {
        "tags": [
          "Labels"
        ],
        "summary": "Get Categories and Labels",
        "description": "Returns categories for the company, each with its labels, filtered by which entity type those categories apply to (users, projects, or tasks). Names are returned in the authenticated user's language.\n\nUse **`model`** to choose the taxonomy: `user` for user/operation labels, `project` for project labels, and `task` for task labels. Any other value yields a validation error.",
        "parameters": [
          {
            "name": "model",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "user",
                "project",
                "task"
              ],
              "default": "user"
            },
            "description": "Entity type whose category/label tree to return: `user` (user labels), `project` (project labels), `task` (task labels).",
            "example": "user"
          },
          {
            "name": "is_filterable",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true
            },
            "description": "When `true` (default), only categories with `is_filterable` set are returned. Use `false` to include categories that are not marked filterable."
          }
        ],
        "responses": {
          "400": {
            "description": "Missing or unknown `model` (e.g. empty `model`, or a value not in `user` | `project` | `task`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "200": {
            "description": "List of categories with their associated labels",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Category"
                  }
                },
                "example": [
                  {
                    "id": 101,
                    "name": "Development Team",
                    "labels": [
                      {
                        "id": 3001,
                        "hex": "#FF5733",
                        "hsl": null,
                        "rgb": null,
                        "lang": "en",
                        "name": "Backend",
                        "color_id": 10
                      },
                      {
                        "id": 3002,
                        "hex": "#33FF57",
                        "hsl": null,
                        "rgb": null,
                        "lang": "en",
                        "name": "Frontend",
                        "color_id": 11
                      },
                      {
                        "id": 3003,
                        "hex": "#3357FF",
                        "hsl": null,
                        "rgb": null,
                        "lang": "en",
                        "name": "QA",
                        "color_id": 12
                      },
                      {
                        "id": 3004,
                        "hex": "#FF33A1",
                        "hsl": null,
                        "rgb": null,
                        "lang": "en",
                        "name": "DevOps",
                        "color_id": 13
                      }
                    ]
                  },
                  {
                    "id": 102,
                    "name": "Sales Team",
                    "labels": [
                      {
                        "id": 4001,
                        "hex": "#FFC300",
                        "hsl": null,
                        "rgb": null,
                        "lang": "en",
                        "name": "Lead Generation",
                        "color_id": 14
                      },
                      {
                        "id": 4002,
                        "hex": "#FF5733",
                        "hsl": null,
                        "rgb": null,
                        "lang": "en",
                        "name": "Account Management",
                        "color_id": 15
                      }
                    ]
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/working-time": {
      "post": {
        "tags": [
          "Working Time"
        ],
        "summary": "Create or update working time",
        "description": "Creates or updates the user's working time schedule.\n\n**Fields:**\n- `dayOfWeek` — Day of the week (1 = Sunday, 7 = Saturday)\n- `start` — Start time in HH:MM format (24-hour clock)\n- `end` — End time in HH:MM format (24-hour clock)\n- `breakTime` — Break duration in hours. Valid values: 0, 0.25, 0.5, 0.75, 1, 1.5, 2",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WorkingTimeInput"
              },
              "example": {
                "userId": 11111,
                "companyId": 11111,
                "workingTimes": [
                  {
                    "dayOfWeek": "1",
                    "start": "09:00",
                    "end": "18:00",
                    "breakTime": "0"
                  },
                  {
                    "dayOfWeek": "2",
                    "start": "09:00",
                    "end": "18:00",
                    "breakTime": "1"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Working time saved successfully"
          }
        }
      }
    },
    "/working-time/company/with/users": {
      "get": {
        "tags": [
          "Working Time"
        ],
        "summary": "Get working time users",
        "description": "Gets information about working time for all users in the company. The response is an object where keys are user IDs and values are arrays of working time entries.",
        "responses": {
          "200": {
            "description": "Working time data grouped by user ID",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/WorkingTime"
                    }
                  }
                },
                "example": {
                  "12345": [
                    {
                      "daily_hours": 9,
                      "day_of_week": 1,
                      "start_at": "09:00:00",
                      "end_at": "18:00:00",
                      "user_id": 12345,
                      "break_time": 0
                    },
                    {
                      "daily_hours": 8,
                      "day_of_week": 2,
                      "start_at": "09:00:00",
                      "end_at": "18:00:00",
                      "user_id": 12345,
                      "break_time": 1
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/user/leaves": {
      "get": {
        "tags": [
          "User Leaves"
        ],
        "summary": "Get User Leaves",
        "description": "Gets user leaves for specified users with pagination support.",
        "parameters": [
          {
            "name": "usersId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "User ID to get leaves for",
            "example": 8555
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            },
            "description": "Pagination offset",
            "example": 1
          },
          {
            "name": "size",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 10
            },
            "description": "Number of results per page",
            "example": 10
          }
        ],
        "responses": {
          "200": {
            "description": "List of leaves with their associated leave types",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Leave"
                  }
                },
                "example": [
                  {
                    "id": 14050,
                    "user_id": 8555,
                    "company_id": 2336,
                    "leave_type_id": 1498,
                    "start": "2024-10-18T03:00:00.000Z",
                    "end": "2024-10-18T03:30:00.000Z",
                    "created_at": "2024-10-21 14:19:01",
                    "updated_at": "2024-10-21 14:19:23",
                    "deleted_at": null,
                    "all_day": false,
                    "leaveType": {
                      "id": 1498,
                      "name": "Custom Leave",
                      "type_code": "UL1498",
                      "company_id": 2336,
                      "created_at": "2024-10-21 14:18:36",
                      "updated_at": "2024-10-21 14:18:36",
                      "deleted_at": null,
                      "icon_name": "Futbol"
                    }
                  },
                  {
                    "id": 10030,
                    "user_id": 8555,
                    "company_id": 2336,
                    "leave_type_id": 12,
                    "start": "2024-08-29T13:00:00.000Z",
                    "end": "2024-08-29T15:00:00.000Z",
                    "created_at": "2024-08-29 13:44:13",
                    "updated_at": "2024-08-29 13:44:13",
                    "deleted_at": null,
                    "all_day": false,
                    "leaveType": {
                      "id": 12,
                      "name": "flexday",
                      "type_code": "UL12",
                      "company_id": null,
                      "created_at": "2022-09-14 12:09:10",
                      "updated_at": "2024-07-15 17:16:56",
                      "deleted_at": null,
                      "icon_name": "Loveseat"
                    }
                  }
                ]
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "User Leaves"
        ],
        "summary": "Create User Leave",
        "description": "Creates a new user leave.\n\n⚠️ **Important:**\n- Dates must be sent in UTC format (e.g., `2024-11-18T03:00:00Z`)\n- Dates cannot overlap with existing leaves for the same user\n- If there is an existing date between the submitted dates, the request will not be saved",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeaveInput"
              },
              "example": {
                "userId": 8555,
                "leaveTypeId": 11,
                "start": "2024-11-18T03:00:00Z",
                "end": "2024-11-19T02:59:00Z",
                "allDay": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Leave created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Leave"
                },
                "example": {
                  "user_id": 8555,
                  "company_id": 2336,
                  "leave_type_id": 11,
                  "start": "2024-11-18T03:00:00Z",
                  "end": "2024-11-19T02:59:00Z",
                  "created_at": "2024-11-07 22:11:30",
                  "updated_at": "2024-11-07 22:11:30",
                  "all_day": false,
                  "id": 16332
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "User Leaves"
        ],
        "summary": "Delete User Leave",
        "description": "Deletes a user leave by providing the leave ID and user ID.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeaveDeleteInput"
              },
              "example": {
                "id": 15489,
                "userId": 8555
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Leave deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "id": 15489
                }
              }
            }
          }
        }
      }
    },
    "/user/leaves/{licenseId}": {
      "put": {
        "tags": [
          "User Leaves"
        ],
        "summary": "Update User Leave",
        "description": "Updates an existing user leave. Dates must be in UTC format.",
        "parameters": [
          {
            "name": "licenseId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "User Leave ID to update",
            "example": 16332
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeaveUpdateInput"
              },
              "example": {
                "userId": 8555,
                "leaveTypeId": 12,
                "start": "2024-11-18T03:00:00Z",
                "end": "2024-11-19T05:00:00Z"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Leave updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Leave"
                },
                "example": {
                  "id": 16332,
                  "user_id": 8555,
                  "company_id": 2336,
                  "leave_type_id": 12,
                  "start": "2024-11-18T03:00:00Z",
                  "end": "2024-11-19T05:00:00Z",
                  "created_at": "2024-11-07 22:11:30",
                  "updated_at": "2024-11-07 22:20:48",
                  "deleted_at": null,
                  "all_day": false
                }
              }
            }
          }
        }
      }
    },
    "/company/leaves-types": {
      "get": {
        "tags": [
          "User Leaves"
        ],
        "summary": "Get Leave Types",
        "description": "Retrieves a paginated list of default and custom leave types for your company. By default, responses are paginated with 20 items per page.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": 1
            },
            "description": "Page number (default: 1). Set to `false` to disable pagination."
          },
          {
            "name": "perPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page (default: 20)."
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of leave types",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedLeaveTypesResponse"
                },
                "example": {
                  "total": 2,
                  "perPage": 20,
                  "page": 1,
                  "lastPage": 1,
                  "data": [
                    {
                      "id": 111,
                      "name": "Custom leave",
                      "type_code": "CODE",
                      "company_id": 111,
                      "created_at": "2024-12-06T13:02:53.000Z",
                      "updated_at": "2024-12-06T13:02:53.000Z",
                      "deleted_at": null,
                      "icon_name": "icon name"
                    },
                    {
                      "id": 12,
                      "name": "flexday",
                      "type_code": "UL12",
                      "company_id": null,
                      "created_at": "2022-09-14T12:09:10.000Z",
                      "updated_at": "2024-07-15T17:16:56.000Z",
                      "deleted_at": null,
                      "icon_name": "Loveseat"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "User Leaves"
        ],
        "summary": "Create Leave Type",
        "description": "Creates a new custom leave type for your company.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeaveTypeInput"
              },
              "example": {
                "name": "Custom leave type"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Leave type created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeaveType"
                },
                "example": {
                  "name": "Custom leave type",
                  "company_id": 111,
                  "icon_name": "ICON",
                  "created_at": "2024-12-10 17:57:12",
                  "updated_at": "2024-12-10 17:57:12",
                  "id": 111
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "User Leaves"
        ],
        "summary": "Delete Leave Type",
        "description": "Deletes a custom leave type. Only custom leave types (with a company_id) can be deleted.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeaveTypeDeleteInput"
              },
              "example": {
                "id": 111
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Leave type deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "id": 111
                }
              }
            }
          }
        }
      }
    },
    "/company/leaves-types/{leaveTypeId}": {
      "put": {
        "tags": [
          "User Leaves"
        ],
        "summary": "Update Leave Type",
        "description": "Updates a custom leave type. Only the name can be modified.",
        "parameters": [
          {
            "name": "leaveTypeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "Leave type ID to update",
            "example": 111
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeaveTypeInput"
              },
              "example": {
                "name": "Custom type - edited"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Leave type updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeaveType"
                },
                "example": {
                  "id": 111,
                  "name": "Custom type - edited",
                  "type_code": "CODE",
                  "company_id": 1111,
                  "created_at": "2024-12-10T17:57:12.000Z",
                  "updated_at": "2024-12-10T18:19:13.000Z",
                  "deleted_at": null,
                  "icon_name": "ICON"
                }
              }
            }
          }
        }
      }
    },
    "/transactions": {
      "get": {
        "tags": [
          "Transactions"
        ],
        "summary": "Get transactions",
        "description": "Retrieves a paginated list of transactions. By default, responses are paginated with 20 items per page.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": 1
            },
            "description": "Page number (default: 1). Set to `false` to disable pagination."
          },
          {
            "name": "perPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page (default: 20)."
          },
          {
            "name": "filters",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "URL-encoded JSON object with filter criteria."
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of transactions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedTransactionsResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Transactions"
        ],
        "summary": "Create transaction",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transaction created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transaction"
                }
              }
            }
          }
        }
      }
    },
    "/transactions/{transaction_id}": {
      "put": {
        "tags": [
          "Transactions"
        ],
        "summary": "Update transaction",
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transaction updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transaction"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Transactions"
        ],
        "summary": "Delete transaction",
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Transaction deleted successfully"
          }
        }
      }
    },
    "/transactions/total": {
      "get": {
        "tags": [
          "Transactions"
        ],
        "summary": "Get Total",
        "responses": {
          "200": {
            "description": "Transaction totals",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "total": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/transaction/{transaction_id}/transactionItems": {
      "delete": {
        "tags": [
          "Transactions"
        ],
        "summary": "Delete transaction items",
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Transaction items deleted successfully"
          }
        }
      },
      "post": {
        "tags": [
          "Transactions"
        ],
        "summary": "Create transaction items",
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionItemInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transaction item created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionItem"
                }
              }
            }
          }
        }
      }
    },
    "/transaction/{transaction_id}/transactionItems/{transaction_item_id}": {
      "put": {
        "tags": [
          "Transactions"
        ],
        "summary": "Update transaction item",
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "transaction_item_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionItemInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transaction item updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionItem"
                }
              }
            }
          }
        }
      }
    },
    "/transactions/{transaction_item_id}/suggest-allocation": {
      "get": {
        "tags": [
          "Transactions"
        ],
        "summary": "Get Suggest Allocation",
        "parameters": [
          {
            "name": "transaction_item_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Suggested allocation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/teams": {
      "get": {
        "tags": [
          "Teams"
        ],
        "summary": "Get Teams",
        "description": "Retrieves a paginated list of teams. By default, responses are paginated with 20 items per page.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": 1
            },
            "description": "Page number (default: 1). Set to `false` to disable pagination."
          },
          {
            "name": "perPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page (default: 20)."
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of teams",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedTeamsResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Teams"
        ],
        "summary": "Create a team",
        "description": "Creates a new team entity.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TeamInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Team created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Team"
                }
              }
            }
          }
        }
      }
    },
    "/teams/{team_id}": {
      "get": {
        "tags": [
          "Teams"
        ],
        "summary": "Get team by ID",
        "parameters": [
          {
            "name": "team_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Team details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Team"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Teams"
        ],
        "summary": "Update a team",
        "description": "Updates a team entity.",
        "parameters": [
          {
            "name": "team_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TeamInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Team updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Team"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Teams"
        ],
        "summary": "Delete a team",
        "description": "Deletes a team from the system.",
        "parameters": [
          {
            "name": "team_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Team deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "boolean"
                },
                "example": true
              }
            }
          }
        }
      }
    },
    "/teams/{team_id}/users": {
      "post": {
        "tags": [
          "Teams"
        ],
        "summary": "Add users to a team",
        "description": "Adds users to a team by providing an array of user IDs.",
        "parameters": [
          {
            "name": "team_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TeamUsersInput"
              },
              "example": {
                "users_ids": [
                  8546
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Users added to team successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TeamUserRelation"
                  }
                },
                "example": [
                  {
                    "team_id": 4246,
                    "user_id": 48429,
                    "created_at": "2026-01-20 19:59:53",
                    "updated_at": "2026-01-20 19:59:53",
                    "id": 178149,
                    "__meta__": {
                      "company_id": 2336,
                      "user": {
                        "id": 48429,
                        "first_name": "Gonzalo",
                        "last_name": "Test",
                        "email": "test@projectcor.com",
                        "company_id": 2336
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Teams"
        ],
        "summary": "Remove users from a team",
        "description": "Removes users from a team by providing an array of user IDs.",
        "parameters": [
          {
            "name": "team_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TeamUsersInput"
              },
              "example": {
                "users_ids": [
                  8546
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Users removed from team successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TeamUserRelation"
                  }
                },
                "example": [
                  {
                    "id": 178149,
                    "team_id": 4246,
                    "user_id": 48429,
                    "created_at": "2026-01-20 19:59:53",
                    "updated_at": "2026-01-20 19:59:53",
                    "deleted_at": "2026-01-20T20:00:23.632Z",
                    "__meta__": {
                      "company_id": 2336,
                      "user": {
                        "id": 48429,
                        "first_name": "Gonzalo",
                        "last_name": "Test",
                        "email": "test@projectcor.com",
                        "company_id": 2336
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/ratecards": {
      "get": {
        "tags": [
          "Ratecards"
        ],
        "summary": "Get Ratecards",
        "description": "Retrieves a paginated list of ratecards for the current company. Each ratecard defines pricing configurations such as positions, rates, and custom pricing percentages.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": [
                "integer",
                "boolean"
              ],
              "default": 1
            },
            "description": "Page number (default: 1). Set to `false` to disable pagination."
          },
          {
            "name": "perPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            },
            "description": "Number of items per page (default: 20)."
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of ratecards",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedRatecardsResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Ratecards"
        ],
        "summary": "Create a Ratecard",
        "description": "Creates a new ratecard for the current company.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RatecardInput"
              },
              "example": {
                "name": "Custom Ratecard 1",
                "original_name": "Custom Ratecard 1",
                "percent": 15,
                "currency_id": 1,
                "linked_to_base_price": false,
                "external_key": "BILLING-RC-001"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Ratecard created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ratecard"
                },
                "example": {
                  "id": 51,
                  "original_name": "Custom Ratecard 1",
                  "name": "Custom Ratecard 1",
                  "percent": 15,
                  "company_id": 2336,
                  "system": false,
                  "created_at": "2025-12-15 00:24:41",
                  "updated_at": "2025-12-15 00:24:41",
                  "deleted_at": null,
                  "external_key": "BILLING-RC-001",
                  "currency_id": 1,
                  "linked_to_base_price": false
                }
              }
            }
          }
        }
      }
    },
    "/ratecards/{id}": {
      "put": {
        "tags": [
          "Ratecards"
        ],
        "summary": "Update a Ratecard",
        "description": "Updates an existing ratecard by ID.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "Ratecard ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RatecardUpdate"
              },
              "example": {
                "name": "Custom Ratecard 1 (updated)",
                "original_name": "Custom Ratecard 1",
                "percent": 20,
                "currency_id": 2,
                "linked_to_base_price": true,
                "external_key": "BILLING-RC-001"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Ratecard updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ratecard"
                },
                "example": {
                  "id": 50,
                  "original_name": "Custom Ratecard 1",
                  "name": "Custom Ratecard 1 (updated)",
                  "percent": 20,
                  "company_id": 2336,
                  "system": false,
                  "created_at": "2025-12-15 00:24:41",
                  "updated_at": "2025-12-15 01:10:05",
                  "deleted_at": null,
                  "external_key": "BILLING-RC-001",
                  "currency_id": 2,
                  "linked_to_base_price": true
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Ratecards"
        ],
        "summary": "Delete a Ratecard",
        "description": "Deletes (soft-delete) a ratecard by ID. Returns the deleted ratecard object with `deleted_at` timestamp set.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "Ratecard ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Ratecard deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ratecard"
                },
                "example": {
                  "id": 50,
                  "original_name": "Custom Ratecard 1",
                  "name": "Custom Ratecard 1",
                  "percent": 20,
                  "company_id": 2336,
                  "system": false,
                  "created_at": "2025-12-15 00:24:41",
                  "updated_at": "2025-12-15 01:10:05",
                  "deleted_at": "2025-12-15 01:15:10",
                  "external_key": "BILLING-RC-001",
                  "currency_id": 2,
                  "linked_to_base_price": true
                }
              }
            }
          },
          "204": {
            "description": "Ratecard deleted successfully (no content)"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      },
      "basicAuth": {
        "type": "http",
        "scheme": "basic"
      }
    },
    "schemas": {
      "AuthResponse": {
        "type": "object",
        "properties": {
          "access_token": {
            "type": "string"
          },
          "token_type": {
            "type": "string"
          },
          "expires_in": {
            "type": "integer"
          },
          "refresh_token": {
            "type": "string"
          }
        }
      },
      "UserBase": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "picture": {
            "type": "string",
            "description": "URL to user's profile picture"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "cuil": {
            "type": "string"
          },
          "remaining_hours": {
            "type": "number"
          },
          "user_position_id": {
            "type": "integer"
          },
          "role_id": {
            "type": "integer",
            "description": "1=C-Level, 2=Director, 3=Project Manager, 4=Collaborator, 5=Freelancer, 6=Client"
          },
          "daily_hours": {
            "type": "number"
          },
          "plan_id": {
            "type": "integer",
            "description": "4=Project Management, 5=Capacity Planning"
          },
          "plan_name": {
            "type": "string"
          },
          "hidden": {
            "type": "boolean"
          },
          "position_name": {
            "type": "string",
            "nullable": true
          },
          "category_id": {
            "type": "integer",
            "nullable": true
          },
          "category_name": {
            "type": "string",
            "nullable": true
          },
          "gmt": {
            "type": "string",
            "description": "UTC offset from the user's last login location. Indicates the timezone configured at their last login.",
            "example": "-03:00"
          },
          "leaves": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Leave"
            }
          }
        }
      },
      "User": {
        "allOf": [
          {
            "$ref": "#/components/schemas/UserBase"
          },
          {
            "type": "object",
            "properties": {
              "labels": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Label"
                },
                "nullable": true
              }
            }
          }
        ]
      },
      "ProjectCollaborator": {
        "type": "object",
        "description": "Collaborator item returned by GET /projects/{project_id}/collaborators",
        "properties": {
          "id": {
            "type": "integer",
            "description": "User ID"
          },
          "first_name": {
            "type": "string",
            "description": "User first name"
          },
          "last_name": {
            "type": "string",
            "description": "User last name"
          },
          "picture": {
            "type": "string",
            "nullable": true,
            "description": "Profile picture filename or URL"
          },
          "remaining_hours": {
            "type": "number",
            "description": "Remaining hours for the project"
          }
        }
      },
      "UserListResponse": {
        "type": "object",
        "properties": {
          "total": {
            "type": "string"
          },
          "perPage": {
            "type": "integer"
          },
          "page": {
            "type": "integer"
          },
          "lastPage": {
            "type": "integer"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UserListItem"
            }
          }
        }
      },
      "UserListItem": {
        "description": "User object returned by list endpoints (GET /users, GET /users/search-by-name).",
        "allOf": [
          {
            "$ref": "#/components/schemas/UserBase"
          },
          {
            "type": "object",
            "properties": {
              "labels": {
                "type": "array",
                "description": "Labels assigned to the user.",
                "items": {
                  "$ref": "#/components/schemas/UserAssignedLabel"
                }
              }
            }
          }
        ]
      },
      "Contact": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "phone": {
            "type": "string"
          }
        }
      },
      "PaginatedContactsResponse": {
        "type": "object",
        "description": "Paginated response for contacts list",
        "properties": {
          "total": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Total number of contacts"
          },
          "perPage": {
            "type": "integer",
            "description": "Number of items per page"
          },
          "page": {
            "type": "integer",
            "description": "Current page number"
          },
          "lastPage": {
            "type": "integer",
            "description": "Last available page number"
          },
          "data": {
            "type": "array",
            "description": "Array of contacts for the current page",
            "items": {
              "$ref": "#/components/schemas/Contact"
            }
          }
        }
      },
      "Client": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "business_name": {
            "type": "string"
          },
          "name_contact": {
            "type": "string"
          },
          "last_name_contact": {
            "type": "string"
          },
          "email_contact": {
            "type": "string",
            "format": "email"
          },
          "website": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "condition": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          }
        }
      },
      "PaginatedClientsResponse": {
        "type": "object",
        "description": "Paginated response for clients list",
        "properties": {
          "total": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Total number of clients"
          },
          "perPage": {
            "type": "integer",
            "description": "Number of items per page"
          },
          "page": {
            "type": "integer",
            "description": "Current page number"
          },
          "lastPage": {
            "type": "integer",
            "description": "Last available page number"
          },
          "data": {
            "type": "array",
            "description": "Array of clients for the current page",
            "items": {
              "$ref": "#/components/schemas/Client"
            }
          }
        }
      },
      "ClientInput": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of client"
          },
          "business_name": {
            "type": "string",
            "description": "Business Name"
          },
          "name_contact": {
            "type": "string",
            "description": "Contact First name"
          },
          "last_name_contact": {
            "type": "string",
            "description": "Contact Last name"
          },
          "email_contact": {
            "type": "string",
            "format": "email",
            "description": "Contact email"
          },
          "website": {
            "type": "string",
            "description": "Website"
          },
          "description": {
            "type": "string",
            "description": "Description or comments"
          },
          "condition": {
            "type": "string",
            "description": "Client condition"
          },
          "phone": {
            "type": "string",
            "description": "Phone"
          }
        }
      },
      "Fee": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "estimate": {
            "type": "number",
            "format": "float"
          },
          "work_order": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "frequency": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "inactive"
            ]
          },
          "estimated_time": {
            "type": "integer"
          },
          "start": {
            "type": "string",
            "format": "date"
          },
          "end": {
            "type": "string",
            "format": "date"
          },
          "currency_id": {
            "type": "integer"
          }
        }
      },
      "PaginatedFeesResponse": {
        "type": "object",
        "description": "Paginated response for fees list",
        "properties": {
          "total": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Total number of fees"
          },
          "perPage": {
            "type": "integer",
            "description": "Number of items per page"
          },
          "page": {
            "type": "integer",
            "description": "Current page number"
          },
          "lastPage": {
            "type": "integer",
            "description": "Last available page number"
          },
          "data": {
            "type": "array",
            "description": "Array of fees for the current page",
            "items": {
              "$ref": "#/components/schemas/Fee"
            }
          }
        }
      },
      "FeeInput": {
        "type": "object",
        "required": [
          "name",
          "estimate",
          "work_order"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of fee"
          },
          "estimate": {
            "type": "number",
            "format": "float",
            "description": "Estimate"
          },
          "work_order": {
            "type": "string",
            "description": "Work order"
          },
          "description": {
            "type": "string",
            "description": "Description"
          },
          "frequency": {
            "type": "integer",
            "description": "Frequency"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "inactive"
            ],
            "description": "Status"
          },
          "estimated_time": {
            "type": "integer",
            "description": "Estimated time in hours"
          },
          "start": {
            "type": "string",
            "format": "date",
            "description": "Start date"
          },
          "end": {
            "type": "string",
            "format": "date",
            "description": "End date"
          },
          "currency_id": {
            "type": "integer",
            "description": "Currency of fee"
          }
        }
      },
      "ProjectPutUpdateBody": {
        "type": "object",
        "description": "Fields to update on a project. Include only the properties you want to change.",
        "properties": {
          "name": {
            "type": "string",
            "description": "Project Name"
          },
          "client_id": {
            "type": "integer",
            "description": "Client ID"
          },
          "brief": {
            "type": "string",
            "description": "Project description or brief"
          },
          "start": {
            "type": "string",
            "format": "date",
            "description": "Project start date (YYYY-MM-DD)"
          },
          "end": {
            "type": "string",
            "format": "date",
            "description": "Project end date (YYYY-MM-DD)"
          },
          "pm_id": {
            "type": "integer",
            "description": "Project Manager User ID"
          },
          "estimated_time": {
            "type": "number",
            "description": "Estimated hours for the project"
          },
          "billable": {
            "type": "boolean",
            "description": "Whether the project is billable"
          },
          "status": {
            "type": "string",
            "description": "Project status"
          },
          "currency_id": {
            "type": "integer",
            "description": "Currency ID"
          },
          "evaluation_date": {
            "type": "string",
            "format": "date",
            "description": "Project evaluation date (YYYY-MM-DD)"
          },
          "estimated": {
            "type": "number",
            "description": "Estimated monetary value for the project"
          },
          "fee_id": {
            "type": "integer",
            "description": "Fee ID"
          },
          "contract_id": {
            "type": "integer",
            "description": "Contract ID"
          },
          "deliverables": {
            "type": "string",
            "description": "Project deliverables description"
          },
          "work_order": {
            "type": "string",
            "description": "Work order number or code"
          },
          "income_type": {
            "type": "string",
            "enum": [
              "fee",
              "one_time",
              "hourly_rate",
              "contract"
            ],
            "description": "Income type for the project"
          },
          "archived": {
            "type": "boolean",
            "description": "Whether the project is archived",
            "default": false
          },
          "labels": {
            "type": "array",
            "maxItems": 50,
            "description": "Label IDs to assign to the project. Omit this field entirely to leave existing labels unchanged. Send an empty array (`[]`) to remove all labels from the project. Each entry may be an integer ID or an object with an `id` property (for example `[101, 102]`). Maximum 50 labels. Use **Get Categories and Labels** with `model=project` (`GET /categories/labels-model?model=project`) to list project label objects for your company; use each label's `id` in this array.",
            "items": {
              "oneOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "object",
                  "required": [
                    "id"
                  ],
                  "properties": {
                    "id": {
                      "type": "integer"
                    }
                  }
                }
              ]
            }
          },
          "estimated_by_position": {
            "type": "boolean",
            "description": "When `true`, time estimation is split per position via the `users_positions` array. Mutually exclusive with `estimation_by_categories`."
          },
          "estimation_by_categories": {
            "type": [
              "boolean",
              "integer"
            ],
            "description": "When truthy (`true` or `1`), time estimation is split per category via the `categories` array. Mutually exclusive with `estimated_by_position`."
          },
          "estimated_by_hourly_rates": {
            "type": "boolean",
            "description": "When `true`, the project income is calculated from hourly rates using the assigned ratecard."
          },
          "ratecard_id": {
            "type": "integer",
            "description": "Ratecard ID. Alias for `user_positions_header_id` — if both are sent, `ratecard_id` takes precedence."
          },
          "users_positions": {
            "type": "array",
            "description": "Positions involved in the project with optional per-position hour estimates. Positions present in the project but absent from this array will have their estimated hours set to 0 (or be soft-deleted if no hours have been logged).",
            "items": {
              "$ref": "#/components/schemas/ProjectUserPositionInput"
            }
          },
          "categories": {
            "type": "array",
            "description": "Categories assigned to the project with optional per-category hour estimates.",
            "items": {
              "$ref": "#/components/schemas/ProjectCategoryInput"
            }
          },
          "exchange": {
            "type": "number",
            "description": "Exchange rate when project currency differs from the company base currency."
          },
          "currency_change_amount": {
            "type": "number",
            "description": "Original estimated amount in the selected currency before exchange conversion."
          }
        }
      },
      "Project": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Unique project identifier"
          },
          "name": {
            "type": "string",
            "description": "Project name"
          },
          "brief": {
            "type": "string",
            "description": "Project brief/description"
          },
          "client_id": {
            "type": "integer",
            "description": "Associated client ID"
          },
          "health": {
            "type": "integer",
            "enum": [
              1,
              2,
              3,
              4
            ],
            "description": "Project health indicator: 1 (on track), 2 (at risk), 3 (delayed), 4 (critical)"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "finished",
              "suspended"
            ],
            "description": "Project status"
          },
          "start": {
            "type": "string",
            "format": "date-time",
            "description": "Project start date"
          },
          "end": {
            "type": "string",
            "format": "date-time",
            "description": "Project end date"
          },
          "estimated_time": {
            "type": "number",
            "description": "Estimated hours for the project"
          },
          "elapsed_time": {
            "type": "number",
            "description": "Hours already logged"
          },
          "profitability_now": {
            "type": "number",
            "description": "Current profitability percentage"
          },
          "estimated_profitability": {
            "type": "number",
            "description": "Estimated profitability percentage"
          },
          "archived": {
            "type": "boolean",
            "description": "Whether the project is archived"
          },
          "billable": {
            "type": "boolean",
            "description": "Whether the project is billable"
          },
          "income_type": {
            "type": "string",
            "enum": [
              "fee",
              "one_time",
              "hourly_rate",
              "contract"
            ],
            "description": "Project billing type"
          },
          "pm_id": {
            "type": "integer",
            "description": "Project Manager user ID"
          },
          "created_by": {
            "type": "integer",
            "description": "User ID who created the project"
          },
          "company_id": {
            "type": "integer",
            "description": "Company ID"
          },
          "template_id": {
            "type": "integer",
            "description": "Project template ID used"
          },
          "brand_id": {
            "type": "integer",
            "description": "Associated brand ID"
          },
          "product_id": {
            "type": "integer",
            "description": "Associated product ID"
          },
          "total_estimated": {
            "type": "number",
            "description": "Total estimated budget"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp"
          },
          "labels": {
            "type": "array",
            "description": "IDs of labels assigned to this project. Resolve names and styling via **Get Categories and Labels** with `model=project` (`GET /categories/labels-model?model=project`), which returns label objects including the same `id` values.",
            "items": {
              "type": "integer"
            }
          },
          "client": {
            "type": "object",
            "description": "Associated client object",
            "properties": {
              "id": {
                "type": "integer"
              },
              "name": {
                "type": "string"
              },
              "client_status_id": {
                "type": "integer"
              }
            }
          },
          "pm": {
            "type": "object",
            "description": "Project Manager details",
            "properties": {
              "id": {
                "type": "integer"
              },
              "first_name": {
                "type": "string"
              },
              "last_name": {
                "type": "string"
              },
              "email": {
                "type": "string"
              },
              "role_id": {
                "type": "integer"
              }
            }
          },
          "estimated_by_position": {
            "type": "boolean",
            "description": "Whether time estimation is split per position"
          },
          "estimation_by_categories": {
            "type": [
              "boolean",
              "integer"
            ],
            "description": "Whether time estimation is split per category"
          },
          "estimated_by_hourly_rates": {
            "type": [
              "boolean",
              "string"
            ],
            "description": "Whether income is calculated from hourly rates using a ratecard"
          },
          "user_positions_header_id": {
            "type": "integer",
            "nullable": true,
            "description": "ID of the ratecard assigned to this project"
          },
          "fee_id": {
            "type": "integer",
            "nullable": true,
            "description": "Associated fee ID"
          },
          "contract_id": {
            "type": "integer",
            "nullable": true,
            "description": "Associated contract ID"
          },
          "usersPositionsProject": {
            "type": "array",
            "description": "Positions assigned to the project with their estimated and logged hours. Only present when fetching a single project (`GET /projects/{project_id}`).",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer",
                  "description": "Row ID in user_positions_projects"
                },
                "user_positions_unified_id": {
                  "type": "integer",
                  "description": "Unified position ID"
                },
                "project_id": {
                  "type": "integer"
                },
                "estimated_hours": {
                  "type": "number",
                  "description": "Estimated hours for this position"
                },
                "hours_charged": {
                  "type": "number",
                  "description": "Hours already logged against this position"
                },
                "total_cost": {
                  "type": "number",
                  "description": "Total cost accrued for this position"
                },
                "userPositionName": {
                  "type": "object",
                  "nullable": true,
                  "description": "Position name in the requested language",
                  "properties": {
                    "name": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "categoriesProject": {
            "type": "array",
            "description": "Categories assigned to the project with their estimated and logged hours. Only present when fetching a single project.",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer"
                },
                "category_id": {
                  "type": "integer"
                },
                "estimated_hours": {
                  "type": "number"
                },
                "hours_charged": {
                  "type": "number"
                },
                "total_cost": {
                  "type": "number"
                }
              }
            }
          },
          "ratecard": {
            "type": "object",
            "nullable": true,
            "description": "Ratecard assigned to this project. Only present when fetching a single project.",
            "properties": {
              "id": {
                "type": "integer"
              },
              "name": {
                "type": "string"
              },
              "original_name": {
                "type": "string"
              },
              "percent": {
                "type": "number"
              },
              "currency_id": {
                "type": "integer",
                "nullable": true
              },
              "linked_to_base_price": {
                "type": "boolean"
              }
            }
          }
        }
      },
      "PaginatedProjectsResponse": {
        "type": "object",
        "description": "Paginated response for projects list",
        "properties": {
          "total": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Total number of projects matching the filters"
          },
          "perPage": {
            "type": "integer",
            "description": "Number of items per page"
          },
          "page": {
            "type": "integer",
            "description": "Current page number"
          },
          "lastPage": {
            "type": "integer",
            "description": "Last available page number"
          },
          "meta_data": {
            "type": "object",
            "description": "Additional metadata",
            "properties": {
              "profitability_limit": {
                "type": "string",
                "description": "Company profitability limit setting"
              }
            }
          },
          "data": {
            "type": "array",
            "description": "Array of projects for the current page",
            "items": {
              "$ref": "#/components/schemas/Project"
            }
          }
        }
      },
      "ProjectInput": {
        "type": "object",
        "required": [
          "name",
          "client_id"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Project Name"
          },
          "client_id": {
            "type": "integer",
            "description": "Client ID"
          },
          "template_id": {
            "type": "integer",
            "description": "Project Template ID"
          },
          "brief": {
            "type": "string",
            "description": "Project description or brief"
          },
          "start": {
            "type": "string",
            "format": "date",
            "description": "Project start date (YYYY-MM-DD)"
          },
          "end": {
            "type": "string",
            "format": "date",
            "description": "Project end date (YYYY-MM-DD)"
          },
          "pm_id": {
            "type": "integer",
            "description": "Project Manager User ID"
          },
          "brand_id": {
            "type": "integer",
            "description": "Brand ID"
          },
          "product_id": {
            "type": "integer",
            "description": "Product ID"
          },
          "estimated_time": {
            "type": "number",
            "description": "Estimated hours for the project"
          },
          "billable": {
            "type": "boolean",
            "description": "Whether the project is billable"
          },
          "status": {
            "type": "string",
            "description": "Project status"
          },
          "currency_id": {
            "type": "integer",
            "description": "Currency ID"
          },
          "evaluation_date": {
            "type": "string",
            "format": "date",
            "description": "Project evaluation date (YYYY-MM-DD)"
          },
          "estimated": {
            "type": "number",
            "description": "Estimated monetary value for the project"
          },
          "fee_id": {
            "type": "integer",
            "description": "Fee ID"
          },
          "contract_id": {
            "type": "integer",
            "description": "Contract ID"
          },
          "deliverables": {
            "type": "string",
            "description": "Project deliverables description"
          },
          "work_order": {
            "type": "string",
            "description": "Work order number or code"
          },
          "income_type": {
            "type": "string",
            "enum": [
              "fee",
              "one_time",
              "hourly_rate",
              "contract"
            ],
            "description": "Income type for the project"
          },
          "archived": {
            "type": "boolean",
            "description": "Whether the project is archived",
            "default": false
          },
          "estimated_by_position": {
            "type": "boolean",
            "description": "When `true`, time estimation is split per position via the `users_positions` array. Mutually exclusive with `estimation_by_categories`. When both are `false` (or omitted), the project uses a single total `estimated_time` value.",
            "default": false
          },
          "estimation_by_categories": {
            "type": [
              "boolean",
              "integer"
            ],
            "description": "When truthy (`true` or `1`), time estimation is split per category via the `categories` array. Mutually exclusive with `estimated_by_position`.",
            "default": false
          },
          "estimated_by_hourly_rates": {
            "type": "boolean",
            "description": "When `true`, the project income is calculated from hourly rates using the assigned ratecard (`ratecard_id` / `user_positions_header_id`). Requires `income_type` to be `\"hourly_rate\"`.",
            "default": false
          },
          "ratecard_id": {
            "type": "integer",
            "description": "Ratecard ID to assign to the project. This is an alias for `user_positions_header_id` — if both are sent, `ratecard_id` takes precedence. Use **Get Ratecards** (`GET /ratecards`) to list available ratecards."
          },
          "users_positions": {
            "type": "array",
            "description": "Positions involved in the project. When `estimated_by_position` is `true`, each item should include `estimated_time` (hours). When `false`, send only the position `id` to associate positions without per-position hour estimates.",
            "items": {
              "$ref": "#/components/schemas/ProjectUserPositionInput"
            }
          },
          "categories": {
            "type": "array",
            "description": "Categories assigned to the project. When `estimation_by_categories` is truthy, each item should include `estimated_time` (hours). When falsy, send only the category `id`.",
            "items": {
              "$ref": "#/components/schemas/ProjectCategoryInput"
            }
          },
          "collaborators": {
            "type": "array",
            "description": "User IDs to add as project collaborators.",
            "items": {
              "type": "integer"
            }
          },
          "labels": {
            "type": "array",
            "maxItems": 50,
            "description": "Label IDs to assign to the project. Maximum 50 labels.",
            "items": {
              "type": "integer"
            }
          },
          "teams": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer",
                  "description": "Team ID"
                },
                "user_id": {
                  "type": "array",
                  "items": {
                    "type": "integer"
                  },
                  "description": "Team user IDs"
                }
              }
            }
          },
          "exchange": {
            "type": "number",
            "description": "Exchange rate to apply when the project currency differs from the company base currency."
          },
          "currency_change_amount": {
            "type": "number",
            "description": "Original estimated amount in the selected currency before exchange conversion."
          }
        }
      },
      "ProjectUserPositionInput": {
        "type": "object",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "description": "Unified position ID (`user_positions_unified.id`). Use **Get Position Segment Labels** or the User Positions endpoints to list available positions."
          },
          "estimated_time": {
            "type": "number",
            "description": "Estimated hours for this position. Required when `estimated_by_position` is `true`. The server persists this value as `estimated_hours` in the `user_positions_projects` table."
          }
        }
      },
      "ProjectCategoryInput": {
        "type": "object",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "description": "Category ID."
          },
          "estimated_time": {
            "type": "number",
            "description": "Estimated hours for this category. Required when `estimation_by_categories` is truthy."
          }
        }
      },
      "Message": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "message": {
            "type": "string"
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Attachment"
            }
          }
        }
      },
      "MessageInput": {
        "type": "object",
        "required": [
          "message"
        ],
        "properties": {
          "message": {
            "type": "string",
            "description": "Text Message"
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AttachmentInput"
            },
            "description": "Optional attachments"
          }
        }
      },
      "Attachment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AttachmentInput": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "ID Attachment"
          },
          "name": {
            "type": "string",
            "description": "Name of file"
          },
          "url": {
            "type": "string",
            "description": "public-url provided by COR"
          },
          "type": {
            "type": "string",
            "description": "File type"
          },
          "source": {
            "type": "string",
            "description": "Source of file: attachments S#, Drive, One Drive, Dropbox"
          }
        }
      },
      "TaskAttachmentListResponse": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "description": "Total number of attachments"
          },
          "perPage": {
            "type": "integer",
            "description": "Items per page"
          },
          "page": {
            "type": "integer",
            "description": "Current page number"
          },
          "lastPage": {
            "type": "integer",
            "description": "Last page number"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TaskAttachmentDetail"
            }
          }
        }
      },
      "TaskAttachmentDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "url": {
            "type": "string"
          },
          "size": {
            "type": "integer",
            "description": "File size in bytes"
          },
          "source": {
            "type": "string",
            "description": "Storage source (e.g. `S3`, `GoogleDrive`, `DropBox`, `OneDrive`)"
          },
          "user_id": {
            "type": "integer"
          },
          "available": {
            "type": "boolean"
          },
          "file_type": {
            "type": "string",
            "description": "File extension (e.g. `png`, `pdf`)"
          },
          "media_type": {
            "type": "string",
            "description": "Media category (e.g. `image`, `pdf`, `video`)"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "originalname": {
            "type": "string",
            "description": "Original file name"
          },
          "discussions_id": {
            "type": "integer",
            "nullable": true
          },
          "parent_type": {
            "type": "string",
            "description": "Parent entity type (e.g. `tasks`)"
          },
          "name": {
            "type": "string"
          },
          "parent_id": {
            "type": "integer"
          },
          "attachment_parent_id": {
            "type": "integer",
            "nullable": true,
            "description": "Parent attachment ID for versioning"
          },
          "version": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "approved",
              "pending",
              "required",
              null
            ]
          },
          "currentVersionData": {
            "type": "object",
            "nullable": true
          },
          "currentVersionId": {
            "type": "integer"
          },
          "currentVersion": {
            "type": "integer"
          },
          "user": {
            "type": "object",
            "properties": {
              "id": {
                "type": "integer"
              },
              "first_name": {
                "type": "string"
              },
              "last_name": {
                "type": "string"
              },
              "picture": {
                "type": "string"
              }
            }
          },
          "graphicsCount": {
            "type": "string",
            "nullable": true
          },
          "taskLogReworksId": {
            "type": "integer",
            "nullable": true
          },
          "createdFrom": {
            "type": "string",
            "description": "Origin: `task_panel`, `rework`, or `feedback`"
          }
        }
      },
      "TaskAttachmentUploadResponse": {
        "type": "object",
        "properties": {
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TaskAttachmentUploadedFile"
            }
          },
          "files_q": {
            "type": "integer",
            "description": "Total number of attachments currently on the task"
          },
          "errors": {
            "type": "array",
            "description": "Present only when individual files failed (size exceeded or invalid extension)",
            "items": {
              "$ref": "#/components/schemas/AttachmentUploadError"
            }
          }
        }
      },
      "TaskAttachmentUploadedFile": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "url": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "source": {
            "type": "string"
          },
          "size": {
            "type": "integer"
          },
          "filename": {
            "type": "string",
            "description": "Internal storage path"
          },
          "available": {
            "type": "boolean"
          },
          "item_id": {
            "type": "integer"
          },
          "originalname": {
            "type": "string"
          },
          "attachment_parent_id": {
            "type": "integer",
            "nullable": true
          },
          "file_type": {
            "type": "string"
          },
          "discussions_id": {
            "type": "integer",
            "nullable": true
          },
          "user_id": {
            "type": "integer"
          },
          "parent_id": {
            "type": "integer"
          },
          "type": {
            "type": "string",
            "description": "Parent type (e.g. `tasks`)"
          },
          "version": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "token": {
            "type": "string",
            "description": "Unique file token"
          },
          "company_id": {
            "type": "integer"
          },
          "task_log_reworks_id": {
            "type": "integer",
            "nullable": true
          },
          "task_log_id": {
            "type": "integer"
          },
          "media_type": {
            "type": "string"
          },
          "graphics_count": {
            "type": "string",
            "nullable": true
          },
          "created_from": {
            "type": "string"
          }
        }
      },
      "TaskAttachmentSourceResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "url": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "source": {
            "type": "string",
            "description": "Source provider (e.g. `GoogleDrive`)"
          },
          "size": {
            "type": "integer"
          },
          "file_type": {
            "type": "string"
          },
          "media_type": {
            "type": "string"
          },
          "user_id": {
            "type": "integer"
          },
          "discussions_id": {
            "type": "integer",
            "nullable": true
          },
          "session_token": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "TaskAttachmentDeleteResponse": {
        "type": "object",
        "properties": {
          "deleted": {
            "type": "boolean"
          },
          "elements": {
            "type": "array",
            "description": "Attachments from the last page that fill the gaps left by deleted items",
            "items": {
              "$ref": "#/components/schemas/TaskAttachmentDetail"
            }
          }
        }
      },
      "AttachmentUploadError": {
        "type": "object",
        "properties": {
          "filename": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "AttachmentUploadBadRequest": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ERROR"
          },
          "code": {
            "type": "string",
            "example": "FS001"
          },
          "message": {
            "type": "string",
            "example": "Unable to upload any file"
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AttachmentUploadError"
            }
          }
        }
      },
      "CORErrorResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "CORCustomError": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "ValidationErrorArray": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "field": {
              "type": "string"
            },
            "validation": {
              "type": "string"
            },
            "message": {
              "type": "string"
            }
          }
        }
      },
      "ProjectCost": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "cost": {
            "type": "number",
            "format": "float"
          },
          "datetime": {
            "type": "string",
            "format": "date"
          },
          "label_id": {
            "type": "integer"
          },
          "project_estimate_id": {
            "type": "integer"
          },
          "id_project_history": {
            "type": "integer"
          }
        }
      },
      "ProjectCostInput": {
        "type": "object",
        "required": [
          "title",
          "cost",
          "datetime"
        ],
        "properties": {
          "title": {
            "type": "string",
            "description": "Title of cost"
          },
          "cost": {
            "type": "number",
            "format": "float",
            "description": "Cost"
          },
          "datetime": {
            "type": "string",
            "format": "date",
            "description": "Date of the estimate"
          },
          "label_id": {
            "type": "integer",
            "description": "Related Label"
          },
          "project_estimate_id": {
            "type": "integer",
            "description": "Related project estimate"
          },
          "id_project_history": {
            "type": "integer",
            "description": "Related project history"
          }
        }
      },
      "ProjectEstimate": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "cost": {
            "type": "string"
          },
          "datetime": {
            "type": "string",
            "format": "date"
          },
          "currency_id": {
            "type": "integer"
          },
          "fee_id": {
            "type": "integer"
          }
        }
      },
      "ProjectEstimateInput": {
        "type": "object",
        "required": [
          "title",
          "cost",
          "datetime"
        ],
        "properties": {
          "title": {
            "type": "string",
            "description": "Title of estimate"
          },
          "cost": {
            "type": "string",
            "description": "Cost of the estimate"
          },
          "datetime": {
            "type": "string",
            "format": "date",
            "description": "Date of the estimate"
          },
          "currency_id": {
            "type": "integer",
            "description": "Currency of the project-estimate"
          },
          "fee_id": {
            "type": "integer",
            "description": "Related Fee"
          }
        }
      },
      "Brand": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "client_id": {
            "type": "integer"
          }
        }
      },
      "PaginatedBrandsResponse": {
        "type": "object",
        "description": "Paginated response for brands list",
        "properties": {
          "total": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Total number of brands"
          },
          "perPage": {
            "type": "integer",
            "description": "Number of items per page"
          },
          "page": {
            "type": "integer",
            "description": "Current page number"
          },
          "lastPage": {
            "type": "integer",
            "description": "Last available page number"
          },
          "data": {
            "type": "array",
            "description": "Array of brands for the current page",
            "items": {
              "$ref": "#/components/schemas/Brand"
            }
          }
        }
      },
      "BrandInput": {
        "type": "object",
        "required": [
          "name",
          "client_id"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Brand Name"
          },
          "client_id": {
            "type": "integer",
            "description": "Client ID"
          }
        }
      },
      "Product": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "client_id": {
            "type": "integer"
          },
          "brand_id": {
            "type": "integer"
          }
        }
      },
      "PaginatedProductsResponse": {
        "type": "object",
        "description": "Paginated response for products list",
        "properties": {
          "total": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Total number of products"
          },
          "perPage": {
            "type": "integer",
            "description": "Number of items per page"
          },
          "page": {
            "type": "integer",
            "description": "Current page number"
          },
          "lastPage": {
            "type": "integer",
            "description": "Last available page number"
          },
          "data": {
            "type": "array",
            "description": "Array of products for the current page",
            "items": {
              "$ref": "#/components/schemas/Product"
            }
          }
        }
      },
      "ProductInput": {
        "type": "object",
        "required": [
          "name",
          "client_id",
          "brand_id"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Product Name"
          },
          "client_id": {
            "type": "integer",
            "description": "Client ID"
          },
          "brand_id": {
            "type": "integer",
            "description": "Brand ID"
          }
        }
      },
      "ProjectTemplate": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "PaginatedProjectTemplatesResponse": {
        "type": "object",
        "description": "Paginated response for project templates list",
        "properties": {
          "total": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Total number of project templates"
          },
          "perPage": {
            "type": "integer",
            "description": "Number of items per page"
          },
          "page": {
            "type": "integer",
            "description": "Current page number"
          },
          "lastPage": {
            "type": "integer",
            "description": "Last available page number"
          },
          "data": {
            "type": "array",
            "description": "Array of project templates for the current page",
            "items": {
              "$ref": "#/components/schemas/ProjectTemplate"
            }
          }
        }
      },
      "Task": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "project_id": {
            "type": "integer"
          },
          "description": {
            "type": "string"
          },
          "deadline": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "type": "string",
            "enum": [
              "nueva",
              "en_proceso",
              "estancada",
              "finalizada"
            ]
          },
          "priority": {
            "type": "integer",
            "enum": [
              0,
              1,
              2,
              3
            ],
            "description": "0 = Low, 1 = Medium, 2 = High, 3 = Urgent"
          },
          "archived": {
            "type": "boolean"
          }
        }
      },
      "PaginatedTasksResponse": {
        "type": "object",
        "description": "Paginated response for tasks list",
        "properties": {
          "total": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Total number of tasks"
          },
          "perPage": {
            "type": "integer",
            "description": "Number of items per page"
          },
          "page": {
            "type": "integer",
            "description": "Current page number"
          },
          "lastPage": {
            "type": "integer",
            "description": "Last available page number"
          },
          "data": {
            "type": "array",
            "description": "Array of tasks for the current page",
            "items": {
              "$ref": "#/components/schemas/Task"
            }
          }
        }
      },
      "TaskInput": {
        "type": "object",
        "required": [
          "title"
        ],
        "properties": {
          "title": {
            "type": "string",
            "description": "Task Title"
          },
          "project_id": {
            "type": "integer",
            "description": "Project ID"
          }
        }
      },
      "TaskUpdateInput": {
        "type": "object",
        "required": [
          "title"
        ],
        "properties": {
          "title": {
            "type": "string",
            "description": "Task Title"
          },
          "project_id": {
            "type": "integer",
            "description": "Project ID"
          },
          "description": {
            "type": "string",
            "description": "Description"
          },
          "deadline": {
            "type": "string",
            "format": "date-time",
            "description": "Deadline"
          },
          "status": {
            "type": "string",
            "enum": [
              "nueva",
              "en_proceso",
              "estancada",
              "finalizada"
            ],
            "description": "Task status"
          },
          "priority": {
            "type": "integer",
            "enum": [
              0,
              1,
              2,
              3
            ],
            "description": "Task Priority: 0 = Low, 1 = Medium, 2 = High, 3 = Urgent"
          },
          "archived": {
            "type": "boolean",
            "description": "Archived task"
          }
        }
      },
      "Team": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "workspace_id": {
            "type": "integer"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TeamInput": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Team Name"
          },
          "description": {
            "type": "string",
            "description": "Team description"
          },
          "workspace_id": {
            "type": "integer",
            "description": "Workspace ID"
          }
        }
      },
      "TeamUsersInput": {
        "type": "object",
        "required": [
          "users_ids"
        ],
        "properties": {
          "users_ids": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Array of user IDs to add or remove from the team"
          }
        }
      },
      "TeamUserRelation": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Team-User relation ID"
          },
          "team_id": {
            "type": "integer",
            "description": "Team ID"
          },
          "user_id": {
            "type": "integer",
            "description": "User ID"
          },
          "created_at": {
            "type": "string",
            "description": "Creation timestamp in format YYYY-MM-DD HH:MM:SS",
            "example": "2026-01-21 14:09:52"
          },
          "updated_at": {
            "type": "string",
            "description": "Last update timestamp in format YYYY-MM-DD HH:MM:SS",
            "example": "2026-01-21 14:09:52"
          },
          "deleted_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Deletion timestamp (only present when removing users)"
          },
          "__meta__": {
            "type": "object",
            "properties": {
              "company_id": {
                "type": "integer",
                "description": "Company ID"
              },
              "user": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "integer"
                  },
                  "first_name": {
                    "type": "string"
                  },
                  "last_name": {
                    "type": "string"
                  },
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "company_id": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        }
      },
      "PaginatedTeamsResponse": {
        "type": "object",
        "description": "Paginated response for teams list",
        "properties": {
          "total": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Total number of teams"
          },
          "perPage": {
            "type": "integer",
            "description": "Number of items per page"
          },
          "page": {
            "type": "integer",
            "description": "Current page number"
          },
          "lastPage": {
            "type": "integer",
            "description": "Last available page number"
          },
          "data": {
            "type": "array",
            "description": "Array of teams for the current page",
            "items": {
              "$ref": "#/components/schemas/Team"
            }
          }
        }
      },
      "Hour": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Unique identifier of the time entry"
          },
          "start": {
            "type": "string",
            "format": "date-time",
            "description": "Start timestamp of the time entry"
          },
          "stop": {
            "type": "string",
            "format": "date-time",
            "description": "Stop timestamp of the time entry"
          },
          "duration": {
            "type": "string",
            "description": "Duration of the time entry in hours"
          },
          "cost": {
            "type": "number",
            "description": "Calculated cost for this time entry"
          },
          "user_id": {
            "type": "integer",
            "description": "ID of the user who logged the hours"
          },
          "task_log_id": {
            "type": "integer",
            "description": "ID of the task this time entry is logged against"
          },
          "project_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Project ID (null when the task has no associated project)"
          },
          "client_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Client ID (null when the task has no associated client)"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the time entry was created"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "approved",
              "rejected",
              "paid"
            ],
            "description": "Current approval status of the time entry"
          },
          "status_changed_by": {
            "type": [
              "integer",
              "null"
            ],
            "description": "ID of the user who last changed the status (null if status has not been changed)"
          },
          "status_changed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Timestamp when the status was last changed (null if status has not been changed)"
          },
          "type": {
            "type": "string",
            "description": "Type of time entry (e.g. `TASK`)"
          },
          "task_log_rework_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Rework ID if this time entry is associated with a rework, otherwise null"
          },
          "comments": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional comments on the time entry"
          },
          "user": {
            "type": "object",
            "description": "Summary of the user who logged the time entry",
            "properties": {
              "id": {
                "type": "integer"
              },
              "first_name": {
                "type": "string"
              },
              "last_name": {
                "type": "string"
              },
              "picture": {
                "type": "string",
                "description": "URL to the user's profile picture"
              },
              "remaining_hours": {
                "type": "number",
                "description": "Remaining available hours for the user"
              },
              "timezone": {
                "type": "string",
                "description": "User's timezone (e.g. `America/Buenos_Aires`)"
              },
              "gmt": {
                "type": "string",
                "description": "GMT offset (e.g. `-03:00`)"
              }
            }
          },
          "client": {
            "type": [
              "object",
              "null"
            ],
            "description": "Client information (null when the task has no associated client)"
          },
          "project": {
            "type": [
              "object",
              "null"
            ],
            "description": "Project information (null when the task has no associated project)"
          },
          "task": {
            "type": "object",
            "description": "Task this time entry is logged against",
            "properties": {
              "id": {
                "type": "integer",
                "description": "Task ID"
              },
              "title": {
                "type": "string",
                "description": "Task title"
              },
              "project_id": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "ID of the project this task belongs to"
              },
              "task_father": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "ID of the parent task, if any"
              },
              "status": {
                "type": "string",
                "description": "Current status of the task"
              },
              "father": {
                "type": [
                  "object",
                  "null"
                ],
                "description": "Parent task summary (null if no parent task)",
                "properties": {
                  "id": {
                    "type": "integer"
                  },
                  "title": {
                    "type": "string"
                  }
                }
              },
              "project": {
                "type": [
                  "object",
                  "null"
                ],
                "description": "Project this task belongs to (null if no project)",
                "properties": {
                  "id": {
                    "type": "integer"
                  },
                  "name": {
                    "type": "string"
                  },
                  "client_id": {
                    "type": "integer"
                  },
                  "contract_id": {
                    "type": [
                      "integer",
                      "null"
                    ]
                  },
                  "client": {
                    "type": "object",
                    "description": "Client that owns the project",
                    "properties": {
                      "id": {
                        "type": "integer"
                      },
                      "name": {
                        "type": "string"
                      },
                      "client_status_id": {
                        "type": "integer"
                      }
                    }
                  },
                  "has_expired_contract": {
                    "type": "boolean"
                  }
                }
              },
              "labels": {
                "type": "array",
                "description": "Labels assigned to the task",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "integer"
                    },
                    "hex": {
                      "type": "string",
                      "description": "Hex color code for the label"
                    },
                    "names": {
                      "type": "array",
                      "description": "Localized label names",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "lang": {
                            "type": "string",
                            "description": "Language code (e.g. `en`, `es`, `pt`, `fr`)"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "userPosition": {
            "type": [
              "object",
              "null"
            ],
            "description": "User's position information (null if not set)"
          },
          "billInput": {
            "type": [
              "object",
              "null"
            ],
            "description": "Billing information, present when the time entry has been invoiced (status `paid`)",
            "properties": {
              "id": {
                "type": "integer",
                "description": "Bill input ID"
              },
              "entity_id": {
                "type": "integer",
                "description": "ID of the time entry this billing relates to"
              },
              "bill_id": {
                "type": "integer",
                "description": "ID of the associated bill"
              },
              "updated_at": {
                "type": "string",
                "format": "date-time",
                "description": "Last update timestamp"
              },
              "bill": {
                "type": "object",
                "description": "Associated bill details",
                "properties": {
                  "id": {
                    "type": "integer"
                  },
                  "receipt_number": {
                    "type": "string",
                    "description": "Receipt or invoice number"
                  }
                }
              }
            }
          },
          "rework_hour": {
            "type": [
              "object",
              "null"
            ],
            "description": "Rework details, present when `task_log_rework_id` is set",
            "properties": {
              "requested_by": {
                "type": "string",
                "description": "Source of the rework request (e.g. `internal`)"
              },
              "description": {
                "type": "string",
                "description": "Description of the rework"
              },
              "on": {
                "type": "string",
                "format": "date-time",
                "description": "Date the rework was requested"
              }
            }
          }
        }
      },
      "PaginatedHoursResponse": {
        "type": "object",
        "description": "Paginated response for time entries list",
        "properties": {
          "total_hours": {
            "type": "string",
            "description": "Total hours summed across all entries matching the query"
          },
          "total_cost": {
            "type": "number",
            "description": "Total cost summed across all entries matching the query"
          },
          "total": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Total number of time entries"
          },
          "perPage": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Number of items per page"
          },
          "page": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Current page number"
          },
          "lastPage": {
            "type": "integer",
            "description": "Last available page number"
          },
          "data": {
            "type": "array",
            "description": "Array of time entries for the current page",
            "items": {
              "$ref": "#/components/schemas/Hour"
            }
          }
        }
      },
      "HourInput": {
        "type": "object",
        "required": [
          "task_log_id",
          "start"
        ],
        "properties": {
          "task_log_id": {
            "type": "integer",
            "description": "Task ID"
          },
          "start": {
            "type": "string",
            "format": "date-time",
            "description": "Start Timestamp"
          },
          "stop": {
            "type": "string",
            "format": "date-time",
            "description": "Stop Timestamp"
          }
        }
      },
      "UserInput": {
        "type": "object",
        "required": [
          "first_name",
          "last_name",
          "email",
          "password",
          "password_confirm",
          "role_id"
        ],
        "properties": {
          "first_name": {
            "type": "string",
            "description": "First Name"
          },
          "last_name": {
            "type": "string",
            "description": "Last Name"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "User E-Mail"
          },
          "password": {
            "type": "string",
            "format": "password",
            "description": "User Password"
          },
          "password_confirm": {
            "type": "string",
            "format": "password",
            "description": "User Password Confirmation"
          },
          "role_id": {
            "type": "integer",
            "enum": [
              1,
              2,
              3,
              4,
              5
            ],
            "description": "User Role: 1=C-Level, 2=Director, 3=Project Manager, 4=Collaborator, 5=Freelancer"
          }
        }
      },
      "UserCreateInput": {
        "type": "object",
        "required": [
          "first_name",
          "last_name",
          "email",
          "role_id"
        ],
        "properties": {
          "first_name": {
            "type": "string",
            "description": "User given name"
          },
          "last_name": {
            "type": "string",
            "description": "User family name"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "User email"
          },
          "role_id": {
            "type": "integer",
            "enum": [
              1,
              2,
              3,
              4,
              5,
              6
            ],
            "description": "User Role: 1=C-Level, 2=Director, 3=Project Manager, 4=Collaborator, 5=Freelancer, 6=Client"
          },
          "user_position_id": {
            "type": "integer",
            "description": "ID of the user's position"
          },
          "phone": {
            "type": "string",
            "description": "User phone number"
          },
          "description": {
            "type": "string",
            "description": "User description"
          },
          "birthday": {
            "type": "string",
            "format": "date",
            "description": "User birthday (YYYY-MM-DD)"
          },
          "work_in": {
            "type": "string",
            "description": "Department or area"
          },
          "hourly_rate": {
            "type": "number",
            "description": "Hourly rate"
          },
          "monthly_hours": {
            "type": "integer",
            "description": "Monthly hours"
          },
          "daily_hours": {
            "type": "integer",
            "description": "Daily hours"
          },
          "plan_id": {
            "type": "integer",
            "enum": [
              4,
              5
            ],
            "description": "Plan ID: 4=Project Management, 5=Capacity Planning"
          },
          "hidden": {
            "type": "boolean",
            "description": "Whether user is hidden"
          },
          "charge_hours": {
            "type": "boolean",
            "description": "Whether to charge hours"
          },
          "salary": {
            "type": "integer",
            "description": "Monthly salary amount"
          }
        }
      },
      "UserUpdateInput": {
        "type": "object",
        "properties": {
          "first_name": {
            "type": "string",
            "description": "User given name"
          },
          "last_name": {
            "type": "string",
            "description": "User family name"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "User email"
          },
          "role_id": {
            "type": "integer",
            "enum": [
              1,
              2,
              3,
              4,
              5,
              6
            ],
            "description": "User Role: 1=C-Level, 2=Director, 3=Project Manager, 4=Collaborator, 5=Freelancer, 6=Client"
          },
          "user_position_id": {
            "type": "integer",
            "description": "ID of the user's position"
          },
          "phone": {
            "type": "string",
            "description": "User phone number"
          },
          "description": {
            "type": "string",
            "description": "User description"
          },
          "birthday": {
            "type": "string",
            "format": "date",
            "description": "User birthday (YYYY-MM-DD)"
          },
          "work_in": {
            "type": "string",
            "description": "Department or area"
          },
          "hourly_rate": {
            "type": "number",
            "description": "Hourly rate"
          },
          "monthly_hours": {
            "type": "integer",
            "description": "Monthly hours"
          },
          "daily_hours": {
            "type": "integer",
            "description": "Daily hours"
          },
          "plan_id": {
            "type": "integer",
            "enum": [
              4,
              5
            ],
            "description": "Plan ID: 4=Project Management, 5=Capacity Planning"
          },
          "hidden": {
            "type": "boolean",
            "description": "Whether user is hidden"
          },
          "charge_hours": {
            "type": "boolean",
            "description": "Whether to charge hours"
          },
          "salary": {
            "type": "integer",
            "description": "Monthly salary amount"
          },
          "salary_from": {
            "type": "string",
            "description": "Month from which salary should apply (MM-YYYY). Defaults to the current month if salary is provided."
          }
        }
      },
      "UserLabelInput": {
        "type": "object",
        "required": [
          "labelId"
        ],
        "properties": {
          "labelId": {
            "type": "integer",
            "description": "Label ID to assign or unassign"
          },
          "unassign": {
            "type": "boolean",
            "description": "Set to true to remove label from the user. Omit or set to false to assign the label.",
            "default": false
          }
        }
      },
      "Transaction": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "receipt_number": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "total": {
            "type": "number"
          },
          "currency_change_amount": {
            "type": "number"
          },
          "exchange": {
            "type": "number"
          },
          "source_id": {
            "type": "integer"
          },
          "currency_id": {
            "type": "integer"
          },
          "is_income": {
            "type": "boolean"
          },
          "client_id": {
            "type": "integer"
          },
          "company_id": {
            "type": "integer"
          }
        }
      },
      "PaginatedTransactionsResponse": {
        "type": "object",
        "description": "Paginated response for transactions list",
        "properties": {
          "total": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Total number of transactions"
          },
          "perPage": {
            "type": "integer",
            "description": "Number of items per page"
          },
          "page": {
            "type": "integer",
            "description": "Current page number"
          },
          "lastPage": {
            "type": "integer",
            "description": "Last available page number"
          },
          "data": {
            "type": "array",
            "description": "Array of transactions for the current page",
            "items": {
              "$ref": "#/components/schemas/Transaction"
            }
          }
        }
      },
      "TransactionInput": {
        "type": "object",
        "required": [
          "date",
          "type",
          "total",
          "currency_change_amount",
          "exchange",
          "source_id",
          "currency_id"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "description": "Date"
          },
          "receipt_number": {
            "type": "string",
            "description": "Receipt number"
          },
          "type": {
            "type": "string",
            "description": "Type"
          },
          "total": {
            "type": "number",
            "description": "Total"
          },
          "currency_change_amount": {
            "type": "number",
            "description": "Currency change amount"
          },
          "exchange": {
            "type": "number",
            "description": "Exchange"
          },
          "source_id": {
            "type": "integer",
            "description": "Source ID"
          },
          "currency_id": {
            "type": "integer",
            "description": "Currency ID"
          },
          "is_income": {
            "type": "boolean",
            "description": "Is income"
          },
          "client_id": {
            "type": "integer",
            "description": "Client ID"
          },
          "company_id": {
            "type": "integer",
            "description": "Company ID"
          },
          "can_update": {
            "type": "boolean",
            "description": "Can update"
          },
          "can_delete": {
            "type": "boolean",
            "description": "Can delete"
          }
        }
      },
      "TransactionItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "description": {
            "type": "string"
          },
          "client_id": {
            "type": "integer"
          },
          "project_id": {
            "type": "integer"
          },
          "amount": {
            "type": "number"
          },
          "status": {
            "type": "string"
          },
          "transaction_id": {
            "type": "integer"
          },
          "company_id": {
            "type": "integer"
          }
        }
      },
      "TransactionItemInput": {
        "type": "object",
        "required": [
          "description",
          "amount",
          "status",
          "transaction_id",
          "company_id"
        ],
        "properties": {
          "description": {
            "type": "string",
            "description": "Description"
          },
          "client_id": {
            "type": "integer",
            "description": "Client ID"
          },
          "project_id": {
            "type": "integer",
            "description": "Project ID"
          },
          "amount": {
            "type": "number",
            "description": "Amount"
          },
          "status": {
            "type": "string",
            "description": "Status"
          },
          "transaction_id": {
            "type": "integer",
            "description": "Transaction ID"
          },
          "company_id": {
            "type": "integer",
            "description": "Company ID"
          },
          "can_update": {
            "type": "boolean",
            "description": "Can update"
          },
          "can_delete": {
            "type": "boolean",
            "description": "Can delete"
          },
          "integrated": {
            "type": "boolean",
            "description": "Integrated"
          }
        }
      },
      "UserAssignedLabel": {
        "type": "object",
        "description": "Label assigned to a user, as returned in user list endpoints.",
        "properties": {
          "id": {
            "type": "integer"
          },
          "lang": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "Label": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "hex": {
            "type": "string",
            "description": "Hex color code"
          },
          "hsl": {
            "type": "string",
            "nullable": true
          },
          "rgb": {
            "type": "string",
            "nullable": true
          },
          "lang": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "color_id": {
            "type": "integer"
          }
        }
      },
      "Category": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "labels": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Label"
            }
          }
        }
      },
      "ProjectLabelsResponse": {
        "type": "object",
        "required": [
          "labels"
        ],
        "properties": {
          "labels": {
            "type": "array",
            "description": "Categories with their labels, scoped to the project label entity type.",
            "items": {
              "$ref": "#/components/schemas/Category"
            }
          },
          "selected": {
            "type": "array",
            "description": "Labels currently assigned to the project (present when a valid `project_id` is provided).",
            "items": {
              "$ref": "#/components/schemas/Label"
            }
          }
        }
      },
      "Leave": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "user_id": {
            "type": "integer"
          },
          "company_id": {
            "type": "integer"
          },
          "leave_type_id": {
            "type": "integer"
          },
          "start": {
            "type": "string",
            "format": "date-time"
          },
          "end": {
            "type": "string",
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "deleted_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "all_day": {
            "type": "boolean"
          },
          "leaveType": {
            "$ref": "#/components/schemas/LeaveType"
          }
        }
      },
      "LeaveType": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "type_code": {
            "type": "string"
          },
          "company_id": {
            "type": "integer",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "deleted_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "icon_name": {
            "type": "string"
          }
        }
      },
      "LeaveInput": {
        "type": "object",
        "required": [
          "userId",
          "leaveTypeId",
          "start",
          "end"
        ],
        "properties": {
          "userId": {
            "type": "integer",
            "description": "User ID"
          },
          "leaveTypeId": {
            "type": "integer",
            "description": "Leave type ID"
          },
          "start": {
            "type": "string",
            "format": "date-time",
            "description": "Start date in UTC format (e.g., 2024-11-18T03:00:00Z)"
          },
          "end": {
            "type": "string",
            "format": "date-time",
            "description": "End date in UTC format"
          },
          "allDay": {
            "type": "boolean",
            "description": "Whether the leave is for the entire day",
            "default": false
          }
        }
      },
      "LeaveUpdateInput": {
        "type": "object",
        "required": [
          "userId",
          "leaveTypeId",
          "start",
          "end"
        ],
        "properties": {
          "userId": {
            "type": "integer",
            "description": "User ID"
          },
          "leaveTypeId": {
            "type": "integer",
            "description": "Leave type ID"
          },
          "start": {
            "type": "string",
            "format": "date-time",
            "description": "Start date in UTC format"
          },
          "end": {
            "type": "string",
            "format": "date-time",
            "description": "End date in UTC format"
          }
        }
      },
      "LeaveDeleteInput": {
        "type": "object",
        "required": [
          "id",
          "userId"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "description": "Leave ID to delete"
          },
          "userId": {
            "type": "integer",
            "description": "User ID"
          }
        }
      },
      "PaginatedLeaveTypesResponse": {
        "type": "object",
        "description": "Paginated response for leave types list",
        "properties": {
          "total": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Total number of leave types"
          },
          "perPage": {
            "type": "integer",
            "description": "Number of items per page"
          },
          "page": {
            "type": "integer",
            "description": "Current page number"
          },
          "lastPage": {
            "type": "integer",
            "description": "Last available page number"
          },
          "data": {
            "type": "array",
            "description": "Array of leave types for the current page",
            "items": {
              "$ref": "#/components/schemas/LeaveType"
            }
          }
        }
      },
      "LeaveTypeInput": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the leave type"
          }
        }
      },
      "LeaveTypeDeleteInput": {
        "type": "object",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "description": "Leave type ID to delete"
          }
        }
      },
      "WorkingTime": {
        "type": "object",
        "properties": {
          "daily_hours": {
            "type": "number"
          },
          "day_of_week": {
            "type": "integer",
            "description": "Day of the week (1=Sunday, 7=Saturday)"
          },
          "start_at": {
            "type": "string",
            "description": "Start time (HH:MM:SS)"
          },
          "end_at": {
            "type": "string",
            "description": "End time (HH:MM:SS)"
          },
          "user_id": {
            "type": "integer"
          },
          "break_time": {
            "type": "number",
            "description": "Break duration in hours"
          }
        }
      },
      "WorkingTimeInput": {
        "type": "object",
        "required": [
          "userId",
          "companyId",
          "workingTimes"
        ],
        "properties": {
          "userId": {
            "type": "integer",
            "description": "User ID"
          },
          "companyId": {
            "type": "integer",
            "description": "Company ID"
          },
          "workingTimes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "dayOfWeek": {
                  "type": "string",
                  "description": "Day of the week (1=Sunday, 7=Saturday)"
                },
                "start": {
                  "type": "string",
                  "description": "Start time in HH:MM format (24-hour clock)"
                },
                "end": {
                  "type": "string",
                  "description": "End time in HH:MM format (24-hour clock)"
                },
                "breakTime": {
                  "type": "string",
                  "description": "Break duration in hours (0, 0.25, 0.5, 0.75, 1, 1.5, 2)"
                }
              }
            }
          }
        }
      },
      "UserPositionInput": {
        "type": "object",
        "required": [
          "name",
          "type"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Position name. Must be unique within the company and pass validation rules."
          },
          "type": {
            "type": "string",
            "enum": [
              "C",
              "P"
            ],
            "description": "Type of position: 'C' for category, 'P' for position"
          },
          "rate": {
            "type": "number",
            "description": "Base rate for the position"
          },
          "seniority": {
            "type": "string",
            "nullable": true,
            "description": "Seniority level of the position"
          },
          "user_position_category_id": {
            "type": "integer",
            "nullable": true,
            "description": "ID of the parent category (only for positions, not categories). This field is required if you need to see positions in capacity planning and positions list"
          },
          "segmentLabel": {
            "type": "string",
            "nullable": true,
            "description": "Segment label used to group positions. Required only if company has feature flag to manage positions by labels enabled. Ignored if feature flag is not enabled."
          }
        }
      },
      "UserPositionUpdateInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Position name. Must be unique within the company and pass validation rules if provided."
          },
          "rate": {
            "type": "number",
            "description": "Base rate for the position"
          },
          "seniority": {
            "type": "string",
            "nullable": true,
            "description": "Seniority level of the position"
          },
          "segmentLabel": {
            "type": "string",
            "nullable": true,
            "description": "Segment label used to group positions. Required only if company has feature flag to manage positions by labels enabled. Ignored if feature flag is not enabled."
          }
        }
      },
      "UserPosition": {
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "user_position_category_id": {
            "type": "number"
          },
          "type": {
            "type": "string",
            "enum": [
              "C",
              "P"
            ],
            "description": "Type of position: 'C' for category, 'P' for position"
          },
          "rate": {
            "type": "integer"
          },
          "seniority": {
            "type": "string"
          },
          "company_id": {
            "type": "integer"
          }
        }
      },
      "UserPositionActiveFlatItem": {
        "type": "object",
        "description": "Active position row in flat list responses",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Position ID"
          },
          "name": {
            "type": "string",
            "description": "Position name (localized when `lang` is used)"
          },
          "category_id": {
            "type": "integer",
            "description": "Parent category ID"
          },
          "category_name": {
            "type": "string",
            "description": "Category name (localized when `lang` is used)"
          }
        }
      },
      "UserPositionActiveInCategory": {
        "type": "object",
        "description": "Position object inside a category group",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "UserPositionsGroupedByCategoryItem": {
        "type": "object",
        "description": "Category bucket when `groupedByCategory` is truthy",
        "properties": {
          "categoryName": {
            "type": "string"
          },
          "categoryId": {
            "type": "integer"
          },
          "positions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UserPositionActiveInCategory"
            }
          }
        }
      },
      "SegmentLabel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Label ID"
          },
          "name": {
            "type": "string",
            "description": "Label name"
          }
        }
      },
      "Ratecard": {
        "type": "object",
        "description": "A ratecard defines pricing configurations for the company",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Unique identifier for the ratecard"
          },
          "name": {
            "type": "string",
            "description": "Display name of the ratecard"
          },
          "original_name": {
            "type": "string",
            "description": "Original/system name of the ratecard"
          },
          "percent": {
            "type": "number",
            "description": "Percentage applied by this ratecard"
          },
          "company_id": {
            "type": "integer",
            "description": "Company ID that owns this ratecard"
          },
          "system": {
            "type": "boolean",
            "description": "Whether this is a system-generated ratecard"
          },
          "currency_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Associated currency ID. Defaults to the system's base currency if not specified."
          },
          "linked_to_base_price": {
            "type": "boolean",
            "description": "Whether the ratecard is calculated based on base price"
          },
          "external_key": {
            "type": [
              "string",
              "null"
            ],
            "description": "External key for integration with external systems"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp"
          },
          "deleted_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Deletion timestamp (soft delete)"
          }
        }
      },
      "RatecardInput": {
        "type": "object",
        "required": [
          "name"
        ],
        "description": "Input schema for creating a new ratecard",
        "properties": {
          "name": {
            "type": "string",
            "description": "Display name of the ratecard"
          },
          "original_name": {
            "type": "string",
            "description": "Original/system name of the ratecard (usually same as name)"
          },
          "percent": {
            "type": "number",
            "description": "Percentage applied by this ratecard (e.g., 0, 10, 15)"
          },
          "currency_id": {
            "type": "integer",
            "description": "Associated currency ID. Defaults to the system's base currency if not specified."
          },
          "linked_to_base_price": {
            "type": "boolean",
            "description": "Whether the ratecard should be calculated based on base price"
          },
          "external_key": {
            "type": "string",
            "description": "External key for integration with external systems"
          }
        }
      },
      "RatecardUpdate": {
        "type": "object",
        "description": "Input schema for updating an existing ratecard",
        "properties": {
          "name": {
            "type": "string",
            "description": "Display name of the ratecard"
          },
          "original_name": {
            "type": "string",
            "description": "Original/system name of the ratecard"
          },
          "percent": {
            "type": "number",
            "description": "Percentage applied by this ratecard"
          },
          "currency_id": {
            "type": "integer",
            "description": "Associated currency ID. Defaults to the system's base currency."
          },
          "linked_to_base_price": {
            "type": "boolean",
            "description": "Whether the ratecard should be calculated based on base price"
          },
          "external_key": {
            "type": "string",
            "description": "External key for integration with external systems"
          }
        }
      },
      "PaginatedRatecardsResponse": {
        "type": "object",
        "description": "Paginated response for ratecards list",
        "properties": {
          "total": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Total number of ratecards"
          },
          "perPage": {
            "type": "integer",
            "description": "Number of items per page"
          },
          "page": {
            "type": "integer",
            "description": "Current page number"
          },
          "lastPage": {
            "type": "integer",
            "description": "Last available page number"
          },
          "data": {
            "type": "array",
            "description": "Array of ratecards for the current page",
            "items": {
              "$ref": "#/components/schemas/Ratecard"
            }
          }
        }
      },
      "Contract": {
        "type": "object",
        "description": "Contract entity",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Contract ID"
          },
          "client_id": {
            "type": "integer",
            "description": "Client ID"
          },
          "json_integrations": {
            "type": [
              "object",
              "array",
              "string",
              "number",
              "boolean",
              "null"
            ],
            "description": "Integration payload stored as JSON"
          },
          "name": {
            "type": "string",
            "description": "Contract name"
          },
          "type": {
            "type": "string",
            "description": "Contract type"
          },
          "source": {
            "type": "string",
            "description": "Source of the contract"
          },
          "status": {
            "type": "string",
            "description": "Contract status"
          },
          "company_id": {
            "type": "integer",
            "description": "Company ID"
          },
          "start": {
            "type": "string",
            "format": "date-time",
            "description": "Contract start date-time"
          },
          "end": {
            "type": "string",
            "format": "date-time",
            "description": "Contract end date-time"
          },
          "frequency": {
            "type": "string",
            "description": "Contract billing frequency"
          },
          "currency_id": {
            "type": "integer",
            "description": "Currency ID"
          },
          "currency": {
            "type": "object",
            "properties": {
              "id": {
                "type": "integer",
                "description": "Currency ID"
              },
              "name": {
                "type": "string",
                "description": "Currency name"
              }
            }
          },
          "url": {
            "type": "string",
            "description": "External URL"
          },
          "url_name": {
            "type": "string",
            "description": "External URL name"
          },
          "user_positions_header_id": {
            "type": "integer",
            "description": "User positions header ID"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp"
          },
          "deleted_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Deletion timestamp (soft delete)"
          }
        }
      },
      "PaginatedContractsResponse": {
        "type": "object",
        "description": "Paginated response for contracts list",
        "properties": {
          "total": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Total number of contracts"
          },
          "perPage": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Number of items per page"
          },
          "page": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Current page number"
          },
          "data": {
            "type": "array",
            "description": "Array of contracts for the current page",
            "items": {
              "$ref": "#/components/schemas/Contract"
            }
          }
        }
      },
      "ContractCreateInput": {
        "type": "object",
        "required": [
          "client_id",
          "name",
          "type",
          "source",
          "status",
          "company_id",
          "start",
          "end",
          "frequency",
          "currency_id"
        ],
        "properties": {
          "client_id": {
            "type": "integer",
            "description": "Client ID"
          },
          "json_integrations": {
            "type": [
              "object",
              "array",
              "string",
              "number",
              "boolean",
              "null"
            ],
            "description": "Integration payload stored as JSON"
          },
          "name": {
            "type": "string",
            "description": "Contract name"
          },
          "type": {
            "type": "string",
            "description": "Contract type"
          },
          "source": {
            "type": "string",
            "description": "Source of the contract"
          },
          "status": {
            "type": "string",
            "description": "Contract status"
          },
          "company_id": {
            "type": "integer",
            "description": "Company ID"
          },
          "start": {
            "type": "string",
            "format": "date-time",
            "description": "Contract start date-time"
          },
          "end": {
            "type": "string",
            "format": "date-time",
            "description": "Contract end date-time"
          },
          "frequency": {
            "type": "string",
            "description": "Contract billing frequency"
          },
          "currency_id": {
            "type": "integer",
            "description": "Currency ID"
          },
          "url": {
            "type": "string",
            "description": "External URL"
          },
          "url_name": {
            "type": "string",
            "description": "External URL name"
          },
          "user_positions_header_id": {
            "type": "integer",
            "description": "User positions header ID"
          }
        }
      },
      "ContractUpdateInput": {
        "type": "object",
        "properties": {
          "client_id": {
            "type": "integer",
            "description": "Client ID"
          },
          "json_integrations": {
            "type": [
              "object",
              "array",
              "string",
              "number",
              "boolean",
              "null"
            ],
            "description": "Integration payload stored as JSON"
          },
          "name": {
            "type": "string",
            "description": "Contract name"
          },
          "type": {
            "type": "string",
            "description": "Contract type"
          },
          "source": {
            "type": "string",
            "description": "Source of the contract"
          },
          "status": {
            "type": "string",
            "description": "Contract status"
          },
          "company_id": {
            "type": "integer",
            "description": "Company ID"
          },
          "start": {
            "type": "string",
            "format": "date-time",
            "description": "Contract start date-time"
          },
          "end": {
            "type": "string",
            "format": "date-time",
            "description": "Contract end date-time"
          },
          "frequency": {
            "type": "string",
            "description": "Contract billing frequency"
          },
          "currency_id": {
            "type": "integer",
            "description": "Currency ID"
          },
          "url": {
            "type": "string",
            "description": "External URL"
          },
          "url_name": {
            "type": "string",
            "description": "External URL name"
          },
          "user_positions_header_id": {
            "type": "integer",
            "description": "User positions header ID"
          }
        }
      },
      "ContractAttachUsersDateInput": {
        "type": "object",
        "required": [
          "start",
          "end"
        ],
        "properties": {
          "start": {
            "type": "string",
            "format": "date",
            "description": "Assignment start date"
          },
          "end": {
            "type": "string",
            "format": "date",
            "description": "Assignment end date"
          }
        }
      },
      "ContractAttachUsersUserInput": {
        "type": "object",
        "required": [
          "id",
          "dates"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "description": "User ID"
          },
          "dates": {
            "type": "array",
            "description": "Date ranges to assign for the user",
            "items": {
              "$ref": "#/components/schemas/ContractAttachUsersDateInput"
            }
          }
        }
      },
      "ContractAttachUsersInput": {
        "type": "object",
        "required": [
          "users"
        ],
        "properties": {
          "users": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContractAttachUsersUserInput"
            }
          }
        }
      },
      "ContractUserAssignment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Assignment ID"
          },
          "user_id": {
            "type": "integer",
            "description": "User ID"
          },
          "contract_id": {
            "type": "integer",
            "description": "Contract ID"
          },
          "company_id": {
            "type": "integer",
            "description": "Company ID"
          },
          "start_date": {
            "type": "string",
            "format": "date-time",
            "description": "Assignment start date-time"
          },
          "end_date": {
            "type": "string",
            "format": "date-time",
            "description": "Assignment end date-time"
          }
        }
      },
      "ContractAttachUsersErrorDate": {
        "type": "object",
        "properties": {
          "start": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "end": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "ContractAttachUsersError": {
        "type": "object",
        "properties": {
          "id": {
            "type": [
              "integer",
              "string"
            ],
            "description": "User ID that contains rejected dates"
          },
          "dates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContractAttachUsersErrorDate"
            }
          },
          "start": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "description": "Legacy start date field used in malformed payloads"
          },
          "end": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "description": "Legacy end date field used in malformed payloads"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "ContractAttachUsersResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "success",
              "partial_success",
              "failure"
            ],
            "description": "Result status for attach operation"
          },
          "company_id": {
            "type": "integer",
            "description": "Company ID"
          },
          "contract_id": {
            "type": "integer",
            "description": "Contract ID"
          },
          "records_received": {
            "type": "integer",
            "description": "Total number of date records received"
          },
          "records_created": {
            "type": "integer",
            "description": "Total number of date records successfully created"
          },
          "records_rejected": {
            "type": "integer",
            "description": "Total number of date records rejected"
          },
          "user_ids": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Array of user IDs that were successfully assigned to the contract"
          },
          "assigned": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContractUserAssignment"
            },
            "description": "Array of user assignments for the contract"
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContractAttachUsersError"
            },
            "description": "Array of user assignments that failed to be assigned to the contract"
          }
        }
      },
      "ContractListBodyInput": {
        "type": "object",
        "properties": {
          "with_milestones": {
            "type": "boolean",
            "description": "Include milestones in each contract response."
          },
          "with_ratecards": {
            "type": "boolean",
            "description": "Include ratecards in each contract response."
          },
          "with_positions": {
            "type": "boolean",
            "description": "Include contract positions in each contract response."
          },
          "status": {
            "type": "string",
            "description": "Filter contracts by status.",
            "example": "expired"
          },
          "type": {
            "type": "string",
            "description": "Filter contracts by type.",
            "example": "time_and_materials"
          }
        },
        "example": {
          "with_milestones": true,
          "with_ratecards": true,
          "with_positions": true,
          "status": "expired",
          "type": "time_and_materials"
        }
      },
      "PaginatedContractPositionRatesResponse": {
        "type": "object",
        "description": "Paginated response for contract positions list",
        "properties": {
          "total": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Total number of contract position rates"
          },
          "perPage": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Number of items per page"
          },
          "page": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Current page number"
          },
          "lastPage": {
            "type": "integer",
            "description": "Last available page number"
          },
          "data": {
            "type": "array",
            "description": "Array of contract positions for the current page",
            "items": {
              "$ref": "#/components/schemas/ContractPositionRate"
            }
          }
        },
        "example": {
          "total": "1",
          "perPage": 20,
          "page": 1,
          "lastPage": 1,
          "data": [
            {
              "id": 1,
              "user_positions_header_id": 1,
              "contract_id": 1,
              "position_id": 1,
              "team_id": 1,
              "rate": 1.00,
              "hours": 10,
              "currency_id": 1,
              "currency": {
                "id": 1,
                "name": "USD"
              },
              "team": {
                "id": 1,
                "name": "Team 1",
                "workspace_id": null
              },
              "position": {
                "id": 1,
                "name": "User Position 1"
              }
            }
          ]
        }
      },
      "ContractPositionRate": {
        "type": "object",
        "description": "Contract position rate configuration",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Contract position rate ID"
          },
          "user_positions_header_id": {
            "type": "integer",
            "description": "User positions header ID"
          },
          "contract_id": {
            "type": "integer",
            "description": "Contract ID"
          },
          "position_id": {
            "type": "integer",
            "description": "Position ID"
          },
          "team_id": {
            "type": "integer",
            "description": "Team ID"
          },
          "currency_id": {
            "type": "integer",
            "description": "Currency ID"
          },
          "rate": {
            "type": "number",
            "description": "Configured hourly rate"
          },
          "hours": {
            "type": "number",
            "description": "Configured contract hours"
          },
          "team": {
            "type": "object",
            "properties": {
              "id": {
                "type": "integer",
                "description": "Team ID"
              },
              "name": {
                "type": "string",
                "description": "Team name"
              }
            }
          },
          "currency": {
            "type": "object",
            "properties": {
              "id": {
                "type": "integer",
                "description": "Currency ID"
              },
              "name": {
                "type": "string",
                "description": "Currency name"
              }
            }
          },
          "position": {
            "type": "object",
            "properties": {
              "id": {
                "type": "integer",
                "description": "Position Id"
              },
              "name": {
                "type": "string",
                "description": "Position name"
              },
              "seniority": {
                "type": "string",
                "description": "Seniority name"
              }
            }
          }
        }
      },
      "ContractPositionCreateInput": {
        "type": "object",
        "required": [
          "position_id",
          "team_id",
          "rate",
          "hours"
        ],
        "properties": {
          "position_id": {
            "type": "integer",
            "description": "Position ID"
          },
          "team_id": {
            "type": "integer",
            "description": "Team ID"
          },
          "rate": {
            "type": "number",
            "description": "Hourly rate to assign"
          },
          "hours": {
            "type": "number",
            "description": "Hours to assign"
          }
        }
      },
      "ContractPositionUpdateInput": {
        "type": "object",
        "properties": {
          "rate": {
            "type": "number",
            "description": "Updated hourly rate"
          },
          "hours": {
            "type": "number",
            "description": "Updated hours"
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "properties": {
          "error": {
            "type": "integer",
            "format": "int32"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "TaskCollaboratorsInput": {
        "type": "object",
        "required": [
          "collaborators"
        ],
        "properties": {
          "collaborators": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Array of user IDs that should be assigned to the task. Pass an empty array [] to remove all collaborators."
          },
          "reasignEstimate": {
            "type": "boolean",
            "default": false,
            "description": "If true, redistributes the estimated hours evenly among the new collaborators."
          }
        }
      },
      "TaskCollaboratorSummary": {
        "type": "object",
        "description": "Summary of a collaborator assigned to a task (used in GET /tasks/{task_id}/collaborators)",
        "properties": {
          "id": {
            "type": "integer"
          },
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "picture": {
            "type": "string"
          },
          "remaining_hours": {
            "type": "number"
          },
          "estimated_by_user": {
            "type": "integer"
          }
        }
      },
      "TaskCollaborator": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "picture": {
            "type": "string"
          },
          "user_position_id": {
            "type": "integer",
            "nullable": true
          },
          "role_id": {
            "type": "integer"
          },
          "userPosition": {
            "type": "object",
            "nullable": true,
            "properties": {
              "id": {
                "type": "integer"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "pivot": {
            "type": "object",
            "properties": {
              "user_id": {
                "type": "integer"
              },
              "task_log_id": {
                "type": "integer"
              },
              "created_at": {
                "type": "string"
              },
              "estimated_by_user": {
                "type": "integer"
              }
            }
          }
        }
      }
    }
  }
}