Errors

How the ListBee API communicates failures

All error responses use RFC 9457 Problem Details with Content-Type: application/problem+json.

Error structure

1{
2 "type": "https://docs.listbee.so/errors/invalid-request",
3 "title": "Invalid Request",
4 "status": 422,
5 "detail": "Price must be greater than 0",
6 "code": "invalid_price",
7 "param": "price"
8}
FieldTypeDescription
typestringURI identifying the error type. Links to documentation.
titlestringStable, human-readable category label.
statusintegerHTTP status code, echoed in the body.
detailstringSpecific explanation of what went wrong.
codestringMachine-readable code for programmatic handling.
paramstring | nullThe request field that caused the error, if applicable.

Use code for programmatic branching — title and detail may change, code does not.

Extension members

Some errors include additional structured fields beyond the standard six. These are RFC 9457 extension members — extra context that helps agents self-correct without parsing the detail text.

1{
2 "type": "https://docs.listbee.so/errors/not-in-draft",
3 "title": "Conflict",
4 "status": 409,
5 "detail": "Listing is not in draft status",
6 "code": "not_in_draft",
7 "current_status": "published",
8 "required_status": "draft"
9}

Extension members vary by error code. Use code to determine which extras are present.

Readiness-bridged errors

publish_failed includes the full readiness actions array — the same structured guidance you get from GET /v1/listings/{id}. Your agent gets the fix instructions inline with the error:

1{
2 "type": "https://docs.listbee.so/errors/publish-failed",
3 "title": "Conflict",
4 "status": 409,
5 "detail": "Listing cannot be published: missing payment configuration",
6 "code": "publish_failed",
7 "actions": [
8 {
9 "code": "connect_stripe",
10 "kind": "api",
11 "priority": "required",
12 "message": "Connect Stripe account to accept payments.",
13 "resolve": {
14 "method": "POST",
15 "endpoint": "/v1/account/stripe/connect"
16 }
17 }
18 ],
19 "next": "connect_stripe"
20}

State and constraint errors

Other errors include flat metadata about the current state or constraint:

Error codeExtension membersMeaning
not_in_draftcurrent_status, required_statusListing must be in draft for this operation
invalid_transitioncurrent_status, allowed_statusesOrder is not in the required status
refund_not_allowedcurrent_status, allowed_statusesOrder cannot be refunded in this status
conflict (deliverables)current_count, max_countDeliverable capacity reached
rate_limitedretry_afterSeconds until the rate limit resets

HTTP status codes

StatusWhen
400Malformed request (bad JSON, missing required fields).
401Missing or invalid API key.
403Valid API key but insufficient permissions.
404Resource not found.
409Conflict — resource already exists, or idempotency key in progress.
422Valid request format but failed business validation (e.g. invalid price, key reuse).
429Rate limit exceeded. See Rate limits.
500Internal server error. Contact support with x-correlation-id header value.

Common error codes

CodeStatusMeaning
authentication_error401API key missing, expired, or revoked.
not_found404Resource does not exist or belongs to another account.
not_in_draft409Operation requires the listing to be in draft status.
publish_failed409Listing cannot be published — check actions for what’s needed.
invalid_transition409Order is not in the required status for this operation.
conflict409Resource constraint violated (e.g. max deliverables reached).
refund_not_allowed422Order cannot be refunded in its current status.
missing_payment_intent422Order has no payment to refund.
missing_stripe_connection422Seller’s Stripe account is disconnected.
validation_error422Request field validation failed.
rate_limited429Too many requests. Check retry_after in body.
idempotency_key_reuse422Same idempotency key sent with different request body.
idempotency_request_in_progress409Concurrent request with this key still in flight.

Handling errors in Python

1from listbee import ListBee
2from listbee.exceptions import (
3 ListBeeError,
4 AuthenticationError,
5 NotFoundError,
6 ConflictError,
7 ValidationError,
8 RateLimitError,
9)
10
11client = ListBee(api_key="lb_...")
12
13try:
14 listing = client.listings.publish(listing_id="lst_abc123")
15except AuthenticationError:
16 print("Invalid API key")
17except NotFoundError as e:
18 print(f"Not found: {e.detail}")
19except ConflictError as e:
20 if e.code == "publish_failed":
21 # Readiness actions embedded in the error
22 for action in e.extras.get("actions", []):
23 print(f"Fix: {action['message']}")
24 elif e.code == "not_in_draft":
25 print(f"Listing is {e.extras.get('current_status')}, must be draft")
26 else:
27 print(f"Conflict: {e.detail}")
28except ValidationError as e:
29 print(f"Validation error on '{e.param}': {e.detail}")
30except RateLimitError as e:
31 retry_after = e.extras.get("retry_after", 10)
32 print(f"Rate limited — retry in {retry_after}s")
33except ListBeeError as e:
34 print(f"API error {e.status}: {e.code} — {e.detail}")

Accessing extras in SDKs

Both SDKs expose extension members via error.extras — a dict/object of all fields beyond the standard six.

1from listbee.exceptions import ConflictError
2
3try:
4 client.listings.publish(listing_id="lst_abc123")
5except ConflictError as e:
6 print(e.code) # "publish_failed"
7 print(e.extras.get("actions")) # [{...}, ...]
8 print(e.extras.get("next")) # "connect_stripe"

Unknown extension members are preserved verbatim — as the API adds new fields, your code receives them immediately without an SDK update.

Correlation IDs

Every response includes an x-correlation-id header. Include it when contacting support — it ties your request to the server-side logs.

1import httpx
2
3response = httpx.get(
4 "https://api.listbee.so/v1/listings/lst_abc123",
5 headers={"Authorization": "Bearer lb_..."},
6)
7
8if response.status_code >= 400:
9 correlation_id = response.headers.get("x-correlation-id")
10 print(f"Request failed. Correlation ID: {correlation_id}")