Errors
HIOBuy uses two error shapes: protocol errors (non-2xx HTTP with an error object) and business outcomes (HTTP 200 with success: false on some order routes).
Protocol errors (HTTP 4xx / 5xx) {#protocol-errors}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "product_id, url, mi_id, or tao_password is required.",
"request_id": "req_abc123",
"category": "VALIDATION_ERROR"
}
}| Field | Description |
|---|---|
error.code | Machine-readable enum — use for branching logic |
error.message | Human-readable explanation (English) |
error.request_id | Same as x-request-id response header |
error.category | Coarse grouping: AUTH_ERROR, RATE_LIMIT_ERROR, VALIDATION_ERROR, CHANNEL_ERROR, INTERNAL_ERROR |
error.upstream | Optional vendor error summary on CHANNEL_UPSTREAM_ERROR (sanitized) |
Error code reference {#error-codes}
The canonical machine-readable catalog is data/errors.catalog.json. Summary:
| Code | HTTP | Category | When |
|---|---|---|---|
INVALID_API_KEY | 401 | AUTH_ERROR | Invalid or missing Bearer token |
CHANNEL_NOT_AUTHORIZED | 401 | AUTH_ERROR | Channel not authorized for this app |
INSUFFICIENT_SCOPE | 403 | AUTH_ERROR | Operation not permitted for this key/app |
FULFILLMENT_MODE_NOT_SUPPORTED | 403 | AUTH_ERROR | /v1/fulfillment/* on self-fulfillment app |
VALIDATION_ERROR | 400 | VALIDATION_ERROR | Missing/invalid body fields, unsupported currency |
UNSUPPORTED_CHANNEL | 400 | VALIDATION_ERROR | Unknown channel value |
UNSUPPORTED_FIELD | 400 | VALIDATION_ERROR | e.g. currency on product routes |
NOT_FOUND | 404 | VALIDATION_ERROR | Order or resource does not exist |
RATE_LIMIT_EXCEEDED | 429 | RATE_LIMIT_ERROR | Per-minute rate limit |
QUOTA_EXCEEDED | 429 | RATE_LIMIT_ERROR | Daily channel quota exhausted |
PLATFORM_QUOTA_EXCEEDED | 429 | RATE_LIMIT_ERROR | Platform-wide capacity limit |
CHANNEL_CAPABILITY_NOT_SUPPORTED | 400 | CHANNEL_ERROR | Operation not available on this channel |
CHANNEL_UPSTREAM_ERROR | 502 | CHANNEL_ERROR | Marketplace rejected the call |
INTERNAL_ERROR | 500 | INTERNAL_ERROR | Unexpected Gateway failure — retry with backoff |
PARCEL_NOT_FOUND | 404 | VALIDATION_ERROR | Invalid or not yet inbound parcel (fulfillment) |
INVALID_SHIPPING_CHANNEL | 400 | VALIDATION_ERROR | Bad shipping_channel_code |
INSUFFICIENT_BALANCE | 402 | VALIDATION_ERROR | Fulfillment wallet too low for pay |
Business failures (HTTP 200) {#business-failures}
Procurement preview/create/pay may return HTTP 200 with success: false when the marketplace refuses the operation but the Gateway request was valid.
{
"channel": "1688",
"success": false,
"code": "ORDER_CREATE_FAILED",
"message": "One or more lines could not be purchased.",
"failed_offers": [
{
"offer_id": "...",
"spec_id": "...",
"error_code": "STOCK_NOT_ENOUGH",
"error_message": "Insufficient stock"
}
],
"request_id": "req_..."
}- Check
successbefore treating the call as completed - Inspect
unavailable_lines(preview) orfailed_offers(create) - Partial success: 1688 may return
success: truewith non-emptyfailed_offers
Product upstream failures {#upstream-product-errors}
Invalid Taobao口令, missing product, or vendor timeouts on product routes typically return 502 with CHANNEL_UPSTREAM_ERROR — not an empty product shell.
Recommended handling {#handling}
- Log
request_idon every error path. - Retry
429and500with exponential backoff; do not retry400/401without fixing input. - On
502 CHANNEL_UPSTREAM_ERROR, surface vendor message to ops; optionally retry once for transient outages. - Order create: use
external_order_id/ Taobaoouter_purchase_idfor idempotency — see Procurement orders.