public function send() {
        $curlUrl = $this->url;
        if ($this->params) {
            $queryString = http_build_query($this->params);
            $separator = parse_url($curlUrl, PHP_URL_QUERY) ? '&' : '?';
            $curlUrl .= $separator . $queryString;
        }

        // Mock the request if self::$mock exists
        if (self::$mock) {
            if (self::$mock['url'] == $curlUrl && self::$mock['method'] == $this->method) {
                return self::$mock['response'];
            }
            return null;
        }

        // Open and configure curl connection
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_URL, $curlUrl);
        curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
        $headers = array(
            'User-Agent: SiftScience/v' . $this->version . ' sift-php/' . Sift::VERSION
        );
        if ($this->auth) {
            curl_setopt($ch, CURLOPT_USERPWD, $this->auth);
        }

        // HTTP-method-specific configuration.
        if ($this->method == self::POST) {
            if (function_exists('json_encode')) {
                $jsonString = json_encode($this->body);
            } else {
                require_once(dirname(__FILE__) . '/Services_JSON-1.0.3/JSON.php');
                $json = new Services_JSON();
                $jsonString = $json->encodeUnsafe($this->body);
            }

            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonString);
            array_push($headers, 'Content-Type: application/json',
                'Content-Length: ' . strlen($jsonString)
            );

        } else if ($this->method == self::DELETE) {
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
        }

        foreach ($this->curl_opts as $option => $value) {
            if ($option !== CURLOPT_HTTPHEADER) {
                curl_setopt($ch, $option, $value);
            } else {
                $headers = array_merge($headers, $value);
            }
        }

        // Send the request using curl and parse result
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        $result = curl_exec($ch);
        $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curlErrno = curl_errno($ch);
        $curlError = curl_error($ch);
        curl_close($ch);

        return new SiftResponse($result, $httpStatusCode, $this, $curlErrno, $curlError);
    }