{"versions":[{"version":"2.5.0","released":"2026-04-26","changes":["`GET /pick_lists/{id}?expand=equipment,category` and `GET /pick_lists?expand=items,equipment,category` now nest the equipment_categories record (id, name, color) one level deeper than the equipment object, so a single call returns the full case + dims + category breakdown. Saves a per-line `GET /equipment/{id}?expand=category` round-trip when integrators want to color-code or group cases by category.","`category` is opt-in and only takes effect when `equipment` is also requested (and `items` on the list endpoint). Existing consumers continue to receive only `category_id` on the equipment object, no breaking changes."]},{"version":"2.4.0","released":"2026-04-25","changes":["`GET /pick_lists/{id}?expand=equipment` and `GET /pick_lists?expand=items,equipment` now nest the full equipment record (name, brand, category_id, case_length_in, case_width_in, case_height_in, weight_lbs, daily_rate) under each pick-list item. Cuts a typical TruckPacker load plan from N+1 calls (`/pick_lists/{id}` + one `/equipment/{id}` per line) down to a single request.","`equipment` is opt-in and only takes effect when `items` is present (or implicitly on the detail endpoint where items are always inlined). Existing consumers continue to receive `equipment_id` only, no breaking changes."]},{"version":"2.3.0","released":"2026-04-23","changes":["Write coverage for pick lists: `PATCH /pick_lists/{id}` (update status / name / notes / archived). Typical TruckPacker flow: flip `status` from `draft` → `in_progress` when packing starts, then to `packed` or `complete` when done.","Full CRUD on pick list items: `POST /pick_list_items` (add an on-site case, provide either `equipment_id` or `custom_description`), `PATCH /pick_list_items/{id}` (advance `stage` `pending` → `checked` → `staged` → `loaded` → `installing` → `installed`, update quantity/notes), `DELETE /pick_list_items/{id}`. All gated by the `pick_lists:write` scope introduced in 2.2.0.","Cross-tenant safety: every write verifies `pick_list_id` / `equipment_id` resolve within the caller's org before inserting/updating, matching the pattern used by quotes + reservations."]},{"version":"2.2.2","released":"2026-04-23","changes":["Fixed: `GET /equipment?expand=category` and `GET /equipment/{id}?expand=category` actually return the inlined category object now. The expand parameter was documented in 2.1.2 but the list + detail handlers were hardcoding the select string and silently ignoring it, so callers saw `category: null` even when the equipment row had a valid `category_id`. No change needed on the integrator side, add `?expand=category` and you get `{id, name, color}` back."]},{"version":"2.2.1","released":"2026-04-23","changes":["Added `GET /equipment_reservations` (list) and `GET /equipment_reservations/{id}` (detail) so integrators can re-hydrate a truck-pack plan on reopen instead of reconstructing state from POST responses. List supports `?event_id`, `?vehicle_id`, `?status` filters and `?expand=equipment,event,vehicle`. Same `equipment_reservations:read` scope as before."]},{"version":"2.2.0","released":"2026-04-23","changes":["Added `GET /pick_lists` and `GET /pick_lists/{id}` so integrators (TruckPacker) can pull the case/equipment manifest for a job in one call. `?event_id=<job_id>` filters to a single job; `?expand=event,items` inlines relations on the list endpoint; `/pick_lists/{id}` always returns the full `items` array without expand.","New scopes `pick_lists:read` and `pick_lists:write` added to the API-key whitelist. The new GET endpoints also accept `events:read` or `jobs:read` for backward compatibility, so existing keys continue to work without re-minting.","OpenAPI spec adds `PickList` and `PickListItem` schemas documenting every field, including container hierarchy (`is_container`, `container_id`, `parent_item_id`) and serial-number arrays."]},{"version":"2.1.2","released":"2026-04-18","changes":["`GET /equipment?expand=category` and `GET /equipment/{id}?expand=category` now include `color` (hex code) on the expanded category object. Enables integrations like TruckPacker to color-code cases by category without a separate lookup.","OpenAPI spec adds a `Category` schema documenting the expanded shape (`id`, `name`, `color`). No breaking changes."]},{"version":"2.1.1","released":"2026-04-18","changes":["`/equipment` list and detail now return physical dimensions (`case_length_in`, `case_width_in`, `case_height_in`) and `weight_lbs`. These are required inputs for load planning and were previously only queryable directly in the database.","OpenAPI schema updated with the new Equipment properties. No breaking changes; existing consumers that ignored unknown fields continue to work."]},{"version":"2.1.0","released":"2026-04-18","changes":["Added `GET /vehicles` and `GET /vehicles/{id}` so integrators can discover the assignable Stagera fleet before importing pick lists.","Equipment reservations now support structured vehicle assignment with `vehicle_id` and `truck_position` instead of forcing truck placement into free-text notes.","Reservation readbacks now expose vehicle assignment fields, including event expansions that include `equipment_reservations`.","Vehicle assignment is limited to vehicles in the caller's organization with `status = available`."]},{"version":"2.0.0","released":"2026-04-17","changes":["Renamed public namespace to /api/v2/* (previous /api/v1/* was never in external use).","Full read coverage: events, jobs (alias), clients, equipment, quotes (with line_items), invoices (with line_items), crew_members.","Full write coverage: POST+PATCH for events, clients, crew_members, quotes, invoices; POST+PATCH+DELETE for equipment_reservations.","Auto-generated quote_number and invoice_number on writes when omitted (uses existing Stagera RPCs).","API key auth with 14-scope enforcement plus legacy jobs:read accepted for backward-compat.","Expandable relations: ?expand=client,event,equipment,equipment_reservations on supported endpoints.","Cursor pagination with (created_at, id) tie-breaker.","Per-org rate limiting via GitHub-style X-RateLimit-* headers (1000 req/min default).","Idempotency-Key on every write (24h TTL). Replay returns cached response; mismatched body returns 409.","Sandbox mode: stg_test_* keys flag writes is_demo_data=true; set DEMO_ORG_ID to route to dedicated demo org.","Observability: api_request_logs (90d retention) + PostHog emit when POSTHOG_API_KEY is set.","OpenAPI 3.1 spec at /api/v2/openapi.json + Scalar interactive docs at /api/v2/reference.","Deprecation policy published: breaking changes ship under /api/v3/* with a 6-month overlap window."]},{"version":"2.0.1","released":"2026-04-17","changes":["Write-path error handling: Postgres unique-constraint violations (error code 23505) now return 409 `duplicate_record` with a tailored message (e.g. 'This equipment is already reserved for this event') instead of 500 `internal_error`.","FK violations (23503) return 422 `validation_error` instead of 500.","Write handlers no longer echo raw Postgres error text to the client; the detail is logged internally. Integrators: check `error.code` to route, not `error.message`."]}],"deprecation_policy":"/api/v2/* is stable. Breaking changes ship under /api/v3/* with a minimum 6-month overlap window. Deprecated endpoints return a Sunset header with the removal date and a Deprecation header with true.","contact":"support@stagera.ai"}