错误码参考
完整的 API 错误码列表,帮助您快速定位和解决问题。
错误码参考#
本文档列出了 eBay AI 广告平台 Open API 可能返回的所有错误码,以及对应的处理建议。
错误响应格式#
当 API 请求失败时,会返回以下格式的 JSON 响应:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "错误描述信息",
"details": {
"field": "额外的错误详情(可选)"
},
"request_id": "req_abc123xyz"
}
}
响应字段说明#
| 字段 | 类型 | 说明 |
|------|------|------|
| success | boolean | 始终为 false |
| error.code | string | 错误码(用于程序判断) |
| error.message | string | 人类可读的错误描述 |
| error.details | object | 额外的错误详情(如字段校验失败的具体字段) |
| error.request_id | string | 请求 ID,用于问题排查 |
遇到问题时,请提供 request_id 联系技术支持,我们可以快速定位问题。
错误码分类#
认证错误 (4xx)#
HTTP 状态码:401 Unauthorized 或 403 Forbidden
| 错误码 | HTTP 状态 | 说明 | 解决方案 |
|--------|-----------|------|----------|
| UNAUTHORIZED | 401 | API Key 无效或未提供 | 检查 API Key 是否正确,是否包含 X-API-Key Header |
| INVALID_SIGNATURE | 401 | 请求签名验证失败 | 检查签名算法实现,确保参数拼接顺序正确 |
| TIMESTAMP_EXPIRED | 401 | 请求时间戳已过期 | 确保服务器时间准确,时间戳在 ±5 分钟内 |
| API_KEY_DISABLED | 403 | API Key 已被禁用 | 联系管理员启用,或创建新的 API Key |
| IP_NOT_ALLOWED | 403 | 请求 IP 不在白名单中 | 在控制台添加当前 IP 到白名单 |
| PERMISSION_DENIED | 403 | 无权限访问该资源 | 检查 API Key 的权限配置 |
参数错误 (400)#
HTTP 状态码:400 Bad Request
| 错误码 | 说明 | 示例 |
|--------|------|------|
| INVALID_PARAMS | 请求参数校验失败 | 必填字段缺失、格式错误 |
| INVALID_JSON | 请求体不是有效的 JSON | 检查 JSON 语法 |
| MISSING_REQUIRED_FIELD | 缺少必填字段 | details.field 会指明缺失的字段 |
| INVALID_FIELD_VALUE | 字段值不合法 | 如数值超出范围、枚举值无效 |
| INVALID_DATE_FORMAT | 日期格式错误 | 应使用 YYYY-MM-DD 或 ISO 8601 格式 |
| INVALID_ENUM_VALUE | 枚举值无效 | 检查允许的枚举值列表 |
参数错误响应示例#
{
"success": false,
"error": {
"code": "INVALID_PARAMS",
"message": "请求参数校验失败",
"details": {
"errors": [
{
"field": "budget_daily",
"message": "日预算必须大于等于 1.00"
},
{
"field": "name",
"message": "活动名称不能超过 200 个字符"
}
]
},
"request_id": "req_abc123"
}
}
资源错误 (404)#
HTTP 状态码:404 Not Found
| 错误码 | 说明 | 解决方案 |
|--------|------|----------|
| RESOURCE_NOT_FOUND | 请求的资源不存在 | 检查资源 ID 是否正确 |
| CAMPAIGN_NOT_FOUND | 广告活动不存在 | 确认活动 ID 存在且有访问权限 |
| AD_GROUP_NOT_FOUND | 广告组不存在 | 确认广告组 ID 正确 |
| KEYWORD_NOT_FOUND | 关键词不存在 | 确认关键词 ID 正确 |
| EBAY_ACCOUNT_NOT_FOUND | eBay 账户不存在 | 确认账户已授权绑定 |
业务错误 (400/409)#
HTTP 状态码:400 Bad Request 或 409 Conflict
| 错误码 | HTTP 状态 | 说明 | 解决方案 |
|--------|-----------|------|----------|
| QUOTA_EXCEEDED | 400 | 资源配额已用尽 | 升级套餐或删除不需要的资源 |
| DUPLICATE_NAME | 409 | 名称已存在 | 使用不同的名称 |
| INVALID_STATUS_TRANSITION | 400 | 状态转换不合法 | 检查当前状态和目标状态的转换规则 |
| CAMPAIGN_BUDGET_TOO_LOW | 400 | 广告活动预算过低 | 日预算至少 1.00 美元 |
| KEYWORD_BID_TOO_LOW | 400 | 关键词出价过低 | 出价至少 0.02 美元 |
| KEYWORD_BID_TOO_HIGH | 400 | 关键词出价过高 | 检查出价上限设置 |
| EBAY_ACCOUNT_NOT_AUTHORIZED | 400 | eBay 账户未授权或授权已过期 | 重新授权 eBay 账户 |
| SYNC_IN_PROGRESS | 409 | 数据正在同步中 | 等待同步完成后重试 |
配额与限制 (429)#
HTTP 状态码:429 Too Many Requests
| 错误码 | 说明 | 解决方案 |
|--------|------|----------|
| RATE_LIMITED | 请求频率超过限制 | 降低请求频率,实现指数退避重试 |
| DAILY_QUOTA_EXCEEDED | 日请求配额已用尽 | 等待次日配额重置,或升级套餐 |
| CONCURRENT_LIMIT_EXCEEDED | 并发请求数超限 | 减少并发请求数 |
限流响应 Header#
当触发限流时,响应会包含以下 Header:
| Header | 说明 |
|--------|------|
| X-RateLimit-Limit | 当前时间窗口的请求上限 |
| X-RateLimit-Remaining | 剩余可用请求数 |
| X-RateLimit-Reset | 限额重置的 Unix 时间戳 |
| Retry-After | 建议等待的秒数 |
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1704873660
Retry-After: 60
{
"success": false,
"error": {
"code": "RATE_LIMITED",
"message": "请求过于频繁,请稍后重试",
"request_id": "req_abc123"
}
}
外部服务错误 (502/503)#
HTTP 状态码:502 Bad Gateway 或 503 Service Unavailable
| 错误码 | HTTP 状态 | 说明 | 解决方案 |
|--------|-----------|------|----------|
| EBAY_API_ERROR | 502 | eBay API 调用失败 | 稍后重试,如持续失败请联系支持 |
| EBAY_API_TIMEOUT | 504 | eBay API 响应超时 | 稍后重试 |
| SERVICE_UNAVAILABLE | 503 | 服务暂时不可用 | 系统维护中,请稍后重试 |
| INTERNAL_ERROR | 500 | 服务器内部错误 | 记录 request_id 联系技术支持 |
服务器错误 (5xx)#
HTTP 状态码:500 Internal Server Error
| 错误码 | 说明 | 解决方案 |
|--------|------|----------|
| INTERNAL_ERROR | 服务器内部错误 | 记录 request_id 联系技术支持 |
| DATABASE_ERROR | 数据库操作失败 | 稍后重试,如持续失败请联系支持 |
错误处理最佳实践#
1. 实现指数退避重试#
对于可重试的错误(如 RATE_LIMITED、SERVICE_UNAVAILABLE),建议实现指数退避重试:
import time
import random
def retry_with_backoff(func, max_retries=5, base_delay=1):
"""带指数退避的重试逻辑"""
for attempt in range(max_retries):
try:
return func()
except RateLimitError as e:
if attempt == max_retries - 1:
raise
# 计算退避时间:base_delay * 2^attempt + 随机抖动
delay = base_delay * (2 ** attempt) + random.uniform(0, 1)
# 如果响应中有 Retry-After,优先使用
if e.retry_after:
delay = e.retry_after
print(f"请求被限流,{delay:.1f}秒后重试...")
time.sleep(delay)
2. 区分可重试与不可重试错误#
| 可重试 | 不可重试 |
|--------|----------|
| RATE_LIMITED | UNAUTHORIZED |
| SERVICE_UNAVAILABLE | INVALID_SIGNATURE |
| EBAY_API_TIMEOUT | INVALID_PARAMS |
| INTERNAL_ERROR (偶发) | RESOURCE_NOT_FOUND |
| SYNC_IN_PROGRESS | PERMISSION_DENIED |
3. 记录请求日志#
import logging
logger = logging.getLogger(__name__)
def handle_api_error(response):
"""处理 API 错误响应"""
error = response.json().get('error', {})
logger.error(
"API 请求失败",
extra={
"error_code": error.get('code'),
"message": error.get('message'),
"request_id": error.get('request_id'),
"status_code": response.status_code,
}
)
# 根据错误码采取不同处理策略
if error.get('code') == 'RATE_LIMITED':
# 重试逻辑
pass
elif error.get('code') == 'INVALID_SIGNATURE':
# 检查签名配置
pass
4. 用户友好的错误提示#
将技术性错误码转换为用户友好的提示:
const ERROR_MESSAGES: Record<string, string> = {
'UNAUTHORIZED': '认证失败,请检查 API 配置',
'INVALID_SIGNATURE': '签名验证失败,请检查密钥配置',
'RATE_LIMITED': '请求过于频繁,请稍后再试',
'RESOURCE_NOT_FOUND': '请求的资源不存在',
'QUOTA_EXCEEDED': '配额已用尽,请升级套餐',
'EBAY_API_ERROR': 'eBay 服务暂时不可用,请稍后重试',
};
function getErrorMessage(code: string): string {
return ERROR_MESSAGES[code] || '操作失败,请稍后重试';
}
常见问题排查#
签名验证失败 (INVALID_SIGNATURE)#
-
检查消息拼接顺序
正确顺序:
timestamp + method + path + body✅ 正确: "1704873600GET/campaigns" ❌ 错误: "GET/campaigns1704873600" -
检查 HTTP 方法大小写
✅ 正确: "GET", "POST", "PUT", "DELETE" ❌ 错误: "get", "post" -
检查请求体一致性
签名时使用的 body 必须与实际发送的完全一致,包括空格和顺序:
✅ 签名: {"name":"test","budget":100} ✅ 发送: {"name":"test","budget":100} ❌ 签名: {"name":"test","budget":100} ❌ 发送: {"budget":100,"name":"test"} // 顺序不同 -
检查 API Secret
确保没有多余的空格或换行符:
# ✅ 正确 API_SECRET = "sk_abcdef1234567890" # ❌ 错误 API_SECRET = "sk_abcdef1234567890 " # 末尾有空格 API_SECRET = " sk_abcdef1234567890" # 开头有空格
时间戳过期 (TIMESTAMP_EXPIRED)#
-
检查服务器时间
# 检查当前时间 date -u # 同步 NTP 时间 sudo ntpdate pool.ntp.org -
检查时区设置
时间戳应为 UTC 时间:
import time # ✅ 正确:UTC 时间戳 timestamp = int(time.time()) # ❌ 错误:使用本地时间可能导致偏差
资源不存在 (RESOURCE_NOT_FOUND)#
- 确认资源 ID 正确无误
- 确认资源属于当前 API Key 关联的租户
- 资源可能已被删除
获取帮助#
如果您无法解决问题,请通过以下方式联系我们:
- 📧 发送邮件至 developer@eaby-ads.com
- 💬 在开发者社区发帖
- 📝 提交工单时请提供
request_id