protected function request($path, $params = [], $static = false, $isVersionized = true)
	{
		// get and validate the region
		if ($this->region->isLocked($this->permittedRegions))
		{
			throw new RegionException('The region "'.$this->region->getRegion().'" is not permited to query this API.');
		}

		$this->client->baseUrl($this->getDomain());

		if ($this->timeout > 0)
		{
			$this->client->setTimeout($this->timeout);
		}

		// add the key to the param list
		$params['api_key'] = $this->key;

		$uri = ($isVersionized) ? $this->getVersion().'/'.$path : $path;


		// check cache
		if ($this->cache instanceof CacheInterface)
		{
			$cacheKey = md5($this->getDomain().$uri.'?'.http_build_query($params));
			if ($this->cache->has($cacheKey))
			{
				$content = $this->cache->get($cacheKey);
				if ($content instanceof HttpClientError ||
					$content instanceof HttpServerError
				)
				{
					// this was a cached client error... throw it
					throw $content;
				}
			}
			elseif ($this->cacheOnly)
			{
				throw new CacheNotFoundException("A cache item for '$uri?".http_build_query($params)."' was not found!");
			}
			else
			{
				try
				{
					$content = $this->clientRequest($static, $uri, $params);
					// we want to cache this response
					$this->cache->set($cacheKey, $content, $this->seconds);
				}
				catch (HttpClientError $clientError)
				{
					if ($this->cacheClientError)
					{
						// cache client errors
						$this->cache->set($cacheKey, $clientError, $this->seconds);
					}
					// rethrow the exception
					throw $clientError;
				}
				catch (HttpServerError $serverError)
				{
					if ($this->cacheServerError)
					{
						// cache server errors
						$this->cache->set($cacheKey, $serverError, $this->seconds);
					}
					// rethrow the exception
					throw $serverError;
				}
			}
		}
		elseif ($this->cacheOnly)
		{
			throw new CacheNotFoundException('The cache is not enabled but we were told to use only the cache!');
		}
		else
		{
			$content = $this->clientRequest($static, $uri, $params);
		}

		// decode the content
		return json_decode($content, true);
	}