Tips on debugging Ebay API 401 error for a novice

For a personal project, I’ve been trying to formulate a Ebay api script that pulls data on Ebay item listings. Using the freeCodeCamp API course, I’ve been working myself up the ladders of error, but now I can’t get past this error:

HTTP Error: 401 Client Error: Unauthorized for url: https://api.ebay.com/buy/browse/v1/item_summary/search?q=laptop&q=laptop

I would like to know how to debug and fix this error.

Thanks in advance!

More info:

I do get a status 200 success code on Ebays API Explorer

This is the format of my ebay_credentials.json file:

{
    "app_id": "",
    "cert_id": "",
    "dev_id": "",
    "api_endpoint": "",
    "access_token": ""
  }

And my ebay_api3.py file (not my code):

import json
import os
import requests

def load_credentials():
    try:
        with open('ebay_credentials.json', 'r') as file:
            credentials = json.load(file)
            credentials['access_token'] = os.getenv('EBAY_ACCESS_TOKEN')
            if 'api_endpoint' not in credentials:
                raise ValueError("Error: 'api_endpoint' not found in eBay credentials.")

            return credentials
    except FileNotFoundError:
        print("Error: eBay credentials file not found.")
        return None
    except json.JSONDecodeError as json_err:
        print(f"Error decoding eBay credentials JSON: {json_err}")
        return None
    except ValueError as val_err:
        print(val_err)
        return None

def build_headers(credentials):
    headers = {
        'Content-Type': 'application/json',
        'Authorization': f"Bearer {credentials['access_token']}"
    }

    return headers

def search_ebay_listings(query):
    credentials = load_credentials()

    if credentials is None:
        return None

    headers = build_headers(credentials)

    url = credentials.get('api_endpoint', '')
    params = {'q': query}

    try:
        response = requests.get(url, headers=headers, params=params)
        response.raise_for_status()

        data = response.json()
        return data

    except requests.exceptions.HTTPError as errh:
        print("HTTP Error:", errh)
    except requests.exceptions.ConnectionError as errc:
        print("Error Connecting:", errc)
    except requests.exceptions.Timeout as errt:
        print("Timeout Error:", errt)
    except requests.exceptions.RequestException as err:
        print("Something went wrong:", err)

if __name__ == '__main__':
    query = 'laptop'
    ebay_data = search_ebay_listings(query)

    if ebay_data:
        print(json.dumps(ebay_data, indent=2))

This error indicates that the request to the ebay api is not authorized. It is due to issues with your credentials.

Your ebay_credentials.json file appears to be missing the actual values for the keys app_id, cert_id, dev_id, api_endpoint, and access_token. You need to add appropriate values to these fields obtained from your ebay developer account.

In my code I do have my actual values from Ebay. I’ve left them out for security reasons. Sorry, I should have made that clear.

Yes good u should not expose api credentials because of security reasons.

Verify that the load_credentials function correctly loads the credentials from your ebay_credentials.json file also verify environment variable of access token.

In try add print statement and verify if the headers and parameters are correctly set before making the api call. (No need to post print answer here because of security reason)

try:
    print("Request URL:", url)
    print("Request Headers:", headers)
    print("Request Params:", params)

    response = requests.get(url, headers=headers, params=params)
    print("Response Status Code:", response.status_code)
    response.raise_for_status()
1 Like
credentials['access_token'] = os.getenv('EBAY_ACCESS_TOKEN')

If the access_token is already in the JSON file why would you need this?

Also, as far as I can tell os.getenv is for getting system environment variables. I doubt you have the access token in your system variables.

1 Like

Thanks for the idea! I ran something similiar (just ‘print(credentials)’) and got this response, minus the actual api creds:

{'app_id': '', 'cert_id': '', 'dev_id': '', 'api_endpoint': 'https://api.ebay.com/buy/browse/v1/item_summary/search?q=laptop', 'access_token': ''}

I think this looks alright, but maybe the format is off?

I’m confused with the second section of lines and don’t know how to get them to run. I know the ‘requests’ python package, but what is it requesting? How do I set this up? Mostly, I just need to know what to set the values to.

Thank you!

Thank you for catching this! I ran print(credentials['access_token']) and got None.

I removed the line, but in case anyone was wondering, it did not fix the error, but it might have been a piece of it!

I’m not very confident in whether the api creds I’m using are the right ones, as I found the Ebay web site quite confusing. If anyone might know how these apis work, where to find the correct ones or has had success with Ebay’s api I would greatly appreciate it!

I’m currently using the ‘Sandbox’ credentials.

In this case the script is using the package to send a get request to ebay’s api endpoint for searching item summaries. Check if credentials expired maybe it is a reason for not working.

I see! I ran the code again with that code and got this:

Request URL: https://api.ebay.com/buy/browse/v1/item_summary/search?
Request Headers: {'Content-Type': 'application/json', 'Authorization': 'Bearer my_token'}
Request Params: {'q': 'laptop'}
Response Status Code: 401
HTTP Error: 401 Client Error: Unauthorized for url: https://api.ebay.com/buy/browse/v1/item_summary/search?q=laptop

The only modification to the output I did was changing my actual token with my_token. The token is the only one that was actually in the output, it looks like the rest are being referred to by 'application/json'. Is this a formatting issue?

I rechecked my Ebay creds, none have changed.

That might not work locally. You might need a production keyset. Try it with proper credentials.

1 Like

Thank you! Using the production key fixed the issue!