protected function doRequest(string $method, string $relativeUrl, array $data)
    {
        $url = 'https://doodle.com' . $relativeUrl;
        $cookieFileName = $this->getCookieFileName();

        $dataQuery = '';

        if (strpos($relativeUrl, 'api') !== false) {
            if (!empty($data)) {
                $dataQuery = json_encode($data);
            }
        } else {
            $dataQuery = http_build_query($data);
            $dataQuery = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '%5B%5D=', $dataQuery);
        }

        $ch = curl_init();

        switch ($method) {
            case 'GET':
                if (!empty($dataQuery)) {
                    $url .= '?' . $dataQuery;
                }
                if (strpos($relativeUrl, 'api') !== false) {
                    curl_setopt($ch, CURLOPT_HTTPHEADER, [
                        'Access-Token: ' . $this->token
                    ]);
                }
                break;
            case 'POST':
            case 'DELETE':
                if ($method === 'DELETE') {
                    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
                } else {
                    curl_setopt($ch, CURLOPT_POST, 1);
                    curl_setopt($ch, CURLOPT_POSTFIELDS, $dataQuery);
                }
                if (strpos($relativeUrl, 'api') !== false) {
                    if ($method === 'POST') {
                        curl_setopt($ch, CURLOPT_HTTPHEADER, [
                            'Content-Type: application/json',
                            'Content-Length: ' . strlen($dataQuery)]
                        );
                    }
                }
                break;
        }

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFileName);
        curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFileName);
        curl_setopt($ch, CURLOPT_VERBOSE, true);
        //$verbose = fopen('php://temp', 'wb+');
        curl_setopt($ch, CURLOPT_STDERR, $verbose);
        curl_setopt($ch, CURLINFO_HEADER_OUT, true);

        $result = curl_exec($ch);

        $info = curl_getinfo($ch);

        if ($result === FALSE) {
            printf("cUrl error (#%d): %s\n", curl_errno($ch), curl_error($ch));
            //$verboseLog = stream_get_contents($verbose);
            //echo "Verbose information:\n", $verboseLog, "\n";
        }
        //rewind($verbose);

        curl_close($ch);

        if (strpos($relativeUrl, 'api') !== false) {
            if ($method === 'DELETE') {
                return $info['http_code'] === 200;
            }
            if ($result) {
                if ($result[0] === 'E') {
                    $result = substr($result, 1);
                }

                return json_decode($result, true);
            }
        }

        return $result;
    }