Skip to content

Changelog

Each heading is a release tag. GET /health reports the same version without the v prefix (v1.21.0 here is 1.21.0 there). Entries before v1.20.0 were renumbered from an earlier, independent scheme.

Released: October 2026

  • get_entity also accepts type as another name for entity_type.

Released: October 2026

  • MCP tools accept a few more common ways of passing purchase-order status filters and entity ids.

Released: October 2026

  • MCP sign-in now works with more AI tools that discover sign-in settings automatically.

Released: September 2026

  • Simplified naming: create_purchase_order/update_purchase_order now document only lines (not line_items), and list_entities now documents only location (not warehouse) for its entity type. Both old names still work if you’re already using them.

Released: September 2026

  • Enum-valued parameters (entity_type, status, metrics, order_types, expand, format, and others) now accept any letter-casing, not just the documented one.
  • MCP tool enum values (entity types, statuses, order types, and similar) are now uniformly lower-case instead of a mix of upper- and lower-case. Old upper-case values are still accepted as input.
  • receive_po_units and receive_transfer_units lines give a clearer error when sent received_units — use received_quantity instead.
  • list_entities accepts "warehouse" as an alias for the location entity type.
  • search_purchase_orders’s status filter accepts a single status as well as a list.
  • search_inventory’s metrics filter gives a clearer error naming the current metric name when sent a retired one (e.g. days_of_stock, lead_time_to, re_order_status).
  • create_purchase_order and update_purchase_order now accept line_items as an alias for lines.

Released: September 2026

  • New receive_transfer_units write tool: record received quantities against stock-transfer lines, mirroring receive_po_units for PO lines.
  • receive_units is renamed to receive_po_units. receive_units is still accepted as a deprecated alias until a future release; calls made through the alias are now audit-logged under receive_po_units, not receive_units.
  • receive_po_units and receive_transfer_units lines accept two new optional fields: mark_as_received (receive the full confirmed quantity in one shot) and is_closed (close a line without changing its received quantity, e.g. a short-close).

Released: September 2026

  • New update_forecast_plan write tool: apply manual overrides to demand-plan cells. dry_run=true returns the current value, the proposed value and the delta for every cell before anything is written.

Released: September 2026

  • New stock-transfer tools: search_transfers, create_transfer and update_transfer. Transfer ids are prefixed tr_… and transfer lines tprt_…; get_entity and get_change_history accept them. get_entity returns a transfer with its lines, and update_transfer also moves a transfer’s status.
  • Purchase-order lines are keyed by line_id instead of order_part_id, in both inputs and responses. order_part_id is still accepted when sent to the server until the next release.
  • update_purchase_order, receive_units and export_purchase_order take purchase_order_id instead of po_id. po_id is still accepted when sent to the server until the next release.
  • Purchase orders and stock transfers now use the same words throughout: lines, ordered_units, received_units, delivery_window and is_late.
  • get_change_history detail rows use line_id / line_ids instead of order_part_id / part_ids, for both purchase orders and stock transfers.

Released: September 2026

  • MCP: the tool list now advertises a 5-minute cache lifetime, so clients that support it pick up tool schema changes sooner.

Released: September 2026

  • Fixed the total row count reported by MCP search_inventory when filtering on stock_health or stock_health_projected.

Released: September 2026

  • Error responses always include their JSON body.
  • MCP search_inventory docs now explain how stock_health filters behave at SKU and product level.

Released: September 2026

  • Breaking: stock_health and stock_health_projected values are product labels. stock_health is now NO_STOCK, BELOW_SAFETY_STOCK, OVER_SAFETY_STOCK or OVER_DAYS_OF_COVER; stock_health_projected is STOCKOUT_LIKELY, AT_RISK, NO_RISK or OVERSTOCK_RISK. The new labels apply everywhere the fields appear, in rows, filters and change-history diffs.
  • Breaking: days_of_stock is now days_left. The metric, the response key and the filter/sort fields all move: days_of_stock_min / days_of_stock_max become days_left_min / days_left_max.
  • Breaking: re_order_status is now reorder_status on the MCP surface. The REST API field is unchanged and still spelled re_order_status.
  • Breaking: update_sku_settings’ max_days_of_cover is now days_of_cover. Change-history diffs name it the same way.
  • Breaking: expected_delivery_date is now confirmed_delivery_date. It moves on PO rows and lines, on the create_purchase_order parameter, on the update_purchase_order line patch field, and in change-history diffs.
  • Breaking: purchase-order line writes take ordered_units, not quantity. Both create_purchase_order’s lines[].quantity and update_purchase_order’s patch.lines[].quantity are now ordered_units, as are the update_purchase_order dry-run diff and the applied[].applied_updates echo.

