Inventory Pro
Skip to main content

Contents

api

Errors

Errors

When a request fails, the API returns a consistent JSON error object regardless of the endpoint. The HTTP status code indicates the category of failure; the body provides specifics.

Error Shape

{
  "statusCode": 400,
  "error": "validation_error",
  "message": "Model validation failed.",
  "details": {
    "itemID": ["The itemID field is required."],
    "units": ["The field units must be greater than 0."]
  }
}
FieldTypeDescription
statusCodeintegerHTTP status code (mirrors the response status)
errorstringMachine-readable error code (see table below)
messagestringHuman-readable description of what went wrong
detailsobject or nullField-level validation errors (only present for validation failures)

The details object maps field names to arrays of error messages. It is only present when the error code is validation_error.

Error Codes

CodeHTTP StatusMeaning
bad_request400Request is malformed or missing required data
validation_error400One or more fields failed validation (see details)
unauthorized401Authentication is missing or the token is expired
forbidden403Authenticated but lacking permission (enforced; see Authentication)
not_found404The requested resource does not exist
conflict409Request conflicts with current state (e.g., duplicate ShortID)
rate_limited429Too many requests — slow down and retry
not_implemented501Endpoint exists but the operation is not available
internal_error500Unexpected server error

HTTP Status Codes

StatusWhen You’ll See It
200 OKSuccessful read or update
201 CreatedResource successfully created
400 Bad RequestInvalid input, missing fields, malformed JSON
401 UnauthorizedNo token, expired token, or invalid token
403 ForbiddenAuthenticated but action not allowed (enforced; see Authentication)
404 Not FoundResource ID doesn’t exist
409 ConflictDuplicate or state conflict
429 Too Many RequestsRate limit exceeded
500 Internal Server ErrorServer-side failure (report to your administrator)

Validation Errors

When you submit invalid data, the API returns a 400 with field-level detail:

curl -X POST https://your-host/api/v2/Item \
  -H "Authorization: Bearer ..." \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "statusCode": 400,
  "error": "validation_error",
  "message": "Model validation failed.",
  "details": {
    "itemID": ["The itemID field is required."]
  }
}

Fix the flagged fields and retry.

Permission Errors

Every endpoint enforces action permissions. Each resource requires a specific permission (Security ID); if your integration user’s group lacks it, the API returns 403 Insufficient permissions. Accounts marked read-only receive 403 on all write verbs. Warehouse writes outside your assigned scope return 403; note that read endpoints are not warehouse-scoped — a scoped integration user can read inventory data across all warehouses. Unauthenticated requests return 401.

Response shapes for errors: permission, read-only, warehouse-scope, and report-access rejections (403) return a reduced body with statusCode and message only. 401 Unauthorized responses have no JSON body at all — check the status code and the WWW-Authenticate: Bearer header. The full four-field envelope (statusCode, error, message, details) applies to validation (400) and internal errors (500).

A permission failure has this shape:

{
  "statusCode": 403,
  "error": "forbidden",
  "message": "Insufficient permissions."
}

Rate Limit Errors

{
  "message": "Rate Limit Exceeded. <limit>"
}

Note: The rate limit response uses a simpler format than the standard error envelope, and the message names whichever limit was hit (e.g., requests per second, per minute, or per hour). Limits are configured per client — contact us for the limits on your subscription. Back off and retry after a reasonable interval (30–60 seconds).

Handling Errors in Code

var response = await client.PostAsync(url, content);
if (!response.IsSuccessStatusCode)
{
    var body = await response.Content.ReadAsStringAsync();
    var error = JsonConvert.DeserializeObject<ApiError>(body);

    switch (error.Error)
    {
        case "validation_error":
            // Fix the fields listed in error.Details
            break;
        case "rate_limited":
            // Wait and retry
            break;
        case "unauthorized":
            // Token expired — refresh and retry
            break;
        default:
            // Log and alert
            break;
    }
}
$response = Invoke-WebRequest -Uri $url -Method Post -Body $json `
    -Headers @{ Authorization = "Bearer $token" } `
    -ContentType "application/json" -ErrorAction SilentlyContinue

if ($response.StatusCode -ge 400) {
    $error = $response.Content | ConvertFrom-Json
    Write-Warning "$($error.error): $($error.message)"
}