Skip to main content

Error Handling

The API uses standard HTTP status codes and returns structured error responses with actionable details.

Error response format

{
"error": {
"code": "INVALID_ADDRESS",
"message": "The destination address could not be validated",
"details": [
{ "field": "to.zip", "message": "Invalid ZIP code for state OR" }
]
}
}
FieldTypeDescription
error.codestringMachine-readable error code (see table below)
error.messagestringHuman-readable description
error.detailsarrayOptional field-level validation errors
error.details[].fieldstringJSON path to the invalid field
error.details[].messagestringWhat's wrong with the field

HTTP status codes

CodeMeaningRetry?
200Success--
201Created--
400Bad Request — invalid parametersNo — fix the request
401Unauthorized — missing or invalid API keyNo — check your API key
403Forbidden — insufficient permissionsNo — check your workspace permissions
404Not FoundNo — verify the resource ID
409Conflict — duplicate idempotency key with different bodyNo — use a new idempotency key
422Unprocessable Entity — valid JSON but business rule violationNo — see error details
429Too Many Requests — rate limit exceededYes — after retryAfter seconds
500Internal Server ErrorYes — with exponential backoff
502Bad Gateway — carrier API unavailableYes — after 30 seconds
503Service UnavailableYes — after 60 seconds

Error codes and resolution

CodeHTTPDescriptionHow to fix
INVALID_ADDRESS422Address validation failedVerify street, city, state, and ZIP match. Use POST /v1/addresses/validate first.
CARRIER_UNAVAILABLE502Carrier API is temporarily downRetry after 30 seconds. If persistent, try a different carrier.
RATE_NOT_FOUND404No rates for this lane/parcelCheck carrier supports the origin/destination pair. Verify parcel weight/dimensions.
LABEL_ALREADY_CANCELLED409Label has already been voidedNo action needed — label is already cancelled.
WEIGHT_EXCEEDS_LIMIT422Parcel exceeds carrier weight limitReduce weight or use a carrier with higher limits (FedEx/UPS: 150 lb, USPS: 70 lb).
CUSTOMS_REQUIRED422International shipment missing customsAdd a customs object with contentsType, items[] (description, quantity, value, HS code).
INSUFFICIENT_BALANCE402Wallet balance too lowFund your wallet in the Dashboard, or enable auto-recharge.
INVALID_SERVICE400Carrier does not offer this service codeUse GET /v1/carriers/:code to list available services.
DUPLICATE_SHIPMENT409Same idempotency key with different request bodyUse a unique Idempotency-Key for each distinct request.
DIMENSION_REQUIRED422Carrier requires dimensions for this serviceAdd lengthIn, widthIn, and heightIn to the parcel object.
HAZMAT_NOT_SUPPORTED422Carrier/service does not support hazardous materialsUse a service that supports hazmat (e.g., FedEx Ground).
VOID_WINDOW_EXPIRED422Label can no longer be cancelledThe carrier's void window has passed. Contact support for manual cancellation.

Handling errors in SDKs

All FlexOps SDKs throw typed exceptions that map to error codes:

import { FlexOpsClient, RateLimitError, FlexOpsError } from '@flexops/sdk';

try {
const label = await client.labels.create({ ... });
} catch (err) {
if (err instanceof RateLimitError) {
// Retry after err.retryAfter seconds
await sleep(err.retryAfter * 1000);
} else if (err instanceof FlexOpsError) {
console.error(`${err.code}: ${err.message}`);
// err.details contains field-level errors
}
}