Rename these in existing calls — the old names and values are not accepted.


Released: September 2026

  • GET /health and the OpenAPI document now report the deployed release version. Changelog versions below are renumbered to match release tags.

Released: September 2026

  • Breaking: warehouses are called locations across the whole MCP surface. create_purchase_order’s warehouse_id parameter is now location_id, search_forecasts’ warehouse_ids is location_ids, search_inventory’s warehouse_id / warehouse_name filter fields are location_id / location_name and its sku_warehouse granularity is SKU_LOCATION. The WAREHOUSE value becomes LOCATION in find_entity(types=…), list_entities(entity_type=…), get_entity(entity_type=…), search_forecasts(group_by=…) and get_change_history(entity_type=…), where WAREHOUSE_TRANSFER also becomes LOCATION_TRANSFER. Responses follow: rows and PO lines carry location_id / location_name, PO rows carry location_names, a PO summary reports distinct_locations, receive_units’ stock_movements name the location, and get_entity(LOCATION) returns is_logical_location / child_locations. Rename these in existing calls — the old names are not accepted.
  • Breaking: the wh_ id prefix is now loc_. Location ids are returned with the loc_ prefix and must be passed back in that form; an id sent with the old wh_ prefix is rejected with a validation error naming loc_. The ids themselves are unchanged, so wh_… and loc_… refer to the same location.
  • Breaking: renamed fields and values. search_purchase_orders’ order_status parameter is now status, and PO rows carry status rather than order_status; PO rows and lines carry ordered_units (was quantity_confirmed), received_units (was quantity_received), expected_delivery_date (was confirmed_delivery_date) and recommended_units (was recommended_to_order). search_inventory’s name_like filter is now product_name (still matched with contains) and its lead_time_to metric/filter is now earliest_arrival_date. update_sku_settings’ min_days_on_hand / max_days_on_hand are now safety_stock_days / max_days_of_cover. get_entity(SUPPLIER) returns lead_time_days as a number (it was a "30 days" string) and shopify_vendors instead of vendors — those are Shopify’s per-product Vendor labels, not suppliers. get_entity(PRODUCT) returns re_order_status instead of the inverted non_replenishable. Change-history diffs use the same new names. Rename these in existing calls — the old names are not accepted.
  • Breaking: update_sku_settings no longer accepts status: active|discontinued. Pass re_order_status instead (discontinued is re_order_status: false); a patch still using status is rejected with a validation error naming it.
  • Breaking: search_inventory’s granularity values are uppercase. sku / sku_location / product are now SKU / SKU_LOCATION / PRODUCT. The response’s requested.granularity echoes the uppercase form, as do the drill_down specs on get_insights cards.
  • stock_health is available as a metric and a filter on search_inventory. It reports the app’s Stock status (now) — STOCK_OUT (No stock), AT_RISK (Below Safety Stock), HEALTHY (Over Safety Stock), EXCESS (Over Days of Cover) — at every grain, and is returned inline on get_entity(SKU) and get_entity(PRODUCT). At SKU and PRODUCT grain the row spans several locations, so the worst label wins.
  • search_inventory’s filters[].value now declares its accepted types. A string, number or boolean — or a list of those for in / not_in. Existing calls are unaffected.
  • Tool and field descriptions were rewritten in the product’s language. The advertised schema text differs throughout; behaviour is unchanged.
  • search_forecasts no longer reports a phantom aggregation downgrade. group_by_overridden is true only when a coarser grain than the one requested was returned.
  • search_forecasts really does cover the next 12 months. The window is the current calendar month plus the following 11, and requested reports it as months, start_date and end_date — the old horizon_days field is gone. A month with no forecast is omitted rather than returned as a zero.
  • Purchase orders no longer expose origin. It is gone from PO rows and from get_entity(PURCHASE_ORDER).
  • PO attachments and tags are shaped for callers. Attachments carry name, extension and uploaded_at; tags are a plain list of tag names.
  • search_inventory returns days_of_stock at PRODUCT granularity. It was always null there. Product rows now carry the {min, max} range across the product’s SKUs, the same shape as SKU grain, as does get_entity(PRODUCT).
  • receive_units refuses to receive against an unplaced PO. A receipt on a DRAFT, SENT_FOR_APPROVAL or APPROVED order now fails with a validation error naming the status and pointing at update_purchase_order(patch={status: 'ORDERED'}). Receipts against ORDERED and PARTIALLY_RECEIVED orders are unaffected.
  • get_change_history rows no longer carry reversible. To undo a change, apply the inverse with the relevant write tool.
  • export_purchase_order is no longer annotated read-only. Each call writes an export file, so readOnlyHint is now false; destructiveHint stays false and idempotentHint true. Clients that hide non-read-only tools behind a confirmation will now prompt for it.
  • A purchase order with no status reads as DRAFT. search_purchase_orders, get_entity(PURCHASE_ORDER), receive_units and update_purchase_order all treat it that way.
  • search_forecasts supports group_by=LOCATION. Location-grouped calls return location-grain rows and no longer raise group_by_overridden.
  • PO lines report received_units. receive_units’ per-line applied rows report new_received_units to match.
  • Change-history diffs name SKU settings the way the tools do. A SKU settings change reads as lead_time_days, safety_stock_days, max_days_of_cover, re_order_status and moq, and an id inside a diff’s old / new values carries its type prefix, so it can be passed straight to get_entity.
  • get_entity(LOCATION) returns usable child location ids. Each child_locations entry carries location_id, with the loc_ prefix, alongside the child’s name.
  • search_inventory rejects a filter value of the wrong type for its field. Numeric fields require a number, re_order_status a boolean, and id / text / status fields a string, with a validation error naming the field. Date fields are unchanged — they take ISO strings.
  • update_sku_settings dry-run output is trimmed. Preview rows carry patch, sku_count, sku_ids and unsupported_fields only.

