"granularity argument is invalid" error

I am writing my own Python script to use the Advanced Trade API.

I am trying to use the /api/v3/brokerage/products/{product_id}/candles endpoint to fetch historical data. Authentication works, but I get the following error {"error":"INVALID_ARGUMENT","error_details":"granularity argument is invalid ","message":"granularity argument is invalid "}

The base code is the following

import hmac, hashlib, requests
import time
import urllib.parse
from requests.auth import AuthBase
import datetime

class CoinbaseAuth(AuthBase):
	def __init__(self, api_key, api_secret):
		self.api_key = api_key
		self.api_secret = api_secret
	
	def __call__(self, request):
		timestamp = str(int(time.time()))
		message = timestamp + request.method + request.path_url + (request.body or b'').decode()
		
		signature = hmac.new(self.api_secret.encode('utf-8'),
		                     message.encode('utf-8'),
		                     digestmod=hashlib.sha256).digest().hex()
		
		request.headers.update({
			'CB-ACCESS-SIGN': signature,
			'CB-ACCESS-TIMESTAMP': timestamp,
			'CB-ACCESS-KEY': self.api_key,
			'Content-Type': 'application/json'
		})
		return request
	
	def return_headers(self, path_url, body=''):
		timestamp = str(int(time.time()))
		message = timestamp + 'GET' + path_url + body
		signature = hmac.new(self.api_secret.encode('utf-8'),
		                    message.encode('utf-8'),
		                    digestmod=hashlib.sha256).digest().hex()
		return {
			'CB-ACCESS-SIGN': signature,
			'CB-ACCESS-TIMESTAMP': timestamp,
			'CB-ACCESS-KEY': self.api_key,
			'Content-Type': 'application/json'
		}

class CoinbaseClient:
	def __init__(self, auth: CoinbaseAuth):
		self.auth = auth
	
	def request(self, http_method: str, endpoint: str, body: dict = None):
		if body is None:
			body = {}
		url = urllib.parse.urljoin('https://api.coinbase.com/', endpoint)
		response = requests.request(http_method, url, json=body, auth=self.auth)
		return response
	
	def dummy_request(self):
		url = 'https://api.coinbase.com/api/v3/brokerage/products/BTC-USDC/candles?start=1672527600&end=1672614000&granularity=ONE_DAY'
		headers = self.auth.return_headers('/api/v3/brokerage/products/BTC-USDC/candles')
		response = requests.get(url, headers=headers)
		return response

and I get this error by running the following lines


config = {'api_key': 'YOUR_API_KEY',
          'api_secret': 'YOUR_SECRET_API'}

auth = CoinbaseAuth(api_key=config['api_key'], api_secret=config['api_secret'])
client = CoinbaseClient(auth=auth)


start = str(int(datetime.datetime(2023, 1, 1).timestamp()))
end = str(int(datetime.datetime(2023, 1, 3).timestamp()))

response = client.request(http_method='GET', endpoint='/api/v3/brokerage/products/BTC-USD/candles',
                          body={"start": start, "end": end, 'granularity': 'ONE_DAY'})
print(response.text)

however, if I make the same request but without specifying a body request, I get the data I was looking for. To test this, I have defined a dummy_request method of the CoinbaseClient function that you see in the code above.
Running these extra lines

response = client.dummy_request()
print(response.text)

I get {"candles":[{"start":"1672531200", "low":"16490", "high":"16621", "open":"16531.83", "close":"16611.58", "volume":"10668.73697739"}]}

Why am I getting this error when I specify the body request?

Probably because you need to pass granularity as query parameter like you do in dummy_request. Also GET request typically does not have body…