使用Python调用eBay API发布商品时遇Error ID 2004问题求助
调用eBay Inventory API发布商品时2004错误的排查与解决
问题现象
- 调用eBay
sell/inventory/v1/inventory_itemAPI发布商品时,返回错误:{"errors":[{"errorId":2004,"domain":"ACCESS","category":"REQUEST","message":"Invalid request","longMessage":"The request has errors. For help, see the documentation for this API."}]} - 确认未达调用限额,access code有效
- 在API Explorer测试时,得到更详细错误提示:
{ "errors": [ { "errorId": 2004, "domain": "ACCESS", "category": "REQUEST", "message": "Invalid request", "longMessage": "The request has errors. For help, see the documentation for this API.", "parameters": [ { "name": "reason", "value": "Can not instantiate value of type [simple type, class com.ebay.raptor.slrinvapi.app.entities.InventoryItem] from JSON String; no single-String constructor/factory method" } ] } ] }
问题根源
错误提示的核心是API无法解析请求体,本质原因是请求方法和URL不符合API规范:
- eBay创建/更新inventory item的接口要求使用
PUT方法,且必须在URL中指定唯一SKU(格式为https://api.ebay.com/sell/inventory/v1/inventory_item/{sku}) - 你当前使用
POST请求不带SKU的URL,API会错误地将请求体当作字符串解析,导致无法实例化InventoryItem对象
修复方案
1. 修正请求方法与URL
将请求方法从POST改为PUT,并在URL末尾拼接自定义的唯一SKU:
# 替换为你的商品唯一SKU sku = "BLUETOOTH_SPEAKER_001" response = requests.put(f"{api_url}/{sku}", headers=headers, json=data)
2. 完善请求体必填字段
根据eBay API文档,补充availability等必填字段(原代码中直接用quantity不符合规范):
data = { "title": "Bluetooth Speaker", "condition": "NEW", "description": "This is a very good speaker and sounds amazing", "imageUrls": [ "https://amazon.adamkhattab.co.uk/photo.jpg" ], "price": { "value": "20.00", "currency": "GBP" }, "availability": { "shipToLocationAvailability": { "quantity": 1 } } }
3. 优化请求写法
使用requests的json参数替代手动序列化,自动处理Content-Type头:
response = requests.put(f"{api_url}/{sku}", headers=headers, json=data)
完整修复后的代码
import requests import json import base64 client_id = '#################################' client_secret = '#################################' redirect_uri = 'https://amazon.adamkhattab.co.uk/callback.php' auth_url = 'https://auth.ebay.com/oauth2/authorize' token_url = 'https://api.ebay.com/identity/v1/oauth2/token' api_url = 'https://api.ebay.com/sell/inventory/v1/inventory_item' def get_access_token(client_id, client_secret, redirect_uri): auth_code = input('Please enter the authorization code: ') headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': f'Basic {base64.b64encode(f"{client_id}:{client_secret}".encode()).decode()}' } data = { 'grant_type': 'authorization_code', 'code': auth_code, 'redirect_uri': redirect_uri } response = requests.post(token_url, headers=headers, data=data) # 添加token获取失败的错误处理 if response.status_code != 200: print(f"获取token失败: {response.text}") return None access_token = json.loads(response.text)['access_token'] return access_token def list_item(access_token): if not access_token: return headers = { 'Authorization': f'Bearer {access_token}', 'Content-Type': 'application/json', 'Accept': 'application/json' } data = { "title": "Bluetooth Speaker", "condition": "NEW", "description": "This is a very good speaker and sounds amazing", "imageUrls": [ "https://amazon.adamkhattab.co.uk/photo.jpg" ], "price": { "value": "20.00", "currency": "GBP" }, "availability": { "shipToLocationAvailability": { "quantity": 1 } } } sku = "BLUETOOTH_SPEAKER_001" response = requests.put(f"{api_url}/{sku}", headers=headers, json=data) print(response.text) auth_url += f'?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code&scope=https://api.ebay.com/oauth/api_scope/sell.inventory' print(f'Please visit the following URL and authorize the application:\n{auth_url}') access_token = get_access_token(client_id, client_secret, redirect_uri) list_item(access_token)
内容的提问来源于stack exchange,提问作者Adam Khattab
相关产品推荐
相关产品推荐