Released: September 2026

  • list_entities’s entity_type and find_entity’s types no longer advertise values that always errored. list_entities(entity_type=…) no longer lists SKU, PRODUCT or PURCHASE_ORDER — use search_inventory or search_purchase_orders instead; find_entity(types=…) no longer lists PURCHASE_ORDER — use search_purchase_orders or get_entity. Callers already avoiding those values are unaffected.
  • search_purchase_orders: internal_status and origin removed. Which orders are returned is unchanged. Neither has a replacement.
  • search_purchase_orders: date_from / date_to renamed to created_after / created_before. Both bound the PO’s creation date, not its delivery date. Behaviour is unchanged — rename the parameters in existing calls.
  • Purchase orders are named by name everywhere. create_purchase_order’s reference parameter and update_purchase_order’s patch.reference are now name, matching the name field the read tools have always returned for a PO.
  • update_purchase_order: delivery dates are now settable, per line. The header-level patch.expected_delivery_date and patch.confirmed_delivery_date fields have been removed; set a date with patch.lines[].expected_delivery_date on an update line. The PO-level delivery_window in read responses is derived from them.
  • update_purchase_order: patch.supplier_note renamed to patch.notes. It writes the PO’s notes — the same field create_purchase_order already called notes.
  • get_change_history covers more entity types. entity_type now also accepts SUPPLIER, WAREHOUSE, PRODUCT, WAREHOUSE_TRANSFER, STOCK_TAKE, SHIPMENT, FORECAST, FORECASTING_ENGINE and TAG. SUPPLIER, WAREHOUSE and PRODUCT take prefixed ids (sup_…, wh_…, prod_…); the others take the raw id shown in the feed’s entity_id.

Released: August 2026

  • Connecting https://mcp.prediko.io/mcp from Gemini now works. Other clients are unaffected.

Released: August 2026

  • POST /api/v1/orders accepts CONFIRMED and APPROVED. The status field previously allowed only DRAFT, PARTIALLY_RECEIVED and FULLY_RECEIVED, so an order that had been placed with a supplier but not yet received could only be sent as DRAFT. Re-sending such an order moved it back to draft in Prediko on every call, while the transfer already pushed to a connected store or WMS stayed in place. Send CONFIRMED for orders you have placed. Existing integrations are unaffected — the three previous values behave exactly as before.
  • An unrecognised status no longer resets a PO to draft. A status value Prediko cannot map now leaves an existing purchase order’s status untouched instead of downgrading it to DRAFT. New purchase orders still open as DRAFT.

Released: August 2026

  • Bug fixes. CANCELLED is no longer accepted on update_purchase_order or the search_purchase_orders status filter — Prediko has no cancelled state for a purchase order, so writing it always failed and filtering on it never matched anything.

