I’ve been trying to get information about our products that we have listed on amazon seller central using the SP-API, but I keep getting error messages:
Assumed IAM role successfully.
Obtained LWA access token successfully.
403 Forbidden error. Response details:
{
"errors": [
{
"code": "Unauthorized",
"message": "Access to requested resource is denied.",
"details": ""
}
]
}
HTTP error occurred: 403 Client Error: for url: https://sellingpartnerapi-eu.amazon.com/listings/2020-09-01/items?marketplaceIds=A1PA6795UKMFR9
I’ve set up my IAM role and can make succesful calls to this endpoint: “https://sellingpartnerapi-eu.amazon.com/sellers/v1/marketplaceParticipations”. But for product listings it does not want to work. How do I fix this?
My code:
import boto3
import requests
import json
from requests.auth import AuthBase
from aws_requests_auth.aws_auth import AWSRequestsAuth
from botocore.exceptions import NoCredentialsError, PartialCredentialsError
# Load credentials from JSON file
with open('amazon_creds.json', 'r') as f:
creds = json.load(f)
# Assume IAM Role
def assume_role(role_arn, aws_access_key, aws_secret_key):
sts_client = boto3.client('sts',
aws_access_key_id=aws_access_key,
aws_secret_access_key=aws_secret_key)
assumed_role_object = sts_client.assume_role(
RoleArn=role_arn,
RoleSessionName="AssumeRoleSession1"
)
return assumed_role_object['Credentials']
# Get LWA Access Token
def get_lwa_access_token(client_id, client_secret, refresh_token):
url = "https://api.amazon.com/auth/o2/token"
params = {
'grant_type': 'refresh_token',
'refresh_token': refresh_token,
'client_id': client_id,
'client_secret': client_secret
}
response = requests.post(url, data=params)
response.raise_for_status() # Raise an error for bad status codes
return response.json()['access_token']
# Custom Auth Class for AWS SigV4
class AWSV4Auth(AuthBase):
def __init__(self, aws_access_key, aws_secret_access_key, aws_session_token, region, service):
self.aws_access_key = aws_access_key
self.aws_secret_access_key = aws_secret_access_key
self.aws_session_token = aws_session_token
self.region = region
self.service = service
def __call__(self, r):
auth = AWSRequestsAuth(
aws_access_key=self.aws_access_key,
aws_secret_access_key=self.aws_secret_access_key,
aws_token=self.aws_session_token,
aws_host='sellingpartnerapi-eu.amazon.com',
aws_region=self.region,
aws_service=self.service
)
return auth(r)
# Make API Request
def make_sp_api_request(credentials, access_token, region, marketplace_ids):
endpoint = f"https://sellingpartnerapi-eu.amazon.com/listings/2020-09-01/items"
headers = {
'x-amz-access-token': access_token,
'Content-Type': 'application/json',
'Accept': 'application/json'
}
params = {
'marketplaceIds': marketplace_ids
}
auth = AWSV4Auth(
aws_access_key=credentials['AccessKeyId'],
aws_secret_access_key=credentials['SecretAccessKey'],
aws_session_token=credentials['SessionToken'],
region=region,
service='execute-api'
)
response = requests.get(endpoint, headers=headers, params=params, auth=auth)
if response.status_code == 403:
print("403 Forbidden error. Response details:")
print(response.text)
response.raise_for_status() # Raise an error for bad status codes
return response.json()
try:
# Assume the IAM role
credentials = assume_role(creds['role_arn'], creds['aws_access_key'], creds['aws_secret_key'])
print("Assumed IAM role successfully.")
# Get LWA access token
access_token = get_lwa_access_token(creds['lwa_client_id'], creds['lwa_client_secret'], creds['refresh_token'])
print("Obtained LWA access token successfully.")
# Make the SP-API request
region = 'eu-north-1'
marketplace_ids = 'A1PA6795UKMFR9'
response = make_sp_api_request(credentials, access_token, region, marketplace_ids)
print("API response received successfully.")
print(json.dumps(response, indent=4))
except (NoCredentialsError, PartialCredentialsError) as e:
print("Error with AWS credentials: ", str(e))
except requests.exceptions.HTTPError as e:
print("HTTP error occurred: ", str(e))
except Exception as e:
print("An error occurred: ", str(e))
New contributor
joel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.