Errors
The Seller API uses conventional HTTP response codes to indicate the success or failure of an API request. In general:
- Codes in the
2xxrange indicate success. - Codes in the
4xxrange indicate an error that failed given the information provided. - Codes in the
5xxrange indicate an error with the Whatnot servers (these are rare).
Most error bodies follow RFC 9457 ("Problem Details for HTTP APIs") and are served as application/problem+json. The exception is 422 Unprocessable Content — see Validation errors below.
Attributes
type(string) A slug identifying the problem type, such asinvalid-parameterorproduct-not-found. Stable for a given kind of error; use it for programmatic branching rather than parsingdetail.title(string) A short, human-readable summary of the problem type. The same for every occurrence of a giventype.status(integer) The HTTP status code, repeated here so the body stands on its own.detail(string) A human-readable explanation specific to this occurrence of the problem.- Additional fields may appear depending on
type— for exampleinvalid-parameteraddsparam, naming the request field that failed validation, andmissing-scopeaddsrequired_scopes.
Handling errors
We recommend writing code that branches on the HTTP status code first, then on type for anything in the 4xx/5xx range, rather than parsing detail, which is meant for humans and may change wording over time.
Example error response
{
"type": "invalid-parameter",
"title": "Invalid parameter",
"status": 422,
"detail": "Quantity must be greater than or equal to 0.",
"param": "items.0.quantity"
}
Validation errors
A 422 for a malformed request body or query parameters doesn't follow the type/title/status/detail shape above. Instead it's served as application/json with a detail array, one entry per failed field:
{
"detail": [
{
"loc": ["body", "items", 0, "quantity"],
"msg": "Input should be greater than or equal to 0",
"type": "greater_than_equal"
}
]
}
loc(array) The path to the failing field, as alternating keys and indices starting withbody,query, orpath.msg(string) A human-readable explanation of the failure.type(string) A machine-readable validation failure code, such asgreater_than_equalormissing.
Best practices
- Check the HTTP status code first, then branch on
typefor anything in the4xx/5xxrange. - Retry
429and5xxresponses with exponential backoff; don't retry other4xxerrors without changing the request. - For idempotent writes (such as setting or adjusting inventory), reuse the same per-item
idempotency_keywhen retrying so it isn't applied twice. - Log the request ID from failed responses — it's the fastest way for support to look up what happened.
HTTP Status Code Summary
| Code | Status | Description |
|---|---|---|
| 200 | OK | Everything worked as expected. |
| 204 | No Content | The request succeeded and there's nothing to return. |
| 207 | Multi-Status | A batch request was accepted; check each item's own status in the response body. |
| 400 | Bad Request | The request was malformed. |
| 401 | Unauthorized | No valid API token was provided. |
| 403 | Forbidden | The token's scopes, or the seller's enrollment, doesn't permit this request. |
| 404 | Not Found | The requested resource doesn't exist. |
| 405 | Method Not Allowed | The HTTP method isn't supported on this path. |
| 409 | Conflict | The request conflicts with the resource's current state. |
| 422 | Unprocessable Content | The request's parameters failed validation. |
| 429 | Too Many Requests | Too many requests hit the API too quickly. Back off and retry. |
| 500, 503 | Server Errors | Something went wrong on Whatnot's end (these are rare). |
Problem Types
| Type | Description |
|---|---|
invalid-parameter |
A request parameter failed validation. |
invalid-product |
The product described in the request can't be created or updated as given. |
missing-scope |
The token lacks every scope that would authorize this request. |
product-not-found |
No product exists with the given ID. |
product-not-deletable |
The product can't be deleted in its current state. |
seller-not-approved |
The seller isn't approved to create or update products. |
merchandising-rejected |
The requested merchandising change can't be applied to the product. |
variant-not-found |
No variant exists with the given ID. |
variants-disabled |
Variant reads or updates aren't enabled for this seller. |
inventory-writes-disabled |
Inventory writes aren't enabled for this seller. |
variant-batch-rejected |
A batch variant update had invalid variants and allow_partial_updates was false, so none were applied. |
shipment-not-found |
No shipment exists with the given ID. |
shipment-item-not-found |
No shipment item exists with the given ID. |
label-generation-rejected |
The shipment's state, settings, or seller setup prevents label generation. |
seller-verification-required |
The seller must complete verification before this action is allowed. |
tracking-code-not-allowed |
The seller can't supply their own tracking code for this shipment. |
tracking-code-rejected |
The order items can't be moved onto one shipment with the given tracking code. |
invalid-tracking-code |
The supplied tracking code failed validation. |
dimension-profile-not-found |
No dimension profile exists with the given ID. |
show-not-found |
No show exists with the given ID. |
order-not-found |
No order exists with the given ID. |
order-not-cancellable |
The order can't be cancelled in its current state. |
order-item-not-found |
No order item exists with the given ID. |
disconnect-failed |
Disconnecting the app's installation failed; try again. |
malformed-request |
The request couldn't be parsed. |
unauthenticated |
No valid API token was provided. |
endpoint-not-found |
No route matches this path. |
method-not-allowed |
No route matches this path and method. |
rate-limited |
Too many requests hit the API too quickly. |
service-unavailable |
The service is temporarily unavailable. |
internal-error |
An unexpected failure occurred; the cause is logged on our end but not returned to callers. |
about:blank |
An HTTP error with no Seller API-specific problem type. |