final private function send(string $resource, int $id = null, array $query = [])
    {
        $query['apikey'] = $this->publicApiKey;
        $query['ts'] = time();
        $query['hash'] = md5("{$query['ts']}{$this->privateApiKey}{$this->publicApiKey}");
        $cacheKey = urlencode($resource) . ($id !== null ? "/{$id}" : '') . '?' . http_build_query($query);
        $url = self::BASE_URL . $cacheKey;

        $response = $this->cache->get($cacheKey);
        if ($response === null) {
            $response = $this->guzzleClient->request('GET', $url, self::$guzzleRequestOptions);
        }

        if ($response->getStatusCode() !== 200) {
            return null;
        }

        $this->cache->set($cacheKey, $response, self::MAX_TTL);

        return DataWrapper::fromJson((string)$response->getBody());
    }