"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

from .basesdk import BaseSDK
from datetime import datetime
from jsonpath import JSONPath
from kombo import errors, models, utils
from kombo._hooks import HookContext
from kombo.types import BaseModel, Nullable, OptionalNullable, UNSET
from kombo.utils.unmarshal_json_response import unmarshal_json_response
from typing import Any, Awaitable, Dict, List, Mapping, Optional, Union, cast


class Hris(BaseSDK):
    def get_employees(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        employment_statuses: Optional[List[str]] = None,
        group_ids: Optional[List[str]] = None,
        legal_entity_ids: Optional[List[str]] = None,
        work_location_ids: Optional[List[str]] = None,
        work_emails: Optional[List[str]] = None,
        personal_emails: Optional[List[str]] = None,
        custom_fields: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisEmployeesResponse]:
        r"""Get employees

        Retrieve all employees.

        <Note>Not interested in most fields? You can use our [our Scopes feature](/scopes) to customize what data points are synced.</Note>

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param employment_statuses: Filter by a comma-separated list of `ACTIVE`, `PENDING`, `INACTIVE`, `LEAVE`
            * `ACTIVE`: the employee is **actively employed**
            * `PENDING`: the employee is **not actively employed yet** (but they signed their contract or are part of an onboarding process)
            * `INACTIVE`: a full-time employee is no longer employed, or, for a contract worker when their contract runs out
            * `LEAVE`: the employee is still employed but **currently on leave** (note that not all HR systems support this status — use our absences API for detailed information)


            Leave this blank to get results matching all values.
        :param group_ids: Filter by a comma-separated list of group IDs. We will only return employees that are members of _any_ of the groups.
        :param legal_entity_ids: Filter by a comma-separated list of legal entity IDs. We will only return employees that are members of _any_ of the legal entities.
        :param work_location_ids: Filter by a comma-separated list of work location IDs. We will only return employees who are at _any_ of the work locations.
        :param work_emails: Filter by a comma-separated list of work emails. We will only return employees who have _any_ of the work emails. The format of the emails is case-insensitive.
        :param personal_emails: Filter by a comma-separated list of personal emails. We will only return employees who have _any_ of the personal emails. The format of the emails is case-insensitive.
        :param custom_fields: A JSON string with a single key-value pair like {\"fieldKey\":\"fieldValue\"} to filter employees by a specific custom field value. Note that the value must be a string, number, boolean or null and the key must be a valid custom field key. Custom fields with a value of type array or object are not supported.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisEmployeesRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
            employment_statuses=employment_statuses,
            group_ids=group_ids,
            legal_entity_ids=legal_entity_ids,
            work_location_ids=work_location_ids,
            work_emails=work_emails,
            personal_emails=personal_emails,
            custom_fields=custom_fields,
        )

        req = self._build_request(
            method="GET",
            path="/hris/employees",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisEmployeesGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisEmployees",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.GetHrisEmployeesResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return None

            return self.get_employees(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                employment_statuses=employment_statuses,
                group_ids=group_ids,
                legal_entity_ids=legal_entity_ids,
                work_location_ids=work_location_ids,
                work_emails=work_emails,
                personal_emails=personal_emails,
                custom_fields=custom_fields,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisEmployeesResponse(
                result=unmarshal_json_response(
                    models.GetHrisEmployeesPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def get_employees_async(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        employment_statuses: Optional[List[str]] = None,
        group_ids: Optional[List[str]] = None,
        legal_entity_ids: Optional[List[str]] = None,
        work_location_ids: Optional[List[str]] = None,
        work_emails: Optional[List[str]] = None,
        personal_emails: Optional[List[str]] = None,
        custom_fields: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisEmployeesResponse]:
        r"""Get employees

        Retrieve all employees.

        <Note>Not interested in most fields? You can use our [our Scopes feature](/scopes) to customize what data points are synced.</Note>

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param employment_statuses: Filter by a comma-separated list of `ACTIVE`, `PENDING`, `INACTIVE`, `LEAVE`
            * `ACTIVE`: the employee is **actively employed**
            * `PENDING`: the employee is **not actively employed yet** (but they signed their contract or are part of an onboarding process)
            * `INACTIVE`: a full-time employee is no longer employed, or, for a contract worker when their contract runs out
            * `LEAVE`: the employee is still employed but **currently on leave** (note that not all HR systems support this status — use our absences API for detailed information)


            Leave this blank to get results matching all values.
        :param group_ids: Filter by a comma-separated list of group IDs. We will only return employees that are members of _any_ of the groups.
        :param legal_entity_ids: Filter by a comma-separated list of legal entity IDs. We will only return employees that are members of _any_ of the legal entities.
        :param work_location_ids: Filter by a comma-separated list of work location IDs. We will only return employees who are at _any_ of the work locations.
        :param work_emails: Filter by a comma-separated list of work emails. We will only return employees who have _any_ of the work emails. The format of the emails is case-insensitive.
        :param personal_emails: Filter by a comma-separated list of personal emails. We will only return employees who have _any_ of the personal emails. The format of the emails is case-insensitive.
        :param custom_fields: A JSON string with a single key-value pair like {\"fieldKey\":\"fieldValue\"} to filter employees by a specific custom field value. Note that the value must be a string, number, boolean or null and the key must be a valid custom field key. Custom fields with a value of type array or object are not supported.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisEmployeesRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
            employment_statuses=employment_statuses,
            group_ids=group_ids,
            legal_entity_ids=legal_entity_ids,
            work_location_ids=work_location_ids,
            work_emails=work_emails,
            personal_emails=personal_emails,
            custom_fields=custom_fields,
        )

        req = self._build_request_async(
            method="GET",
            path="/hris/employees",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisEmployeesGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisEmployees",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Awaitable[Optional[models.GetHrisEmployeesResponse]]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            async def empty_result():
                return None

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return empty_result()

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return empty_result()

            return self.get_employees_async(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                employment_statuses=employment_statuses,
                group_ids=group_ids,
                legal_entity_ids=legal_entity_ids,
                work_location_ids=work_location_ids,
                work_emails=work_emails,
                personal_emails=personal_emails,
                custom_fields=custom_fields,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisEmployeesResponse(
                result=unmarshal_json_response(
                    models.GetHrisEmployeesPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def get_employee_form(
        self,
        *,
        request: Union[
            models.GetHrisEmployeesFormRequest,
            models.GetHrisEmployeesFormRequestTypedDict,
        ] = models.GetHrisEmployeesFormRequest(),
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.GetHrisEmployeesFormPositiveResponse:
        r"""Get employee form

        Get the form for creating an employee. This form can be rendered dynamically on your frontend to allow your customers to create employees in their HRIS.

        Follow our [create employee guide here](/hris/features/create-employee) to learn how this form is generated and how you can use it.

        ### Example Form
        ```json
        {
        \"properties\": {
        \"firstName\": {
        \"type\": \"text\",
        \"label\": \"First Name\",
        \"required\": true,
        \"description\": \"Employee's first name\",
        \"unified_key\": \"first_name\",
        \"min_length\": 1,
        \"max_length\": 100
        },
        \"startDate\": {
        \"type\": \"date\",
        \"label\": \"Start Date\",
        \"required\": true,
        \"description\": \"Employee's start date\",
        \"unified_key\": \"start_date\"
        },
        \"workLocation\": {
        \"type\": \"object\",
        \"label\": \"Work Location\",
        \"required\": false,
        \"description\": \"Employee's work location\",
        \"unified_key\": null,
        \"properties\": {
        \"site\": {
        \"type\": \"single_select\",
        \"label\": \"Site\",
        \"required\": true,
        \"description\": \"Employee's site\",
        \"unified_key\": null,
        \"options\": {
        \"type\": \"inline\",
        \"entries\": [
        {
        \"label\": \"Site 1\",
        \"id\": \"FXrER44xubBqA9DLgZ3PFNNx\",
        \"unified_value\": \"1\",
        \"remote_id\": \"site_1\"
        },
        {
        \"label\": \"Site 2\",
        \"id\": \"2rv75UKT2XBoQXsUb9agiTUm\",
        \"unified_value\": \"2\",
        \"remote_id\": \"site_2\"
        }
        ]
        }
        },
        \"keyNumbers\": {
        \"type\": \"array\",
        \"label\": \"Key Numbers\",
        \"required\": false,
        \"description\": \"Employee's key numbers\",
        \"unified_key\": null,
        \"min_items\": 2,
        \"max_items\": 5,
        \"item_type\": {
        \"type\": \"number\",
        \"label\": \"Key Number\",
        \"required\": false,
        \"description\": \"The number of the keys which belong to the employee\",
        \"unified_key\": null,
        \"min\": 0,
        \"max\": 99
        }
        }
        }
        }
        }
        }
        ```

        :param request: The request object to send.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        if not isinstance(request, BaseModel):
            request = utils.unmarshal(request, models.GetHrisEmployeesFormRequest)
        request = cast(models.GetHrisEmployeesFormRequest, request)

        req = self._build_request(
            method="GET",
            path="/hris/employees/form",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisEmployeesFormGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisEmployeesForm",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.GetHrisEmployeesFormPositiveResponse, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def get_employee_form_async(
        self,
        *,
        request: Union[
            models.GetHrisEmployeesFormRequest,
            models.GetHrisEmployeesFormRequestTypedDict,
        ] = models.GetHrisEmployeesFormRequest(),
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.GetHrisEmployeesFormPositiveResponse:
        r"""Get employee form

        Get the form for creating an employee. This form can be rendered dynamically on your frontend to allow your customers to create employees in their HRIS.

        Follow our [create employee guide here](/hris/features/create-employee) to learn how this form is generated and how you can use it.

        ### Example Form
        ```json
        {
        \"properties\": {
        \"firstName\": {
        \"type\": \"text\",
        \"label\": \"First Name\",
        \"required\": true,
        \"description\": \"Employee's first name\",
        \"unified_key\": \"first_name\",
        \"min_length\": 1,
        \"max_length\": 100
        },
        \"startDate\": {
        \"type\": \"date\",
        \"label\": \"Start Date\",
        \"required\": true,
        \"description\": \"Employee's start date\",
        \"unified_key\": \"start_date\"
        },
        \"workLocation\": {
        \"type\": \"object\",
        \"label\": \"Work Location\",
        \"required\": false,
        \"description\": \"Employee's work location\",
        \"unified_key\": null,
        \"properties\": {
        \"site\": {
        \"type\": \"single_select\",
        \"label\": \"Site\",
        \"required\": true,
        \"description\": \"Employee's site\",
        \"unified_key\": null,
        \"options\": {
        \"type\": \"inline\",
        \"entries\": [
        {
        \"label\": \"Site 1\",
        \"id\": \"FXrER44xubBqA9DLgZ3PFNNx\",
        \"unified_value\": \"1\",
        \"remote_id\": \"site_1\"
        },
        {
        \"label\": \"Site 2\",
        \"id\": \"2rv75UKT2XBoQXsUb9agiTUm\",
        \"unified_value\": \"2\",
        \"remote_id\": \"site_2\"
        }
        ]
        }
        },
        \"keyNumbers\": {
        \"type\": \"array\",
        \"label\": \"Key Numbers\",
        \"required\": false,
        \"description\": \"Employee's key numbers\",
        \"unified_key\": null,
        \"min_items\": 2,
        \"max_items\": 5,
        \"item_type\": {
        \"type\": \"number\",
        \"label\": \"Key Number\",
        \"required\": false,
        \"description\": \"The number of the keys which belong to the employee\",
        \"unified_key\": null,
        \"min\": 0,
        \"max\": 99
        }
        }
        }
        }
        }
        }
        ```

        :param request: The request object to send.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        if not isinstance(request, BaseModel):
            request = utils.unmarshal(request, models.GetHrisEmployeesFormRequest)
        request = cast(models.GetHrisEmployeesFormRequest, request)

        req = self._build_request_async(
            method="GET",
            path="/hris/employees/form",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisEmployeesFormGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisEmployeesForm",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.GetHrisEmployeesFormPositiveResponse, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def create_employee_with_form(
        self,
        *,
        properties: Union[
            Dict[str, models.Schema4], Dict[str, models.Schema4TypedDict]
        ],
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.PostHrisEmployeesFormPositiveResponse:
        r"""Create employee with form

        Create an employee, based on the form schema.

        <Note>
        This endpoint requires the permission **Create and manage employees** to be enabled in [your scope config](/scopes).
        </Note>

        ### Example Request Body

        ```json
        {
        \"properties\": {
        \"firstName\": \"John\",
        \"startDate\": \"2025-01-01\",
        \"workLocation\": {
        \"site\": \"8e422bf8cav\",
        \"keyNumbers\": [
        142,
        525,
        63
        ]
        }
        }
        }
        ```

        :param properties:
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.PostHrisEmployeesFormRequestBody(
            properties=properties,
        )

        req = self._build_request(
            method="POST",
            path="/hris/employees/form",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.PostHrisEmployeesFormGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request, False, False, "json", models.PostHrisEmployeesFormRequestBody
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="PostHrisEmployeesForm",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.PostHrisEmployeesFormPositiveResponse, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def create_employee_with_form_async(
        self,
        *,
        properties: Union[
            Dict[str, models.Schema4], Dict[str, models.Schema4TypedDict]
        ],
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.PostHrisEmployeesFormPositiveResponse:
        r"""Create employee with form

        Create an employee, based on the form schema.

        <Note>
        This endpoint requires the permission **Create and manage employees** to be enabled in [your scope config](/scopes).
        </Note>

        ### Example Request Body

        ```json
        {
        \"properties\": {
        \"firstName\": \"John\",
        \"startDate\": \"2025-01-01\",
        \"workLocation\": {
        \"site\": \"8e422bf8cav\",
        \"keyNumbers\": [
        142,
        525,
        63
        ]
        }
        }
        }
        ```

        :param properties:
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.PostHrisEmployeesFormRequestBody(
            properties=properties,
        )

        req = self._build_request_async(
            method="POST",
            path="/hris/employees/form",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.PostHrisEmployeesFormGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request, False, False, "json", models.PostHrisEmployeesFormRequestBody
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="PostHrisEmployeesForm",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.PostHrisEmployeesFormPositiveResponse, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def add_employee_document(
        self,
        *,
        employee_id: str,
        category_id: str,
        document: Union[models.Document, models.DocumentTypedDict],
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.PostHrisEmployeesEmployeeIDDocumentsPositiveResponse:
        r"""Add document to employee

        Uploads an document file for the specified employee.

        <Note>
        This endpoint requires the permission **Manage documents** to be enabled in [your scope config](/scopes).
        </Note>

        ### Example Request Body

        ```json
        {
        \"category_id\": \"3Cjwu7nA7pH5cX5X1NAPmb7M\",
        \"document\": {
        \"name\": \"Frank Doe Employment Contract.txt\",
        \"data\": \"SGkgdGhlcmUsIEtvbWJvIGlzIGN1cnJlbnRseSBoaXJpbmcgZW5naW5lZXJzIHRoYXQgbG92ZSB0byB3b3JrIG9uIGRldmVsb3BlciBwcm9kdWN0cy4=\",
        \"content_type\": \"text/plain\"
        }
        }
        ```

        :param employee_id: POST /hris/employees/:employee_id/documents Parameter
        :param category_id:
        :param document:
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.PostHrisEmployeesEmployeeIDDocumentsRequest(
            employee_id=employee_id,
            body=models.PostHrisEmployeesEmployeeIDDocumentsRequestBody(
                category_id=category_id,
                document=utils.get_pydantic_model(document, models.Document),
            ),
        )

        req = self._build_request(
            method="POST",
            path="/hris/employees/{employee_id}/documents",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.PostHrisEmployeesEmployeeIDDocumentsGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.body,
                False,
                False,
                "json",
                models.PostHrisEmployeesEmployeeIDDocumentsRequestBody,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="PostHrisEmployeesEmployeeIdDocuments",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.PostHrisEmployeesEmployeeIDDocumentsPositiveResponse, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def add_employee_document_async(
        self,
        *,
        employee_id: str,
        category_id: str,
        document: Union[models.Document, models.DocumentTypedDict],
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.PostHrisEmployeesEmployeeIDDocumentsPositiveResponse:
        r"""Add document to employee

        Uploads an document file for the specified employee.

        <Note>
        This endpoint requires the permission **Manage documents** to be enabled in [your scope config](/scopes).
        </Note>

        ### Example Request Body

        ```json
        {
        \"category_id\": \"3Cjwu7nA7pH5cX5X1NAPmb7M\",
        \"document\": {
        \"name\": \"Frank Doe Employment Contract.txt\",
        \"data\": \"SGkgdGhlcmUsIEtvbWJvIGlzIGN1cnJlbnRseSBoaXJpbmcgZW5naW5lZXJzIHRoYXQgbG92ZSB0byB3b3JrIG9uIGRldmVsb3BlciBwcm9kdWN0cy4=\",
        \"content_type\": \"text/plain\"
        }
        }
        ```

        :param employee_id: POST /hris/employees/:employee_id/documents Parameter
        :param category_id:
        :param document:
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.PostHrisEmployeesEmployeeIDDocumentsRequest(
            employee_id=employee_id,
            body=models.PostHrisEmployeesEmployeeIDDocumentsRequestBody(
                category_id=category_id,
                document=utils.get_pydantic_model(document, models.Document),
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/hris/employees/{employee_id}/documents",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.PostHrisEmployeesEmployeeIDDocumentsGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.body,
                False,
                False,
                "json",
                models.PostHrisEmployeesEmployeeIDDocumentsRequestBody,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="PostHrisEmployeesEmployeeIdDocuments",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.PostHrisEmployeesEmployeeIDDocumentsPositiveResponse, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def get_employee_document_categories(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisEmployeeDocumentCategoriesResponse]:
        r"""Get employee document categories

        Get employee document categories.

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisEmployeeDocumentCategoriesRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
        )

        req = self._build_request(
            method="GET",
            path="/hris/employee-document-categories",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisEmployeeDocumentCategoriesGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisEmployeeDocumentCategories",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.GetHrisEmployeeDocumentCategoriesResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return None

            return self.get_employee_document_categories(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisEmployeeDocumentCategoriesResponse(
                result=unmarshal_json_response(
                    models.GetHrisEmployeeDocumentCategoriesPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def get_employee_document_categories_async(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisEmployeeDocumentCategoriesResponse]:
        r"""Get employee document categories

        Get employee document categories.

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisEmployeeDocumentCategoriesRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
        )

        req = self._build_request_async(
            method="GET",
            path="/hris/employee-document-categories",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisEmployeeDocumentCategoriesGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisEmployeeDocumentCategories",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> (
            Awaitable[Optional[models.GetHrisEmployeeDocumentCategoriesResponse]]
        ):
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            async def empty_result():
                return None

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return empty_result()

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return empty_result()

            return self.get_employee_document_categories_async(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisEmployeeDocumentCategoriesResponse(
                result=unmarshal_json_response(
                    models.GetHrisEmployeeDocumentCategoriesPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def get_groups(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        types: Optional[List[str]] = None,
        name_contains: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisGroupsResponse]:
        r"""Get groups

        Retrieve all \"groups\" (teams, departments, and cost centers).

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param types: Filter by a comma-separated list of group types: `DEPARTMENT`, `TEAM`, `COST_CENTER`, or `null` to filter groups without a type.

            Leave this blank to get results matching all values.
        :param name_contains: Filter by the `name` field. Can be used to find a group by keywords present in the group name.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisGroupsRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
            types=types,
            name_contains=name_contains,
        )

        req = self._build_request(
            method="GET",
            path="/hris/groups",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisGroupsGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisGroups",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.GetHrisGroupsResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return None

            return self.get_groups(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                types=types,
                name_contains=name_contains,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisGroupsResponse(
                result=unmarshal_json_response(
                    models.GetHrisGroupsPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def get_groups_async(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        types: Optional[List[str]] = None,
        name_contains: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisGroupsResponse]:
        r"""Get groups

        Retrieve all \"groups\" (teams, departments, and cost centers).

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param types: Filter by a comma-separated list of group types: `DEPARTMENT`, `TEAM`, `COST_CENTER`, or `null` to filter groups without a type.

            Leave this blank to get results matching all values.
        :param name_contains: Filter by the `name` field. Can be used to find a group by keywords present in the group name.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisGroupsRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
            types=types,
            name_contains=name_contains,
        )

        req = self._build_request_async(
            method="GET",
            path="/hris/groups",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisGroupsGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisGroups",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Awaitable[Optional[models.GetHrisGroupsResponse]]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            async def empty_result():
                return None

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return empty_result()

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return empty_result()

            return self.get_groups_async(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                types=types,
                name_contains=name_contains,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisGroupsResponse(
                result=unmarshal_json_response(
                    models.GetHrisGroupsPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def get_employments(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisEmploymentsResponse]:
        r"""Get employments

        Retrieve all employments.

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisEmploymentsRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
        )

        req = self._build_request(
            method="GET",
            path="/hris/employments",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisEmploymentsGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisEmployments",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.GetHrisEmploymentsResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return None

            return self.get_employments(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisEmploymentsResponse(
                result=unmarshal_json_response(
                    models.GetHrisEmploymentsPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def get_employments_async(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisEmploymentsResponse]:
        r"""Get employments

        Retrieve all employments.

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisEmploymentsRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
        )

        req = self._build_request_async(
            method="GET",
            path="/hris/employments",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisEmploymentsGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisEmployments",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Awaitable[Optional[models.GetHrisEmploymentsResponse]]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            async def empty_result():
                return None

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return empty_result()

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return empty_result()

            return self.get_employments_async(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisEmploymentsResponse(
                result=unmarshal_json_response(
                    models.GetHrisEmploymentsPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def get_locations(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        name_contains: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisLocationsResponse]:
        r"""Get work locations

        Retrieve all work locations.

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param name_contains: Filter by the `name` field. Can be used to find a location by keywords present in the location name.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisLocationsRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
            name_contains=name_contains,
        )

        req = self._build_request(
            method="GET",
            path="/hris/locations",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisLocationsGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisLocations",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.GetHrisLocationsResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return None

            return self.get_locations(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                name_contains=name_contains,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisLocationsResponse(
                result=unmarshal_json_response(
                    models.GetHrisLocationsPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def get_locations_async(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        name_contains: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisLocationsResponse]:
        r"""Get work locations

        Retrieve all work locations.

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param name_contains: Filter by the `name` field. Can be used to find a location by keywords present in the location name.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisLocationsRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
            name_contains=name_contains,
        )

        req = self._build_request_async(
            method="GET",
            path="/hris/locations",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisLocationsGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisLocations",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Awaitable[Optional[models.GetHrisLocationsResponse]]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            async def empty_result():
                return None

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return empty_result()

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return empty_result()

            return self.get_locations_async(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                name_contains=name_contains,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisLocationsResponse(
                result=unmarshal_json_response(
                    models.GetHrisLocationsPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def get_absence_types(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisAbsenceTypesResponse]:
        r"""Get absence types

        Retrieve all absence types.

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisAbsenceTypesRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
        )

        req = self._build_request(
            method="GET",
            path="/hris/absence-types",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisAbsenceTypesGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisAbsenceTypes",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.GetHrisAbsenceTypesResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return None

            return self.get_absence_types(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisAbsenceTypesResponse(
                result=unmarshal_json_response(
                    models.GetHrisAbsenceTypesPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def get_absence_types_async(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisAbsenceTypesResponse]:
        r"""Get absence types

        Retrieve all absence types.

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisAbsenceTypesRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
        )

        req = self._build_request_async(
            method="GET",
            path="/hris/absence-types",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisAbsenceTypesGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisAbsenceTypes",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Awaitable[Optional[models.GetHrisAbsenceTypesResponse]]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            async def empty_result():
                return None

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return empty_result()

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return empty_result()

            return self.get_absence_types_async(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisAbsenceTypesResponse(
                result=unmarshal_json_response(
                    models.GetHrisAbsenceTypesPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def get_time_off_balances(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        employee_id: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisTimeOffBalancesResponse]:
        r"""Get time off balances

        Retrieve all time off balances.

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param employee_id: Filter by a specific employee using their ID.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisTimeOffBalancesRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
            employee_id=employee_id,
        )

        req = self._build_request(
            method="GET",
            path="/hris/time-off-balances",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisTimeOffBalancesGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisTimeOffBalances",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.GetHrisTimeOffBalancesResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return None

            return self.get_time_off_balances(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                employee_id=employee_id,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisTimeOffBalancesResponse(
                result=unmarshal_json_response(
                    models.GetHrisTimeOffBalancesPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def get_time_off_balances_async(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        employee_id: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisTimeOffBalancesResponse]:
        r"""Get time off balances

        Retrieve all time off balances.

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param employee_id: Filter by a specific employee using their ID.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisTimeOffBalancesRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
            employee_id=employee_id,
        )

        req = self._build_request_async(
            method="GET",
            path="/hris/time-off-balances",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisTimeOffBalancesGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisTimeOffBalances",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Awaitable[Optional[models.GetHrisTimeOffBalancesResponse]]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            async def empty_result():
                return None

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return empty_result()

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return empty_result()

            return self.get_time_off_balances_async(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                employee_id=employee_id,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisTimeOffBalancesResponse(
                result=unmarshal_json_response(
                    models.GetHrisTimeOffBalancesPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def get_absences(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        date_from: Optional[datetime] = None,
        date_until: Optional[datetime] = None,
        type_ids: Optional[List[str]] = None,
        employee_id: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisAbsencesResponse]:
        r"""Get absences

        Retrieve all absences.

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param date_from: Filter for all the absences that either start _or_ haven't ended yet on/after this day. If you imagine a calendar displaying absences, this defines the left-most visible day. This is a plain date (i.e., `yyyy-MM-dd`), all time information is discarded.
        :param date_until: Filter for absences that start on or before this day (but might continue after). If you imagine a calendar displaying absences, this defines the right-most visible day. This is a plain date (i.e., `yyyy-MM-dd`), all time information is discarded.
        :param type_ids: Filter by a comma-separated list of absence type IDs.
        :param employee_id: Filter by a specific employee using their ID.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisAbsencesRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
            date_from=date_from,
            date_until=date_until,
            type_ids=type_ids,
            employee_id=employee_id,
        )

        req = self._build_request(
            method="GET",
            path="/hris/absences",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisAbsencesGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisAbsences",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.GetHrisAbsencesResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return None

            return self.get_absences(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                date_from=date_from,
                date_until=date_until,
                type_ids=type_ids,
                employee_id=employee_id,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisAbsencesResponse(
                result=unmarshal_json_response(
                    models.GetHrisAbsencesPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def get_absences_async(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        date_from: Optional[datetime] = None,
        date_until: Optional[datetime] = None,
        type_ids: Optional[List[str]] = None,
        employee_id: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisAbsencesResponse]:
        r"""Get absences

        Retrieve all absences.

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param date_from: Filter for all the absences that either start _or_ haven't ended yet on/after this day. If you imagine a calendar displaying absences, this defines the left-most visible day. This is a plain date (i.e., `yyyy-MM-dd`), all time information is discarded.
        :param date_until: Filter for absences that start on or before this day (but might continue after). If you imagine a calendar displaying absences, this defines the right-most visible day. This is a plain date (i.e., `yyyy-MM-dd`), all time information is discarded.
        :param type_ids: Filter by a comma-separated list of absence type IDs.
        :param employee_id: Filter by a specific employee using their ID.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisAbsencesRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
            date_from=date_from,
            date_until=date_until,
            type_ids=type_ids,
            employee_id=employee_id,
        )

        req = self._build_request_async(
            method="GET",
            path="/hris/absences",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisAbsencesGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisAbsences",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Awaitable[Optional[models.GetHrisAbsencesResponse]]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            async def empty_result():
                return None

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return empty_result()

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return empty_result()

            return self.get_absences_async(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                date_from=date_from,
                date_until=date_until,
                type_ids=type_ids,
                employee_id=employee_id,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisAbsencesResponse(
                result=unmarshal_json_response(
                    models.GetHrisAbsencesPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def create_absence(
        self,
        *,
        employee_id: str,
        absence_type_id: str,
        start_date: datetime,
        end_date: datetime,
        employee_note: Nullable[str],
        status: Optional[models.PostHrisAbsencesRequestBodyStatus] = "REQUESTED",
        start_half_day: Optional[bool] = False,
        end_half_day: Optional[bool] = False,
        amount: Optional[float] = None,
        unit: Optional[models.PostHrisAbsencesRequestBodyUnit] = None,
        start_time: Optional[str] = None,
        end_time: Optional[str] = None,
        remote_fields: Optional[
            Union[
                models.PostHrisAbsencesRequestBodyRemoteFields,
                models.PostHrisAbsencesRequestBodyRemoteFieldsTypedDict,
            ]
        ] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.PostHrisAbsencesPositiveResponse:
        r"""Create absence

        Create a new absence.

        Check [this page](/hris/features/creating-absences) for a detailed guide.

        <Note>
        This endpoint requires the permission **Manage absences** to be enabled in [your scope config](/scopes).
        </Note>

        ### Example Request Body

        ```json
        {
        \"employee_id\": \"wXJMxwDvPAjrJ4CyqdV9\",
        \"absence_type_id\": \"3YKtQ7qedsrcCady1jSyAkY1\",
        \"start_date\": \"2019-09-17\",
        \"end_date\": \"2019-09-21\",
        \"start_time\": \"08:30:00\",
        \"end_time\": \"16:00:00\",
        \"start_half_day\": false,
        \"end_half_day\": false,
        \"employee_note\": \"Visiting the aliens\"
        }
        ```

        :param employee_id: The ID of the employee in Kombo or their ID in the remote system by prefixing it with `remote:` (e.g., `remote:12312`)
        :param absence_type_id: The ID of the absence type in Kombo (not its `remote_id`).
        :param start_date: The date that the absence starts. This is a plain date (i.e., `yyyy-MM-dd`), with all time information discarded.
        :param end_date: When the absence ends.The date that the absence ends. This is a plain date (i.e., `yyyy-MM-dd`), with all time information discarded.
        :param employee_note: A note describing the reason for this absence.
        :param status: The state that the absence should be created in. Some tools may approve absences automatically if they were created for an absence type that does not require approval.
        :param start_half_day: `true` if the absence should start in the middle of the day.
        :param end_half_day: `true` if the absence should end in the middle of the day.
        :param amount: The amount of time of the absence. Specifying this also requires specifying `unit`. This is supported by very few tools.
        :param unit: The time unit of the `amount` value. Specifying this also requires specifying `amount`.
        :param start_time: The time of when the absence begins. Follows the format `HH:mm` or `HH:mm:ss` (e.g., `14:45:15`). If `start_time` is specified, `end_time` has to be specified as well.
        :param end_time: The time of when the absence ends. Follows the format `HH:mm` or `HH:mm:ss` (e.g., `14:45:15`). If `end_time` is specified, `start_time` has to be specified as well.
        :param remote_fields: Additional fields that we will pass through to specific HRIS systems.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.PostHrisAbsencesRequestBody(
            employee_id=employee_id,
            absence_type_id=absence_type_id,
            status=status,
            start_date=start_date,
            end_date=end_date,
            start_half_day=start_half_day,
            end_half_day=end_half_day,
            amount=amount,
            unit=unit,
            employee_note=employee_note,
            start_time=start_time,
            end_time=end_time,
            remote_fields=utils.get_pydantic_model(
                remote_fields, Optional[models.PostHrisAbsencesRequestBodyRemoteFields]
            ),
        )

        req = self._build_request(
            method="POST",
            path="/hris/absences",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.PostHrisAbsencesGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request, False, False, "json", models.PostHrisAbsencesRequestBody
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="PostHrisAbsences",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.PostHrisAbsencesPositiveResponse, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def create_absence_async(
        self,
        *,
        employee_id: str,
        absence_type_id: str,
        start_date: datetime,
        end_date: datetime,
        employee_note: Nullable[str],
        status: Optional[models.PostHrisAbsencesRequestBodyStatus] = "REQUESTED",
        start_half_day: Optional[bool] = False,
        end_half_day: Optional[bool] = False,
        amount: Optional[float] = None,
        unit: Optional[models.PostHrisAbsencesRequestBodyUnit] = None,
        start_time: Optional[str] = None,
        end_time: Optional[str] = None,
        remote_fields: Optional[
            Union[
                models.PostHrisAbsencesRequestBodyRemoteFields,
                models.PostHrisAbsencesRequestBodyRemoteFieldsTypedDict,
            ]
        ] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.PostHrisAbsencesPositiveResponse:
        r"""Create absence

        Create a new absence.

        Check [this page](/hris/features/creating-absences) for a detailed guide.

        <Note>
        This endpoint requires the permission **Manage absences** to be enabled in [your scope config](/scopes).
        </Note>

        ### Example Request Body

        ```json
        {
        \"employee_id\": \"wXJMxwDvPAjrJ4CyqdV9\",
        \"absence_type_id\": \"3YKtQ7qedsrcCady1jSyAkY1\",
        \"start_date\": \"2019-09-17\",
        \"end_date\": \"2019-09-21\",
        \"start_time\": \"08:30:00\",
        \"end_time\": \"16:00:00\",
        \"start_half_day\": false,
        \"end_half_day\": false,
        \"employee_note\": \"Visiting the aliens\"
        }
        ```

        :param employee_id: The ID of the employee in Kombo or their ID in the remote system by prefixing it with `remote:` (e.g., `remote:12312`)
        :param absence_type_id: The ID of the absence type in Kombo (not its `remote_id`).
        :param start_date: The date that the absence starts. This is a plain date (i.e., `yyyy-MM-dd`), with all time information discarded.
        :param end_date: When the absence ends.The date that the absence ends. This is a plain date (i.e., `yyyy-MM-dd`), with all time information discarded.
        :param employee_note: A note describing the reason for this absence.
        :param status: The state that the absence should be created in. Some tools may approve absences automatically if they were created for an absence type that does not require approval.
        :param start_half_day: `true` if the absence should start in the middle of the day.
        :param end_half_day: `true` if the absence should end in the middle of the day.
        :param amount: The amount of time of the absence. Specifying this also requires specifying `unit`. This is supported by very few tools.
        :param unit: The time unit of the `amount` value. Specifying this also requires specifying `amount`.
        :param start_time: The time of when the absence begins. Follows the format `HH:mm` or `HH:mm:ss` (e.g., `14:45:15`). If `start_time` is specified, `end_time` has to be specified as well.
        :param end_time: The time of when the absence ends. Follows the format `HH:mm` or `HH:mm:ss` (e.g., `14:45:15`). If `end_time` is specified, `start_time` has to be specified as well.
        :param remote_fields: Additional fields that we will pass through to specific HRIS systems.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.PostHrisAbsencesRequestBody(
            employee_id=employee_id,
            absence_type_id=absence_type_id,
            status=status,
            start_date=start_date,
            end_date=end_date,
            start_half_day=start_half_day,
            end_half_day=end_half_day,
            amount=amount,
            unit=unit,
            employee_note=employee_note,
            start_time=start_time,
            end_time=end_time,
            remote_fields=utils.get_pydantic_model(
                remote_fields, Optional[models.PostHrisAbsencesRequestBodyRemoteFields]
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/hris/absences",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.PostHrisAbsencesGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request, False, False, "json", models.PostHrisAbsencesRequestBody
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="PostHrisAbsences",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.PostHrisAbsencesPositiveResponse, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def delete_absence(
        self,
        *,
        absence_id: str,
        remote_fields: Optional[
            Union[
                models.DeleteHrisAbsencesAbsenceIDRequestBodyRemoteFields,
                models.DeleteHrisAbsencesAbsenceIDRequestBodyRemoteFieldsTypedDict,
            ]
        ] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.DeleteHrisAbsencesAbsenceIDPositiveResponse:
        r"""Delete absence

        Delete this absence.

        <Note>
        This endpoint requires the permission **Manage absences** to be enabled in [your scope config](/scopes).
        </Note>

        ### Example Request Body

        ```json
        {
        \"absence_id\": \"wXJMxwDvPAjrJ4CyqdV9\"
        }
        ```

        :param absence_id: The Kombo ID of the absence
        :param remote_fields: Additional fields that we will pass through to specific HRIS systems.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.DeleteHrisAbsencesAbsenceIDRequest(
            absence_id=absence_id,
            body=models.DeleteHrisAbsencesAbsenceIDRequestBody(
                remote_fields=utils.get_pydantic_model(
                    remote_fields,
                    Optional[models.DeleteHrisAbsencesAbsenceIDRequestBodyRemoteFields],
                ),
            ),
        )

        req = self._build_request(
            method="DELETE",
            path="/hris/absences/{absence_id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.DeleteHrisAbsencesAbsenceIDGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.body,
                False,
                False,
                "json",
                models.DeleteHrisAbsencesAbsenceIDRequestBody,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="DeleteHrisAbsencesAbsenceId",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.DeleteHrisAbsencesAbsenceIDPositiveResponse, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def delete_absence_async(
        self,
        *,
        absence_id: str,
        remote_fields: Optional[
            Union[
                models.DeleteHrisAbsencesAbsenceIDRequestBodyRemoteFields,
                models.DeleteHrisAbsencesAbsenceIDRequestBodyRemoteFieldsTypedDict,
            ]
        ] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.DeleteHrisAbsencesAbsenceIDPositiveResponse:
        r"""Delete absence

        Delete this absence.

        <Note>
        This endpoint requires the permission **Manage absences** to be enabled in [your scope config](/scopes).
        </Note>

        ### Example Request Body

        ```json
        {
        \"absence_id\": \"wXJMxwDvPAjrJ4CyqdV9\"
        }
        ```

        :param absence_id: The Kombo ID of the absence
        :param remote_fields: Additional fields that we will pass through to specific HRIS systems.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.DeleteHrisAbsencesAbsenceIDRequest(
            absence_id=absence_id,
            body=models.DeleteHrisAbsencesAbsenceIDRequestBody(
                remote_fields=utils.get_pydantic_model(
                    remote_fields,
                    Optional[models.DeleteHrisAbsencesAbsenceIDRequestBodyRemoteFields],
                ),
            ),
        )

        req = self._build_request_async(
            method="DELETE",
            path="/hris/absences/{absence_id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.DeleteHrisAbsencesAbsenceIDGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.body,
                False,
                False,
                "json",
                models.DeleteHrisAbsencesAbsenceIDRequestBody,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="DeleteHrisAbsencesAbsenceId",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.DeleteHrisAbsencesAbsenceIDPositiveResponse, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def get_legal_entities(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        name_contains: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisLegalEntitiesResponse]:
        r"""Get legal entities

        Retrieve all legal entites.

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param name_contains: Filter by the `name` field. Can be used to find a legal entity by keywords present in the legal entity name.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisLegalEntitiesRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
            name_contains=name_contains,
        )

        req = self._build_request(
            method="GET",
            path="/hris/legal-entities",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisLegalEntitiesGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisLegalEntities",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.GetHrisLegalEntitiesResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return None

            return self.get_legal_entities(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                name_contains=name_contains,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisLegalEntitiesResponse(
                result=unmarshal_json_response(
                    models.GetHrisLegalEntitiesPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def get_legal_entities_async(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        name_contains: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisLegalEntitiesResponse]:
        r"""Get legal entities

        Retrieve all legal entites.

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param name_contains: Filter by the `name` field. Can be used to find a legal entity by keywords present in the legal entity name.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisLegalEntitiesRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
            name_contains=name_contains,
        )

        req = self._build_request_async(
            method="GET",
            path="/hris/legal-entities",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisLegalEntitiesGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisLegalEntities",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Awaitable[Optional[models.GetHrisLegalEntitiesResponse]]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            async def empty_result():
                return None

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return empty_result()

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return empty_result()

            return self.get_legal_entities_async(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                name_contains=name_contains,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisLegalEntitiesResponse(
                result=unmarshal_json_response(
                    models.GetHrisLegalEntitiesPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def get_timesheets(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        employee_id: Optional[str] = None,
        started_before: Optional[datetime] = None,
        started_after: Optional[datetime] = None,
        ended_before: Optional[datetime] = None,
        ended_after: Optional[datetime] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisTimesheetsResponse]:
        r"""Get timesheets

        Get timesheets

        Retrieve attendance data and timesheets from HRIS tools.

        <Warning>**Open Beta Feature:** This endpoint is currently in beta. Please reach out to our support team if you need assistance with implementation.</Warning>

        For a detailed explanation of the data model, validation rules, time zones, payable hours, approvals, and break patterns, see the [Time & Attendance guide](/hris/features/time-and-attendance).

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param employee_id: Returns timesheets for a specific employee.
        :param started_before: Return timesheets whose start time is before the given timestamp.
        :param started_after: Return timesheets whose start time is on or after the given timestamp.
        :param ended_before: Return timesheets whose end time is on or before the given timestamp.
        :param ended_after: Return timesheets whose end time is on or after the given timestamp.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisTimesheetsRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
            employee_id=employee_id,
            started_before=started_before,
            started_after=started_after,
            ended_before=ended_before,
            ended_after=ended_after,
        )

        req = self._build_request(
            method="GET",
            path="/hris/timesheets",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisTimesheetsGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisTimesheets",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.GetHrisTimesheetsResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return None

            return self.get_timesheets(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                employee_id=employee_id,
                started_before=started_before,
                started_after=started_after,
                ended_before=ended_before,
                ended_after=ended_after,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisTimesheetsResponse(
                result=unmarshal_json_response(
                    models.GetHrisTimesheetsPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def get_timesheets_async(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        employee_id: Optional[str] = None,
        started_before: Optional[datetime] = None,
        started_after: Optional[datetime] = None,
        ended_before: Optional[datetime] = None,
        ended_after: Optional[datetime] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisTimesheetsResponse]:
        r"""Get timesheets

        Get timesheets

        Retrieve attendance data and timesheets from HRIS tools.

        <Warning>**Open Beta Feature:** This endpoint is currently in beta. Please reach out to our support team if you need assistance with implementation.</Warning>

        For a detailed explanation of the data model, validation rules, time zones, payable hours, approvals, and break patterns, see the [Time & Attendance guide](/hris/features/time-and-attendance).

        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param employee_id: Returns timesheets for a specific employee.
        :param started_before: Return timesheets whose start time is before the given timestamp.
        :param started_after: Return timesheets whose start time is on or after the given timestamp.
        :param ended_before: Return timesheets whose end time is on or before the given timestamp.
        :param ended_after: Return timesheets whose end time is on or after the given timestamp.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisTimesheetsRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
            employee_id=employee_id,
            started_before=started_before,
            started_after=started_after,
            ended_before=ended_before,
            ended_after=ended_after,
        )

        req = self._build_request_async(
            method="GET",
            path="/hris/timesheets",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisTimesheetsGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisTimesheets",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Awaitable[Optional[models.GetHrisTimesheetsResponse]]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            async def empty_result():
                return None

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return empty_result()

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return empty_result()

            return self.get_timesheets_async(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                employee_id=employee_id,
                started_before=started_before,
                started_after=started_after,
                ended_before=ended_before,
                ended_after=ended_after,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisTimesheetsResponse(
                result=unmarshal_json_response(
                    models.GetHrisTimesheetsPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def get_performance_review_cycles(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisPerformanceReviewCyclesResponse]:
        r"""Get performance review cycles

        Get performance review cycles

        Retrieve performance review cycles data from HRIS tools.

        <Warning>**Open Beta Feature:** This endpoint is currently in beta. Please reach out to our support team if you need assistance with implementation.</Warning>



        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisPerformanceReviewCyclesRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
        )

        req = self._build_request(
            method="GET",
            path="/hris/performance-review-cycles",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisPerformanceReviewCyclesGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisPerformanceReviewCycles",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.GetHrisPerformanceReviewCyclesResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return None

            return self.get_performance_review_cycles(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisPerformanceReviewCyclesResponse(
                result=unmarshal_json_response(
                    models.GetHrisPerformanceReviewCyclesPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def get_performance_review_cycles_async(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisPerformanceReviewCyclesResponse]:
        r"""Get performance review cycles

        Get performance review cycles

        Retrieve performance review cycles data from HRIS tools.

        <Warning>**Open Beta Feature:** This endpoint is currently in beta. Please reach out to our support team if you need assistance with implementation.</Warning>



        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisPerformanceReviewCyclesRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
        )

        req = self._build_request_async(
            method="GET",
            path="/hris/performance-review-cycles",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisPerformanceReviewCyclesGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisPerformanceReviewCycles",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> (
            Awaitable[Optional[models.GetHrisPerformanceReviewCyclesResponse]]
        ):
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            async def empty_result():
                return None

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return empty_result()

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return empty_result()

            return self.get_performance_review_cycles_async(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisPerformanceReviewCyclesResponse(
                result=unmarshal_json_response(
                    models.GetHrisPerformanceReviewCyclesPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def get_performance_reviews(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        types: Optional[List[str]] = None,
        review_cycle_ids: Optional[List[str]] = None,
        reviewee_ids: Optional[List[str]] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisPerformanceReviewsResponse]:
        r"""Get performance reviews

        Get performance reviews

        Retrieve performance review data from HRIS tools.

        <Warning>**Open Beta Feature:** This endpoint is currently in beta. Please reach out to our support team if you need assistance with implementation.</Warning>



        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param types: Filter by a comma-separated list of `MANAGER`, `DIRECT_REPORT`, `PEER`, `SELF`

            Leave this blank to get results matching all values.
        :param review_cycle_ids: Filter by a comma-separated list of review cycle IDs.
        :param reviewee_ids: Filter by a comma-separated list of reviewee IDs.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisPerformanceReviewsRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
            types=types,
            review_cycle_ids=review_cycle_ids,
            reviewee_ids=reviewee_ids,
        )

        req = self._build_request(
            method="GET",
            path="/hris/performance-reviews",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisPerformanceReviewsGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisPerformanceReviews",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.GetHrisPerformanceReviewsResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return None

            return self.get_performance_reviews(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                types=types,
                review_cycle_ids=review_cycle_ids,
                reviewee_ids=reviewee_ids,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisPerformanceReviewsResponse(
                result=unmarshal_json_response(
                    models.GetHrisPerformanceReviewsPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def get_performance_reviews_async(
        self,
        *,
        cursor: Optional[str] = None,
        page_size: Optional[int] = 100,
        updated_after: Optional[datetime] = None,
        include_deleted: Optional[bool] = False,
        ids: Optional[List[str]] = None,
        remote_ids: Optional[List[str]] = None,
        types: Optional[List[str]] = None,
        review_cycle_ids: Optional[List[str]] = None,
        reviewee_ids: Optional[List[str]] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.GetHrisPerformanceReviewsResponse]:
        r"""Get performance reviews

        Get performance reviews

        Retrieve performance review data from HRIS tools.

        <Warning>**Open Beta Feature:** This endpoint is currently in beta. Please reach out to our support team if you need assistance with implementation.</Warning>



        Top level filters use AND, while individual filters use OR if they accept multiple arguments. That means filters will be resolved like this: `(id IN ids) AND (remote_id IN remote_ids)`

        :param cursor: An optional cursor string used for pagination. This can be retrieved from the `next` property of the previous page response.
        :param page_size: The number of results to return per page. Maximum is 250.
        :param updated_after: Filter the entries based on the modification date in format `YYYY-MM-DDTHH:mm:ss.sssZ`. Returns records where either the record itself **OR** its nested data has been updated since this timestamp, even if the record's own `changed_at` field remains unchanged.

            If you want to track entry deletion, also set the `include_deleted=true` query parameter, because otherwise, deleted entries will be hidden.

            For more details, see [Understanding changed_at vs updated_after Behavior](https://docs.kombo.dev/ats/getting-started/fetching-data#understanding-changed_at-vs-updated_after-behavior).
        :param include_deleted: By default, deleted entries are not returned. Use the `include_deleted` query param to include deleted entries too.
        :param ids: Filter by a comma-separated list of IDs such as `222k7eCGyUdgt2JWZDNnkDs3,B5DVmypWENfU6eMe6gYDyJG3`.
        :param remote_ids: Filter by a comma-separated list of remote IDs.
        :param types: Filter by a comma-separated list of `MANAGER`, `DIRECT_REPORT`, `PEER`, `SELF`

            Leave this blank to get results matching all values.
        :param review_cycle_ids: Filter by a comma-separated list of review cycle IDs.
        :param reviewee_ids: Filter by a comma-separated list of reviewee IDs.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetHrisPerformanceReviewsRequest(
            cursor=cursor,
            page_size=page_size,
            updated_after=updated_after,
            include_deleted=include_deleted,
            ids=ids,
            remote_ids=remote_ids,
            types=types,
            review_cycle_ids=review_cycle_ids,
            reviewee_ids=reviewee_ids,
        )

        req = self._build_request_async(
            method="GET",
            path="/hris/performance-reviews",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.GetHrisPerformanceReviewsGlobals(
                integration_id=self.sdk_configuration.globals.integration_id,
            ),
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["429", "500", "502", "503", "504"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="GetHrisPerformanceReviews",
                oauth2_scopes=None,
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["default"],
            retry_config=retry_config,
        )

        def next_func() -> (
            Awaitable[Optional[models.GetHrisPerformanceReviewsResponse]]
        ):
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])

            async def empty_result():
                return None

            next_cursor = JSONPath("$.data.next").parse(body)

            if len(next_cursor) == 0:
                return empty_result()

            next_cursor = next_cursor[0]
            if next_cursor is None or str(next_cursor).strip() == "":
                return empty_result()

            return self.get_performance_reviews_async(
                cursor=next_cursor,
                page_size=page_size,
                updated_after=updated_after,
                include_deleted=include_deleted,
                ids=ids,
                remote_ids=remote_ids,
                types=types,
                review_cycle_ids=review_cycle_ids,
                reviewee_ids=reviewee_ids,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetHrisPerformanceReviewsResponse(
                result=unmarshal_json_response(
                    models.GetHrisPerformanceReviewsPositiveResponse, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "default", "application/json"):
            response_data = unmarshal_json_response(errors.KomboHrisErrorData, http_res)
            raise errors.KomboHrisError(response_data, http_res)

        raise errors.SDKDefaultError("Unexpected response received", http_res)
