private function callApi($method, $path, $params, $isMultiPart)
    {
        // init session
        $ch = curl_init();

        // request settings
        curl_setopt_array($ch, $this->curlSettings); // basic settings

        // url
        $url = $this->endpoint . $path;
        $url .= $method == 'get' ? $this->getAuthQueryStringWithParams($params) : $this->getAuthQueryString();

        curl_setopt($ch, CURLOPT_URL, $url);

        // http header
        $requestHeaders = $this->httpHeaders;
        if (!$isMultiPart) {
            $requestHeaders[] = "Content-Type: application/json";
        }
        curl_setopt($ch, CURLOPT_HTTPHEADER, $requestHeaders);

        // method specific settings
        switch ($method) {
            case 'post':
                curl_setopt($ch, CURLOPT_POST, 1);

                // request body
                if ($isMultiPart) {
                    if (version_compare(PHP_VERSION, '5.5.0') === -1) {
                        // fallback to old method
                        $params['file'] = '@' . $params['file'];
                    } else {
                        // make use of CURLFile
                        curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true);
                        $params['file'] = new \CURLFile($params['file']);
                    }
                    $postBody = $params;
                } else {
                    $postBody = json_encode($params);
                }
                curl_setopt($ch, CURLOPT_POSTFIELDS, $postBody);
                break;

            case 'put':
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
                curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
                break;

            case 'delete':
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
                curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
                break;
        }

        // execute request
        $response = curl_exec($ch);

        // error handling
        if ($response === false) {
            throw new \UnexpectedValueException(curl_error($ch));
        }

        // close connection
        curl_close($ch);

        // return response
        return $response;
    }