Errors
The ErrorResult envelope, the status codes the API returns and how to report a problem.
When a request fails, the API answers with a 4xx or 5xx status and a JSON body called ErrorResult. The shape is the same for every endpoint.
The error body
Deleting a document that other records still depend on:
curl -X DELETE https://<your-instance>/api/documents/orders/internet/8841 \
-H "Authorization: Bearer $ACCESS_TOKEN"HTTP/1.1 400 Bad Request
Content-Type: application/json{
"messages": ["Document cannot be deleted"],
"exception": "Document cannot be deleted",
"errorId": "5f0c2a4e-6f43-4c0b-9a55-0d5b8f1f3c21",
"supportMessage": "Provide the ErrorId 5f0c2a4e-6f43-4c0b-9a55-0d5b8f1f3c21 to the support team for further analysis.",
"statusCode": 400
}| Field | Type | Meaning |
|---|---|---|
messages | string[] | Human-readable reasons, in English. A validation failure lists one entry per violation, so show or log all of them. |
exception | string | Short technical message behind the failure. For diagnostics only. |
source | string | Component that raised the error. Sent only when the caller is an administrator, so do not depend on it. |
errorId | string | Unique id of this one failure. Quote it when you contact support. |
supportMessage | string | A ready-made sentence that tells a user how to report the failure. |
statusCode | number | The HTTP status code, repeated in the body. |
code | string | Stable machine-readable code. Present only on some failures, see below. |
params | object | Values that belong to code, as string key and string value pairs. |
As everywhere in the API, a field without a value is left out.
Validation errors list everything at once
The server validates the whole request before it writes anything. If you create an order without a customer and without a warehouse, you get both problems in one response:
{
"messages": ["CustomerId is required for new order.", "WarehouseId is required for new order."],
"statusCode": 400
}(Shortened; the other fields are present as above.)
code and params
Most errors carry only messages. A failure gets a code when a client is expected to react to that specific situation in its own way, for example by showing its own translated text. params then holds the values to put into that text.
- If
codeis present, branch on it. Do not parsemessages. - If
codeis absent, show your own generic error message and logmessagesanderrorId.
When a coded validation failure covers several violations, the body also has an errors array with one code, message and params per violation.
Status codes
| Status | Meaning | What to do |
|---|---|---|
400 Bad Request | The request is invalid or the operation is not allowed in the current state. messages lists every violation. | Fix the request. Retrying unchanged will fail again. |
401 Unauthorized | The access token is missing or expired. | Get a new token and repeat the call once. |
403 Forbidden | The role of your client lacks the permission the endpoint needs. | Ask WinShop support to adjust the role. |
404 Not Found | The resource, or the route, does not exist on this instance. | Check the id. If the whole endpoint is missing, the instance may run an older release. |
409 Conflict | The request conflicts with the current state of the resource. | Read the resource again and decide whether to repeat the call. |
429 Too Many Requests | You hit a rate limit, in practice on the token endpoint. | Wait for the seconds given in Retry-After. |
499 | You closed the connection before the server finished. You normally see this only in logs. | Raise your client timeout or request less data per call. |
500 Internal Server Error | A failure on the server. | Retry later with a delay, and send the errorId to support if it persists. |
Handling errors in code
using System.Net.Http.Json;
var response = await http.DeleteAsync("/api/documents/orders/internet/8841");
if (!response.IsSuccessStatusCode)
{
var error = await response.Content.ReadFromJsonAsync<ErrorResult>();
if (error?.Code is not null)
{
// a failure you are expected to handle: branch on error.Code
}
throw new InvalidOperationException(
$"WinShop API {(int)response.StatusCode}: {string.Join("; ", error?.Messages ?? [])} (errorId {error?.ErrorId})");
}
record ErrorResult(
List<string> Messages,
string? Exception,
string? Source,
string? ErrorId,
string? SupportMessage,
int StatusCode,
string? Code,
Dictionary<string, string>? Params);Reporting a problem
Write to [email protected] and include:
- the
errorIdfrom the response, - the instance address, the HTTP method and the path,
- the time of the request.
With the errorId, support can find the exact failure in the server log.