Released: August 2026

  • Permission-aware tool calls: MCP tool calls now respect user permission profiles. A call that touches data the calling user’s permission profile does not allow now returns a code="permission" error with the message “Permission denied: your permission profile does not allow this action. Ask a workspace admin to update it.” instead of the previous behaviour. Rolling out gradually per workspace.

Released: August 2026

The MCP surface versions independently of the REST endpoints below; this change is listed here because it is customer-visible.

  • Stricter tool input validation. Every MCP tool’s input schema now declares "additionalProperties": false at the top level, so calls that include unknown top-level fields are rejected instead of having those fields silently ignored. No parameter was added, removed or renamed. Clients that send only the documented parameters are unaffected.

Released: August 2026

  • Retail price on SKUs: POST /api/v1/skus now returns retail_price, the current Shopify selling price in your store’s default currency. It is the same value already returned as retail_price on purchase-order lines, so a SKU export and an order export now agree without a join. A number at SKU and SKU_LOCATION, and a {min, max} object at PRODUCT covering the product’s SKUs — the same shape days_on_hand uses there.
  • The field is omitted for a SKU Prediko holds no price for in your store’s default currency — raw materials, typically. Purchase-order lines differ here: they report 0 in that case rather than dropping the field.
  • retail_price is the live catalogue price, not the price captured on any past date. That is true of the purchase-order line field too: a line’s retail_price reflects today’s selling price for that SKU, not the price when the order was placed. Prediko does not currently expose historical price-at-date.
  • The field is additive — no existing field changed name, type or meaning. Clients that ignore unknown fields are unaffected.

Released: August 2026

The MCP surface versions independently of the REST endpoints above; these changes are listed here because they are customer-visible.

  • Reorder status is now writable. update_sku_settings takes re_order_status (boolean) in a SKU patch — the app’s Reorder Yes/No column. It was already readable as a metric and filter on search_inventory. status (active / discontinued) is the deprecated spelling of the same field and still works; passing both in one patch is rejected.
  • Reorder status at product granularity. search_inventory with granularity: "product" now returns re_order_status as a {yes, no} count of the product’s SKUs instead of rejecting the metric. It stays a boolean at sku and sku_warehouse granularity.
  • Setting re_order_status: true on a bundle SKU is now rejected. Prediko always excludes bundles from re-order planning, so the call previously succeeded and changed nothing. Set it on the bundle’s component SKUs instead.
  • update_sku_settings silently skipped bundle and archived SKUs: they resolved as valid but then matched nothing on the write, so a batch containing them reported every SKU as updated while only the others changed.

Released: August 2026

  • GET /api/v1/bundles - List bundles and the SKUs each one is composed of
  • Bundles: Pull the bundles (kits) configured for your account, each with the list of child SKU names it’s made up of. Useful for reconciling sales/forecast data at the component level when a customer buys a bundle.
  • ABC category on SKUs: POST /api/v1/skus now returns abc_category, the ABC classification Prediko computes for each SKU from your ABC settings. Available at every aggregation_level — a string at SKU and SKU_LOCATION (null when the SKU is unclassified or ABC is not configured), and an array of the distinct categories across a product’s SKUs at PRODUCT. Category names come from your ABC settings, so treat the value as a string rather than a fixed A/B/C enum.
  • Per-line cost on purchase orders: POST /api/v1/orders lines now accept an optional unit_cost, expressed in the supplier’s currency. Previously a cost sent in the payload was silently dropped, so there was no way to set a PO line’s cost through this endpoint.
  • Cost fields sent on POST /api/v1/orders lines (cost, unit_cost, unit_cost_supplier) were accepted with a 200 and then discarded, never reaching the purchase order. Send unit_cost to set a line’s cost; the other two names are still ignored.
  • abc_category and unit_cost are both additive — no existing field changed name, type or meaning. Clients that ignore unknown fields are unaffected.
  • Cost resolution on PO lines is unchanged when unit_cost is omitted: Prediko still resolves the SKU’s supplier-specific cost for that line’s supplier, falling back to the SKU’s generic unit cost. Only send unit_cost to override what Prediko already holds. A negative unit_cost is rejected with 422; 0 is kept as a real cost (free samples) rather than treated as unset.

