错误代码
Listings API 的 HTTP 状态码、Listings 和 Social 的 SYxxxxx 错误代码,以及 v4 API 返回的 3 种错误响应结构。
Listings API 使用常规 HTTP 状态码报告请求的处理结果。错误代码以 SY 为前缀,包含在错误的 message 字符串中,格式为 SYxxxxx: <human-readable reason>。
HTTP 状态码
HTTP status code summary
3 种响应结构
大多数失败响应都包含一个 errors 数组,该数组位于顶层或嵌套在操作结果中,如下文各节所示。少数失败响应会改为返回单个 error 对象:触发速率限制(429)以及某些请求级别的失败(400/500,带有 code,例如 INTERNAL_SERVER_ERROR)。请检查这两种情况:errors 是数组,error 是对象。
1. 请求级别:顶层 errors[]
身份验证失败、授权失败和请求格式错误会在操作执行前直接中止处理。它们会返回相应的 4xx 状态码(见上文),并将错误放在响应的顶层。
{ "data": { "createLocation": null }, "errors": [{ "message": "SY90005: Invalid Token" }]}2. 写入验证:嵌套的 data.<operation>.errors[]
创建、更新或发布请求在其他方面格式正确时,会返回 HTTP 200。如果输入违反业务规则,失败信息会嵌套在操作自身的载荷中,位于 data.<operation>.errors。成功时,此数组仍然存在,但为空("errors": [])。
{ "data": { "createLocation": { "errors": [ { "message": "SY10126: City is Mandatory" }, { "message": "SY10010: state_iso" } ], "location": null } }}3. 网关级别:单个顶层 error 对象
触发速率限制和意外的网关故障会在转换之前直接中止处理,并返回一个 error 对象,其中包含 code、message 和 correlation_id。有关 429 响应体,请参阅下方的 rate_limited。
执行写入操作时,请始终读取 data.<operation>.errors,即使返回的是 200 且 data.<operation> 对象中已有数据:写入操作可能部分失败,并在此处报告。
402 Payment Required 响应没有 error 封装层:code、message、doc_url 均位于顶层,有待支付账单时,pay_url 也位于顶层。请参阅下方的 payment_required。
重试写入操作并非没有代价
v4 API 不支持 Idempotency-Key:该请求头会被忽略,而且没有任何端点会检测重复写入。创建、更新或发布调用即使超时或返回 5xx,也可能已在服务器上完成提交,因此盲目重试可能产生重复的地点、帖子或评价回复。
读取操作可以放心地采用退避策略重试。对于写入操作,请先回读数据:使用您可控制的键(storeId、门店代码、互动的回复列表)查找记录,仅在确认记录确实不存在时才重复调用。
常见代码
Common SY error codes
SY10xxx 范围内的验证代码对应特定的输入字段;message 指明未通过验证的字段或规则。SY90xxx 范围内的身份验证和授权代码属于请求级别,会在顶层返回,并附带相应的状态。
已连接账户代码
SY810xx 范围内的代码来自用于导入或关联发布平台商家信息的 Connected Accounts 端点。这些代码会在 HTTP 200 的响应正文中以嵌套形式返回(上文的响应结构 2),因此,即使状态表示成功,也请读取 data.<operation>.errors。
SY810xx connected-account and import codes
Social 错误代码
SY950xx 范围内的代码来自 Social 端点:品牌、连接和社交帖子。与已连接账户代码一样,它们会在 HTTP 200 时嵌套在响应体中返回,因此即使状态表示成功,也要读取 data.<operation>.error(批量路由还需读取 data.<operation>.errors)。
SY950xx Social codes
SY95042 和 SY95044 表示权益校验失败,而非输入错误:如果不更改套餐,重试仍会以同样的方式失败。SY95045、SY95046、SY95049 和 SY95052 是输入错误,可在下一次请求中修正。
Listings 权益代码
Listings plan codes
rate_limited
429 Too Many Requests:该账户已超出其套餐的速率限制。响应正文为标准错误响应,其中包含 retry_after_seconds 提示、供您在支持请求中引用的 correlation_id,以及链接回本节的 doc_url:
{ "error": { "code": "RATE_LIMITED", "message": "Too many requests. Slow down.", "retry_after_seconds": 30, "correlation_id": "9f2c1e64-2b1a-4b0e-9f1a-2c7d5e8a1b3c", "doc_url": "https://listingsapi.com/docs/error-codes#rate_limited" }}请等待 retry_after_seconds 指定的时间(如果存在 Retry-After 响应头,则等待该响应头指定的时间),然后采用指数退避策略重试。有关各套餐的限制和退避策略的参考实现,请参阅速率限制。
payment_required
402:该账户最近一次付款未成功,因此所有 /api/v4 端点均已暂停。若有未付款账单对应的 Stripe 页面,响应正文会包含指向该页面的 pay_url,且 X-Error-Code 响应头会携带相同的 code。您仍可打开控制台中的账单页面进行付款。
{ "code": "payment_required", "message": "This account has an unpaid invoice, so API access is paused. Pay the invoice to restore access.", "pay_url": "https://invoice.stripe.com/i/acct_123/test_abc", "doc_url": "https://listingsapi.com/docs/error-codes#payment_required"}付清最后一张未结清账单后,访问权限会在 1 分钟内恢复。如果首次付款失败 3 天后该账单仍未付款,Listings 订阅将被取消,该账户的地点也将被归档。如果该账户还拥有有效的 Social 订阅,则会保留 Social 访问权限;否则,该账户将被关闭,其 API 密钥将失效。
social_payment_required
402:Social 订阅最近一次付款未成功,因此 Social 端点(/api/v4/social/*)已暂停。Listings 端点仍可正常使用。响应正文包含与 payment_required 相同的字段,其中包含 "code": "social_payment_required"。如果首次付款失败 3 天后该账单仍未付款,Social 订阅将被取消,该账户的品牌也将被归档。没有 Listings 订阅的账户将被关闭,其 API 密钥将失效。
开发者门户控制平面错误
开发者门户中的账户和密钥管理端点(即控制台自身的 API 路由)统一返回一种结构化错误响应,其格式不同于上述 REST errors[] 格式。每个 code 都携带一个 correlation_id 和一个链接回本文对应章节的 doc_url。
{ "error": { "code": "AUTH_INVALID_KEY", "message": "Session is invalid or expired.", "correlation_id": "9f2c1e64-2b1a-4b0e-9f1a-2c7d5e8a1b3c", "doc_url": "https://listingsapi.com/docs/error-codes#auth_invalid_key" }}auth_missing_key
401:未提供凭据。请重新登录,或以 Authorization: API <your-key> 的形式发送您的密钥。
auth_invalid_key
401:会话或密钥无效或已过期。请重新进行身份验证,或在控制台中重新签发密钥。
auth_insufficient_scope
403:凭据有效,但无权执行此操作。仅具有读取权限的密钥无法调用写入端点;如有需要,请签发具有写入权限的密钥。
not_found
404:所请求的资源或通过 ID 指定的资源不存在。
conflict
409:请求与资源的当前状态冲突(例如,撤销已被撤销的密钥)。
validation_failed
422:请求体未通过验证。响应中的 field 和 details 指出了有问题的输入。
internal_error
500:发生了意外的服务器端错误。对于读取操作,请采用指数退避策略重试;对于写入操作,请先回读该记录(请参阅重试写入并非没有代价)。如果您联系支持团队,请引用 correlation_id。
dependency_unavailable
503:API 所依赖的某项服务暂时不可用。请采用退避策略重试。
有关 429,请参阅上文的 rate_limited。
在代码中处理错误
先检查 HTTP 状态;然后,对于写入操作,检查响应体中是否存在嵌套的 errors 数组:
from listingsapi import APIError, ListingsAPI client = ListingsAPI(api_key=os.environ["LISTINGSAPI_KEY"]) try: location = client.locations.create(input=payload)except APIError as e: # Raised for a non-2xx status (AuthenticationError, ValidationError, and # so on) and for an error payload returned inside a 200 body. raise RuntimeError(f"Listings API error: {e}") from e直接使用原始 HTTP API 时,需要显式执行相同的 2 项检查:先检查状态码,再检查响应载荷:
resp = requests.post( "https://listingsapi.com/api/v4/locations", headers={"Authorization": f"API {os.environ['LISTINGSAPI_KEY']}"}, json=payload, timeout=30,)resp.raise_for_status()body = resp.json() op = (body.get("data") or {}).get("createLocation") or {}if op.get("errors"): messages = [e["message"] for e in op["errors"]] raise RuntimeError(f"Listings API error: {messages}")Python SDK 会为您完成这 2 项检查:它会将每个 HTTP 状态映射为具有特定类型的异常,并在 200 响应体内返回错误载荷时引发异常。