Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.retailgrid.io/llms.txt

Use this file to discover all available pages before exploring further.

Status codes

StatusMeaningWhen you see it
200 OKSuccessGET, PATCH, and /bulk responses
201 CreatedResource createdPOST /v1/<entity>/{entity_id} and POST /v1/competitor_prices
202 AcceptedJob queuedPOST /v1/imports/* returning a JobHandle
204 No ContentSuccess, no bodyDELETE /v1/<entity>/{entity_id}
401 UnauthorizedAPI key missing, malformed, or rotatedAuth header issue - see Authentication
404 Not FoundThe path’s entity_id is unknownPatching or deleting a non-existent row
422 Unprocessable EntityValidation failedBad payload shape, missing required field, type mismatch
429 Too Many RequestsRate limit hitBack off and retry per Retry-After
5xxServer errorRetry with exponential backoff; if persistent, contact support

Validation error shape

When a request fails schema validation, the API returns a 422 with an HTTPValidationError body:
{
  "detail": [
    {
      "loc": ["body", "items", 0, "regular_price"],
      "msg": "field required",
      "type": "missing"
    },
    {
      "loc": ["body", "items", 1, "observed_at"],
      "msg": "input should be a valid datetime",
      "type": "datetime_parsing"
    }
  ]
}
Each entry in detail is a ValidationError:
  • loc - JSON path to the offending field, including array indices.
  • msg - human-readable message.
  • type - machine-readable error code (e.g., missing, string_too_long, value_error).

Bulk endpoints: per-item errors

/bulk endpoints return 200 OK even when individual rows fail. Per-row failures are reported inside BulkResponse.results rather than as a top-level error:
{
  "results": [
    { "index": 0, "ok": true,  "id": "1c2d..." },
    { "index": 1, "ok": false, "code": "validation_error", "message": "product_name too long" }
  ]
}
Always iterate results and check ok. A 200 does not mean every row was written.

Common 422 cases by endpoint family

  • Products / variants - missing product_id, missing sku on a variant create, product_id referencing an unknown product on a variant.
  • Transactions - missing product_id, malformed transaction_timestamp, decimal field that can’t parse.
  • Competitor prices - missing one of the four required fields (competitor_name, observed_at, regular_price, effective_price).
  • Imports (CSV) - file not attached, file empty, file not UTF-8, header row missing.

Retry strategy

  • Idempotent endpoints (POST /v1/<entity>/{entity_id}, PATCH, DELETE, /bulk) - retry on 5xx and on transport errors with exponential backoff (start at 1s, cap at 30s, max 5 attempts).
  • POST /v1/competitor_prices - this is a non-idempotent create (no path id). Retrying after a successful response will create a duplicate row. Check the network outcome before retrying.
  • Async imports - if POST /v1/imports/* fails, retry the upload. If it succeeds and the subsequent job fails, fix the CSV and submit a fresh job rather than retrying the same upload.