Released: July 2026

  • PATCH /api/v1/skus - Update attributes on up to 200 SKUs per call
  • SKU updates: Set a SKU’s reorder status (patch.re_order_status) — true (Yes) makes it replenishable and included in reorder recommendations, false (No) excludes it from replenishment. This is the writable counterpart of the re_order_status field already returned by POST /api/v1/skus.
  • Extensible patch body: the endpoint takes a patch object rather than a per-attribute URL, so further SKU attributes (lead time, MOQ, minimum/maximum days on hand) will be added as additional patch fields without a new endpoint or a breaking change.
  • POST /api/v1/transactions now takes store_name instead of store_id. Store names are what you see in Prediko, so no internal identifier is needed. Matching ignores case and surrounding whitespace — URL-encode names containing spaces.
  • store_id on POST /api/v1/transactions. It is still accepted so existing integrations keep working, but it will be removed in a future version. Supply either store_name or store_id, not both — sending both returns 422.
  • An unrecognised store is now rejected with 422, listing the store names available on your account. Previously an incorrect store_id returned 200 and the transactions were recorded against a store that did not exist, so they never appeared in Prediko.
  • Transaction dates: timestamp values on the 1st-12th of a month were being recorded in the wrong month — the day and month were transposed, so 2026-12-03 (3 December) was stored as 12 March. Dates from the 13th onward were unaffected. ISO 8601 timestamps are now recorded exactly as sent.
  • A timestamp that is not a valid ISO 8601 datetime is now rejected with 422 rather than being interpreted as a best guess.
  • This is a behaviour change for anyone currently sending an invalid store_id: those requests returned 200 before and now return 422. The data was not being recorded in either case.
  • Bundle SKUs cannot be given a reorder status of true — they are replenished through their components — and return 422.
  • Setting re_order_status to false also dismisses stock-health alerts for those SKUs; re-enabling does not restore previously dismissed alerts.
  • POST /api/v1/skus serves from a planning dashboard rebuilt by a queued refresh, so it can report the previous value for several minutes after a write. Treat the 200 from PATCH /api/v1/skus as the confirmation.

Released: June 2026

  • SKUs: Added period sales metrics as default response fields across all aggregation levels (SKU, SKU_LOCATION, PRODUCT). For each weekly / monthly / quarterly / yearly window: *_quantity (units sold, historical), *_plan_quantity (forecast unit sales plan), *_sales (sales revenue, historical), and *_plan_sales (forecast sales revenue plan) — 16 columns in total. This lets API consumers pull historical units sold and the sales plan (e.g. past/next 3 months) programmatically.

Released: April 2026

  • Deliveries: Each line now exposes order_id, created_at, and a stable 10-character shipment_id (hash of order_id + the created_at calendar day). Lines from the same order recorded on the same created_at day share the same shipment_id. The created_after / created_before filters now accept ISO 8601 datetimes and apply on the new created_at field.

Released: April 2026

  • GET /api/v1/orders/delivery - List deliveries (stock arrivals) across all orders with optional date filtering

Released: March 2026

  • GET /api/v1/bill-of-materials - List BOM recipes for all finished goods (JSON or Excel format)
  • GET /api/v1/orders/{id}/consumption - Get raw material consumption per production order
  • PUT /api/v1/orders/{id}/consumption - Update actual consumption quantities for yield/waste tracking
  • Bill of Materials: Pull BOM recipes showing which raw materials compose each finished good and in what quantities. Supports JSON (paginated) and Excel export formats
  • Production Consumption: Query raw material quantities planned and consumed per production order, with automatic variance calculation for yield/waste tracking
  • Variance Tracking: Computed quantity_variance field on consumption data (positive = loss, negative = better yield)

Released: March 2026

  • SKUs: Added RE_ORDER_STATUS (re-order status), supplier_name, RECOMMENDED_UNITS_TO_ORDER, and lead_time_to as default response fields across all aggregation levels
  • SKUs: Added PRODUCT aggregation level to retrieve inventory data aggregated by product

Released: January 2025

Initial release of the Prediko Public API.

  • GET /api/v1/orders - List orders
  • GET /api/v1/orders/{id} - Get order details
  • POST /api/v1/orders - Create or update orders
  • PATCH /api/v1/orders/status - Update order status
  • DELETE /api/v1/orders/{id} - Delete order
  • POST /api/v1/skus - List SKUs (paginated)
  • GET /api/v1/suppliers - List suppliers
  • GET /api/v1/warehouses - List warehouses
  • Orders: order_types filter includes FINISHED_GOOD, RAW_MATERIAL, and PRODUCTION_ORDER options
  • Orders: aggregation_level parameter supports SKU (aggregated) and SKU_LOCATION (by warehouse)
  • SKUs: aggregation_level parameter supports SKU (aggregated, default) and SKU_LOCATION (by warehouse)
  • Pagination: Only the SKUs endpoint is paginated (max 5000 results per page)