Errors

Every error uses the same envelope with a stable code, a message, optional validation and repair details, and the request id.

Envelope

{
  "error": {
    "type": "validation_error",
    "code": "validation_failed",
    "message": "Request validation failed.",
    "param": "type",
    "errors": [{ "path": "type", "message": "Use types instead." }],
    "suggestedAction": "replace_param",
    "repairCategory": "unknown_param",
    "documentationPath": "/api/v1/openapi.json",
    "doNotRetrySameRequest": true,
    "requestId": "request-id"
  }
}

Keep the requestId for debugging.

Repair metadata

Errors can include machine-readable repair fields, including write-readiness, impact details, Current Source state, and Price Book value or plan context. Treat them as the next-request plan, not as hints that relax the documented request.

FieldUse it for
repairCategoryClassify the failure, such as unknown_param, invalid_enum, unsupported_sync_filter, standalone_status, invalid_window, or rate_limited.
suggestedActionChoose the next action, such as add_required_filter, replace_param, choose_valid_value, pair_date_window, narrow_filter, wait_and_retry, or stop_and_fix_request.
validValuesUse only accepted values for the named parameter.
acceptedFiltersPick one of the endpoint's supported narrowing filters instead of inventing a broad sync request.
requiredCombinationSend the fields together, such as paired date-window parameters.
maxWindowDaysSplit changed-record discovery windows that are too wide.
documentationPathOpen /api/v1/openapi.json or /llms.txt for the exact contract guidance.
exampleShape the corrected request with an endpoint-specific example.
doNotRetrySameRequestChange the request before retrying. Do not loop the identical request.
writeReadinessReview machine-readable readiness details when a write request fails validation or policy checks.
impactAnalysisInspect product or product-family impact details before retrying a constrained catalog write.
repairContextReview the rule, expected and received values, a safe read path, and any visible affected Price Book entry ids before correcting the request.

For example, if /search rejects type, replace it with types. If /contacts rejects a broad list request, provide parentType and parentId. If /orders or /purchase-orders rejects standalone status, pair it with an exact identifier or a bounded date window.

Common codes

CodeCaller action
invalid_api_keyCheck the environment value and bearer header format.
api_key_revokedStop and request a new key.
api_key_expiredStop and request a new key.
api_actor_inactiveStop and issue a key to an active user.
missing_scopeUse a key with the required scope.
missing_permissionUse an acting user with the required ShelfCycle permission.
rate_limitedWait for Retry-After or retryAfterSeconds. Retry POSTs with the same idempotency key.
validation_failedFix the field named in param or errors[].
finder_filter_requiredAdd a supported narrowing predicate before retrying a root finder.
unsupported_sync_filterRemove unsupported sync-style filters such as updatedSince. Reference directory and child-list routes use their documented cursor paging. For sales orders and purchase orders, use paired changedFrom/changedTo for bounded changed-record discovery.
not_foundRe-search and confirm the id. Cross-org, unsupported, archived, or invisible records can also return not_found.
idempotency_key_requiredSend a stable Idempotency-Key for POST requests.
idempotency_key_reusedRetry with the original body or choose a new key for a new source event.
duplicate_customerUse the existing customer or change the source data before retrying.
duplicate_supplierUse the existing supplier or change the source data before retrying.
duplicate_productUse the existing product or change product setup references before retrying.
duplicate_familyUse the existing product family or change the family identity before retrying.
duplicate_contactUse the existing contact or change the source data before retrying.
duplicate_customer_location, duplicate_customer_address, duplicate_supplier_ship_from_locationUse the existing child record or change source identity/address data before retrying.
duplicate_documentUse the existing attached document or change the source URL before retrying.
stale_recordRefresh context before retrying.
stale_price_book_planRun a new Price Book preview and review its affected entries before applying the update.
stale_current_cost_sourceRead Current Source again, review the supplier-and-origin change, and retry with the returned expected supplier and ship-from location ids.
cost_ship_from_location_not_visibleChoose an active ship-from location belonging to the selected supplier and visible organization.
cost_book_base_ambiguousReview the supplier's general Cost Book entry before creating a constructed cost.
cost_source_ambiguousReview the returned supplier choices and retry product cost context with an explicitly selected supplierId.
current_cost_source_unavailableReview the product's Current Source state, then replace or clear the selected supplier-origin combination before relying on product-only cost context.
fixed_product_source_authorityUse the fixed supplier shown by the Current Source read instead of selecting a variable-product Current Source.
invalid_price_precision, nonpositive_price, unsupported_price_basis, unsupported_price_uom, foreign_currency_write_not_supportedUse repairContext and the corrected example to send an exact positive value with the product's base unit, an accepted basis, and the organization's base currency.
reference_packaging_required, reference_packaging_not_visible, reference_packaging_uom_mismatchResolve an active reference package for the selected variable product and match its base unit before retrying.
archived_recordDo not write to archived records.
unsupported_linked_recordRemove unsupported records. Orders and purchase orders are context, not note subjects or links.
not_api_createdDo not patch that note through the public API.
primary_change_unsupported, address_role_requiredRemove primary switching from customer location requests, or keep customer addresses marked billing or shipping.
unsupported_product_field, unsupported_family_field, invalid_variable_qty, reference_visibility_blockedKeep product setup inside the public contract, use quantity 1 for variable packaging, and verify referenced records are visible.
document_url_invalid, document_url_cross_org, unsupported_document_fieldSend only fileName and an HTTPS URL that belongs to the authenticated org when it points at a ShelfCycle bucket.
unsupported_document_type, document_too_large, document_checksum_invalid, upload_integrity_invalidChoose a supported file, keep it at or below 15 MiB, and request a new upload using the file's actual size, content type, and SHA-256 checksum.
upload_not_foundComplete the returned file upload, then retry the same attachment or SDS request.
upload_verification_unavailableRetry the same attachment or SDS request later.
blocked_order_sensitive_updateChange only allowed metadata fields, or leave order-sensitive product identity, packaging, and supplier fields unchanged.

On dryRun=true, HTTP 200 can still return data.status: "blocked". Inspect blocked checks such as duplicate_candidate_found, idempotency_target_missing, idempotency_key_required, idempotency_key_reused, stale_record, archived_record, target_not_found_or_not_visible, unsupported_profile_shape, primary_change_unsupported, address_role_required, product_family_reference_active, product_packaging_reference_active, supplier_reference_active, reference_visibility_blocked, order_sensitive_update_blocked, unsupported_linked_record, not_api_created, or validation_failed before execution.

Rate limits

Default private v1 limits are 60 read requests per minute per key and endpoint, and 20 write requests per minute per key and endpoint.

Authenticated requests that reach the rate-limit check include the complete active window:

  • X-RateLimit-Limit: the request allowance for the current key, endpoint, and rate-limit family.
  • X-RateLimit-Remaining: requests remaining after the current request.
  • X-RateLimit-Reset: the Unix time in seconds when the active window resets.

On 429 rate_limited, the same window headers remain available and Retry-After reports how many seconds to wait. Retry a POST with the same idempotency key and unchanged body.

Guardrail

Stop on stale, duplicate, missing access, unsupported sync, revoked, expired, archived, or rate-limit errors. Do not keep retrying without new information.