You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Amazon SP-API Listings接口调用失败(403错误)求助

解决Amazon SP-API调用Listings接口返回403 Unauthorized的问题

以下是针对你遇到的问题的排查和解决步骤:

1. 检查SP-API应用权限配置

你能成功调用sellers/v1/marketplaceParticipations接口,说明IAM角色的基础权限和LWA令牌的获取流程是正常的,但Listings接口需要额外的权限授权:

  • 登录亚马逊开发者后台,找到你的SP-API应用,确认已申请并获批Listings Items相关权限(具体为listings_items:read)。
  • 如果是刚更新的权限,需要重新生成刷新令牌(refresh_token),旧令牌不会自动包含新增的权限。

2. 修正AWS区域参数

你的代码中使用的region是eu-north-1,但欧盟区域的SP-API对应的正确AWS签名区域是eu-west-1,区域不匹配会导致SigV4签名验证失败,进而返回403错误。修改代码中的区域参数:

# 原代码
region = 'eu-north-1'
# 修改为
region = 'eu-west-1'

3. 验证请求参数完整性

Listings 2020-09-01版本的items接口,若你的IAM角色关联了多个卖家账户,需要额外指定sellerId参数,确保参数与目标店铺信息匹配:

params = {
    'marketplaceIds': marketplace_ids,
    'sellerId': '你的卖家账户ID'  # 单账户场景可省略,多账户场景必须添加
}

你的错误日志:

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

你的代码:

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))

内容的提问来源于stack exchange,提问作者joel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 12:22:01